mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
Merge tag 'drm-intel-next-2025-02-24' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
drm/i915 feature pull for v6.15: Features and functionality: - Enable DP 128b/132b SST DSC (Jani, Imre) - Allow DSB to perform commits when VRR is enabled (Ville) - Compute HDMI PLLs for SNPS/C10 PHYs for rates not in fixed tables (Ankit) - Allow DSB usage when PSR is enabled on LNL+ (Jouni) - Enable Panel Replay mode change without full modeset (Jouni) - Enable async flips with compressed buffers on ICL+ (Ville) - Support luminance based brightness control via DPCD for eDP (Suraj) - Enable VRR enable/disable without full modeset (Mitul, Ankit) - Add debugfs facility for force testing HDCP 1.4 (Suraj) - Add scaler tracepoints, improve plane tracepoints (Ville) - Improve DMC wakelock debugging facilities (Gustavo) - Allow GuC SLPC default strategies on MTL+ for performance (Rodrigo) - Provide more information on display faults (Ville) Refactoring and cleanups: - Continue conversions to struct intel_display (Ville, Jani, Suraj, Imre) - Joiner and Y plane reorganization (Ville) - Move HDCP debugfs to intel_hdcp.c (Jani) - Clean up and unify LSPCON interfaces (Jani) - Move code out of intel_display.c to reduce its size (Ville) - Clean up and simplify DDI port enabling/disabling (Imre) - Make LPT LP a dedicated PCH type, refactor (Jani) - Simplify DSC range BPG offset calculation (Ankit) - Scaler cleanups (Ville) - Remove unused code from GVT (David Alan Gilbert) - Improve plane debugging (Ville) - DSB and VRR refactoring (Ville) Fixes: - Check if vblank is sufficient for DSC prefill and scaler (Mitul) - Fix Mesa clear color alignment regression (Ville) - Add missing TC DP PHY lane stagger delay (Imre) - Fix DSB + VRR usage for PTL+ (Ville) - Improve robustness of display VT-d workarounds (Ville) - Fix platforms for dbuf tracker state service programming (Ravi) - Fix DMC wakelock support conditions (Gustavo) - Amend DMC wakelock register ranges (Gustavo) - Disable the Common Primary Timing Generator (CMTG) (Gustavo) - Enable C20 PHY SSC (Suraj) - Add workaround for DKL PHY DP mode write (Nemesa) - Fix build warnings on clamp() usage (Guenter Roeck, Ankit) - Fix error handling while adding a connector (Imre) - Avoid full modeset at probe on vblank delay mismatches (Ville) - Fix encoder HDMI check for HDCP line rekeying (Suraj) - Fix HDCP repeater authentication during topology change (Suraj) - Handle display PHY power state reset for power savings (Mika) - Fix typos all over the place (Nitin) - Update HDMI TMDS C20 parameters for various platforms (Dnyaneshwar) - Guarantee a minimum hblank time for 128b/132b and 8b/10b MST (Arun, Imre) - Do not hardcode LSPCON settle timeout (Giedrius Statkevičius) Xe driver changes: - Re-use display vmas when possible (Maarten) - Remove double pageflip (Maarten) - Enable DP tunneling (Imre) - Separate i915 and xe tracepoints (Ville) DRM core changes: - Increase DPCD eDP display control CAP size to 5 bytes (Suraj) - Add DPCD eDP version 1.5 definition (Suraj) - Add timeout parameter to drm_lspcon_set_mode() (Giedrius Statkevičius) Merges: - Backmerge drm-next (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87h64j7b7n.fsf@intel.com
This commit is contained in:
commit
16893dd23f
|
|
@ -11635,7 +11635,7 @@ F: drivers/gpio/gpio-tangier.c
|
|||
F: drivers/gpio/gpio-tangier.h
|
||||
|
||||
INTEL GVT-g DRIVERS (Intel GPU Virtualization)
|
||||
M: Zhenyu Wang <zhenyuw@linux.intel.com>
|
||||
M: Zhenyu Wang <zhenyuw.linux@gmail.com>
|
||||
M: Zhi Wang <zhi.wang.linux@gmail.com>
|
||||
L: intel-gvt-dev@lists.freedesktop.org
|
||||
L: intel-gfx@lists.freedesktop.org
|
||||
|
|
|
|||
|
|
@ -486,16 +486,16 @@ EXPORT_SYMBOL(drm_lspcon_get_mode);
|
|||
* @dev: &drm_device to use
|
||||
* @adapter: I2C-over-aux adapter
|
||||
* @mode: required mode of operation
|
||||
* @time_out: LSPCON mode change settle timeout
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, -error on failure/timeout
|
||||
*/
|
||||
int drm_lspcon_set_mode(const struct drm_device *dev, struct i2c_adapter *adapter,
|
||||
enum drm_lspcon_mode mode)
|
||||
enum drm_lspcon_mode mode, int time_out)
|
||||
{
|
||||
u8 data = 0;
|
||||
int ret;
|
||||
int time_out = 200;
|
||||
enum drm_lspcon_mode current_mode;
|
||||
|
||||
if (mode == DRM_LSPCON_MODE_PCON)
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ i915-y += \
|
|||
display/intel_bo.o \
|
||||
display/intel_bw.o \
|
||||
display/intel_cdclk.o \
|
||||
display/intel_cmtg.o \
|
||||
display/intel_color.o \
|
||||
display/intel_combo_phy.o \
|
||||
display/intel_connector.o \
|
||||
|
|
@ -346,6 +347,7 @@ i915-y += \
|
|||
display/intel_pps.o \
|
||||
display/intel_qp_tables.o \
|
||||
display/intel_sdvo.o \
|
||||
display/intel_snps_hdmi_pll.o \
|
||||
display/intel_snps_phy.o \
|
||||
display/intel_tv.o \
|
||||
display/intel_vdsc.o \
|
||||
|
|
|
|||
|
|
@ -517,7 +517,7 @@ static enum drm_connector_status ns2501_detect(struct intel_dvo_device *dvo)
|
|||
* Even if not, the detection bit of the 2501 is unreliable as
|
||||
* it only works for some display types.
|
||||
* It is even more unreliable as the PLL must be active for
|
||||
* allowing reading from the chiop.
|
||||
* allowing reading from the chip.
|
||||
*/
|
||||
return connector_status_connected;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,28 +51,29 @@ static const struct dpll chv_dpll[] = {
|
|||
{ .dot = 270000, .p1 = 4, .p2 = 1, .n = 1, .m1 = 2, .m2 = 0x6c00000 /* 27.0 */ },
|
||||
};
|
||||
|
||||
const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
|
||||
const struct dpll *vlv_get_dpll(struct intel_display *display)
|
||||
{
|
||||
return IS_CHERRYVIEW(i915) ? &chv_dpll[0] : &vlv_dpll[0];
|
||||
return display->platform.cherryview ? &chv_dpll[0] : &vlv_dpll[0];
|
||||
}
|
||||
|
||||
static void g4x_dp_set_clock(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
const struct dpll *divisor = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
if (IS_G4X(dev_priv)) {
|
||||
if (display->platform.g4x) {
|
||||
divisor = g4x_dpll;
|
||||
count = ARRAY_SIZE(g4x_dpll);
|
||||
} else if (HAS_PCH_SPLIT(dev_priv)) {
|
||||
divisor = pch_dpll;
|
||||
count = ARRAY_SIZE(pch_dpll);
|
||||
} else if (IS_CHERRYVIEW(dev_priv)) {
|
||||
} else if (display->platform.cherryview) {
|
||||
divisor = chv_dpll;
|
||||
count = ARRAY_SIZE(chv_dpll);
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
} else if (display->platform.valleyview) {
|
||||
divisor = vlv_dpll;
|
||||
count = ARRAY_SIZE(vlv_dpll);
|
||||
}
|
||||
|
|
@ -129,7 +130,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
|
|||
|
||||
/* Split out the IBX/CPU vs CPT settings */
|
||||
|
||||
if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
|
||||
if (display->platform.ivybridge && port == PORT_A) {
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
intel_dp->DP |= DP_SYNC_HS_HIGH;
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
|
||||
|
|
@ -148,7 +149,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
|
|||
pipe_config->enhanced_framing ?
|
||||
TRANS_DP_ENH_FRAMING : 0);
|
||||
} else {
|
||||
if (IS_G4X(dev_priv) && pipe_config->limited_color_range)
|
||||
if (display->platform.g4x && pipe_config->limited_color_range)
|
||||
intel_dp->DP |= DP_COLOR_RANGE_16_235;
|
||||
|
||||
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
|
||||
|
|
@ -160,7 +161,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
|
|||
if (pipe_config->enhanced_framing)
|
||||
intel_dp->DP |= DP_ENHANCED_FRAMING;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe);
|
||||
else
|
||||
intel_dp->DP |= DP_PIPE_SEL(crtc->pipe);
|
||||
|
|
@ -180,9 +181,8 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state)
|
|||
}
|
||||
#define assert_dp_port_disabled(d) assert_dp_port((d), false)
|
||||
|
||||
static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
|
||||
static void assert_edp_pll(struct intel_display *display, bool state)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
bool cur_state = intel_de_read(display, DP_A) & DP_PLL_ENABLE;
|
||||
|
||||
INTEL_DISPLAY_STATE_WARN(display, cur_state != state,
|
||||
|
|
@ -197,11 +197,10 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
|
||||
assert_transcoder_disabled(dev_priv, pipe_config->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, pipe_config->cpu_transcoder);
|
||||
assert_dp_port_disabled(intel_dp);
|
||||
assert_edp_pll_disabled(dev_priv);
|
||||
assert_edp_pll_disabled(display);
|
||||
|
||||
drm_dbg_kms(display->drm, "enabling eDP PLL for clock %d\n",
|
||||
pipe_config->port_clock);
|
||||
|
|
@ -223,8 +222,8 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp,
|
|||
* 1. Wait for the start of vertical blank on the enabled pipe going to FDI
|
||||
* 2. Program DP PLL enable
|
||||
*/
|
||||
if (IS_IRONLAKE(dev_priv))
|
||||
intel_wait_for_vblank_if_active(dev_priv, !crtc->pipe);
|
||||
if (display->platform.ironlake)
|
||||
intel_wait_for_vblank_if_active(display, !crtc->pipe);
|
||||
|
||||
intel_dp->DP |= DP_PLL_ENABLE;
|
||||
|
||||
|
|
@ -237,12 +236,10 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp,
|
|||
const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
|
||||
assert_transcoder_disabled(dev_priv, old_crtc_state->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, old_crtc_state->cpu_transcoder);
|
||||
assert_dp_port_disabled(intel_dp);
|
||||
assert_edp_pll_enabled(dev_priv);
|
||||
assert_edp_pll_enabled(display);
|
||||
|
||||
drm_dbg_kms(display->drm, "disabling eDP PLL\n");
|
||||
|
||||
|
|
@ -253,10 +250,9 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp,
|
|||
udelay(200);
|
||||
}
|
||||
|
||||
static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
|
||||
static bool cpt_dp_port_selected(struct intel_display *display,
|
||||
enum port port, enum pipe *pipe)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
enum pipe p;
|
||||
|
||||
for_each_pipe(display, p) {
|
||||
|
|
@ -277,11 +273,11 @@ static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
||||
bool g4x_dp_port_enabled(struct intel_display *display,
|
||||
i915_reg_t dp_reg, enum port port,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
bool ret;
|
||||
u32 val;
|
||||
|
||||
|
|
@ -290,11 +286,11 @@ bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
|||
ret = val & DP_PORT_EN;
|
||||
|
||||
/* asserts want to know the pipe even if the port is disabled */
|
||||
if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
|
||||
if (display->platform.ivybridge && port == PORT_A)
|
||||
*pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
|
||||
else if (HAS_PCH_CPT(dev_priv) && port != PORT_A)
|
||||
ret &= cpt_dp_port_selected(dev_priv, port, pipe);
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
ret &= cpt_dp_port_selected(display, port, pipe);
|
||||
else if (display->platform.cherryview)
|
||||
*pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
|
||||
else
|
||||
*pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
|
||||
|
|
@ -305,20 +301,20 @@ bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
|||
static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
wakeref = intel_display_power_get_if_enabled(display,
|
||||
encoder->power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
ret = g4x_dp_port_enabled(dev_priv, intel_dp->output_reg,
|
||||
ret = g4x_dp_port_enabled(display, intel_dp->output_reg,
|
||||
encoder->port, pipe);
|
||||
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -390,7 +386,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
|
|||
|
||||
pipe_config->hw.adjusted_mode.flags |= flags;
|
||||
|
||||
if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
|
||||
if (display->platform.g4x && tmp & DP_COLOR_RANGE_16_235)
|
||||
pipe_config->limited_color_range = true;
|
||||
|
||||
pipe_config->lane_count =
|
||||
|
|
@ -432,7 +428,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
|
|||
|
||||
drm_dbg_kms(display->drm, "\n");
|
||||
|
||||
if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
|
||||
if ((display->platform.ivybridge && port == PORT_A) ||
|
||||
(HAS_PCH_CPT(dev_priv) && port != PORT_A)) {
|
||||
intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT;
|
||||
intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT;
|
||||
|
|
@ -457,8 +453,8 @@ intel_dp_link_down(struct intel_encoder *encoder,
|
|||
* We get CPU/PCH FIFO underruns on the other pipe when
|
||||
* doing the workaround. Sweep them under the rug.
|
||||
*/
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
|
||||
/* always enable with pattern 1 (as per spec) */
|
||||
intel_dp->DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK);
|
||||
|
|
@ -471,14 +467,14 @@ intel_dp_link_down(struct intel_encoder *encoder,
|
|||
intel_de_write(display, intel_dp->output_reg, intel_dp->DP);
|
||||
intel_de_posting_read(display, intel_dp->output_reg);
|
||||
|
||||
intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_wait_for_vblank_if_active(display, PIPE_A);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
}
|
||||
|
||||
msleep(intel_dp->pps.panel_power_down_delay);
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
vlv_pps_port_disable(encoder, old_crtc_state);
|
||||
}
|
||||
|
||||
|
|
@ -681,7 +677,6 @@ static void intel_enable_dp(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
u32 dp_reg = intel_de_read(display, intel_dp->output_reg);
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -690,7 +685,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
|
|||
return;
|
||||
|
||||
with_intel_pps_lock(intel_dp, wakeref) {
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
vlv_pps_port_enable_unlocked(encoder, pipe_config);
|
||||
|
||||
intel_dp_enable_port(intel_dp, pipe_config);
|
||||
|
|
@ -700,13 +695,13 @@ static void intel_enable_dp(struct intel_atomic_state *state,
|
|||
intel_pps_vdd_off_unlocked(intel_dp, true);
|
||||
}
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
if (display->platform.valleyview || display->platform.cherryview) {
|
||||
unsigned int lane_mask = 0x0;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
lane_mask = intel_dp_unused_lane_mask(pipe_config->lane_count);
|
||||
|
||||
vlv_wait_port_ready(display, dp_to_dig_port(intel_dp), lane_mask);
|
||||
vlv_wait_port_ready(encoder, lane_mask);
|
||||
}
|
||||
|
||||
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
|
||||
|
|
@ -1263,7 +1258,6 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
|
|||
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder->dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
|
||||
|
||||
intel_dp->DP = intel_de_read(display, intel_dp->output_reg);
|
||||
|
|
@ -1271,7 +1265,7 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
|||
intel_dp->reset_link_params = true;
|
||||
intel_dp_invalidate_source_oui(intel_dp);
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
vlv_pps_pipe_reset(intel_dp);
|
||||
|
||||
intel_pps_encoder_reset(intel_dp);
|
||||
|
|
@ -1282,17 +1276,17 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
|
|||
.destroy = intel_dp_encoder_destroy,
|
||||
};
|
||||
|
||||
bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
bool g4x_dp_init(struct intel_display *display,
|
||||
i915_reg_t output_reg, enum port port)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
struct intel_digital_port *dig_port;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct drm_encoder *encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
if (!assert_port_valid(display, port))
|
||||
return false;
|
||||
|
||||
devdata = intel_bios_encoder_data_lookup(display, port);
|
||||
|
|
@ -1336,14 +1330,14 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
|||
intel_encoder->suspend = intel_dp_encoder_suspend;
|
||||
intel_encoder->suspend_complete = g4x_dp_suspend_complete;
|
||||
intel_encoder->shutdown = intel_dp_encoder_shutdown;
|
||||
if (IS_CHERRYVIEW(dev_priv)) {
|
||||
if (display->platform.cherryview) {
|
||||
intel_encoder->pre_pll_enable = chv_dp_pre_pll_enable;
|
||||
intel_encoder->pre_enable = chv_pre_enable_dp;
|
||||
intel_encoder->enable = vlv_enable_dp;
|
||||
intel_encoder->disable = vlv_disable_dp;
|
||||
intel_encoder->post_disable = chv_post_disable_dp;
|
||||
intel_encoder->post_pll_disable = chv_dp_post_pll_disable;
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
} else if (display->platform.valleyview) {
|
||||
intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
|
||||
intel_encoder->pre_enable = vlv_pre_enable_dp;
|
||||
intel_encoder->enable = vlv_enable_dp;
|
||||
|
|
@ -1358,24 +1352,24 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
|||
intel_encoder->audio_enable = g4x_dp_audio_enable;
|
||||
intel_encoder->audio_disable = g4x_dp_audio_disable;
|
||||
|
||||
if ((IS_IVYBRIDGE(dev_priv) && port == PORT_A) ||
|
||||
if ((display->platform.ivybridge && port == PORT_A) ||
|
||||
(HAS_PCH_CPT(dev_priv) && port != PORT_A))
|
||||
dig_port->dp.set_link_train = cpt_set_link_train;
|
||||
else
|
||||
dig_port->dp.set_link_train = g4x_set_link_train;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
intel_encoder->set_signal_levels = chv_set_signal_levels;
|
||||
else if (IS_VALLEYVIEW(dev_priv))
|
||||
else if (display->platform.valleyview)
|
||||
intel_encoder->set_signal_levels = vlv_set_signal_levels;
|
||||
else if (IS_IVYBRIDGE(dev_priv) && port == PORT_A)
|
||||
else if (display->platform.ivybridge && port == PORT_A)
|
||||
intel_encoder->set_signal_levels = ivb_cpu_edp_set_signal_levels;
|
||||
else if (IS_SANDYBRIDGE(dev_priv) && port == PORT_A)
|
||||
else if (display->platform.sandybridge && port == PORT_A)
|
||||
intel_encoder->set_signal_levels = snb_cpu_edp_set_signal_levels;
|
||||
else
|
||||
intel_encoder->set_signal_levels = g4x_set_signal_levels;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv) ||
|
||||
if (display->platform.valleyview || display->platform.cherryview ||
|
||||
(HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) {
|
||||
dig_port->dp.preemph_max = intel_dp_preemph_max_3;
|
||||
dig_port->dp.voltage_max = intel_dp_voltage_max_3;
|
||||
|
|
@ -1388,8 +1382,8 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
|||
dig_port->max_lanes = 4;
|
||||
|
||||
intel_encoder->type = INTEL_OUTPUT_DP;
|
||||
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
|
||||
if (IS_CHERRYVIEW(dev_priv)) {
|
||||
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port);
|
||||
if (display->platform.cherryview) {
|
||||
if (port == PORT_D)
|
||||
intel_encoder->pipe_mask = BIT(PIPE_C);
|
||||
else
|
||||
|
|
@ -1399,7 +1393,7 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
intel_encoder->cloneable = 0;
|
||||
intel_encoder->port = port;
|
||||
intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
|
||||
intel_encoder->hpd_pin = intel_hpd_pin_default(port);
|
||||
|
||||
dig_port->hpd_pulse = intel_dp_hpd_pulse;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,30 +12,30 @@
|
|||
|
||||
enum pipe;
|
||||
enum port;
|
||||
struct drm_i915_private;
|
||||
struct intel_crtc_state;
|
||||
struct intel_display;
|
||||
struct intel_dp;
|
||||
struct intel_encoder;
|
||||
|
||||
#ifdef I915
|
||||
const struct dpll *vlv_get_dpll(struct drm_i915_private *i915);
|
||||
bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
||||
const struct dpll *vlv_get_dpll(struct intel_display *display);
|
||||
bool g4x_dp_port_enabled(struct intel_display *display,
|
||||
i915_reg_t dp_reg, enum port port,
|
||||
enum pipe *pipe);
|
||||
bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
bool g4x_dp_init(struct intel_display *display,
|
||||
i915_reg_t output_reg, enum port port);
|
||||
#else
|
||||
static inline const struct dpll *vlv_get_dpll(struct drm_i915_private *i915)
|
||||
static inline const struct dpll *vlv_get_dpll(struct intel_display *display)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static inline bool g4x_dp_port_enabled(struct drm_i915_private *dev_priv,
|
||||
static inline bool g4x_dp_port_enabled(struct intel_display *display,
|
||||
i915_reg_t dp_reg, int port,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline bool g4x_dp_init(struct drm_i915_private *dev_priv,
|
||||
static inline bool g4x_dp_init(struct intel_display *display,
|
||||
i915_reg_t output_reg, int port)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
static void intel_hdmi_prepare(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
|
||||
|
|
@ -54,31 +54,31 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
|
|||
|
||||
if (HAS_PCH_CPT(dev_priv))
|
||||
hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe);
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
else if (display->platform.cherryview)
|
||||
hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe);
|
||||
else
|
||||
hdmi_val |= SDVO_PIPE_SEL(crtc->pipe);
|
||||
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, hdmi_val);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, hdmi_val);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
}
|
||||
|
||||
static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
wakeref = intel_display_power_get_if_enabled(display,
|
||||
encoder->power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);
|
||||
ret = intel_sdvo_port_enabled(display, intel_hdmi->hdmi_reg, pipe);
|
||||
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -131,6 +131,7 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
|
|||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
|
|
@ -141,7 +142,7 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_G4X(i915))
|
||||
if (display->platform.g4x)
|
||||
crtc_state->has_hdmi_sink = g4x_compute_has_hdmi_sink(state, crtc);
|
||||
else
|
||||
crtc_state->has_hdmi_sink =
|
||||
|
|
@ -153,15 +154,15 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder,
|
|||
static void intel_hdmi_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
u32 tmp, flags = 0;
|
||||
int dotclock;
|
||||
|
||||
pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
|
||||
|
||||
tmp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
tmp = intel_de_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
if (tmp & SDVO_HSYNC_ACTIVE_HIGH)
|
||||
flags |= DRM_MODE_FLAG_PHSYNC;
|
||||
|
|
@ -221,33 +222,32 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
|
|||
static void g4x_hdmi_enable_port(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *pipe_config)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
u32 temp;
|
||||
|
||||
temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
temp = intel_de_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
temp |= SDVO_ENABLE;
|
||||
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
}
|
||||
|
||||
static void g4x_hdmi_audio_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);
|
||||
|
||||
if (!crtc_state->has_audio)
|
||||
return;
|
||||
|
||||
drm_WARN_ON(&i915->drm, !crtc_state->has_hdmi_sink);
|
||||
drm_WARN_ON(display->drm, !crtc_state->has_hdmi_sink);
|
||||
|
||||
/* Enable audio presence detect */
|
||||
intel_de_rmw(i915, hdmi->hdmi_reg, 0, HDMI_AUDIO_ENABLE);
|
||||
intel_de_rmw(display, hdmi->hdmi_reg, 0, HDMI_AUDIO_ENABLE);
|
||||
|
||||
intel_audio_codec_enable(encoder, crtc_state, conn_state);
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ static void g4x_hdmi_audio_disable(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder);
|
||||
|
||||
if (!old_crtc_state->has_audio)
|
||||
|
|
@ -265,7 +265,7 @@ static void g4x_hdmi_audio_disable(struct intel_encoder *encoder,
|
|||
intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
|
||||
|
||||
/* Disable audio presence detect */
|
||||
intel_de_rmw(i915, hdmi->hdmi_reg, HDMI_AUDIO_ENABLE, 0);
|
||||
intel_de_rmw(display, hdmi->hdmi_reg, HDMI_AUDIO_ENABLE, 0);
|
||||
}
|
||||
|
||||
static void g4x_enable_hdmi(struct intel_atomic_state *state,
|
||||
|
|
@ -281,12 +281,11 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
u32 temp;
|
||||
|
||||
temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
temp = intel_de_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
temp |= SDVO_ENABLE;
|
||||
|
||||
|
|
@ -294,10 +293,10 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state,
|
|||
* HW workaround, need to write this twice for issue
|
||||
* that may result in first write getting masked.
|
||||
*/
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
/*
|
||||
* HW workaround, need to toggle enable bit off and on
|
||||
|
|
@ -308,18 +307,18 @@ static void ibx_enable_hdmi(struct intel_atomic_state *state,
|
|||
*/
|
||||
if (pipe_config->pipe_bpp > 24 &&
|
||||
pipe_config->pixel_multiplier > 1) {
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg,
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg,
|
||||
temp & ~SDVO_ENABLE);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
/*
|
||||
* HW workaround, need to write this twice for issue
|
||||
* that may result in first write getting masked.
|
||||
*/
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -328,14 +327,13 @@ static void cpt_enable_hdmi(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 temp;
|
||||
|
||||
temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
temp = intel_de_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
temp |= SDVO_ENABLE;
|
||||
|
||||
|
|
@ -350,24 +348,24 @@ static void cpt_enable_hdmi(struct intel_atomic_state *state,
|
|||
*/
|
||||
|
||||
if (pipe_config->pipe_bpp > 24) {
|
||||
intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
|
||||
intel_de_rmw(display, TRANS_CHICKEN1(pipe),
|
||||
0, TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE);
|
||||
|
||||
temp &= ~SDVO_COLOR_FORMAT_MASK;
|
||||
temp |= SDVO_COLOR_FORMAT_8bpc;
|
||||
}
|
||||
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
if (pipe_config->pipe_bpp > 24) {
|
||||
temp &= ~SDVO_COLOR_FORMAT_MASK;
|
||||
temp |= HDMI_COLOR_FORMAT_12bpc;
|
||||
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
intel_de_rmw(dev_priv, TRANS_CHICKEN1(pipe),
|
||||
intel_de_rmw(display, TRANS_CHICKEN1(pipe),
|
||||
TRANS_CHICKEN1_HDMIUNIT_GC_DISABLE, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -384,19 +382,19 @@ static void intel_disable_hdmi(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
|
||||
struct intel_digital_port *dig_port =
|
||||
hdmi_to_dig_port(intel_hdmi);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
u32 temp;
|
||||
|
||||
temp = intel_de_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
temp = intel_de_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
temp &= ~SDVO_ENABLE;
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
/*
|
||||
* HW workaround for IBX, we need to move the port
|
||||
|
|
@ -408,8 +406,8 @@ static void intel_disable_hdmi(struct intel_atomic_state *state,
|
|||
* We get CPU/PCH FIFO underruns on the other pipe when
|
||||
* doing the workaround. Sweep them under the rug.
|
||||
*/
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
|
||||
temp &= ~SDVO_PIPE_SEL_MASK;
|
||||
temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
|
||||
|
|
@ -417,18 +415,18 @@ static void intel_disable_hdmi(struct intel_atomic_state *state,
|
|||
* HW workaround, need to write this twice for issue
|
||||
* that may result in first write getting masked.
|
||||
*/
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
temp &= ~SDVO_ENABLE;
|
||||
intel_de_write(dev_priv, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(dev_priv, intel_hdmi->hdmi_reg);
|
||||
intel_de_write(display, intel_hdmi->hdmi_reg, temp);
|
||||
intel_de_posting_read(display, intel_hdmi->hdmi_reg);
|
||||
|
||||
intel_wait_for_vblank_if_active(dev_priv, PIPE_A);
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_wait_for_vblank_if_active(display, PIPE_A);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
}
|
||||
|
||||
dig_port->set_infoframes(encoder,
|
||||
|
|
@ -481,7 +479,6 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
|
||||
vlv_phy_pre_encoder_enable(encoder, pipe_config);
|
||||
|
|
@ -497,7 +494,7 @@ static void vlv_hdmi_pre_enable(struct intel_atomic_state *state,
|
|||
|
||||
g4x_hdmi_enable_port(encoder, pipe_config);
|
||||
|
||||
vlv_wait_port_ready(display, dig_port, 0x0);
|
||||
vlv_wait_port_ready(encoder, 0x0);
|
||||
}
|
||||
|
||||
static void vlv_hdmi_pre_pll_enable(struct intel_atomic_state *state,
|
||||
|
|
@ -542,8 +539,8 @@ static void chv_hdmi_post_disable(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
|
||||
|
|
@ -558,7 +555,6 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
|
||||
chv_phy_pre_encoder_enable(encoder, pipe_config);
|
||||
|
|
@ -573,7 +569,7 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
|
|||
|
||||
g4x_hdmi_enable_port(encoder, pipe_config);
|
||||
|
||||
vlv_wait_port_ready(display, dig_port, 0x0);
|
||||
vlv_wait_port_ready(encoder, 0x0);
|
||||
|
||||
/* Second common lane will stay alive on its own now */
|
||||
chv_phy_release_cl2_override(encoder);
|
||||
|
|
@ -612,7 +608,7 @@ intel_hdmi_hotplug(struct intel_encoder *encoder,
|
|||
int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->dev);
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_connector *conn;
|
||||
int ret;
|
||||
|
|
@ -621,7 +617,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!IS_G4X(i915))
|
||||
if (!display->platform.g4x)
|
||||
return 0;
|
||||
|
||||
if (!intel_connector_needs_modeset(to_intel_atomic_state(state), connector))
|
||||
|
|
@ -635,7 +631,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
|||
*
|
||||
* See also g4x_compute_has_hdmi_sink().
|
||||
*/
|
||||
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
|
||||
drm_connector_list_iter_begin(display->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
|
@ -644,7 +640,7 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
|||
if (!connector_is_hdmi(conn))
|
||||
continue;
|
||||
|
||||
drm_dbg_kms(&i915->drm, "Adding [CONNECTOR:%d:%s]\n",
|
||||
drm_dbg_kms(display->drm, "Adding [CONNECTOR:%d:%s]\n",
|
||||
conn->base.id, conn->name);
|
||||
|
||||
conn_state = drm_atomic_get_connector_state(state, conn);
|
||||
|
|
@ -669,40 +665,40 @@ int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool is_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
static bool is_hdmi_port_valid(struct intel_display *display, enum port port)
|
||||
{
|
||||
if (IS_G4X(i915) || IS_VALLEYVIEW(i915))
|
||||
if (display->platform.g4x || display->platform.valleyview)
|
||||
return port == PORT_B || port == PORT_C;
|
||||
else
|
||||
return port == PORT_B || port == PORT_C || port == PORT_D;
|
||||
}
|
||||
|
||||
static bool assert_hdmi_port_valid(struct drm_i915_private *i915, enum port port)
|
||||
static bool assert_hdmi_port_valid(struct intel_display *display, enum port port)
|
||||
{
|
||||
return !drm_WARN(&i915->drm, !is_hdmi_port_valid(i915, port),
|
||||
return !drm_WARN(display->drm, !is_hdmi_port_valid(display, port),
|
||||
"Platform does not support HDMI %c\n", port_name(port));
|
||||
}
|
||||
|
||||
bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
bool g4x_hdmi_init(struct intel_display *display,
|
||||
i915_reg_t hdmi_reg, enum port port)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
const struct intel_bios_encoder_data *devdata;
|
||||
struct intel_digital_port *dig_port;
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_connector *intel_connector;
|
||||
|
||||
if (!assert_port_valid(dev_priv, port))
|
||||
if (!assert_port_valid(display, port))
|
||||
return false;
|
||||
|
||||
if (!assert_hdmi_port_valid(dev_priv, port))
|
||||
if (!assert_hdmi_port_valid(display, port))
|
||||
return false;
|
||||
|
||||
devdata = intel_bios_encoder_data_lookup(display, port);
|
||||
|
||||
/* FIXME bail? */
|
||||
if (!devdata)
|
||||
drm_dbg_kms(&dev_priv->drm, "No VBT child device for HDMI-%c\n",
|
||||
drm_dbg_kms(display->drm, "No VBT child device for HDMI-%c\n",
|
||||
port_name(port));
|
||||
|
||||
dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
|
||||
|
|
@ -721,7 +717,7 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
|
||||
mutex_init(&dig_port->hdcp_mutex);
|
||||
|
||||
if (drm_encoder_init(&dev_priv->drm, &intel_encoder->base,
|
||||
if (drm_encoder_init(display->drm, &intel_encoder->base,
|
||||
&intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
|
||||
"HDMI %c", port_name(port)))
|
||||
goto err_encoder_init;
|
||||
|
|
@ -736,13 +732,13 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
|
||||
intel_encoder->get_config = intel_hdmi_get_config;
|
||||
if (IS_CHERRYVIEW(dev_priv)) {
|
||||
if (display->platform.cherryview) {
|
||||
intel_encoder->pre_pll_enable = chv_hdmi_pre_pll_enable;
|
||||
intel_encoder->pre_enable = chv_hdmi_pre_enable;
|
||||
intel_encoder->enable = vlv_enable_hdmi;
|
||||
intel_encoder->post_disable = chv_hdmi_post_disable;
|
||||
intel_encoder->post_pll_disable = chv_hdmi_post_pll_disable;
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
} else if (display->platform.valleyview) {
|
||||
intel_encoder->pre_pll_enable = vlv_hdmi_pre_pll_enable;
|
||||
intel_encoder->pre_enable = vlv_hdmi_pre_enable;
|
||||
intel_encoder->enable = vlv_enable_hdmi;
|
||||
|
|
@ -761,9 +757,9 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
intel_encoder->shutdown = intel_hdmi_encoder_shutdown;
|
||||
|
||||
intel_encoder->type = INTEL_OUTPUT_HDMI;
|
||||
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(dev_priv, port);
|
||||
intel_encoder->power_domain = intel_display_power_ddi_lanes_domain(display, port);
|
||||
intel_encoder->port = port;
|
||||
if (IS_CHERRYVIEW(dev_priv)) {
|
||||
if (display->platform.cherryview) {
|
||||
if (port == PORT_D)
|
||||
intel_encoder->pipe_mask = BIT(PIPE_C);
|
||||
else
|
||||
|
|
@ -772,13 +768,13 @@ bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
|||
intel_encoder->pipe_mask = ~0;
|
||||
}
|
||||
intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);
|
||||
intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
|
||||
intel_encoder->hpd_pin = intel_hpd_pin_default(port);
|
||||
/*
|
||||
* BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
|
||||
* to work on real hardware. And since g4x can send infoframes to
|
||||
* only one port anyway, nothing is lost by allowing it.
|
||||
*/
|
||||
if (IS_G4X(dev_priv))
|
||||
if (display->platform.g4x)
|
||||
intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);
|
||||
|
||||
dig_port->hdmi.hdmi_reg = hdmi_reg;
|
||||
|
|
|
|||
|
|
@ -13,15 +13,15 @@
|
|||
enum port;
|
||||
struct drm_atomic_state;
|
||||
struct drm_connector;
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
|
||||
#ifdef I915
|
||||
bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
bool g4x_hdmi_init(struct intel_display *display,
|
||||
i915_reg_t hdmi_reg, enum port port);
|
||||
int g4x_hdmi_connector_atomic_check(struct drm_connector *connector,
|
||||
struct drm_atomic_state *state);
|
||||
#else
|
||||
static inline bool g4x_hdmi_init(struct drm_i915_private *dev_priv,
|
||||
static inline bool g4x_hdmi_init(struct intel_display *display,
|
||||
i915_reg_t hdmi_reg, int port)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
|
|||
if (display->ips.false_color)
|
||||
val |= IPS_FALSE_COLOR;
|
||||
|
||||
if (IS_BROADWELL(i915)) {
|
||||
if (display->platform.broadwell) {
|
||||
drm_WARN_ON(display->drm,
|
||||
snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL,
|
||||
val | IPS_PCODE_CONTROL));
|
||||
|
|
@ -71,7 +71,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
|
|||
if (!crtc_state->ips_enabled)
|
||||
return need_vblank_wait;
|
||||
|
||||
if (IS_BROADWELL(i915)) {
|
||||
if (display->platform.broadwell) {
|
||||
drm_WARN_ON(display->drm,
|
||||
snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0));
|
||||
/*
|
||||
|
|
@ -96,7 +96,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
|
|||
static bool hsw_ips_need_disable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
|
|
@ -114,7 +114,7 @@ static bool hsw_ips_need_disable(struct intel_atomic_state *state,
|
|||
*
|
||||
* Disable IPS before we program the LUT.
|
||||
*/
|
||||
if (IS_HASWELL(i915) &&
|
||||
if (display->platform.haswell &&
|
||||
intel_crtc_needs_color_update(new_crtc_state) &&
|
||||
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
|
||||
return true;
|
||||
|
|
@ -137,7 +137,7 @@ bool hsw_ips_pre_update(struct intel_atomic_state *state,
|
|||
static bool hsw_ips_need_enable(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
|
|
@ -155,7 +155,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state,
|
|||
*
|
||||
* Re-enable IPS after the LUT has been programmed.
|
||||
*/
|
||||
if (IS_HASWELL(i915) &&
|
||||
if (display->platform.haswell &&
|
||||
intel_crtc_needs_color_update(new_crtc_state) &&
|
||||
new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
|
||||
return true;
|
||||
|
|
@ -194,7 +194,6 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
|
||||
/* IPS only exists on ULT machines and is tied to pipe A. */
|
||||
if (!hsw_crtc_supports_ips(crtc))
|
||||
|
|
@ -213,7 +212,7 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state
|
|||
*
|
||||
* Should measure whether using a lower cdclk w/o IPS
|
||||
*/
|
||||
if (IS_BROADWELL(i915) &&
|
||||
if (display->platform.broadwell &&
|
||||
crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100)
|
||||
return false;
|
||||
|
||||
|
|
@ -222,9 +221,9 @@ static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state
|
|||
|
||||
int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
if (!IS_BROADWELL(i915))
|
||||
if (!display->platform.broadwell)
|
||||
return 0;
|
||||
|
||||
if (!hsw_crtc_state_ips_capable(crtc_state))
|
||||
|
|
@ -237,7 +236,7 @@ int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state)
|
|||
int hsw_ips_compute_config(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
|
|
@ -259,7 +258,7 @@ int hsw_ips_compute_config(struct intel_atomic_state *state,
|
|||
if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
|
||||
return 0;
|
||||
|
||||
if (IS_BROADWELL(i915)) {
|
||||
if (display->platform.broadwell) {
|
||||
const struct intel_cdclk_state *cdclk_state;
|
||||
|
||||
cdclk_state = intel_atomic_get_cdclk_state(state);
|
||||
|
|
@ -280,12 +279,11 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
|
||||
if (!hsw_crtc_supports_ips(crtc))
|
||||
return;
|
||||
|
||||
if (IS_HASWELL(i915)) {
|
||||
if (display->platform.haswell) {
|
||||
crtc_state->ips_enabled = intel_de_read(display, IPS_CTL) & IPS_ENABLE;
|
||||
} else {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -109,42 +109,42 @@ static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
|
|||
}
|
||||
}
|
||||
|
||||
static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv,
|
||||
static bool i9xx_plane_has_fbc(struct intel_display *display,
|
||||
enum i9xx_plane_id i9xx_plane)
|
||||
{
|
||||
if (!HAS_FBC(dev_priv))
|
||||
if (!HAS_FBC(display))
|
||||
return false;
|
||||
|
||||
if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
if (display->platform.broadwell || display->platform.haswell)
|
||||
return i9xx_plane == PLANE_A; /* tied to pipe A */
|
||||
else if (IS_IVYBRIDGE(dev_priv))
|
||||
else if (display->platform.ivybridge)
|
||||
return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
|
||||
i9xx_plane == PLANE_C;
|
||||
else if (DISPLAY_VER(dev_priv) >= 4)
|
||||
else if (DISPLAY_VER(display) >= 4)
|
||||
return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
|
||||
else
|
||||
return i9xx_plane == PLANE_A;
|
||||
}
|
||||
|
||||
static struct intel_fbc *i9xx_plane_fbc(struct drm_i915_private *dev_priv,
|
||||
static struct intel_fbc *i9xx_plane_fbc(struct intel_display *display,
|
||||
enum i9xx_plane_id i9xx_plane)
|
||||
{
|
||||
if (i9xx_plane_has_fbc(dev_priv, i9xx_plane))
|
||||
return dev_priv->display.fbc[INTEL_FBC_A];
|
||||
if (i9xx_plane_has_fbc(display, i9xx_plane))
|
||||
return display->fbc[INTEL_FBC_A];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool i9xx_plane_has_windowing(struct intel_plane *plane)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
return i9xx_plane == PLANE_B;
|
||||
else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
return false;
|
||||
else if (DISPLAY_VER(dev_priv) == 4)
|
||||
else if (DISPLAY_VER(display) == 4)
|
||||
return i9xx_plane == PLANE_C;
|
||||
else
|
||||
return i9xx_plane == PLANE_B ||
|
||||
|
|
@ -154,16 +154,15 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane)
|
|||
static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
u32 dspcntr;
|
||||
|
||||
dspcntr = DISP_ENABLE;
|
||||
|
||||
if (IS_G4X(dev_priv) || IS_IRONLAKE(dev_priv) ||
|
||||
IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
|
||||
if (display->platform.g4x || display->platform.ironlake ||
|
||||
display->platform.sandybridge || display->platform.ivybridge)
|
||||
dspcntr |= DISP_TRICKLE_FEED_DISABLE;
|
||||
|
||||
switch (fb->format->format) {
|
||||
|
|
@ -211,7 +210,7 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4 &&
|
||||
if (DISPLAY_VER(display) >= 4 &&
|
||||
fb->modifier == I915_FORMAT_MOD_X_TILED)
|
||||
dspcntr |= DISP_TILED;
|
||||
|
||||
|
|
@ -226,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
|
|||
|
||||
int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int src_x, src_y, src_w;
|
||||
u32 offset;
|
||||
|
|
@ -245,12 +244,16 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
src_y = plane_state->uapi.src.y1 >> 16;
|
||||
|
||||
/* Undocumented hardware limit on i965/g4x/vlv/chv */
|
||||
if (HAS_GMCH(dev_priv) && fb->format->cpp[0] == 8 && src_w > 2048)
|
||||
if (HAS_GMCH(display) && fb->format->cpp[0] == 8 && src_w > 2048) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] plane too wide (%d) for 64bpp\n",
|
||||
plane->base.base.id, plane->base.name, src_w);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
|
||||
plane_state, 0);
|
||||
else
|
||||
|
|
@ -267,14 +270,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
* Linear surfaces seem to work just fine, even on hsw/bdw
|
||||
* despite them not using the linear offset anymore.
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
|
||||
if (DISPLAY_VER(display) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
|
||||
unsigned int alignment = plane->min_alignment(plane, fb, 0);
|
||||
int cpp = fb->format->cpp[0];
|
||||
|
||||
while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
|
||||
if (offset == 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Unable to find suitable display surface offset due to X-tiling\n");
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -291,7 +295,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
src_x << 16, src_y << 16);
|
||||
|
||||
/* HSW/BDW do this automagically in hardware */
|
||||
if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) {
|
||||
if (!display->platform.haswell && !display->platform.broadwell) {
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
|
||||
int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
|
||||
|
|
@ -304,11 +308,11 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
|
||||
drm_WARN_ON(&dev_priv->drm, src_x > 8191 || src_y > 4095);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4 &&
|
||||
if (display->platform.haswell || display->platform.broadwell) {
|
||||
drm_WARN_ON(display->drm, src_x > 8191 || src_y > 4095);
|
||||
} else if (DISPLAY_VER(display) >= 4 &&
|
||||
fb->modifier == I915_FORMAT_MOD_X_TILED) {
|
||||
drm_WARN_ON(&dev_priv->drm, src_x > 4095 || src_y > 4095);
|
||||
drm_WARN_ON(display->drm, src_x > 4095 || src_y > 4095);
|
||||
}
|
||||
|
||||
plane_state->view.color_plane[0].offset = offset;
|
||||
|
|
@ -354,8 +358,8 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
|
|||
|
||||
static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
u32 dspcntr = 0;
|
||||
|
||||
if (crtc_state->gamma_enable)
|
||||
|
|
@ -364,7 +368,7 @@ static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
|||
if (crtc_state->csc_enable)
|
||||
dspcntr |= DISP_PIPE_CSC_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 5)
|
||||
if (DISPLAY_VER(display) < 5)
|
||||
dspcntr |= DISP_PIPE_SEL(crtc->pipe);
|
||||
|
||||
return dspcntr;
|
||||
|
|
@ -422,13 +426,13 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
intel_de_write_fw(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPSTRIDE(display, i9xx_plane),
|
||||
plane_state->view.color_plane[0].mapping_stride);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 4) {
|
||||
if (DISPLAY_VER(display) < 4) {
|
||||
int crtc_x = plane_state->uapi.dst.x1;
|
||||
int crtc_y = plane_state->uapi.dst.y1;
|
||||
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
|
||||
|
|
@ -439,9 +443,9 @@ static void i9xx_plane_update_noarm(struct intel_dsb *dsb,
|
|||
* generator but let's assume we still need to
|
||||
* program whatever is there.
|
||||
*/
|
||||
intel_de_write_fw(dev_priv, DSPPOS(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPPOS(display, i9xx_plane),
|
||||
DISP_POS_Y(crtc_y) | DISP_POS_X(crtc_x));
|
||||
intel_de_write_fw(dev_priv, DSPSIZE(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPSIZE(display, i9xx_plane),
|
||||
DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -451,7 +455,7 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
int x = plane_state->view.color_plane[0].x;
|
||||
int y = plane_state->view.color_plane[0].y;
|
||||
|
|
@ -466,32 +470,32 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
|
|||
|
||||
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
dspaddr_offset = plane_state->view.color_plane[0].offset;
|
||||
else
|
||||
dspaddr_offset = linear_offset;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
|
||||
if (display->platform.cherryview && i9xx_plane == PLANE_B) {
|
||||
int crtc_x = plane_state->uapi.dst.x1;
|
||||
int crtc_y = plane_state->uapi.dst.y1;
|
||||
int crtc_w = drm_rect_width(&plane_state->uapi.dst);
|
||||
int crtc_h = drm_rect_height(&plane_state->uapi.dst);
|
||||
|
||||
intel_de_write_fw(dev_priv, PRIMPOS(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, PRIMPOS(display, i9xx_plane),
|
||||
PRIM_POS_Y(crtc_y) | PRIM_POS_X(crtc_x));
|
||||
intel_de_write_fw(dev_priv, PRIMSIZE(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, PRIMSIZE(display, i9xx_plane),
|
||||
PRIM_HEIGHT(crtc_h - 1) | PRIM_WIDTH(crtc_w - 1));
|
||||
intel_de_write_fw(dev_priv,
|
||||
PRIMCNSTALPHA(dev_priv, i9xx_plane), 0);
|
||||
intel_de_write_fw(display,
|
||||
PRIMCNSTALPHA(display, i9xx_plane), 0);
|
||||
}
|
||||
|
||||
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
|
||||
intel_de_write_fw(dev_priv, DSPOFFSET(dev_priv, i9xx_plane),
|
||||
if (display->platform.haswell || display->platform.broadwell) {
|
||||
intel_de_write_fw(display, DSPOFFSET(display, i9xx_plane),
|
||||
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
intel_de_write_fw(dev_priv, DSPLINOFF(dev_priv, i9xx_plane),
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
intel_de_write_fw(display, DSPLINOFF(display, i9xx_plane),
|
||||
linear_offset);
|
||||
intel_de_write_fw(dev_priv, DSPTILEOFF(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPTILEOFF(display, i9xx_plane),
|
||||
DISP_OFFSET_Y(y) | DISP_OFFSET_X(x));
|
||||
}
|
||||
|
||||
|
|
@ -500,13 +504,13 @@ static void i9xx_plane_update_arm(struct intel_dsb *dsb,
|
|||
* disabled. Try to make the plane enable atomic by writing
|
||||
* the control register just before the surface register.
|
||||
*/
|
||||
intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
|
||||
intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
|
||||
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
|
||||
else
|
||||
intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPADDR(display, i9xx_plane),
|
||||
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +533,7 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
|
|||
struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
u32 dspcntr;
|
||||
|
||||
|
|
@ -545,12 +549,46 @@ static void i9xx_plane_disable_arm(struct intel_dsb *dsb,
|
|||
*/
|
||||
dspcntr = i9xx_plane_ctl_crtc(crtc_state);
|
||||
|
||||
intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
|
||||
intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), 0);
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
intel_de_write_fw(display, DSPSURF(display, i9xx_plane), 0);
|
||||
else
|
||||
intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), 0);
|
||||
intel_de_write_fw(display, DSPADDR(display, i9xx_plane), 0);
|
||||
}
|
||||
|
||||
static void g4x_primary_capture_error(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
|
||||
error->surflive = intel_de_read(display, DSPSURFLIVE(display, i9xx_plane));
|
||||
}
|
||||
|
||||
static void i965_plane_capture_error(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
error->surf = intel_de_read(display, DSPSURF(display, i9xx_plane));
|
||||
}
|
||||
|
||||
static void i8xx_plane_capture_error(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
error->ctl = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
error->surf = intel_de_read(display, DSPADDR(display, i9xx_plane));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -560,7 +598,7 @@ g4x_primary_async_flip(struct intel_dsb *dsb,
|
|||
const struct intel_plane_state *plane_state,
|
||||
bool async_flip)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
u32 dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
|
||||
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
|
@ -568,9 +606,9 @@ g4x_primary_async_flip(struct intel_dsb *dsb,
|
|||
if (async_flip)
|
||||
dspcntr |= DISP_ASYNC_FLIP;
|
||||
|
||||
intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr);
|
||||
intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr);
|
||||
|
||||
intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPSURF(display, i9xx_plane),
|
||||
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
|
||||
}
|
||||
|
||||
|
|
@ -581,11 +619,11 @@ vlv_primary_async_flip(struct intel_dsb *dsb,
|
|||
const struct intel_plane_state *plane_state,
|
||||
bool async_flip)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
|
||||
intel_de_write_fw(dev_priv, DSPADDR_VLV(dev_priv, i9xx_plane),
|
||||
intel_de_write_fw(display, DSPADDR_VLV(display, i9xx_plane),
|
||||
intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
|
||||
}
|
||||
|
||||
|
|
@ -673,10 +711,15 @@ vlv_primary_disable_flip_done(struct intel_plane *plane)
|
|||
spin_unlock_irq(&i915->irq_lock);
|
||||
}
|
||||
|
||||
static bool i9xx_plane_can_async_flip(u64 modifier)
|
||||
{
|
||||
return modifier == I915_FORMAT_MOD_X_TILED;
|
||||
}
|
||||
|
||||
static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum intel_display_power_domain power_domain;
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -689,20 +732,20 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
|
|||
* display power wells.
|
||||
*/
|
||||
power_domain = POWER_DOMAIN_PIPE(plane->pipe);
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
||||
wakeref = intel_display_power_get_if_enabled(display, power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
|
||||
val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
|
||||
ret = val & DISP_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 5)
|
||||
if (DISPLAY_VER(display) >= 5)
|
||||
*pipe = plane->pipe;
|
||||
else
|
||||
*pipe = REG_FIELD_GET(DISP_PIPE_SEL_MASK, val);
|
||||
|
||||
intel_display_power_put(dev_priv, power_domain, wakeref);
|
||||
intel_display_power_put(display, power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -771,16 +814,21 @@ i8xx_plane_max_stride(struct intel_plane *plane,
|
|||
return 8 * 1024;
|
||||
}
|
||||
|
||||
static unsigned int vlv_primary_min_alignment(struct intel_plane *plane,
|
||||
const struct drm_framebuffer *fb,
|
||||
int color_plane)
|
||||
unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
|
||||
const struct drm_framebuffer *fb,
|
||||
int color_plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
|
||||
if (intel_plane_can_async_flip(plane, fb->modifier))
|
||||
return 256 * 1024;
|
||||
|
||||
/* FIXME undocumented so not sure what's actually needed */
|
||||
if (intel_scanout_needs_vtd_wa(display))
|
||||
return 256 * 1024;
|
||||
|
||||
switch (fb->modifier) {
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
if (HAS_ASYNC_FLIPS(i915))
|
||||
return 256 * 1024;
|
||||
return 4 * 1024;
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
return 128 * 1024;
|
||||
|
|
@ -794,13 +842,16 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane,
|
|||
const struct drm_framebuffer *fb,
|
||||
int color_plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
|
||||
if (intel_plane_can_async_flip(plane, fb->modifier))
|
||||
return 256 * 1024;
|
||||
|
||||
if (intel_scanout_needs_vtd_wa(display))
|
||||
return 256 * 1024;
|
||||
|
||||
switch (fb->modifier) {
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
if (HAS_ASYNC_FLIPS(i915))
|
||||
return 256 * 1024;
|
||||
return 4 * 1024;
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
return 4 * 1024;
|
||||
default:
|
||||
|
|
@ -850,7 +901,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = {
|
|||
};
|
||||
|
||||
struct intel_plane *
|
||||
intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
intel_primary_plane_create(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
struct intel_plane *plane;
|
||||
const struct drm_plane_funcs *plane_funcs;
|
||||
|
|
@ -869,20 +920,20 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
* On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
|
||||
* port is hooked to pipe B. Hence we want plane A feeding pipe B.
|
||||
*/
|
||||
if (HAS_FBC(dev_priv) && DISPLAY_VER(dev_priv) < 4 &&
|
||||
INTEL_NUM_PIPES(dev_priv) == 2)
|
||||
if (HAS_FBC(display) && DISPLAY_VER(display) < 4 &&
|
||||
INTEL_NUM_PIPES(display) == 2)
|
||||
plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
|
||||
else
|
||||
plane->i9xx_plane = (enum i9xx_plane_id) pipe;
|
||||
plane->id = PLANE_PRIMARY;
|
||||
plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
|
||||
|
||||
intel_fbc_add_plane(i9xx_plane_fbc(dev_priv, plane->i9xx_plane), plane);
|
||||
intel_fbc_add_plane(i9xx_plane_fbc(display, plane->i9xx_plane), plane);
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
if (display->platform.valleyview || display->platform.cherryview) {
|
||||
formats = vlv_primary_formats;
|
||||
num_formats = ARRAY_SIZE(vlv_primary_formats);
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
/*
|
||||
* WaFP16GammaEnabling:ivb
|
||||
* "Workaround : When using the 64-bit format, the plane
|
||||
|
|
@ -896,7 +947,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
* planes, so we choose not to expose fp16 on IVB primary
|
||||
* planes. HSW primary planes no longer have this problem.
|
||||
*/
|
||||
if (IS_IVYBRIDGE(dev_priv)) {
|
||||
if (display->platform.ivybridge) {
|
||||
formats = ivb_primary_formats;
|
||||
num_formats = ARRAY_SIZE(ivb_primary_formats);
|
||||
} else {
|
||||
|
|
@ -908,44 +959,48 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
num_formats = ARRAY_SIZE(i8xx_primary_formats);
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
plane_funcs = &i965_plane_funcs;
|
||||
else
|
||||
plane_funcs = &i8xx_plane_funcs;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
plane->min_cdclk = vlv_plane_min_cdclk;
|
||||
else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
else if (display->platform.broadwell || display->platform.haswell)
|
||||
plane->min_cdclk = hsw_plane_min_cdclk;
|
||||
else if (IS_IVYBRIDGE(dev_priv))
|
||||
else if (display->platform.ivybridge)
|
||||
plane->min_cdclk = ivb_plane_min_cdclk;
|
||||
else
|
||||
plane->min_cdclk = i9xx_plane_min_cdclk;
|
||||
|
||||
if (HAS_GMCH(dev_priv)) {
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (HAS_GMCH(display)) {
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
plane->max_stride = i965_plane_max_stride;
|
||||
else if (DISPLAY_VER(dev_priv) == 3)
|
||||
else if (DISPLAY_VER(display) == 3)
|
||||
plane->max_stride = i915_plane_max_stride;
|
||||
else
|
||||
plane->max_stride = i8xx_plane_max_stride;
|
||||
} else {
|
||||
if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
if (display->platform.broadwell || display->platform.haswell)
|
||||
plane->max_stride = hsw_primary_max_stride;
|
||||
else
|
||||
plane->max_stride = ilk_primary_max_stride;
|
||||
}
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
plane->min_alignment = vlv_primary_min_alignment;
|
||||
else if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
plane->min_alignment = vlv_plane_min_alignment;
|
||||
else if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
plane->min_alignment = g4x_primary_min_alignment;
|
||||
else if (DISPLAY_VER(dev_priv) == 4)
|
||||
else if (DISPLAY_VER(display) == 4)
|
||||
plane->min_alignment = i965_plane_min_alignment;
|
||||
else
|
||||
plane->min_alignment = i9xx_plane_min_alignment;
|
||||
|
||||
if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
|
||||
/* FIXME undocumented for VLV/CHV so not sure what's actually needed */
|
||||
if (intel_scanout_needs_vtd_wa(display))
|
||||
plane->vtd_guard = 128;
|
||||
|
||||
if (display->platform.i830 || display->platform.i845g) {
|
||||
plane->update_arm = i830_plane_update_arm;
|
||||
} else {
|
||||
plane->update_noarm = i9xx_plane_update_noarm;
|
||||
|
|
@ -955,36 +1010,49 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
plane->get_hw_state = i9xx_plane_get_hw_state;
|
||||
plane->check_plane = i9xx_plane_check;
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
|
||||
plane->async_flip = vlv_primary_async_flip;
|
||||
plane->enable_flip_done = vlv_primary_enable_flip_done;
|
||||
plane->disable_flip_done = vlv_primary_disable_flip_done;
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
plane->need_async_flip_toggle_wa = true;
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = bdw_primary_enable_flip_done;
|
||||
plane->disable_flip_done = bdw_primary_disable_flip_done;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 7) {
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = ivb_primary_enable_flip_done;
|
||||
plane->disable_flip_done = ivb_primary_disable_flip_done;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 5) {
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = ilk_primary_enable_flip_done;
|
||||
plane->disable_flip_done = ilk_primary_disable_flip_done;
|
||||
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
plane->capture_error = g4x_primary_capture_error;
|
||||
else if (DISPLAY_VER(display) >= 4)
|
||||
plane->capture_error = i965_plane_capture_error;
|
||||
else
|
||||
plane->capture_error = i8xx_plane_capture_error;
|
||||
|
||||
if (HAS_ASYNC_FLIPS(display)) {
|
||||
if (display->platform.valleyview || display->platform.cherryview) {
|
||||
plane->async_flip = vlv_primary_async_flip;
|
||||
plane->enable_flip_done = vlv_primary_enable_flip_done;
|
||||
plane->disable_flip_done = vlv_primary_disable_flip_done;
|
||||
plane->can_async_flip = i9xx_plane_can_async_flip;
|
||||
} else if (display->platform.broadwell) {
|
||||
plane->need_async_flip_toggle_wa = true;
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = bdw_primary_enable_flip_done;
|
||||
plane->disable_flip_done = bdw_primary_disable_flip_done;
|
||||
plane->can_async_flip = i9xx_plane_can_async_flip;
|
||||
} else if (DISPLAY_VER(display) >= 7) {
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = ivb_primary_enable_flip_done;
|
||||
plane->disable_flip_done = ivb_primary_disable_flip_done;
|
||||
plane->can_async_flip = i9xx_plane_can_async_flip;
|
||||
} else if (DISPLAY_VER(display) >= 5) {
|
||||
plane->async_flip = g4x_primary_async_flip;
|
||||
plane->enable_flip_done = ilk_primary_enable_flip_done;
|
||||
plane->disable_flip_done = ilk_primary_disable_flip_done;
|
||||
plane->can_async_flip = i9xx_plane_can_async_flip;
|
||||
}
|
||||
}
|
||||
|
||||
modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X);
|
||||
modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
|
||||
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
ret = drm_universal_plane_init(display->drm, &plane->base,
|
||||
0, plane_funcs,
|
||||
formats, num_formats,
|
||||
modifiers,
|
||||
DRM_PLANE_TYPE_PRIMARY,
|
||||
"primary %c", pipe_name(pipe));
|
||||
else
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
|
||||
ret = drm_universal_plane_init(display->drm, &plane->base,
|
||||
0, plane_funcs,
|
||||
formats, num_formats,
|
||||
modifiers,
|
||||
|
|
@ -997,18 +1065,18 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
|
||||
if (display->platform.cherryview && pipe == PIPE_B) {
|
||||
supported_rotations =
|
||||
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
|
||||
DRM_MODE_REFLECT_X;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
supported_rotations =
|
||||
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
|
||||
} else {
|
||||
supported_rotations = DRM_MODE_ROTATE_0;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
drm_plane_create_rotation_property(&plane->base,
|
||||
DRM_MODE_ROTATE_0,
|
||||
supported_rotations);
|
||||
|
|
@ -1063,8 +1131,7 @@ void
|
|||
i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_device *dev = crtc->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
|
||||
enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
|
||||
enum pipe pipe;
|
||||
|
|
@ -1077,21 +1144,21 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
|||
if (!plane->get_hw_state(plane, &pipe))
|
||||
return;
|
||||
|
||||
drm_WARN_ON(dev, pipe != crtc->pipe);
|
||||
drm_WARN_ON(display->drm, pipe != crtc->pipe);
|
||||
|
||||
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
|
||||
if (!intel_fb) {
|
||||
drm_dbg_kms(&dev_priv->drm, "failed to alloc fb\n");
|
||||
drm_dbg_kms(display->drm, "failed to alloc fb\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fb = &intel_fb->base;
|
||||
|
||||
fb->dev = dev;
|
||||
fb->dev = display->drm;
|
||||
|
||||
val = intel_de_read(dev_priv, DSPCNTR(dev_priv, i9xx_plane));
|
||||
val = intel_de_read(display, DSPCNTR(display, i9xx_plane));
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
if (DISPLAY_VER(display) >= 4) {
|
||||
if (val & DISP_TILED) {
|
||||
plane_config->tiling = I915_TILING_X;
|
||||
fb->modifier = I915_FORMAT_MOD_X_TILED;
|
||||
|
|
@ -1101,50 +1168,51 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
|||
plane_config->rotation = DRM_MODE_ROTATE_180;
|
||||
}
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B &&
|
||||
val & DISP_MIRROR)
|
||||
if (display->platform.cherryview &&
|
||||
pipe == PIPE_B && val & DISP_MIRROR)
|
||||
plane_config->rotation |= DRM_MODE_REFLECT_X;
|
||||
|
||||
pixel_format = val & DISP_FORMAT_MASK;
|
||||
fourcc = i9xx_format_to_fourcc(pixel_format);
|
||||
fb->format = drm_format_info(fourcc);
|
||||
|
||||
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
|
||||
offset = intel_de_read(dev_priv,
|
||||
DSPOFFSET(dev_priv, i9xx_plane));
|
||||
base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
|
||||
} else if (DISPLAY_VER(dev_priv) >= 4) {
|
||||
if (display->platform.haswell || display->platform.broadwell) {
|
||||
offset = intel_de_read(display,
|
||||
DSPOFFSET(display, i9xx_plane));
|
||||
base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
|
||||
} else if (DISPLAY_VER(display) >= 4) {
|
||||
if (plane_config->tiling)
|
||||
offset = intel_de_read(dev_priv,
|
||||
DSPTILEOFF(dev_priv, i9xx_plane));
|
||||
offset = intel_de_read(display,
|
||||
DSPTILEOFF(display, i9xx_plane));
|
||||
else
|
||||
offset = intel_de_read(dev_priv,
|
||||
DSPLINOFF(dev_priv, i9xx_plane));
|
||||
base = intel_de_read(dev_priv, DSPSURF(dev_priv, i9xx_plane)) & DISP_ADDR_MASK;
|
||||
offset = intel_de_read(display,
|
||||
DSPLINOFF(display, i9xx_plane));
|
||||
base = intel_de_read(display, DSPSURF(display, i9xx_plane)) & DISP_ADDR_MASK;
|
||||
} else {
|
||||
offset = 0;
|
||||
base = intel_de_read(dev_priv, DSPADDR(dev_priv, i9xx_plane));
|
||||
base = intel_de_read(display, DSPADDR(display, i9xx_plane));
|
||||
}
|
||||
plane_config->base = base;
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, offset != 0);
|
||||
drm_WARN_ON(display->drm, offset != 0);
|
||||
|
||||
val = intel_de_read(dev_priv, PIPESRC(dev_priv, pipe));
|
||||
val = intel_de_read(display, PIPESRC(display, pipe));
|
||||
fb->width = REG_FIELD_GET(PIPESRC_WIDTH_MASK, val) + 1;
|
||||
fb->height = REG_FIELD_GET(PIPESRC_HEIGHT_MASK, val) + 1;
|
||||
|
||||
val = intel_de_read(dev_priv, DSPSTRIDE(dev_priv, i9xx_plane));
|
||||
val = intel_de_read(display, DSPSTRIDE(display, i9xx_plane));
|
||||
fb->pitches[0] = val & 0xffffffc0;
|
||||
|
||||
aligned_height = intel_fb_align_height(fb, 0, fb->height);
|
||||
|
||||
plane_config->size = fb->pitches[0] * aligned_height;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"%s/%s with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
|
||||
crtc->base.name, plane->base.name, fb->width, fb->height,
|
||||
fb->format->cpp[0] * 8, base, fb->pitches[0],
|
||||
plane_config->size);
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CRTC:%d:%s][PLANE:%d:%s] with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
|
||||
crtc->base.base.id, crtc->base.name,
|
||||
plane->base.base.id, plane->base.name,
|
||||
fb->width, fb->height, fb->format->cpp[0] * 8,
|
||||
base, fb->pitches[0], plane_config->size);
|
||||
|
||||
plane_config->fb = intel_fb;
|
||||
}
|
||||
|
|
@ -1152,7 +1220,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
|||
bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
|
||||
const struct intel_initial_plane_config *plane_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct intel_plane *plane = to_intel_plane(crtc->base.primary);
|
||||
const struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
|
|
@ -1171,10 +1239,10 @@ bool i9xx_fixup_initial_plane_config(struct intel_crtc *crtc,
|
|||
if (plane_config->base == base)
|
||||
return false;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
intel_de_write(dev_priv, DSPSURF(dev_priv, i9xx_plane), base);
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
intel_de_write(display, DSPSURF(display, i9xx_plane), base);
|
||||
else
|
||||
intel_de_write(dev_priv, DSPADDR(dev_priv, i9xx_plane), base);
|
||||
intel_de_write(display, DSPADDR(display, i9xx_plane), base);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@
|
|||
#include <linux/types.h>
|
||||
|
||||
enum pipe;
|
||||
struct drm_i915_private;
|
||||
struct drm_framebuffer;
|
||||
struct intel_crtc;
|
||||
struct intel_display;
|
||||
struct intel_initial_plane_config;
|
||||
struct intel_plane;
|
||||
struct intel_plane_state;
|
||||
|
|
@ -19,10 +20,13 @@ struct intel_plane_state;
|
|||
unsigned int i965_plane_max_stride(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation);
|
||||
unsigned int vlv_plane_min_alignment(struct intel_plane *plane,
|
||||
const struct drm_framebuffer *fb,
|
||||
int colot_plane);
|
||||
int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
|
||||
|
||||
struct intel_plane *
|
||||
intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe);
|
||||
intel_primary_plane_create(struct intel_display *display, enum pipe pipe);
|
||||
|
||||
void i9xx_get_initial_plane_config(struct intel_crtc *crtc,
|
||||
struct intel_initial_plane_config *plane_config);
|
||||
|
|
@ -40,7 +44,7 @@ static inline int i9xx_check_plane_surface(struct intel_plane_state *plane_state
|
|||
return 0;
|
||||
}
|
||||
static inline struct intel_plane *
|
||||
intel_primary_plane_create(struct drm_i915_private *dev_priv, int pipe)
|
||||
intel_primary_plane_create(struct intel_display *display, int pipe)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -446,7 +446,7 @@ static const struct intel_watermark_params i845_wm_info = {
|
|||
* @latency: Memory wakeup latency in 0.1us units
|
||||
*
|
||||
* Compute the watermark using the method 1 or "small buffer"
|
||||
* formula. The caller may additonally add extra cachelines
|
||||
* formula. The caller may additionally add extra cachelines
|
||||
* to account for TLB misses and clock crossings.
|
||||
*
|
||||
* This method is concerned with the short term drain rate
|
||||
|
|
@ -493,7 +493,7 @@ static unsigned int intel_wm_method1(unsigned int pixel_rate,
|
|||
* @latency: Memory wakeup latency in 0.1us units
|
||||
*
|
||||
* Compute the watermark using the method 2 or "large buffer"
|
||||
* formula. The caller may additonally add extra cachelines
|
||||
* formula. The caller may additionally add extra cachelines
|
||||
* to account for TLB misses and clock crossings.
|
||||
*
|
||||
* This method is concerned with the long term drain rate
|
||||
|
|
@ -1562,7 +1562,7 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
|
|||
/*
|
||||
* When enabling sprite0 after sprite1 has already been enabled
|
||||
* we tend to get an underrun unless sprite0 already has some
|
||||
* FIFO space allcoated. Hence we always allocate at least one
|
||||
* FIFO space allocated. Hence we always allocate at least one
|
||||
* cacheline for sprite0 whenever sprite1 is enabled.
|
||||
*
|
||||
* All other plane enable sequences appear immune to this problem.
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
#include <drm/drm_mipi_dsi.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "icl_dsi.h"
|
||||
#include "icl_dsi_regs.h"
|
||||
#include "intel_atomic.h"
|
||||
|
|
@ -243,7 +243,7 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
|
|||
for_each_dsi_phy(phy, intel_dsi->phys) {
|
||||
/*
|
||||
* Program voltage swing and pre-emphasis level values as per
|
||||
* table in BSPEC under DDI buffer programing
|
||||
* table in BSPEC under DDI buffer programming.
|
||||
*/
|
||||
mask = SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK;
|
||||
val = SCALING_MODE_SEL(0x2) | TAP2_DISABLE | TAP3_DISABLE |
|
||||
|
|
@ -345,7 +345,6 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum port port;
|
||||
int afe_clk_khz;
|
||||
|
|
@ -354,7 +353,7 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
|
|||
|
||||
afe_clk_khz = afe_clk(encoder, crtc_state);
|
||||
|
||||
if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) {
|
||||
if (display->platform.alderlake_s || display->platform.alderlake_p) {
|
||||
theo_word_clk = DIV_ROUND_UP(afe_clk_khz, 8 * DSI_MAX_ESC_CLK);
|
||||
act_word_clk = max(3, theo_word_clk + (theo_word_clk + 1) % 2);
|
||||
esc_clk_div_m = act_word_clk * 8;
|
||||
|
|
@ -375,7 +374,7 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
|
|||
intel_de_posting_read(display, ICL_DPHY_ESC_CLK_DIV(port));
|
||||
}
|
||||
|
||||
if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) {
|
||||
if (display->platform.alderlake_s || display->platform.alderlake_p) {
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
intel_de_write(display, ADL_MIPIO_DW(port, 8),
|
||||
esc_clk_div_m_phy & TX_ESC_CLK_DIV_PHY);
|
||||
|
|
@ -387,13 +386,12 @@ static void gen11_dsi_program_esc_clk_div(struct intel_encoder *encoder,
|
|||
static void get_dsi_io_power_domains(struct intel_dsi *intel_dsi)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(&intel_dsi->base);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum port port;
|
||||
|
||||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
drm_WARN_ON(display->drm, intel_dsi->io_wakeref[port]);
|
||||
intel_dsi->io_wakeref[port] =
|
||||
intel_display_power_get(dev_priv,
|
||||
intel_display_power_get(display,
|
||||
port == PORT_A ?
|
||||
POWER_DOMAIN_PORT_DDI_IO_A :
|
||||
POWER_DOMAIN_PORT_DDI_IO_B);
|
||||
|
|
@ -415,19 +413,18 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder)
|
|||
|
||||
static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum phy phy;
|
||||
|
||||
for_each_dsi_phy(phy, intel_dsi->phys)
|
||||
intel_combo_phy_power_up_lanes(dev_priv, phy, true,
|
||||
intel_combo_phy_power_up_lanes(display, phy, true,
|
||||
intel_dsi->lane_count, false);
|
||||
}
|
||||
|
||||
static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum phy phy;
|
||||
u32 tmp;
|
||||
|
|
@ -452,7 +449,7 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
|
|||
intel_de_write(display, ICL_PORT_TX_DW2_GRP(phy), tmp);
|
||||
|
||||
/* For EHL, TGL, set latency optimization for PCS_DW1 lanes */
|
||||
if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv) ||
|
||||
if (display->platform.jasperlake || display->platform.elkhartlake ||
|
||||
(DISPLAY_VER(display) >= 12)) {
|
||||
intel_de_rmw(display, ICL_PORT_PCS_DW1_AUX(phy),
|
||||
LATENCY_OPTIM_MASK, LATENCY_OPTIM_VAL(0));
|
||||
|
|
@ -534,7 +531,6 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum port port;
|
||||
enum phy phy;
|
||||
|
|
@ -564,7 +560,7 @@ gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder,
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
|
||||
if (display->platform.jasperlake || display->platform.elkhartlake) {
|
||||
for_each_dsi_phy(phy, intel_dsi->phys)
|
||||
intel_de_rmw(display, ICL_DPHY_CHKN(phy),
|
||||
0, ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP);
|
||||
|
|
@ -961,7 +957,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
|
|||
for_each_dsi_port(port, intel_dsi->ports) {
|
||||
dsi_trans = dsi_port_to_transcoder(port);
|
||||
/*
|
||||
* FIXME: Programing this by assuming progressive mode, since
|
||||
* FIXME: Programming this by assuming progressive mode, since
|
||||
* non-interlaced info from VBT is not saved inside
|
||||
* struct drm_display_mode.
|
||||
* For interlace mode: program required pixel minus 2
|
||||
|
|
@ -1385,7 +1381,6 @@ static void gen11_dsi_disable_port(struct intel_encoder *encoder)
|
|||
static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum port port;
|
||||
|
||||
|
|
@ -1393,7 +1388,7 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder)
|
|||
intel_wakeref_t wakeref;
|
||||
|
||||
wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]);
|
||||
intel_display_power_put(dev_priv,
|
||||
intel_display_power_put(display,
|
||||
port == PORT_A ?
|
||||
POWER_DOMAIN_PORT_DDI_IO_A :
|
||||
POWER_DOMAIN_PORT_DDI_IO_B,
|
||||
|
|
@ -1462,10 +1457,10 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state,
|
|||
static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->dev);
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
enum drm_mode_status status;
|
||||
|
||||
status = intel_cpu_transcoder_mode_valid(i915, mode);
|
||||
status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
|
|
@ -1697,7 +1692,6 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
|
|||
enum pipe *pipe)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
|
||||
enum transcoder dsi_trans;
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -1705,7 +1699,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
|
|||
bool ret = false;
|
||||
u32 tmp;
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
wakeref = intel_display_power_get_if_enabled(display,
|
||||
encoder->power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
|
@ -1736,7 +1730,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder,
|
|||
ret = tmp & TRANSCONF_ENABLE;
|
||||
}
|
||||
out:
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "intel_fb.h"
|
||||
#include "intel_fb_pin.h"
|
||||
#include "skl_scaler.h"
|
||||
#include "skl_universal_plane.h"
|
||||
#include "skl_watermark.h"
|
||||
|
||||
static void intel_plane_state_reset(struct intel_plane_state *plane_state,
|
||||
|
|
@ -92,6 +93,19 @@ void intel_plane_free(struct intel_plane *plane)
|
|||
kfree(plane);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_plane_destroy - destroy a plane
|
||||
* @plane: plane to destroy
|
||||
*
|
||||
* Common destruction function for all types of planes (primary, cursor,
|
||||
* sprite).
|
||||
*/
|
||||
void intel_plane_destroy(struct drm_plane *plane)
|
||||
{
|
||||
drm_plane_cleanup(plane);
|
||||
kfree(to_intel_plane(plane));
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_plane_duplicate_state - duplicate plane state
|
||||
* @plane: drm plane
|
||||
|
|
@ -156,6 +170,11 @@ bool intel_plane_needs_physical(struct intel_plane *plane)
|
|||
DISPLAY_INFO(i915)->cursor_needs_physical;
|
||||
}
|
||||
|
||||
bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier)
|
||||
{
|
||||
return plane->can_async_flip && plane->can_async_flip(modifier);
|
||||
}
|
||||
|
||||
unsigned int intel_adjusted_rate(const struct drm_rect *src,
|
||||
const struct drm_rect *dst,
|
||||
unsigned int rate)
|
||||
|
|
@ -663,7 +682,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
|
|||
old_plane_state, new_plane_state);
|
||||
}
|
||||
|
||||
static struct intel_plane *
|
||||
struct intel_plane *
|
||||
intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
|
|
@ -767,7 +786,7 @@ void intel_plane_update_noarm(struct intel_dsb *dsb,
|
|||
{
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
|
||||
trace_intel_plane_update_noarm(plane, crtc);
|
||||
trace_intel_plane_update_noarm(plane_state, crtc);
|
||||
|
||||
if (plane->update_noarm)
|
||||
plane->update_noarm(dsb, plane, crtc_state, plane_state);
|
||||
|
|
@ -797,7 +816,7 @@ void intel_plane_update_arm(struct intel_dsb *dsb,
|
|||
return;
|
||||
}
|
||||
|
||||
trace_intel_plane_update_arm(plane, crtc);
|
||||
trace_intel_plane_update_arm(plane_state, crtc);
|
||||
plane->update_arm(dsb, plane, crtc_state, plane_state);
|
||||
}
|
||||
|
||||
|
|
@ -836,7 +855,7 @@ void intel_crtc_planes_update_noarm(struct intel_dsb *dsb,
|
|||
|
||||
/* TODO: for mailbox updates this should be skipped */
|
||||
if (new_plane_state->uapi.visible ||
|
||||
new_plane_state->planar_slave)
|
||||
new_plane_state->is_y_plane)
|
||||
intel_plane_update_noarm(dsb, plane,
|
||||
new_crtc_state, new_plane_state);
|
||||
}
|
||||
|
|
@ -869,7 +888,7 @@ static void skl_crtc_planes_update_arm(struct intel_dsb *dsb,
|
|||
* would have to be called here as well.
|
||||
*/
|
||||
if (new_plane_state->uapi.visible ||
|
||||
new_plane_state->planar_slave)
|
||||
new_plane_state->is_y_plane)
|
||||
intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
|
||||
else
|
||||
intel_plane_disable_arm(dsb, plane, new_crtc_state);
|
||||
|
|
@ -921,6 +940,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
|||
bool can_position)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct drm_rect *src = &plane_state->uapi.src;
|
||||
struct drm_rect *dst = &plane_state->uapi.dst;
|
||||
|
|
@ -939,9 +959,10 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
|||
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
|
||||
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
|
||||
if (hscale < 0 || vscale < 0) {
|
||||
drm_dbg_kms(&i915->drm, "Invalid scaling of plane\n");
|
||||
drm_rect_debug_print("src: ", src, true);
|
||||
drm_rect_debug_print("dst: ", dst, false);
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[PLANE:%d:%s] invalid scaling "DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst));
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
|
|
@ -955,9 +976,10 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
|||
|
||||
if (!can_position && plane_state->uapi.visible &&
|
||||
!drm_rect_equals(dst, clip)) {
|
||||
drm_dbg_kms(&i915->drm, "Plane must cover entire CRTC\n");
|
||||
drm_rect_debug_print("dst: ", dst, false);
|
||||
drm_rect_debug_print("clip: ", clip, false);
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[PLANE:%d:%s] plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
DRM_RECT_ARG(dst), DRM_RECT_ARG(clip));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -970,6 +992,7 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
|
|||
int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct drm_rect *src = &plane_state->uapi.src;
|
||||
u32 src_x, src_y, src_w, src_h, hsub, vsub;
|
||||
|
|
@ -1025,13 +1048,17 @@ int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
|
|||
hsub = vsub = max(hsub, vsub);
|
||||
|
||||
if (src_x % hsub || src_w % hsub) {
|
||||
drm_dbg_kms(&i915->drm, "src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[PLANE:%d:%s] src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
src_x, src_w, hsub, str_yes_no(rotated));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (src_y % vsub || src_h % vsub) {
|
||||
drm_dbg_kms(&i915->drm, "src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"[PLANE:%d:%s] src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
src_y, src_h, vsub, str_yes_no(rotated));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -1119,7 +1146,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
|||
* This should only fail upon a hung GPU, in which case we
|
||||
* can safely continue.
|
||||
*/
|
||||
if (new_crtc_state && intel_crtc_needs_modeset(new_crtc_state)) {
|
||||
if (intel_crtc_needs_modeset(new_crtc_state)) {
|
||||
ret = add_dma_resv_fences(old_obj->resv,
|
||||
&new_plane_state->uapi);
|
||||
if (ret < 0)
|
||||
|
|
@ -1130,7 +1157,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
|
|||
if (!obj)
|
||||
return 0;
|
||||
|
||||
ret = intel_plane_pin_fb(new_plane_state);
|
||||
ret = intel_plane_pin_fb(new_plane_state, old_plane_state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1210,3 +1237,298 @@ void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_sta
|
|||
drm_vblank_work_init(&old_plane_state->unpin_work, old_plane_state->uapi.crtc,
|
||||
intel_cursor_unpin_work);
|
||||
}
|
||||
|
||||
static void link_nv12_planes(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *uv_plane_state,
|
||||
struct intel_plane_state *y_plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(uv_plane_state);
|
||||
struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane);
|
||||
struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane);
|
||||
|
||||
drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n",
|
||||
uv_plane->base.base.id, uv_plane->base.name,
|
||||
y_plane->base.base.id, y_plane->base.name);
|
||||
|
||||
uv_plane_state->planar_linked_plane = y_plane;
|
||||
|
||||
y_plane_state->is_y_plane = true;
|
||||
y_plane_state->planar_linked_plane = uv_plane;
|
||||
|
||||
crtc_state->enabled_planes |= BIT(y_plane->id);
|
||||
crtc_state->active_planes |= BIT(y_plane->id);
|
||||
crtc_state->update_planes |= BIT(y_plane->id);
|
||||
|
||||
crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id];
|
||||
crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id];
|
||||
|
||||
/* Copy parameters to Y plane */
|
||||
intel_plane_copy_hw_state(y_plane_state, uv_plane_state);
|
||||
y_plane_state->uapi.src = uv_plane_state->uapi.src;
|
||||
y_plane_state->uapi.dst = uv_plane_state->uapi.dst;
|
||||
|
||||
y_plane_state->ctl = uv_plane_state->ctl;
|
||||
y_plane_state->color_ctl = uv_plane_state->color_ctl;
|
||||
y_plane_state->view = uv_plane_state->view;
|
||||
y_plane_state->decrypt = uv_plane_state->decrypt;
|
||||
|
||||
icl_link_nv12_planes(uv_plane_state, y_plane_state);
|
||||
}
|
||||
|
||||
static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
|
||||
plane_state->planar_linked_plane = NULL;
|
||||
|
||||
if (!plane_state->is_y_plane)
|
||||
return;
|
||||
|
||||
drm_WARN_ON(display->drm, plane_state->uapi.visible);
|
||||
|
||||
plane_state->is_y_plane = false;
|
||||
|
||||
crtc_state->enabled_planes &= ~BIT(plane->id);
|
||||
crtc_state->active_planes &= ~BIT(plane->id);
|
||||
crtc_state->update_planes |= BIT(plane->id);
|
||||
crtc_state->data_rate[plane->id] = 0;
|
||||
crtc_state->rel_data_rate[plane->id] = 0;
|
||||
}
|
||||
|
||||
static int icl_check_nv12_planes(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
struct intel_plane_state *plane_state;
|
||||
struct intel_plane *plane;
|
||||
int i;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 11)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Destroy all old plane links and make the Y plane invisible
|
||||
* in the crtc_state->active_planes mask.
|
||||
*/
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
if (plane_state->planar_linked_plane)
|
||||
unlink_nv12_plane(crtc_state, plane_state);
|
||||
}
|
||||
|
||||
if (!crtc_state->nv12_planes)
|
||||
return 0;
|
||||
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
struct intel_plane_state *y_plane_state = NULL;
|
||||
struct intel_plane *y_plane;
|
||||
|
||||
if (plane->pipe != crtc->pipe)
|
||||
continue;
|
||||
|
||||
if ((crtc_state->nv12_planes & BIT(plane->id)) == 0)
|
||||
continue;
|
||||
|
||||
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, y_plane) {
|
||||
if (!icl_is_nv12_y_plane(display, y_plane->id))
|
||||
continue;
|
||||
|
||||
if (crtc_state->active_planes & BIT(y_plane->id))
|
||||
continue;
|
||||
|
||||
y_plane_state = intel_atomic_get_plane_state(state, y_plane);
|
||||
if (IS_ERR(y_plane_state))
|
||||
return PTR_ERR(y_plane_state);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!y_plane_state) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"[CRTC:%d:%s] need %d free Y planes for planar YUV\n",
|
||||
crtc->base.base.id, crtc->base.name,
|
||||
hweight8(crtc_state->nv12_planes));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
link_nv12_planes(crtc_state, plane_state, y_plane_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
u8 plane_ids_mask)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_plane *plane;
|
||||
|
||||
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
|
||||
struct intel_plane_state *plane_state;
|
||||
|
||||
if ((plane_ids_mask & BIT(plane->id)) == 0)
|
||||
continue;
|
||||
|
||||
plane_state = intel_atomic_get_plane_state(state, plane);
|
||||
if (IS_ERR(plane_state))
|
||||
return PTR_ERR(plane_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
return intel_crtc_add_planes_to_state(state, crtc,
|
||||
old_crtc_state->enabled_planes |
|
||||
new_crtc_state->enabled_planes);
|
||||
}
|
||||
|
||||
static bool active_planes_affects_min_cdclk(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
/* See {hsw,vlv,ivb}_plane_ratio() */
|
||||
return IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv) ||
|
||||
IS_CHERRYVIEW(dev_priv) || IS_VALLEYVIEW(dev_priv) ||
|
||||
IS_IVYBRIDGE(dev_priv);
|
||||
}
|
||||
|
||||
static u8 intel_joiner_affected_planes(struct intel_atomic_state *state,
|
||||
u8 joined_pipes)
|
||||
{
|
||||
const struct intel_plane_state *plane_state;
|
||||
struct intel_plane *plane;
|
||||
u8 affected_planes = 0;
|
||||
int i;
|
||||
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
struct intel_plane *linked = plane_state->planar_linked_plane;
|
||||
|
||||
if ((joined_pipes & BIT(plane->pipe)) == 0)
|
||||
continue;
|
||||
|
||||
affected_planes |= BIT(plane->id);
|
||||
if (linked)
|
||||
affected_planes |= BIT(linked->id);
|
||||
}
|
||||
|
||||
return affected_planes;
|
||||
}
|
||||
|
||||
static int intel_joiner_add_affected_planes(struct intel_atomic_state *state,
|
||||
u8 joined_pipes)
|
||||
{
|
||||
u8 prev_affected_planes, affected_planes = 0;
|
||||
|
||||
/*
|
||||
* We want all the joined pipes to have the same
|
||||
* set of planes in the atomic state, to make sure
|
||||
* state copying always works correctly, and the
|
||||
* UV<->Y plane linkage is always up to date.
|
||||
* Keep pulling planes in until we've determined
|
||||
* the full set of affected planes. A bit complicated
|
||||
* on account of each pipe being capable of selecting
|
||||
* their own Y planes independently of the other pipes,
|
||||
* and the selection being done from the set of
|
||||
* inactive planes.
|
||||
*/
|
||||
do {
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) {
|
||||
int ret;
|
||||
|
||||
ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
prev_affected_planes = affected_planes;
|
||||
affected_planes = intel_joiner_affected_planes(state, joined_pipes);
|
||||
} while (affected_planes != prev_affected_planes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int intel_add_affected_planes(struct intel_atomic_state *state)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state;
|
||||
struct intel_crtc *crtc;
|
||||
int i;
|
||||
|
||||
for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
int ret;
|
||||
|
||||
ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intel_atomic_check_planes(struct intel_atomic_state *state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
|
||||
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct intel_plane_state __maybe_unused *plane_state;
|
||||
struct intel_plane *plane;
|
||||
struct intel_crtc *crtc;
|
||||
int i, ret;
|
||||
|
||||
ret = intel_add_affected_planes(state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
|
||||
ret = intel_plane_atomic_check(state, plane);
|
||||
if (ret) {
|
||||
drm_dbg_atomic(&dev_priv->drm,
|
||||
"[PLANE:%d:%s] atomic driver check failed\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
u8 old_active_planes, new_active_planes;
|
||||
|
||||
ret = icl_check_nv12_planes(state, crtc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* On some platforms the number of active planes affects
|
||||
* the planes' minimum cdclk calculation. Add such planes
|
||||
* to the state before we compute the minimum cdclk.
|
||||
*/
|
||||
if (!active_planes_affects_min_cdclk(dev_priv))
|
||||
continue;
|
||||
|
||||
old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
||||
new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
|
||||
|
||||
if (hweight8(old_active_planes) == hweight8(new_active_planes))
|
||||
continue;
|
||||
|
||||
ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ struct intel_plane;
|
|||
struct intel_plane_state;
|
||||
enum plane_id;
|
||||
|
||||
struct intel_plane *
|
||||
intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id);
|
||||
bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier);
|
||||
unsigned int intel_adjusted_rate(const struct drm_rect *src,
|
||||
const struct drm_rect *dst,
|
||||
unsigned int rate);
|
||||
|
|
@ -51,6 +54,7 @@ void intel_plane_disable_arm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
struct intel_plane *intel_plane_alloc(void);
|
||||
void intel_plane_free(struct intel_plane *plane);
|
||||
void intel_plane_destroy(struct drm_plane *plane);
|
||||
struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
|
||||
void intel_plane_destroy_state(struct drm_plane *plane,
|
||||
struct drm_plane_state *state);
|
||||
|
|
@ -80,5 +84,8 @@ void intel_plane_helper_add(struct intel_plane *plane);
|
|||
bool intel_plane_needs_physical(struct intel_plane *plane);
|
||||
void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
|
||||
struct intel_plane_state *new_plane_state);
|
||||
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
int intel_atomic_check_planes(struct intel_atomic_state *state);
|
||||
|
||||
#endif /* __INTEL_ATOMIC_PLANE_H__ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,11 +9,11 @@
|
|||
#include <linux/types.h>
|
||||
|
||||
struct drm_connector_state;
|
||||
struct drm_i915_private;
|
||||
struct intel_crtc_state;
|
||||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
|
||||
void intel_audio_hooks_init(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_hooks_init(struct intel_display *display);
|
||||
bool intel_audio_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state);
|
||||
|
|
@ -25,12 +25,12 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
|
|||
const struct drm_connector_state *old_conn_state);
|
||||
void intel_audio_codec_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_cdclk_change_pre(struct intel_display *display);
|
||||
void intel_audio_cdclk_change_post(struct intel_display *display);
|
||||
int intel_audio_min_cdclk(const struct intel_crtc_state *crtc_state);
|
||||
void intel_audio_init(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_register(struct drm_i915_private *i915);
|
||||
void intel_audio_deinit(struct drm_i915_private *dev_priv);
|
||||
void intel_audio_init(struct intel_display *display);
|
||||
void intel_audio_register(struct intel_display *display);
|
||||
void intel_audio_deinit(struct intel_display *display);
|
||||
void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
#endif /* __INTEL_AUDIO_H__ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -314,27 +314,26 @@ static unsigned int intel_hpll_vco(struct intel_display *display)
|
|||
[4] = 2666667,
|
||||
[5] = 4266667,
|
||||
};
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
const unsigned int *vco_table;
|
||||
unsigned int vco;
|
||||
u8 tmp = 0;
|
||||
|
||||
/* FIXME other chipsets? */
|
||||
if (IS_GM45(dev_priv))
|
||||
if (display->platform.gm45)
|
||||
vco_table = ctg_vco;
|
||||
else if (IS_G45(dev_priv))
|
||||
else if (display->platform.g45)
|
||||
vco_table = elk_vco;
|
||||
else if (IS_I965GM(dev_priv))
|
||||
else if (display->platform.i965gm)
|
||||
vco_table = cl_vco;
|
||||
else if (IS_PINEVIEW(dev_priv))
|
||||
else if (display->platform.pineview)
|
||||
vco_table = pnv_vco;
|
||||
else if (IS_G33(dev_priv))
|
||||
else if (display->platform.g33)
|
||||
vco_table = blb_vco;
|
||||
else
|
||||
return 0;
|
||||
|
||||
tmp = intel_de_read(display,
|
||||
IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);
|
||||
tmp = intel_de_read(display, display->platform.pineview ||
|
||||
display->platform.mobile ? HPLLVCO_MOBILE : HPLLVCO);
|
||||
|
||||
vco = vco_table[tmp & 0x7];
|
||||
if (vco == 0)
|
||||
|
|
@ -508,7 +507,6 @@ static void gm45_get_cdclk(struct intel_display *display,
|
|||
static void hsw_get_cdclk(struct intel_display *display,
|
||||
struct intel_cdclk_config *cdclk_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 lcpll = intel_de_read(display, LCPLL_CTL);
|
||||
u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;
|
||||
|
||||
|
|
@ -518,7 +516,7 @@ static void hsw_get_cdclk(struct intel_display *display,
|
|||
cdclk_config->cdclk = 450000;
|
||||
else if (freq == LCPLL_CLK_FREQ_450)
|
||||
cdclk_config->cdclk = 450000;
|
||||
else if (IS_HASWELL_ULT(dev_priv))
|
||||
else if (display->platform.haswell_ult)
|
||||
cdclk_config->cdclk = 337500;
|
||||
else
|
||||
cdclk_config->cdclk = 540000;
|
||||
|
|
@ -535,7 +533,7 @@ static int vlv_calc_cdclk(struct intel_display *display, int min_cdclk)
|
|||
* Not sure what's wrong. For now use 200MHz only when all pipes
|
||||
* are off.
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev_priv) && min_cdclk > freq_320)
|
||||
if (display->platform.valleyview && min_cdclk > freq_320)
|
||||
return 400000;
|
||||
else if (min_cdclk > 266667)
|
||||
return freq_320;
|
||||
|
|
@ -549,7 +547,7 @@ static u8 vlv_calc_voltage_level(struct intel_display *display, int cdclk)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv)) {
|
||||
if (display->platform.valleyview) {
|
||||
if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
|
||||
return 2;
|
||||
else if (cdclk >= 266667)
|
||||
|
|
@ -585,7 +583,7 @@ static void vlv_get_cdclk(struct intel_display *display,
|
|||
vlv_iosf_sb_put(dev_priv,
|
||||
BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
|
||||
|
||||
if (IS_VALLEYVIEW(dev_priv))
|
||||
if (display->platform.valleyview)
|
||||
cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK) >>
|
||||
DSPFREQGUAR_SHIFT;
|
||||
else
|
||||
|
|
@ -598,14 +596,14 @@ static void vlv_program_pfi_credits(struct intel_display *display)
|
|||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
unsigned int credits, default_credits;
|
||||
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
default_credits = PFI_CREDIT(12);
|
||||
else
|
||||
default_credits = PFI_CREDIT(8);
|
||||
|
||||
if (display->cdclk.hw.cdclk >= dev_priv->czclk_freq) {
|
||||
/* CHV suggested value is 31 or 63 */
|
||||
if (IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.cherryview)
|
||||
credits = PFI_CREDIT_63;
|
||||
else
|
||||
credits = PFI_CREDIT(15);
|
||||
|
|
@ -658,7 +656,7 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
* a system suspend. So grab the display core domain, which covers
|
||||
* the HW blocks needed for the following programming.
|
||||
*/
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE);
|
||||
|
||||
vlv_iosf_sb_get(dev_priv,
|
||||
BIT(VLV_IOSF_SB_CCK) |
|
||||
|
|
@ -718,7 +716,7 @@ static void vlv_set_cdclk(struct intel_display *display,
|
|||
|
||||
vlv_program_pfi_credits(display);
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
|
||||
}
|
||||
|
||||
static void chv_set_cdclk(struct intel_display *display,
|
||||
|
|
@ -747,7 +745,7 @@ static void chv_set_cdclk(struct intel_display *display,
|
|||
* a system suspend. So grab the display core domain, which covers
|
||||
* the HW blocks needed for the following programming.
|
||||
*/
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE);
|
||||
|
||||
vlv_punit_get(dev_priv);
|
||||
val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
|
||||
|
|
@ -767,7 +765,7 @@ static void chv_set_cdclk(struct intel_display *display,
|
|||
|
||||
vlv_program_pfi_credits(display);
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, wakeref);
|
||||
}
|
||||
|
||||
static int bdw_calc_cdclk(int min_cdclk)
|
||||
|
|
@ -1142,7 +1140,7 @@ static void skl_set_cdclk(struct intel_display *display,
|
|||
* minimum 308MHz CDCLK.
|
||||
*/
|
||||
drm_WARN_ON_ONCE(display->drm,
|
||||
IS_SKYLAKE(dev_priv) && vco == 8640000);
|
||||
display->platform.skylake && vco == 8640000);
|
||||
|
||||
ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
|
||||
SKL_CDCLK_PREPARE_FOR_CHANGE,
|
||||
|
|
@ -1662,10 +1660,9 @@ static void icl_readout_refclk(struct intel_display *display,
|
|||
static void bxt_de_pll_readout(struct intel_display *display,
|
||||
struct intel_cdclk_config *cdclk_config)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 val, ratio;
|
||||
|
||||
if (IS_DG2(dev_priv))
|
||||
if (display->platform.dg2)
|
||||
cdclk_config->ref = 38400;
|
||||
else if (DISPLAY_VER(display) >= 11)
|
||||
icl_readout_refclk(display, cdclk_config);
|
||||
|
|
@ -2057,11 +2054,9 @@ static bool cdclk_compute_crawl_and_squash_midpoint(struct intel_display *displa
|
|||
|
||||
static bool pll_enable_wa_needed(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
return (DISPLAY_VERx100(display) == 2000 ||
|
||||
DISPLAY_VERx100(display) == 1400 ||
|
||||
IS_DG2(dev_priv)) &&
|
||||
display->platform.dg2) &&
|
||||
display->cdclk.hw.vco > 0;
|
||||
}
|
||||
|
||||
|
|
@ -2069,7 +2064,6 @@ static u32 bxt_cdclk_ctl(struct intel_display *display,
|
|||
const struct intel_cdclk_config *cdclk_config,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
int cdclk = cdclk_config->cdclk;
|
||||
int vco = cdclk_config->vco;
|
||||
u16 waveform;
|
||||
|
|
@ -2084,7 +2078,7 @@ static u32 bxt_cdclk_ctl(struct intel_display *display,
|
|||
* Disable SSA Precharge when CD clock frequency < 500 MHz,
|
||||
* enable otherwise.
|
||||
*/
|
||||
if ((IS_GEMINILAKE(i915) || IS_BROXTON(i915)) &&
|
||||
if ((display->platform.geminilake || display->platform.broxton) &&
|
||||
cdclk >= 500000)
|
||||
val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
|
||||
|
||||
|
|
@ -2144,8 +2138,8 @@ static void bxt_set_cdclk(struct intel_display *display,
|
|||
* mailbox communication, skip
|
||||
* this step.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 14 || IS_DG2(dev_priv))
|
||||
/* NOOP */;
|
||||
if (DISPLAY_VER(display) >= 14 || display->platform.dg2)
|
||||
; /* NOOP */
|
||||
else if (DISPLAY_VER(display) >= 11)
|
||||
ret = skl_pcode_request(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
|
||||
SKL_CDCLK_PREPARE_FOR_CHANGE,
|
||||
|
|
@ -2186,7 +2180,7 @@ static void bxt_set_cdclk(struct intel_display *display,
|
|||
* NOOP - No Pcode communication needed for
|
||||
* Display versions 14 and beyond
|
||||
*/;
|
||||
else if (DISPLAY_VER(display) >= 11 && !IS_DG2(dev_priv))
|
||||
else if (DISPLAY_VER(display) >= 11 && !display->platform.dg2)
|
||||
ret = snb_pcode_write(&dev_priv->uncore, SKL_PCODE_CDCLK_CONTROL,
|
||||
cdclk_config->voltage_level);
|
||||
if (DISPLAY_VER(display) < 11) {
|
||||
|
|
@ -2250,7 +2244,7 @@ static void bxt_sanitize_cdclk(struct intel_display *display)
|
|||
|
||||
/*
|
||||
* Let's ignore the pipe field, since BIOS could have configured the
|
||||
* dividers both synching to an active pipe, or asynchronously
|
||||
* dividers both syncing to an active pipe, or asynchronously
|
||||
* (PIPE_NONE).
|
||||
*/
|
||||
cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
|
||||
|
|
@ -2318,9 +2312,7 @@ static void bxt_cdclk_uninit_hw(struct intel_display *display)
|
|||
*/
|
||||
void intel_cdclk_init_hw(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915))
|
||||
if (DISPLAY_VER(display) >= 10 || display->platform.broxton)
|
||||
bxt_cdclk_init_hw(display);
|
||||
else if (DISPLAY_VER(display) == 9)
|
||||
skl_cdclk_init_hw(display);
|
||||
|
|
@ -2335,9 +2327,7 @@ void intel_cdclk_init_hw(struct intel_display *display)
|
|||
*/
|
||||
void intel_cdclk_uninit_hw(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 10 || IS_BROXTON(i915))
|
||||
if (DISPLAY_VER(display) >= 10 || display->platform.broxton)
|
||||
bxt_cdclk_uninit_hw(display);
|
||||
else if (DISPLAY_VER(display) == 9)
|
||||
skl_cdclk_uninit_hw(display);
|
||||
|
|
@ -2438,10 +2428,8 @@ static bool intel_cdclk_can_cd2x_update(struct intel_display *display,
|
|||
const struct intel_cdclk_config *a,
|
||||
const struct intel_cdclk_config *b)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
/* Older hw doesn't have the capability */
|
||||
if (DISPLAY_VER(display) < 10 && !IS_BROXTON(dev_priv))
|
||||
if (DISPLAY_VER(display) < 10 && !display->platform.broxton)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
@ -2495,7 +2483,7 @@ static void intel_pcode_notify(struct intel_display *display,
|
|||
int ret;
|
||||
u32 update_mask = 0;
|
||||
|
||||
if (!IS_DG2(i915))
|
||||
if (!display->platform.dg2)
|
||||
return;
|
||||
|
||||
update_mask = DISPLAY_TO_PCODE_UPDATE_MASK(cdclk, active_pipe_count, voltage_level);
|
||||
|
|
@ -2521,7 +2509,6 @@ static void intel_set_cdclk(struct intel_display *display,
|
|||
const struct intel_cdclk_config *cdclk_config,
|
||||
enum pipe pipe, const char *context)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (!intel_cdclk_changed(&display->cdclk.hw, cdclk_config))
|
||||
|
|
@ -2538,7 +2525,7 @@ static void intel_set_cdclk(struct intel_display *display,
|
|||
intel_psr_pause(intel_dp);
|
||||
}
|
||||
|
||||
intel_audio_cdclk_change_pre(dev_priv);
|
||||
intel_audio_cdclk_change_pre(display);
|
||||
|
||||
/*
|
||||
* Lock aux/gmbus while we change cdclk in case those
|
||||
|
|
@ -2568,7 +2555,7 @@ static void intel_set_cdclk(struct intel_display *display,
|
|||
intel_psr_resume(intel_dp);
|
||||
}
|
||||
|
||||
intel_audio_cdclk_change_post(dev_priv);
|
||||
intel_audio_cdclk_change_post(display);
|
||||
|
||||
if (drm_WARN(display->drm,
|
||||
intel_cdclk_changed(&display->cdclk.hw, cdclk_config),
|
||||
|
|
@ -2682,7 +2669,6 @@ void
|
|||
intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
const struct intel_cdclk_state *old_cdclk_state =
|
||||
intel_atomic_get_old_cdclk_state(state);
|
||||
const struct intel_cdclk_state *new_cdclk_state =
|
||||
|
|
@ -2694,7 +2680,7 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
|
|||
&new_cdclk_state->actual))
|
||||
return;
|
||||
|
||||
if (IS_DG2(i915))
|
||||
if (display->platform.dg2)
|
||||
intel_cdclk_pcode_pre_notify(state);
|
||||
|
||||
if (new_cdclk_state->disable_pipes) {
|
||||
|
|
@ -2736,7 +2722,6 @@ void
|
|||
intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
const struct intel_cdclk_state *old_cdclk_state =
|
||||
intel_atomic_get_old_cdclk_state(state);
|
||||
const struct intel_cdclk_state *new_cdclk_state =
|
||||
|
|
@ -2747,7 +2732,7 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
|
|||
&new_cdclk_state->actual))
|
||||
return;
|
||||
|
||||
if (IS_DG2(i915))
|
||||
if (display->platform.dg2)
|
||||
intel_cdclk_pcode_post_notify(state);
|
||||
|
||||
if (!new_cdclk_state->disable_pipes &&
|
||||
|
|
@ -2771,12 +2756,10 @@ static int intel_cdclk_ppc(struct intel_display *display, bool double_wide)
|
|||
/* max pixel rate as % of CDCLK (not accounting for PPC) */
|
||||
static int intel_cdclk_guardband(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 9 ||
|
||||
IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
|
||||
display->platform.broadwell || display->platform.haswell)
|
||||
return 100;
|
||||
else if (IS_CHERRYVIEW(dev_priv))
|
||||
else if (display->platform.cherryview)
|
||||
return 95;
|
||||
else
|
||||
return 90;
|
||||
|
|
@ -2879,7 +2862,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state)
|
|||
* by changing the cd2x divider (see glk_cdclk_table[]) and
|
||||
* thus a full modeset won't be needed then.
|
||||
*/
|
||||
if (IS_GEMINILAKE(dev_priv) && cdclk_state->active_pipes &&
|
||||
if (display->platform.geminilake && cdclk_state->active_pipes &&
|
||||
!is_power_of_2(cdclk_state->active_pipes))
|
||||
min_cdclk = max(min_cdclk, 2 * 96000);
|
||||
|
||||
|
|
@ -3233,7 +3216,6 @@ static bool intel_cdclk_need_serialize(struct intel_display *display,
|
|||
const struct intel_cdclk_state *old_cdclk_state,
|
||||
const struct intel_cdclk_state *new_cdclk_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
bool power_well_cnt_changed = hweight8(old_cdclk_state->active_pipes) !=
|
||||
hweight8(new_cdclk_state->active_pipes);
|
||||
bool cdclk_changed = intel_cdclk_changed(&old_cdclk_state->actual,
|
||||
|
|
@ -3242,7 +3224,7 @@ static bool intel_cdclk_need_serialize(struct intel_display *display,
|
|||
* We need to poke hw for gen >= 12, because we notify PCode if
|
||||
* pipe power well count changes.
|
||||
*/
|
||||
return cdclk_changed || (IS_DG2(i915) && power_well_cnt_changed);
|
||||
return cdclk_changed || (display->platform.dg2 && power_well_cnt_changed);
|
||||
}
|
||||
|
||||
int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
|
||||
|
|
@ -3377,11 +3359,9 @@ static int intel_compute_max_dotclk(struct intel_display *display)
|
|||
*/
|
||||
void intel_update_max_cdclk(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 30) {
|
||||
display->cdclk.max_cdclk_freq = 691200;
|
||||
} else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
|
||||
} else if (display->platform.jasperlake || display->platform.elkhartlake) {
|
||||
if (display->cdclk.hw.ref == 24000)
|
||||
display->cdclk.max_cdclk_freq = 552000;
|
||||
else
|
||||
|
|
@ -3391,9 +3371,9 @@ void intel_update_max_cdclk(struct intel_display *display)
|
|||
display->cdclk.max_cdclk_freq = 648000;
|
||||
else
|
||||
display->cdclk.max_cdclk_freq = 652800;
|
||||
} else if (IS_GEMINILAKE(dev_priv)) {
|
||||
} else if (display->platform.geminilake) {
|
||||
display->cdclk.max_cdclk_freq = 316800;
|
||||
} else if (IS_BROXTON(dev_priv)) {
|
||||
} else if (display->platform.broxton) {
|
||||
display->cdclk.max_cdclk_freq = 624000;
|
||||
} else if (DISPLAY_VER(display) == 9) {
|
||||
u32 limit = intel_de_read(display, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
|
||||
|
|
@ -3417,7 +3397,7 @@ void intel_update_max_cdclk(struct intel_display *display)
|
|||
max_cdclk = 308571;
|
||||
|
||||
display->cdclk.max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
} else if (display->platform.broadwell) {
|
||||
/*
|
||||
* FIXME with extra cooling we can allow
|
||||
* 540 MHz for ULX and 675 Mhz for ULT.
|
||||
|
|
@ -3426,15 +3406,15 @@ void intel_update_max_cdclk(struct intel_display *display)
|
|||
*/
|
||||
if (intel_de_read(display, FUSE_STRAP) & HSW_CDCLK_LIMIT)
|
||||
display->cdclk.max_cdclk_freq = 450000;
|
||||
else if (IS_BROADWELL_ULX(dev_priv))
|
||||
else if (display->platform.broadwell_ulx)
|
||||
display->cdclk.max_cdclk_freq = 450000;
|
||||
else if (IS_BROADWELL_ULT(dev_priv))
|
||||
else if (display->platform.broadwell_ult)
|
||||
display->cdclk.max_cdclk_freq = 540000;
|
||||
else
|
||||
display->cdclk.max_cdclk_freq = 675000;
|
||||
} else if (IS_CHERRYVIEW(dev_priv)) {
|
||||
} else if (display->platform.cherryview) {
|
||||
display->cdclk.max_cdclk_freq = 320000;
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
} else if (display->platform.valleyview) {
|
||||
display->cdclk.max_cdclk_freq = 400000;
|
||||
} else {
|
||||
/* otherwise assume cdclk is fixed */
|
||||
|
|
@ -3458,8 +3438,6 @@ void intel_update_max_cdclk(struct intel_display *display)
|
|||
*/
|
||||
void intel_update_cdclk(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
intel_cdclk_get_cdclk(display, &display->cdclk.hw);
|
||||
|
||||
/*
|
||||
|
|
@ -3468,7 +3446,7 @@ void intel_update_cdclk(struct intel_display *display)
|
|||
* of cdclk that generates 4MHz reference clock freq which is used to
|
||||
* generate GMBus clock. This will vary with the cdclk freq.
|
||||
*/
|
||||
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
if (display->platform.valleyview || display->platform.cherryview)
|
||||
intel_de_write(display, GMBUSFREQ_VLV,
|
||||
DIV_ROUND_UP(display->cdclk.hw.cdclk, 1000));
|
||||
}
|
||||
|
|
@ -3562,7 +3540,7 @@ u32 intel_read_rawclk(struct intel_display *display)
|
|||
freq = cnp_rawclk(display);
|
||||
else if (HAS_PCH_SPLIT(dev_priv))
|
||||
freq = pch_rawclk(display);
|
||||
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
else if (display->platform.valleyview || display->platform.cherryview)
|
||||
freq = vlv_hrawclk(display);
|
||||
else if (DISPLAY_VER(display) >= 3)
|
||||
freq = i9xx_hrawclk(display);
|
||||
|
|
@ -3743,8 +3721,6 @@ static const struct intel_cdclk_funcs i830_cdclk_funcs = {
|
|||
*/
|
||||
void intel_init_cdclk_hooks(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (DISPLAY_VER(display) >= 30) {
|
||||
display->funcs.cdclk = &xe3lpd_cdclk_funcs;
|
||||
display->cdclk.table = xe3lpd_cdclk_table;
|
||||
|
|
@ -3757,80 +3733,80 @@ void intel_init_cdclk_hooks(struct intel_display *display)
|
|||
} else if (DISPLAY_VER(display) >= 14) {
|
||||
display->funcs.cdclk = &rplu_cdclk_funcs;
|
||||
display->cdclk.table = mtl_cdclk_table;
|
||||
} else if (IS_DG2(dev_priv)) {
|
||||
} else if (display->platform.dg2) {
|
||||
display->funcs.cdclk = &tgl_cdclk_funcs;
|
||||
display->cdclk.table = dg2_cdclk_table;
|
||||
} else if (IS_ALDERLAKE_P(dev_priv)) {
|
||||
} else if (display->platform.alderlake_p) {
|
||||
/* Wa_22011320316:adl-p[a0] */
|
||||
if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) {
|
||||
if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) {
|
||||
display->cdclk.table = adlp_a_step_cdclk_table;
|
||||
display->funcs.cdclk = &tgl_cdclk_funcs;
|
||||
} else if (IS_RAPTORLAKE_U(dev_priv)) {
|
||||
} else if (display->platform.alderlake_p_raptorlake_u) {
|
||||
display->cdclk.table = rplu_cdclk_table;
|
||||
display->funcs.cdclk = &rplu_cdclk_funcs;
|
||||
} else {
|
||||
display->cdclk.table = adlp_cdclk_table;
|
||||
display->funcs.cdclk = &tgl_cdclk_funcs;
|
||||
}
|
||||
} else if (IS_ROCKETLAKE(dev_priv)) {
|
||||
} else if (display->platform.rocketlake) {
|
||||
display->funcs.cdclk = &tgl_cdclk_funcs;
|
||||
display->cdclk.table = rkl_cdclk_table;
|
||||
} else if (DISPLAY_VER(display) >= 12) {
|
||||
display->funcs.cdclk = &tgl_cdclk_funcs;
|
||||
display->cdclk.table = icl_cdclk_table;
|
||||
} else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
|
||||
} else if (display->platform.jasperlake || display->platform.elkhartlake) {
|
||||
display->funcs.cdclk = &ehl_cdclk_funcs;
|
||||
display->cdclk.table = icl_cdclk_table;
|
||||
} else if (DISPLAY_VER(display) >= 11) {
|
||||
display->funcs.cdclk = &icl_cdclk_funcs;
|
||||
display->cdclk.table = icl_cdclk_table;
|
||||
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
|
||||
} else if (display->platform.geminilake || display->platform.broxton) {
|
||||
display->funcs.cdclk = &bxt_cdclk_funcs;
|
||||
if (IS_GEMINILAKE(dev_priv))
|
||||
if (display->platform.geminilake)
|
||||
display->cdclk.table = glk_cdclk_table;
|
||||
else
|
||||
display->cdclk.table = bxt_cdclk_table;
|
||||
} else if (DISPLAY_VER(display) == 9) {
|
||||
display->funcs.cdclk = &skl_cdclk_funcs;
|
||||
} else if (IS_BROADWELL(dev_priv)) {
|
||||
} else if (display->platform.broadwell) {
|
||||
display->funcs.cdclk = &bdw_cdclk_funcs;
|
||||
} else if (IS_HASWELL(dev_priv)) {
|
||||
} else if (display->platform.haswell) {
|
||||
display->funcs.cdclk = &hsw_cdclk_funcs;
|
||||
} else if (IS_CHERRYVIEW(dev_priv)) {
|
||||
} else if (display->platform.cherryview) {
|
||||
display->funcs.cdclk = &chv_cdclk_funcs;
|
||||
} else if (IS_VALLEYVIEW(dev_priv)) {
|
||||
} else if (display->platform.valleyview) {
|
||||
display->funcs.cdclk = &vlv_cdclk_funcs;
|
||||
} else if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv)) {
|
||||
} else if (display->platform.sandybridge || display->platform.ivybridge) {
|
||||
display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
|
||||
} else if (IS_IRONLAKE(dev_priv)) {
|
||||
} else if (display->platform.ironlake) {
|
||||
display->funcs.cdclk = &ilk_cdclk_funcs;
|
||||
} else if (IS_GM45(dev_priv)) {
|
||||
} else if (display->platform.gm45) {
|
||||
display->funcs.cdclk = &gm45_cdclk_funcs;
|
||||
} else if (IS_G45(dev_priv)) {
|
||||
} else if (display->platform.g45) {
|
||||
display->funcs.cdclk = &g33_cdclk_funcs;
|
||||
} else if (IS_I965GM(dev_priv)) {
|
||||
} else if (display->platform.i965gm) {
|
||||
display->funcs.cdclk = &i965gm_cdclk_funcs;
|
||||
} else if (IS_I965G(dev_priv)) {
|
||||
} else if (display->platform.i965g) {
|
||||
display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
|
||||
} else if (IS_PINEVIEW(dev_priv)) {
|
||||
} else if (display->platform.pineview) {
|
||||
display->funcs.cdclk = &pnv_cdclk_funcs;
|
||||
} else if (IS_G33(dev_priv)) {
|
||||
} else if (display->platform.g33) {
|
||||
display->funcs.cdclk = &g33_cdclk_funcs;
|
||||
} else if (IS_I945GM(dev_priv)) {
|
||||
} else if (display->platform.i945gm) {
|
||||
display->funcs.cdclk = &i945gm_cdclk_funcs;
|
||||
} else if (IS_I945G(dev_priv)) {
|
||||
} else if (display->platform.i945g) {
|
||||
display->funcs.cdclk = &fixed_400mhz_cdclk_funcs;
|
||||
} else if (IS_I915GM(dev_priv)) {
|
||||
} else if (display->platform.i915gm) {
|
||||
display->funcs.cdclk = &i915gm_cdclk_funcs;
|
||||
} else if (IS_I915G(dev_priv)) {
|
||||
} else if (display->platform.i915g) {
|
||||
display->funcs.cdclk = &i915g_cdclk_funcs;
|
||||
} else if (IS_I865G(dev_priv)) {
|
||||
} else if (display->platform.i865g) {
|
||||
display->funcs.cdclk = &i865g_cdclk_funcs;
|
||||
} else if (IS_I85X(dev_priv)) {
|
||||
} else if (display->platform.i85x) {
|
||||
display->funcs.cdclk = &i85x_cdclk_funcs;
|
||||
} else if (IS_I845G(dev_priv)) {
|
||||
} else if (display->platform.i845g) {
|
||||
display->funcs.cdclk = &i845g_cdclk_funcs;
|
||||
} else if (IS_I830(dev_priv)) {
|
||||
} else if (display->platform.i830) {
|
||||
display->funcs.cdclk = &i830_cdclk_funcs;
|
||||
}
|
||||
|
||||
|
|
|
|||
189
drivers/gpu/drm/i915/display/intel_cmtg.c
Normal file
189
drivers/gpu/drm/i915/display/intel_cmtg.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_print.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_crtc.h"
|
||||
#include "intel_cmtg.h"
|
||||
#include "intel_cmtg_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_device.h"
|
||||
#include "intel_display_power.h"
|
||||
|
||||
/**
|
||||
* DOC: Common Primary Timing Generator (CMTG)
|
||||
*
|
||||
* The CMTG is a timing generator that runs in parallel to transcoders timing
|
||||
* generators (TG) to provide a synchronization mechanism where CMTG acts as
|
||||
* primary and transcoders TGs act as secondary to the CMTG. The CMTG outputs
|
||||
* its TG start and frame sync signals to the transcoders that are configured
|
||||
* as secondary, which use those signals to synchronize their own timing with
|
||||
* the CMTG's.
|
||||
*
|
||||
* The CMTG can be used only with eDP or MIPI command mode and supports the
|
||||
* following use cases:
|
||||
*
|
||||
* - Dual eDP: The CMTG can be used to keep two eDP TGs in sync when on a
|
||||
* dual eDP configuration (with or without PSR/PSR2 enabled).
|
||||
*
|
||||
* - Single eDP as secondary: It is also possible to use a single eDP
|
||||
* configuration with the transcoder TG as secondary to the CMTG. That would
|
||||
* allow a flow that would not require a modeset on the existing eDP when a
|
||||
* new eDP is added for a dual eDP configuration with CMTG.
|
||||
*
|
||||
* - DC6v: In DC6v, the transcoder might be off but the CMTG keeps running to
|
||||
* maintain frame timings. When exiting DC6v, the transcoder TG then is
|
||||
* synced back the CMTG.
|
||||
*
|
||||
* Currently, the driver does not use the CMTG, but we need to make sure that
|
||||
* we disable it in case we inherit a display configuration with it enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We describe here only the minimum data required to allow us to properly
|
||||
* disable the CMTG if necessary.
|
||||
*/
|
||||
struct intel_cmtg_config {
|
||||
bool cmtg_a_enable;
|
||||
/*
|
||||
* Xe2_LPD adds a second CMTG that can be used for dual eDP async mode.
|
||||
*/
|
||||
bool cmtg_b_enable;
|
||||
bool trans_a_secondary;
|
||||
bool trans_b_secondary;
|
||||
};
|
||||
|
||||
static bool intel_cmtg_has_cmtg_b(struct intel_display *display)
|
||||
{
|
||||
return DISPLAY_VER(display) >= 20;
|
||||
}
|
||||
|
||||
static bool intel_cmtg_has_clock_sel(struct intel_display *display)
|
||||
{
|
||||
return DISPLAY_VER(display) >= 14;
|
||||
}
|
||||
|
||||
static void intel_cmtg_dump_config(struct intel_display *display,
|
||||
struct intel_cmtg_config *cmtg_config)
|
||||
{
|
||||
drm_dbg_kms(display->drm,
|
||||
"CMTG readout: CMTG A: %s, CMTG B: %s, Transcoder A secondary: %s, Transcoder B secondary: %s\n",
|
||||
str_enabled_disabled(cmtg_config->cmtg_a_enable),
|
||||
intel_cmtg_has_cmtg_b(display) ? str_enabled_disabled(cmtg_config->cmtg_b_enable) : "n/a",
|
||||
str_yes_no(cmtg_config->trans_a_secondary),
|
||||
str_yes_no(cmtg_config->trans_b_secondary));
|
||||
}
|
||||
|
||||
static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display,
|
||||
enum transcoder trans)
|
||||
{
|
||||
enum intel_display_power_domain power_domain;
|
||||
intel_wakeref_t wakeref;
|
||||
u32 val = 0;
|
||||
|
||||
if (!HAS_TRANSCODER(display, trans))
|
||||
return false;
|
||||
|
||||
power_domain = POWER_DOMAIN_TRANSCODER(trans);
|
||||
|
||||
with_intel_display_power_if_enabled(display, power_domain, wakeref)
|
||||
val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, trans));
|
||||
|
||||
return val & CMTG_SECONDARY_MODE;
|
||||
}
|
||||
|
||||
static void intel_cmtg_get_config(struct intel_display *display,
|
||||
struct intel_cmtg_config *cmtg_config)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(display, TRANS_CMTG_CTL_A);
|
||||
cmtg_config->cmtg_a_enable = val & CMTG_ENABLE;
|
||||
|
||||
if (intel_cmtg_has_cmtg_b(display)) {
|
||||
val = intel_de_read(display, TRANS_CMTG_CTL_B);
|
||||
cmtg_config->cmtg_b_enable = val & CMTG_ENABLE;
|
||||
}
|
||||
|
||||
cmtg_config->trans_a_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_A);
|
||||
cmtg_config->trans_b_secondary = intel_cmtg_transcoder_is_secondary(display, TRANSCODER_B);
|
||||
}
|
||||
|
||||
static bool intel_cmtg_disable_requires_modeset(struct intel_display *display,
|
||||
struct intel_cmtg_config *cmtg_config)
|
||||
{
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
return false;
|
||||
|
||||
return cmtg_config->trans_a_secondary || cmtg_config->trans_b_secondary;
|
||||
}
|
||||
|
||||
static void intel_cmtg_disable(struct intel_display *display,
|
||||
struct intel_cmtg_config *cmtg_config)
|
||||
{
|
||||
u32 clk_sel_clr = 0;
|
||||
u32 clk_sel_set = 0;
|
||||
|
||||
if (cmtg_config->trans_a_secondary)
|
||||
intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_A),
|
||||
CMTG_SECONDARY_MODE, 0);
|
||||
|
||||
if (cmtg_config->trans_b_secondary)
|
||||
intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_B),
|
||||
CMTG_SECONDARY_MODE, 0);
|
||||
|
||||
if (cmtg_config->cmtg_a_enable) {
|
||||
drm_dbg_kms(display->drm, "Disabling CMTG A\n");
|
||||
intel_de_rmw(display, TRANS_CMTG_CTL_A, CMTG_ENABLE, 0);
|
||||
clk_sel_clr |= CMTG_CLK_SEL_A_MASK;
|
||||
clk_sel_set |= CMTG_CLK_SEL_A_DISABLED;
|
||||
}
|
||||
|
||||
if (cmtg_config->cmtg_b_enable) {
|
||||
drm_dbg_kms(display->drm, "Disabling CMTG B\n");
|
||||
intel_de_rmw(display, TRANS_CMTG_CTL_B, CMTG_ENABLE, 0);
|
||||
clk_sel_clr |= CMTG_CLK_SEL_B_MASK;
|
||||
clk_sel_set |= CMTG_CLK_SEL_B_DISABLED;
|
||||
}
|
||||
|
||||
if (intel_cmtg_has_clock_sel(display) && clk_sel_clr)
|
||||
intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read out CMTG configuration and, on platforms that allow disabling it without
|
||||
* a modeset, do it.
|
||||
*
|
||||
* This function must be called before any port PLL is disabled in the general
|
||||
* sanitization process, because we need whatever port PLL that is providing the
|
||||
* clock for CMTG to be on before accessing CMTG registers.
|
||||
*/
|
||||
void intel_cmtg_sanitize(struct intel_display *display)
|
||||
{
|
||||
struct intel_cmtg_config cmtg_config = {};
|
||||
|
||||
if (!HAS_CMTG(display))
|
||||
return;
|
||||
|
||||
intel_cmtg_get_config(display, &cmtg_config);
|
||||
intel_cmtg_dump_config(display, &cmtg_config);
|
||||
|
||||
/*
|
||||
* FIXME: The driver is not prepared to handle cases where a modeset is
|
||||
* required for disabling the CMTG: we need a proper way of tracking
|
||||
* CMTG state and do the right syncronization with respect to triggering
|
||||
* the modeset as part of the disable sequence.
|
||||
*/
|
||||
if (intel_cmtg_disable_requires_modeset(display, &cmtg_config))
|
||||
return;
|
||||
|
||||
intel_cmtg_disable(display, &cmtg_config);
|
||||
}
|
||||
13
drivers/gpu/drm/i915/display/intel_cmtg.h
Normal file
13
drivers/gpu/drm/i915/display/intel_cmtg.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_CMTG_H__
|
||||
#define __INTEL_CMTG_H__
|
||||
|
||||
struct intel_display;
|
||||
|
||||
void intel_cmtg_sanitize(struct intel_display *display);
|
||||
|
||||
#endif /* __INTEL_CMTG_H__ */
|
||||
21
drivers/gpu/drm/i915/display/intel_cmtg_regs.h
Normal file
21
drivers/gpu/drm/i915/display/intel_cmtg_regs.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_CMTG_REGS_H__
|
||||
#define __INTEL_CMTG_REGS_H__
|
||||
|
||||
#include "i915_reg_defs.h"
|
||||
|
||||
#define CMTG_CLK_SEL _MMIO(0x46160)
|
||||
#define CMTG_CLK_SEL_A_MASK REG_GENMASK(31, 29)
|
||||
#define CMTG_CLK_SEL_A_DISABLED REG_FIELD_PREP(CMTG_CLK_SEL_A_MASK, 0)
|
||||
#define CMTG_CLK_SEL_B_MASK REG_GENMASK(15, 13)
|
||||
#define CMTG_CLK_SEL_B_DISABLED REG_FIELD_PREP(CMTG_CLK_SEL_B_MASK, 0)
|
||||
|
||||
#define TRANS_CMTG_CTL_A _MMIO(0x6fa88)
|
||||
#define TRANS_CMTG_CTL_B _MMIO(0x6fb88)
|
||||
#define CMTG_ENABLE REG_BIT(31)
|
||||
|
||||
#endif /* __INTEL_CMTG_REGS_H__ */
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dsb.h"
|
||||
#include "intel_vrr.h"
|
||||
|
||||
struct intel_color_funcs {
|
||||
int (*color_check)(struct intel_atomic_state *state,
|
||||
|
|
@ -998,7 +999,7 @@ static void skl_color_commit_noarm(struct intel_dsb *dsb,
|
|||
* output all black (until CSC_MODE is rearmed and properly latched).
|
||||
* Once PSR exit (and proper register latching) has occurred the
|
||||
* danger is over. Thus when PSR is enabled the CSC coeff/offset
|
||||
* register programming will be peformed from skl_color_commit_arm()
|
||||
* register programming will be performed from skl_color_commit_arm()
|
||||
* which is called after PSR exit.
|
||||
*/
|
||||
if (!crtc_state->has_psr)
|
||||
|
|
@ -1987,8 +1988,12 @@ void intel_color_prepare_commit(struct intel_atomic_state *state,
|
|||
|
||||
display->funcs.color->load_luts(crtc_state);
|
||||
|
||||
intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
|
||||
intel_dsb_interrupt(crtc_state->dsb_color_vblank);
|
||||
if (crtc_state->use_dsb) {
|
||||
intel_vrr_send_push(crtc_state->dsb_color_vblank, crtc_state);
|
||||
intel_dsb_wait_vblank_delay(state, crtc_state->dsb_color_vblank);
|
||||
intel_vrr_check_push_sent(crtc_state->dsb_color_vblank, crtc_state);
|
||||
intel_dsb_interrupt(crtc_state->dsb_color_vblank);
|
||||
}
|
||||
|
||||
intel_dsb_finish(crtc_state->dsb_color_vblank);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,20 +3,20 @@
|
|||
* Copyright © 2018 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_combo_phy.h"
|
||||
#include "intel_combo_phy_regs.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
|
||||
#define for_each_combo_phy(__dev_priv, __phy) \
|
||||
#define for_each_combo_phy(__display, __phy) \
|
||||
for ((__phy) = PHY_A; (__phy) < I915_MAX_PHYS; (__phy)++) \
|
||||
for_each_if(intel_phy_is_combo(__dev_priv, __phy))
|
||||
for_each_if(intel_phy_is_combo(__display, __phy))
|
||||
|
||||
#define for_each_combo_phy_reverse(__dev_priv, __phy) \
|
||||
#define for_each_combo_phy_reverse(__display, __phy) \
|
||||
for ((__phy) = I915_MAX_PHYS; (__phy)-- > PHY_A;) \
|
||||
for_each_if(intel_phy_is_combo(__dev_priv, __phy))
|
||||
for_each_if(intel_phy_is_combo(__display, __phy))
|
||||
|
||||
enum {
|
||||
PROCMON_0_85V_DOT_0,
|
||||
|
|
@ -53,11 +53,11 @@ static const struct icl_procmon {
|
|||
};
|
||||
|
||||
static const struct icl_procmon *
|
||||
icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
|
||||
icl_get_procmon_ref_values(struct intel_display *display, enum phy phy)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
|
||||
val = intel_de_read(display, ICL_PORT_COMP_DW3(phy));
|
||||
switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
|
||||
default:
|
||||
MISSING_CASE(val);
|
||||
|
|
@ -75,57 +75,57 @@ icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
|
|||
}
|
||||
}
|
||||
|
||||
static void icl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
|
||||
static void icl_set_procmon_ref_values(struct intel_display *display,
|
||||
enum phy phy)
|
||||
{
|
||||
const struct icl_procmon *procmon;
|
||||
|
||||
procmon = icl_get_procmon_ref_values(dev_priv, phy);
|
||||
procmon = icl_get_procmon_ref_values(display, phy);
|
||||
|
||||
intel_de_rmw(dev_priv, ICL_PORT_COMP_DW1(phy),
|
||||
intel_de_rmw(display, ICL_PORT_COMP_DW1(phy),
|
||||
(0xff << 16) | 0xff, procmon->dw1);
|
||||
|
||||
intel_de_write(dev_priv, ICL_PORT_COMP_DW9(phy), procmon->dw9);
|
||||
intel_de_write(dev_priv, ICL_PORT_COMP_DW10(phy), procmon->dw10);
|
||||
intel_de_write(display, ICL_PORT_COMP_DW9(phy), procmon->dw9);
|
||||
intel_de_write(display, ICL_PORT_COMP_DW10(phy), procmon->dw10);
|
||||
}
|
||||
|
||||
static bool check_phy_reg(struct drm_i915_private *dev_priv,
|
||||
static bool check_phy_reg(struct intel_display *display,
|
||||
enum phy phy, i915_reg_t reg, u32 mask,
|
||||
u32 expected_val)
|
||||
{
|
||||
u32 val = intel_de_read(dev_priv, reg);
|
||||
u32 val = intel_de_read(display, reg);
|
||||
|
||||
if ((val & mask) != expected_val) {
|
||||
drm_dbg(&dev_priv->drm,
|
||||
"Combo PHY %c reg %08x state mismatch: "
|
||||
"current %08x mask %08x expected %08x\n",
|
||||
phy_name(phy),
|
||||
reg.reg, val, mask, expected_val);
|
||||
drm_dbg_kms(display->drm,
|
||||
"Combo PHY %c reg %08x state mismatch: "
|
||||
"current %08x mask %08x expected %08x\n",
|
||||
phy_name(phy),
|
||||
reg.reg, val, mask, expected_val);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool icl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
|
||||
static bool icl_verify_procmon_ref_values(struct intel_display *display,
|
||||
enum phy phy)
|
||||
{
|
||||
const struct icl_procmon *procmon;
|
||||
bool ret;
|
||||
|
||||
procmon = icl_get_procmon_ref_values(dev_priv, phy);
|
||||
procmon = icl_get_procmon_ref_values(display, phy);
|
||||
|
||||
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
|
||||
ret = check_phy_reg(display, phy, ICL_PORT_COMP_DW1(phy),
|
||||
(0xff << 16) | 0xff, procmon->dw1);
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW9(phy),
|
||||
-1U, procmon->dw9);
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW10(phy),
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW10(phy),
|
||||
-1U, procmon->dw10);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy)
|
||||
static bool has_phy_misc(struct intel_display *display, enum phy phy)
|
||||
{
|
||||
/*
|
||||
* Some platforms only expect PHY_MISC to be programmed for PHY-A and
|
||||
|
|
@ -136,32 +136,30 @@ static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy)
|
|||
* that we program it for PHY A.
|
||||
*/
|
||||
|
||||
if (IS_ALDERLAKE_S(i915))
|
||||
if (display->platform.alderlake_s)
|
||||
return phy == PHY_A;
|
||||
else if ((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) ||
|
||||
IS_ROCKETLAKE(i915) ||
|
||||
IS_DG1(i915))
|
||||
else if ((display->platform.jasperlake || display->platform.elkhartlake) ||
|
||||
display->platform.rocketlake ||
|
||||
display->platform.dg1)
|
||||
return phy < PHY_C;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv,
|
||||
static bool icl_combo_phy_enabled(struct intel_display *display,
|
||||
enum phy phy)
|
||||
{
|
||||
/* The PHY C added by EHL has no PHY_MISC register */
|
||||
if (!has_phy_misc(dev_priv, phy))
|
||||
return intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
|
||||
if (!has_phy_misc(display, phy))
|
||||
return intel_de_read(display, ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
|
||||
else
|
||||
return !(intel_de_read(dev_priv, ICL_PHY_MISC(phy)) &
|
||||
return !(intel_de_read(display, ICL_PHY_MISC(phy)) &
|
||||
ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) &&
|
||||
(intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
|
||||
(intel_de_read(display, ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
|
||||
}
|
||||
|
||||
static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915)
|
||||
static bool ehl_vbt_ddi_d_present(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
|
||||
bool ddi_a_present = intel_bios_is_port_present(display, PORT_A);
|
||||
bool ddi_d_present = intel_bios_is_port_present(display, PORT_D);
|
||||
bool dsi_present = intel_bios_is_dsi_present(display, NULL);
|
||||
|
|
@ -181,13 +179,13 @@ static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915)
|
|||
* in the log and let the internal display win.
|
||||
*/
|
||||
if (ddi_d_present)
|
||||
drm_err(&i915->drm,
|
||||
drm_err(display->drm,
|
||||
"VBT claims to have both internal and external displays on PHY A. Configuring for internal.\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
|
||||
static bool phy_is_master(struct intel_display *display, enum phy phy)
|
||||
{
|
||||
/*
|
||||
* Certain PHYs are connected to compensation resistors and act
|
||||
|
|
@ -207,64 +205,64 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
|
|||
*/
|
||||
if (phy == PHY_A)
|
||||
return true;
|
||||
else if (IS_ALDERLAKE_S(dev_priv))
|
||||
else if (display->platform.alderlake_s)
|
||||
return phy == PHY_D;
|
||||
else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
|
||||
else if (display->platform.dg1 || display->platform.rocketlake)
|
||||
return phy == PHY_C;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
|
||||
static bool icl_combo_phy_verify_state(struct intel_display *display,
|
||||
enum phy phy)
|
||||
{
|
||||
bool ret = true;
|
||||
u32 expected_val = 0;
|
||||
|
||||
if (!icl_combo_phy_enabled(dev_priv, phy))
|
||||
if (!icl_combo_phy_enabled(display, phy))
|
||||
return false;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_TX_DW8_LN(0, phy),
|
||||
if (DISPLAY_VER(display) >= 12) {
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_TX_DW8_LN(0, phy),
|
||||
ICL_PORT_TX_DW8_ODCC_CLK_SEL |
|
||||
ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK,
|
||||
ICL_PORT_TX_DW8_ODCC_CLK_SEL |
|
||||
ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2);
|
||||
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN(0, phy),
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_PCS_DW1_LN(0, phy),
|
||||
DCC_MODE_SELECT_MASK, RUN_DCC_ONCE);
|
||||
}
|
||||
|
||||
ret &= icl_verify_procmon_ref_values(dev_priv, phy);
|
||||
ret &= icl_verify_procmon_ref_values(display, phy);
|
||||
|
||||
if (phy_is_master(dev_priv, phy)) {
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
|
||||
if (phy_is_master(display, phy)) {
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_COMP_DW8(phy),
|
||||
IREFGEN, IREFGEN);
|
||||
|
||||
if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) {
|
||||
if (ehl_vbt_ddi_d_present(dev_priv))
|
||||
if (display->platform.jasperlake || display->platform.elkhartlake) {
|
||||
if (ehl_vbt_ddi_d_present(display))
|
||||
expected_val = ICL_PHY_MISC_MUX_DDID;
|
||||
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PHY_MISC(phy),
|
||||
ret &= check_phy_reg(display, phy, ICL_PHY_MISC(phy),
|
||||
ICL_PHY_MISC_MUX_DDID,
|
||||
expected_val);
|
||||
}
|
||||
}
|
||||
|
||||
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_CL_DW5(phy),
|
||||
ret &= check_phy_reg(display, phy, ICL_PORT_CL_DW5(phy),
|
||||
CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
|
||||
void intel_combo_phy_power_up_lanes(struct intel_display *display,
|
||||
enum phy phy, bool is_dsi,
|
||||
int lane_count, bool lane_reversal)
|
||||
{
|
||||
u8 lane_mask;
|
||||
|
||||
if (is_dsi) {
|
||||
drm_WARN_ON(&dev_priv->drm, lane_reversal);
|
||||
drm_WARN_ON(display->drm, lane_reversal);
|
||||
|
||||
switch (lane_count) {
|
||||
case 1:
|
||||
|
|
@ -302,28 +300,28 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
}
|
||||
|
||||
intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy),
|
||||
intel_de_rmw(display, ICL_PORT_CL_DW10(phy),
|
||||
PWR_DOWN_LN_MASK, lane_mask);
|
||||
}
|
||||
|
||||
static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
|
||||
static void icl_combo_phys_init(struct intel_display *display)
|
||||
{
|
||||
enum phy phy;
|
||||
|
||||
for_each_combo_phy(dev_priv, phy) {
|
||||
for_each_combo_phy(display, phy) {
|
||||
const struct icl_procmon *procmon;
|
||||
u32 val;
|
||||
|
||||
if (icl_combo_phy_verify_state(dev_priv, phy))
|
||||
if (icl_combo_phy_verify_state(display, phy))
|
||||
continue;
|
||||
|
||||
procmon = icl_get_procmon_ref_values(dev_priv, phy);
|
||||
procmon = icl_get_procmon_ref_values(display, phy);
|
||||
|
||||
drm_dbg(&dev_priv->drm,
|
||||
"Initializing combo PHY %c (Voltage/Process Info : %s)\n",
|
||||
phy_name(phy), procmon->name);
|
||||
drm_dbg_kms(display->drm,
|
||||
"Initializing combo PHY %c (Voltage/Process Info : %s)\n",
|
||||
phy_name(phy), procmon->name);
|
||||
|
||||
if (!has_phy_misc(dev_priv, phy))
|
||||
if (!has_phy_misc(display, phy))
|
||||
goto skip_phy_misc;
|
||||
|
||||
/*
|
||||
|
|
@ -334,84 +332,84 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
|
|||
* based on whether our VBT indicates the presence of any
|
||||
* "internal" child devices.
|
||||
*/
|
||||
val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
|
||||
if ((IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) &&
|
||||
val = intel_de_read(display, ICL_PHY_MISC(phy));
|
||||
if ((display->platform.jasperlake || display->platform.elkhartlake) &&
|
||||
phy == PHY_A) {
|
||||
val &= ~ICL_PHY_MISC_MUX_DDID;
|
||||
|
||||
if (ehl_vbt_ddi_d_present(dev_priv))
|
||||
if (ehl_vbt_ddi_d_present(display))
|
||||
val |= ICL_PHY_MISC_MUX_DDID;
|
||||
}
|
||||
|
||||
val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
|
||||
intel_de_write(dev_priv, ICL_PHY_MISC(phy), val);
|
||||
intel_de_write(display, ICL_PHY_MISC(phy), val);
|
||||
|
||||
skip_phy_misc:
|
||||
if (DISPLAY_VER(dev_priv) >= 12) {
|
||||
val = intel_de_read(dev_priv, ICL_PORT_TX_DW8_LN(0, phy));
|
||||
if (DISPLAY_VER(display) >= 12) {
|
||||
val = intel_de_read(display, ICL_PORT_TX_DW8_LN(0, phy));
|
||||
val &= ~ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK;
|
||||
val |= ICL_PORT_TX_DW8_ODCC_CLK_SEL;
|
||||
val |= ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2;
|
||||
intel_de_write(dev_priv, ICL_PORT_TX_DW8_GRP(phy), val);
|
||||
intel_de_write(display, ICL_PORT_TX_DW8_GRP(phy), val);
|
||||
|
||||
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy));
|
||||
val = intel_de_read(display, ICL_PORT_PCS_DW1_LN(0, phy));
|
||||
val &= ~DCC_MODE_SELECT_MASK;
|
||||
val |= RUN_DCC_ONCE;
|
||||
intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val);
|
||||
intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy), val);
|
||||
}
|
||||
|
||||
icl_set_procmon_ref_values(dev_priv, phy);
|
||||
icl_set_procmon_ref_values(display, phy);
|
||||
|
||||
if (phy_is_master(dev_priv, phy))
|
||||
intel_de_rmw(dev_priv, ICL_PORT_COMP_DW8(phy),
|
||||
if (phy_is_master(display, phy))
|
||||
intel_de_rmw(display, ICL_PORT_COMP_DW8(phy),
|
||||
0, IREFGEN);
|
||||
|
||||
intel_de_rmw(dev_priv, ICL_PORT_COMP_DW0(phy), 0, COMP_INIT);
|
||||
intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy),
|
||||
intel_de_rmw(display, ICL_PORT_COMP_DW0(phy), 0, COMP_INIT);
|
||||
intel_de_rmw(display, ICL_PORT_CL_DW5(phy),
|
||||
0, CL_POWER_DOWN_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
|
||||
static void icl_combo_phys_uninit(struct intel_display *display)
|
||||
{
|
||||
enum phy phy;
|
||||
|
||||
for_each_combo_phy_reverse(dev_priv, phy) {
|
||||
for_each_combo_phy_reverse(display, phy) {
|
||||
if (phy == PHY_A &&
|
||||
!icl_combo_phy_verify_state(dev_priv, phy)) {
|
||||
if (IS_TIGERLAKE(dev_priv) || IS_DG1(dev_priv)) {
|
||||
!icl_combo_phy_verify_state(display, phy)) {
|
||||
if (display->platform.tigerlake || display->platform.dg1) {
|
||||
/*
|
||||
* A known problem with old ifwi:
|
||||
* https://gitlab.freedesktop.org/drm/intel/-/issues/2411
|
||||
* Suppress the warning for CI. Remove ASAP!
|
||||
*/
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Combo PHY %c HW state changed unexpectedly\n",
|
||||
phy_name(phy));
|
||||
} else {
|
||||
drm_warn(&dev_priv->drm,
|
||||
drm_warn(display->drm,
|
||||
"Combo PHY %c HW state changed unexpectedly\n",
|
||||
phy_name(phy));
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_phy_misc(dev_priv, phy))
|
||||
if (!has_phy_misc(display, phy))
|
||||
goto skip_phy_misc;
|
||||
|
||||
intel_de_rmw(dev_priv, ICL_PHY_MISC(phy), 0,
|
||||
intel_de_rmw(display, ICL_PHY_MISC(phy), 0,
|
||||
ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN);
|
||||
|
||||
skip_phy_misc:
|
||||
intel_de_rmw(dev_priv, ICL_PORT_COMP_DW0(phy), COMP_INIT, 0);
|
||||
intel_de_rmw(display, ICL_PORT_COMP_DW0(phy), COMP_INIT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void intel_combo_phy_init(struct drm_i915_private *i915)
|
||||
void intel_combo_phy_init(struct intel_display *display)
|
||||
{
|
||||
icl_combo_phys_init(i915);
|
||||
icl_combo_phys_init(display);
|
||||
}
|
||||
|
||||
void intel_combo_phy_uninit(struct drm_i915_private *i915)
|
||||
void intel_combo_phy_uninit(struct intel_display *display)
|
||||
{
|
||||
icl_combo_phys_uninit(i915);
|
||||
icl_combo_phys_uninit(display);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_i915_private;
|
||||
enum phy;
|
||||
struct intel_display;
|
||||
|
||||
void intel_combo_phy_init(struct drm_i915_private *dev_priv);
|
||||
void intel_combo_phy_uninit(struct drm_i915_private *dev_priv);
|
||||
void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
|
||||
void intel_combo_phy_init(struct intel_display *display);
|
||||
void intel_combo_phy_uninit(struct intel_display *display);
|
||||
void intel_combo_phy_power_up_lanes(struct intel_display *display,
|
||||
enum phy phy, bool is_dsi,
|
||||
int lane_count, bool lane_reversal);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_backlight.h"
|
||||
|
|
@ -37,6 +38,44 @@
|
|||
#include "intel_hdcp.h"
|
||||
#include "intel_panel.h"
|
||||
|
||||
static void intel_connector_modeset_retry_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct intel_connector *connector = container_of(work, typeof(*connector),
|
||||
modeset_retry_work);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
|
||||
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.base.id,
|
||||
connector->base.name);
|
||||
|
||||
/* Grab the locks before changing connector property*/
|
||||
mutex_lock(&display->drm->mode_config.mutex);
|
||||
/* Set connector link status to BAD and send a Uevent to notify
|
||||
* userspace to do a modeset.
|
||||
*/
|
||||
drm_connector_set_link_status_property(&connector->base,
|
||||
DRM_MODE_LINK_STATUS_BAD);
|
||||
mutex_unlock(&display->drm->mode_config.mutex);
|
||||
/* Send Hotplug uevent so userspace can reprobe */
|
||||
drm_kms_helper_connector_hotplug_event(&connector->base);
|
||||
|
||||
drm_connector_put(&connector->base);
|
||||
}
|
||||
|
||||
void intel_connector_queue_modeset_retry_work(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
|
||||
drm_connector_get(&connector->base);
|
||||
if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work))
|
||||
drm_connector_put(&connector->base);
|
||||
}
|
||||
|
||||
void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector)
|
||||
{
|
||||
if (cancel_work_sync(&connector->modeset_retry_work))
|
||||
drm_connector_put(&connector->base);
|
||||
}
|
||||
|
||||
int intel_connector_init(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_digital_connector_state *conn_state;
|
||||
|
|
@ -56,6 +95,9 @@ int intel_connector_init(struct intel_connector *connector)
|
|||
|
||||
intel_panel_init_alloc(connector);
|
||||
|
||||
INIT_WORK(&connector->modeset_retry_work,
|
||||
intel_connector_modeset_retry_work_fn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,5 +33,7 @@ void intel_attach_aspect_ratio_property(struct drm_connector *connector);
|
|||
void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
|
||||
void intel_attach_dp_colorspace_property(struct drm_connector *connector);
|
||||
void intel_attach_scaling_mode_property(struct drm_connector *connector);
|
||||
void intel_connector_queue_modeset_retry_work(struct intel_connector *connector);
|
||||
void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector);
|
||||
|
||||
#endif /* __INTEL_CONNECTOR_H__ */
|
||||
|
|
|
|||
|
|
@ -108,19 +108,18 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder,
|
|||
enum pipe *pipe)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crt *crt = intel_encoder_to_crt(encoder);
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv,
|
||||
wakeref = intel_display_power_get_if_enabled(display,
|
||||
encoder->power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
ret = intel_crt_port_enabled(display, crt->adpa_reg, pipe);
|
||||
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -251,11 +250,10 @@ static void hsw_disable_crt(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *old_conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder);
|
||||
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
}
|
||||
|
||||
static void hsw_post_disable_crt(struct intel_atomic_state *state,
|
||||
|
|
@ -265,7 +263,6 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
intel_crtc_vblank_off(old_crtc_state);
|
||||
|
||||
|
|
@ -285,7 +282,7 @@ static void hsw_post_disable_crt(struct intel_atomic_state *state,
|
|||
|
||||
drm_WARN_ON(display->drm, !old_crtc_state->has_pch_encoder);
|
||||
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
}
|
||||
|
||||
static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state,
|
||||
|
|
@ -294,11 +291,10 @@ static void hsw_pre_pll_enable_crt(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
|
||||
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
|
||||
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, false);
|
||||
}
|
||||
|
||||
static void hsw_pre_enable_crt(struct intel_atomic_state *state,
|
||||
|
|
@ -307,13 +303,12 @@ static void hsw_pre_enable_crt(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
drm_WARN_ON(display->drm, !crtc_state->has_pch_encoder);
|
||||
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, pipe, false);
|
||||
|
||||
hsw_fdi_link_train(encoder, crtc_state);
|
||||
|
||||
|
|
@ -326,7 +321,6 @@ static void hsw_enable_crt(struct intel_atomic_state *state,
|
|||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
|
|
@ -344,8 +338,8 @@ static void hsw_enable_crt(struct intel_atomic_state *state,
|
|||
|
||||
intel_crtc_wait_for_next_vblank(crtc);
|
||||
intel_crtc_wait_for_next_vblank(crtc);
|
||||
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
|
||||
intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
|
||||
intel_set_cpu_fifo_underrun_reporting(display, pipe, true);
|
||||
intel_set_pch_fifo_underrun_reporting(display, PIPE_A, true);
|
||||
}
|
||||
|
||||
static void intel_enable_crt(struct intel_atomic_state *state,
|
||||
|
|
@ -366,7 +360,7 @@ intel_crt_mode_valid(struct drm_connector *connector,
|
|||
enum drm_mode_status status;
|
||||
int max_clock;
|
||||
|
||||
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
|
||||
status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
|
|
@ -745,8 +739,10 @@ intel_crt_load_detect(struct intel_crt *crt, enum pipe pipe)
|
|||
transconf | TRANSCONF_FORCE_BORDER);
|
||||
intel_de_posting_read(display,
|
||||
TRANSCONF(display, cpu_transcoder));
|
||||
/* Wait for next Vblank to substitue
|
||||
* border color for Color info */
|
||||
/*
|
||||
* Wait for next Vblank to substitute
|
||||
* border color for Color info.
|
||||
*/
|
||||
intel_crtc_wait_for_next_vblank(intel_crtc_for_pipe(display, pipe));
|
||||
st00 = intel_de_read8(display, _VGA_MSR_WRITE);
|
||||
status = ((st00 & (1 << 4)) != 0) ?
|
||||
|
|
@ -856,7 +852,6 @@ intel_crt_detect(struct drm_connector *connector,
|
|||
bool force)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector));
|
||||
struct intel_encoder *encoder = &crt->base;
|
||||
struct drm_atomic_state *state;
|
||||
|
|
@ -874,7 +869,7 @@ intel_crt_detect(struct drm_connector *connector,
|
|||
return connector->status;
|
||||
|
||||
if (display->params.load_detect_test) {
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
wakeref = intel_display_power_get(display, encoder->power_domain);
|
||||
goto load_detect;
|
||||
}
|
||||
|
||||
|
|
@ -882,7 +877,7 @@ intel_crt_detect(struct drm_connector *connector,
|
|||
if (dmi_check_system(intel_spurious_crt_detect))
|
||||
return connector_status_disconnected;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
wakeref = intel_display_power_get(display, encoder->power_domain);
|
||||
|
||||
if (I915_HAS_HOTPLUG(display)) {
|
||||
/* We can not rely on the HPD pin always being correctly wired
|
||||
|
|
@ -939,7 +934,7 @@ intel_crt_detect(struct drm_connector *connector,
|
|||
}
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -957,7 +952,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
|
|||
if (!intel_display_driver_check_access(display))
|
||||
return drm_edid_connector_add_modes(connector);
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, encoder->power_domain);
|
||||
wakeref = intel_display_power_get(display, encoder->power_domain);
|
||||
|
||||
ret = intel_crt_ddc_get_modes(connector, connector->ddc);
|
||||
if (ret || !IS_G4X(dev_priv))
|
||||
|
|
@ -968,7 +963,7 @@ static int intel_crt_get_modes(struct drm_connector *connector)
|
|||
ret = intel_crt_ddc_get_modes(connector, ddc);
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, encoder->power_domain, wakeref);
|
||||
intel_display_power_put(display, encoder->power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1099,7 +1094,7 @@ void intel_crt_init(struct intel_display *display)
|
|||
connector->base.polled = connector->polled;
|
||||
|
||||
if (HAS_DDI(display)) {
|
||||
assert_port_valid(dev_priv, PORT_E);
|
||||
assert_port_valid(display, PORT_E);
|
||||
|
||||
crt->base.port = PORT_E;
|
||||
crt->base.get_config = hsw_crt_get_config;
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ static void assert_vblank_disabled(struct drm_crtc *crtc)
|
|||
drm_crtc_vblank_put(crtc);
|
||||
}
|
||||
|
||||
struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915)
|
||||
struct intel_crtc *intel_first_crtc(struct intel_display *display)
|
||||
{
|
||||
return to_intel_crtc(drm_crtc_from_index(&i915->drm, 0));
|
||||
return to_intel_crtc(drm_crtc_from_index(display->drm, 0));
|
||||
}
|
||||
|
||||
struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display,
|
||||
|
|
@ -68,10 +68,9 @@ void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc)
|
|||
drm_crtc_wait_one_vblank(&crtc->base);
|
||||
}
|
||||
|
||||
void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
|
||||
void intel_wait_for_vblank_if_active(struct intel_display *display,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
|
||||
if (crtc->active)
|
||||
|
|
@ -93,10 +92,10 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
|
|||
|
||||
u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
|
||||
/*
|
||||
* From Gen 11, In case of dsi cmd mode, frame counter wouldnt
|
||||
* From Gen 11, in case of dsi cmd mode, frame counter wouldn't
|
||||
* have updated at the beginning of TE, if we want to use
|
||||
* the hw counter, then we would find it updated in only
|
||||
* the next TE, hence switching to sw counter.
|
||||
|
|
@ -109,13 +108,13 @@ u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
|
|||
* On i965gm the hardware frame counter reads
|
||||
* zero when the TV encoder is enabled :(
|
||||
*/
|
||||
if (IS_I965GM(dev_priv) &&
|
||||
if (display->platform.i965gm &&
|
||||
(crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT)))
|
||||
return 0;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
return 0xffffffff; /* full 32 bit counter */
|
||||
else if (DISPLAY_VER(dev_priv) >= 3)
|
||||
else if (DISPLAY_VER(display) >= 3)
|
||||
return 0xffffff; /* only 24 bits of frame count */
|
||||
else
|
||||
return 0; /* Gen2 doesn't have a hardware frame counter */
|
||||
|
|
@ -142,8 +141,8 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
|
|||
|
||||
void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
|
||||
/*
|
||||
* Should really happen exactly when we disable the pipe
|
||||
|
|
@ -304,8 +303,9 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = {
|
|||
.get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
|
||||
};
|
||||
|
||||
int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
int intel_crtc_init(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_plane *primary, *cursor;
|
||||
const struct drm_crtc_funcs *funcs;
|
||||
struct intel_crtc *crtc;
|
||||
|
|
@ -316,27 +316,27 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
return PTR_ERR(crtc);
|
||||
|
||||
crtc->pipe = pipe;
|
||||
crtc->num_scalers = DISPLAY_RUNTIME_INFO(dev_priv)->num_scalers[pipe];
|
||||
crtc->num_scalers = DISPLAY_RUNTIME_INFO(display)->num_scalers[pipe];
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9)
|
||||
primary = skl_universal_plane_create(dev_priv, pipe, PLANE_1);
|
||||
if (DISPLAY_VER(display) >= 9)
|
||||
primary = skl_universal_plane_create(display, pipe, PLANE_1);
|
||||
else
|
||||
primary = intel_primary_plane_create(dev_priv, pipe);
|
||||
primary = intel_primary_plane_create(display, pipe);
|
||||
if (IS_ERR(primary)) {
|
||||
ret = PTR_ERR(primary);
|
||||
goto fail;
|
||||
}
|
||||
crtc->plane_ids_mask |= BIT(primary->id);
|
||||
|
||||
intel_init_fifo_underrun_reporting(dev_priv, crtc, false);
|
||||
intel_init_fifo_underrun_reporting(display, crtc, false);
|
||||
|
||||
for_each_sprite(dev_priv, pipe, sprite) {
|
||||
for_each_sprite(display, pipe, sprite) {
|
||||
struct intel_plane *plane;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9)
|
||||
plane = skl_universal_plane_create(dev_priv, pipe, PLANE_2 + sprite);
|
||||
plane = skl_universal_plane_create(display, pipe, PLANE_2 + sprite);
|
||||
else
|
||||
plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
|
||||
plane = intel_sprite_plane_create(display, pipe, sprite);
|
||||
if (IS_ERR(plane)) {
|
||||
ret = PTR_ERR(plane);
|
||||
goto fail;
|
||||
|
|
@ -344,39 +344,41 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
crtc->plane_ids_mask |= BIT(plane->id);
|
||||
}
|
||||
|
||||
cursor = intel_cursor_plane_create(dev_priv, pipe);
|
||||
cursor = intel_cursor_plane_create(display, pipe);
|
||||
if (IS_ERR(cursor)) {
|
||||
ret = PTR_ERR(cursor);
|
||||
goto fail;
|
||||
}
|
||||
crtc->plane_ids_mask |= BIT(cursor->id);
|
||||
|
||||
if (HAS_GMCH(dev_priv)) {
|
||||
if (IS_CHERRYVIEW(dev_priv) ||
|
||||
IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv))
|
||||
if (HAS_GMCH(display)) {
|
||||
if (display->platform.cherryview ||
|
||||
display->platform.valleyview ||
|
||||
display->platform.g4x)
|
||||
funcs = &g4x_crtc_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 4)
|
||||
else if (DISPLAY_VER(display) == 4)
|
||||
funcs = &i965_crtc_funcs;
|
||||
else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
|
||||
else if (display->platform.i945gm ||
|
||||
display->platform.i915gm)
|
||||
funcs = &i915gm_crtc_funcs;
|
||||
else if (DISPLAY_VER(dev_priv) == 3)
|
||||
else if (DISPLAY_VER(display) == 3)
|
||||
funcs = &i915_crtc_funcs;
|
||||
else
|
||||
funcs = &i8xx_crtc_funcs;
|
||||
} else {
|
||||
if (DISPLAY_VER(dev_priv) >= 8)
|
||||
if (DISPLAY_VER(display) >= 8)
|
||||
funcs = &bdw_crtc_funcs;
|
||||
else
|
||||
funcs = &ilk_crtc_funcs;
|
||||
}
|
||||
|
||||
ret = drm_crtc_init_with_planes(&dev_priv->drm, &crtc->base,
|
||||
ret = drm_crtc_init_with_planes(display->drm, &crtc->base,
|
||||
&primary->base, &cursor->base,
|
||||
funcs, "pipe %c", pipe_name(pipe));
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
if (DISPLAY_VER(display) >= 11)
|
||||
drm_crtc_create_scaling_filter_property(&crtc->base,
|
||||
BIT(DRM_SCALING_FILTER_DEFAULT) |
|
||||
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
|
||||
|
|
@ -387,7 +389,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
|
||||
cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE);
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
|
||||
drm_WARN_ON(display->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -512,7 +514,7 @@ int intel_scanlines_to_usecs(const struct drm_display_mode *adjusted_mode,
|
|||
void intel_pipe_update_start(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
struct intel_crtc_state *new_crtc_state =
|
||||
|
|
@ -520,6 +522,8 @@ void intel_pipe_update_start(struct intel_atomic_state *state,
|
|||
struct intel_vblank_evade_ctx evade;
|
||||
int scanline;
|
||||
|
||||
drm_WARN_ON(display->drm, new_crtc_state->use_dsb);
|
||||
|
||||
intel_psr_lock(new_crtc_state);
|
||||
|
||||
if (new_crtc_state->do_async_flip) {
|
||||
|
|
@ -546,7 +550,7 @@ void intel_pipe_update_start(struct intel_atomic_state *state,
|
|||
|
||||
intel_vblank_evade_init(old_crtc_state, new_crtc_state, &evade);
|
||||
|
||||
if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base)))
|
||||
if (drm_WARN_ON(display->drm, drm_crtc_vblank_get(&crtc->base)))
|
||||
goto irq_disable;
|
||||
|
||||
/*
|
||||
|
|
@ -649,6 +653,7 @@ void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state,
|
|||
void intel_pipe_update_end(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(state);
|
||||
struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
|
@ -657,6 +662,8 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
|
|||
ktime_t end_vbl_time = ktime_get();
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
|
||||
drm_WARN_ON(display->drm, new_crtc_state->use_dsb);
|
||||
|
||||
if (new_crtc_state->do_async_flip)
|
||||
goto out;
|
||||
|
||||
|
|
@ -666,7 +673,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
|
|||
* Incase of mipi dsi command mode, we need to set frame update
|
||||
* request for every commit.
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 11 &&
|
||||
if (DISPLAY_VER(display) >= 11 &&
|
||||
intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI))
|
||||
icl_dsi_frame_update(new_crtc_state);
|
||||
|
||||
|
|
@ -714,7 +721,8 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
|
|||
* which would cause the next frame to terminate already at vmin
|
||||
* vblank start instead of vmax vblank start.
|
||||
*/
|
||||
intel_vrr_send_push(new_crtc_state);
|
||||
if (!state->base.legacy_cursor_update)
|
||||
intel_vrr_send_push(NULL, new_crtc_state);
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
|
|
@ -723,7 +731,7 @@ void intel_pipe_update_end(struct intel_atomic_state *state,
|
|||
|
||||
if (crtc->debug.start_vbl_count &&
|
||||
crtc->debug.start_vbl_count != end_vbl_count) {
|
||||
drm_err(&dev_priv->drm,
|
||||
drm_err(display->drm,
|
||||
"Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
|
||||
pipe_name(pipe), crtc->debug.start_vbl_count,
|
||||
end_vbl_count,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ enum pipe;
|
|||
struct drm_device;
|
||||
struct drm_display_mode;
|
||||
struct drm_file;
|
||||
struct drm_i915_private;
|
||||
struct drm_pending_vblank_event;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
|
|
@ -38,7 +37,7 @@ void intel_crtc_arm_vblank_event(struct intel_crtc_state *crtc_state);
|
|||
void intel_crtc_prepare_vblank_event(struct intel_crtc_state *crtc_state,
|
||||
struct drm_pending_vblank_event **event);
|
||||
u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state);
|
||||
int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe);
|
||||
int intel_crtc_init(struct intel_display *display, enum pipe pipe);
|
||||
int intel_crtc_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
|
||||
|
|
@ -52,10 +51,10 @@ void intel_pipe_update_start(struct intel_atomic_state *state,
|
|||
void intel_pipe_update_end(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
void intel_wait_for_vblank_workers(struct intel_atomic_state *state);
|
||||
struct intel_crtc *intel_first_crtc(struct drm_i915_private *i915);
|
||||
struct intel_crtc *intel_first_crtc(struct intel_display *display);
|
||||
struct intel_crtc *intel_crtc_for_pipe(struct intel_display *display,
|
||||
enum pipe pipe);
|
||||
void intel_wait_for_vblank_if_active(struct drm_i915_private *i915,
|
||||
void intel_wait_for_vblank_if_active(struct intel_display *display,
|
||||
enum pipe pipe);
|
||||
void intel_crtc_wait_for_next_vblank(struct intel_crtc *crtc);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "intel_crtc_state_dump.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_hdmi.h"
|
||||
#include "intel_vblank.h"
|
||||
#include "intel_vdsc.h"
|
||||
#include "intel_vrr.h"
|
||||
|
||||
|
|
@ -175,6 +176,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
struct intel_atomic_state *state,
|
||||
const char *context)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(pipe_config);
|
||||
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
|
||||
const struct intel_plane_state *plane_state;
|
||||
|
|
@ -248,11 +250,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
str_enabled_disabled(pipe_config->has_sel_update),
|
||||
str_enabled_disabled(pipe_config->has_panel_replay),
|
||||
str_enabled_disabled(pipe_config->enable_psr2_sel_fetch));
|
||||
drm_printf(&p, "minimum HBlank: %d\n", pipe_config->min_hblank);
|
||||
}
|
||||
|
||||
drm_printf(&p, "framestart delay: %d, MSA timing delay: %d\n",
|
||||
pipe_config->framestart_delay, pipe_config->msa_timing_delay);
|
||||
|
||||
drm_printf(&p, "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n",
|
||||
pipe_config->has_audio, pipe_config->has_infoframe,
|
||||
pipe_config->infoframes.enable);
|
||||
|
|
@ -286,13 +286,23 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
drm_print_hex_dump(&p, "ELD: ", pipe_config->eld,
|
||||
drm_eld_size(pipe_config->eld));
|
||||
|
||||
drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, pipeline full: %d, guardband: %d flipline: %d, vmin vblank: %d, vmax vblank: %d\n",
|
||||
drm_printf(&p, "scanline offset: %d\n",
|
||||
intel_crtc_scanline_offset(pipe_config));
|
||||
|
||||
drm_printf(&p, "vblank delay: %d, framestart delay: %d, MSA timing delay: %d\n",
|
||||
pipe_config->hw.adjusted_mode.crtc_vblank_start -
|
||||
pipe_config->hw.adjusted_mode.crtc_vdisplay,
|
||||
pipe_config->framestart_delay, pipe_config->msa_timing_delay);
|
||||
|
||||
drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n",
|
||||
str_yes_no(pipe_config->vrr.enable),
|
||||
pipe_config->vrr.vmin, pipe_config->vrr.vmax,
|
||||
pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline,
|
||||
pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband,
|
||||
pipe_config->vrr.flipline,
|
||||
intel_vrr_vmin_vblank_start(pipe_config),
|
||||
intel_vrr_vmax_vblank_start(pipe_config));
|
||||
pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end);
|
||||
|
||||
drm_printf(&p, "vrr: vmin vblank: %d, vmax vblank: %d, vmin vtotal: %d, vmax vtotal: %d\n",
|
||||
intel_vrr_vmin_vblank_start(pipe_config), intel_vrr_vmax_vblank_start(pipe_config),
|
||||
intel_vrr_vmin_vtotal(pipe_config), intel_vrr_vmax_vtotal(pipe_config));
|
||||
|
||||
drm_printf(&p, "requested mode: " DRM_MODE_FMT "\n",
|
||||
DRM_MODE_ARG(&pipe_config->hw.mode));
|
||||
|
|
@ -331,7 +341,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
|
|||
pipe_config->ips_enabled, pipe_config->double_wide,
|
||||
pipe_config->has_drrs);
|
||||
|
||||
intel_dpll_dump_hw_state(i915, &p, &pipe_config->dpll_hw_state);
|
||||
intel_dpll_dump_hw_state(display, &p, &pipe_config->dpll_hw_state);
|
||||
|
||||
if (IS_CHERRYVIEW(i915))
|
||||
drm_printf(&p, "cgm_mode: 0x%x gamma_mode: 0x%x gamma_enable: %d csc_enable: %d\n",
|
||||
|
|
|
|||
|
|
@ -35,11 +35,10 @@ static const u32 intel_cursor_formats[] = {
|
|||
|
||||
static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
u32 base;
|
||||
|
||||
if (DISPLAY_INFO(dev_priv)->cursor_needs_physical)
|
||||
if (DISPLAY_INFO(display)->cursor_needs_physical)
|
||||
base = plane_state->phys_dma_addr;
|
||||
else
|
||||
base = intel_plane_ggtt_offset(plane_state);
|
||||
|
|
@ -92,8 +91,8 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
|
|||
|
||||
static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
int src_x, src_y;
|
||||
u32 offset;
|
||||
|
|
@ -114,8 +113,9 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
|
|||
plane_state, 0);
|
||||
|
||||
if (src_x != 0 || src_y != 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Arbitrary cursor panning not supported\n");
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] arbitrary cursor panning not supported\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
|
|||
src_x << 16, src_y << 16);
|
||||
|
||||
/* ILK+ do this automagically in hardware */
|
||||
if (HAS_GMCH(dev_priv) && rotation & DRM_MODE_ROTATE_180) {
|
||||
if (HAS_GMCH(display) && rotation & DRM_MODE_ROTATE_180) {
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
|
||||
int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
|
||||
|
|
@ -145,14 +145,16 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
|
|||
static int intel_check_cursor(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
|
||||
const struct drm_rect src = plane_state->uapi.src;
|
||||
const struct drm_rect dst = plane_state->uapi.dst;
|
||||
int ret;
|
||||
|
||||
if (fb && fb->modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||
drm_dbg_kms(&i915->drm, "cursor cannot be tiled\n");
|
||||
drm_dbg_kms(display->drm, "[PLANE:%d:%s] cursor cannot be tiled\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -233,8 +235,9 @@ static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
|
|||
static int i845_check_cursor(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
|
||||
int ret;
|
||||
|
||||
ret = intel_check_cursor(crtc_state, plane_state);
|
||||
|
|
@ -247,14 +250,15 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
|
|||
|
||||
/* Check for which cursor types we support */
|
||||
if (!i845_cursor_size_ok(plane_state)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Cursor dimension %dx%d not supported\n",
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] cursor dimension %dx%d not supported\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
drm_rect_height(&plane_state->uapi.dst));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drm_WARN_ON(&i915->drm, plane_state->uapi.visible &&
|
||||
drm_WARN_ON(display->drm, plane_state->uapi.visible &&
|
||||
plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
|
||||
|
||||
switch (fb->pitches[0]) {
|
||||
|
|
@ -264,7 +268,8 @@ static int i845_check_cursor(struct intel_crtc_state *crtc_state,
|
|||
case 2048:
|
||||
break;
|
||||
default:
|
||||
drm_dbg_kms(&i915->drm, "Invalid cursor stride (%u)\n",
|
||||
drm_dbg_kms(display->drm, "[PLANE:%d:%s] invalid cursor stride (%u)\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
fb->pitches[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -280,7 +285,7 @@ static void i845_cursor_update_arm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
u32 cntl = 0, base = 0, pos = 0, size = 0;
|
||||
|
||||
if (plane_state && plane_state->uapi.visible) {
|
||||
|
|
@ -302,17 +307,17 @@ static void i845_cursor_update_arm(struct intel_dsb *dsb,
|
|||
if (plane->cursor.base != base ||
|
||||
plane->cursor.size != size ||
|
||||
plane->cursor.cntl != cntl) {
|
||||
intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), 0);
|
||||
intel_de_write_fw(dev_priv, CURBASE(dev_priv, PIPE_A), base);
|
||||
intel_de_write_fw(dev_priv, CURSIZE(dev_priv, PIPE_A), size);
|
||||
intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
|
||||
intel_de_write_fw(dev_priv, CURCNTR(dev_priv, PIPE_A), cntl);
|
||||
intel_de_write_fw(display, CURCNTR(display, PIPE_A), 0);
|
||||
intel_de_write_fw(display, CURBASE(display, PIPE_A), base);
|
||||
intel_de_write_fw(display, CURSIZE(display, PIPE_A), size);
|
||||
intel_de_write_fw(display, CURPOS(display, PIPE_A), pos);
|
||||
intel_de_write_fw(display, CURCNTR(display, PIPE_A), cntl);
|
||||
|
||||
plane->cursor.base = base;
|
||||
plane->cursor.size = size;
|
||||
plane->cursor.cntl = cntl;
|
||||
} else {
|
||||
intel_de_write_fw(dev_priv, CURPOS(dev_priv, PIPE_A), pos);
|
||||
intel_de_write_fw(display, CURPOS(display, PIPE_A), pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -326,21 +331,21 @@ static void i845_cursor_disable_arm(struct intel_dsb *dsb,
|
|||
static bool i845_cursor_get_hw_state(struct intel_plane *plane,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum intel_display_power_domain power_domain;
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
||||
power_domain = POWER_DOMAIN_PIPE(PIPE_A);
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
||||
wakeref = intel_display_power_get_if_enabled(display, power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
ret = intel_de_read(dev_priv, CURCNTR(dev_priv, PIPE_A)) & CURSOR_ENABLE;
|
||||
ret = intel_de_read(display, CURCNTR(display, PIPE_A)) & CURSOR_ENABLE;
|
||||
|
||||
*pipe = PIPE_A;
|
||||
|
||||
intel_display_power_put(dev_priv, power_domain, wakeref);
|
||||
intel_display_power_put(display, power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -372,16 +377,21 @@ static unsigned int i9xx_cursor_min_alignment(struct intel_plane *plane,
|
|||
const struct drm_framebuffer *fb,
|
||||
int color_plane)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
|
||||
if (intel_scanout_needs_vtd_wa(display))
|
||||
return 64 * 1024;
|
||||
|
||||
return 4 * 1024; /* physical for i915/i945 */
|
||||
}
|
||||
|
||||
static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
u32 cntl = 0;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 11)
|
||||
if (DISPLAY_VER(display) >= 11)
|
||||
return cntl;
|
||||
|
||||
if (crtc_state->gamma_enable)
|
||||
|
|
@ -390,7 +400,7 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
|||
if (crtc_state->csc_enable)
|
||||
cntl |= MCURSOR_PIPE_CSC_ENABLE;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
|
||||
if (DISPLAY_VER(display) < 5 && !display->platform.g4x)
|
||||
cntl |= MCURSOR_PIPE_SEL(crtc->pipe);
|
||||
|
||||
return cntl;
|
||||
|
|
@ -399,11 +409,10 @@ static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
|
|||
static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
u32 cntl = 0;
|
||||
|
||||
if (IS_SANDYBRIDGE(dev_priv) || IS_IVYBRIDGE(dev_priv))
|
||||
if (display->platform.sandybridge || display->platform.ivybridge)
|
||||
cntl |= MCURSOR_TRICKLE_FEED_DISABLE;
|
||||
|
||||
switch (drm_rect_width(&plane_state->uapi.dst)) {
|
||||
|
|
@ -425,7 +434,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
|
|||
cntl |= MCURSOR_ROTATE_180;
|
||||
|
||||
/* Wa_22012358565:adl-p */
|
||||
if (DISPLAY_VER(dev_priv) == 13)
|
||||
if (DISPLAY_VER(display) == 13)
|
||||
cntl |= MCURSOR_ARB_SLOTS(1);
|
||||
|
||||
return cntl;
|
||||
|
|
@ -433,8 +442,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
|
|||
|
||||
static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *dev_priv =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
int width = drm_rect_width(&plane_state->uapi.dst);
|
||||
int height = drm_rect_height(&plane_state->uapi.dst);
|
||||
|
||||
|
|
@ -457,7 +465,7 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
|
|||
* cursor is not rotated. Everything else requires square
|
||||
* cursors.
|
||||
*/
|
||||
if (HAS_CUR_FBC(dev_priv) &&
|
||||
if (HAS_CUR_FBC(display) &&
|
||||
plane_state->hw.rotation & DRM_MODE_ROTATE_0) {
|
||||
if (height < 8 || height > width)
|
||||
return false;
|
||||
|
|
@ -472,8 +480,8 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
|
|||
static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
enum pipe pipe = plane->pipe;
|
||||
int ret;
|
||||
|
|
@ -488,22 +496,23 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
|
|||
|
||||
/* Check for which cursor types we support */
|
||||
if (!i9xx_cursor_size_ok(plane_state)) {
|
||||
drm_dbg(&dev_priv->drm,
|
||||
"Cursor dimension %dx%d not supported\n",
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
drm_rect_height(&plane_state->uapi.dst));
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] cursor dimension %dx%d not supported\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
drm_rect_width(&plane_state->uapi.dst),
|
||||
drm_rect_height(&plane_state->uapi.dst));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
drm_WARN_ON(&dev_priv->drm, plane_state->uapi.visible &&
|
||||
drm_WARN_ON(display->drm, plane_state->uapi.visible &&
|
||||
plane_state->view.color_plane[0].mapping_stride != fb->pitches[0]);
|
||||
|
||||
if (fb->pitches[0] !=
|
||||
drm_rect_width(&plane_state->uapi.dst) * fb->format->cpp[0]) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"Invalid cursor stride (%u) (cursor width %d)\n",
|
||||
fb->pitches[0],
|
||||
drm_rect_width(&plane_state->uapi.dst));
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] invalid cursor stride (%u) (cursor width %d)\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
fb->pitches[0], drm_rect_width(&plane_state->uapi.dst));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -517,10 +526,11 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
|
|||
* display power well must be turned off and on again.
|
||||
* Refuse the put the cursor into that compromised position.
|
||||
*/
|
||||
if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
|
||||
if (display->platform.cherryview && pipe == PIPE_C &&
|
||||
plane_state->uapi.visible && plane_state->uapi.dst.x1 < 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
"CHV cursor C not allowed to straddle the left screen edge\n");
|
||||
drm_dbg_kms(display->drm,
|
||||
"[PLANE:%d:%s] cursor not allowed to straddle the left screen edge\n",
|
||||
plane->base.base.id, plane->base.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +543,7 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
|
|||
struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum pipe pipe = plane->pipe;
|
||||
|
||||
if (!crtc_state->enable_psr2_sel_fetch)
|
||||
|
|
@ -547,8 +557,7 @@ static void wa_16021440873(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane->base.dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
u32 ctl = plane_state->ctl;
|
||||
int et_y_position = drm_rect_height(&crtc_state->pipe_src) + 1;
|
||||
enum pipe pipe = plane->pipe;
|
||||
|
|
@ -558,7 +567,7 @@ static void wa_16021440873(struct intel_dsb *dsb,
|
|||
|
||||
intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), ctl);
|
||||
|
||||
intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe),
|
||||
intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(display, pipe),
|
||||
CURSOR_POS_Y(et_y_position));
|
||||
}
|
||||
|
||||
|
|
@ -567,8 +576,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane->base.dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum pipe pipe = plane->pipe;
|
||||
|
||||
if (!crtc_state->enable_psr2_sel_fetch)
|
||||
|
|
@ -579,7 +587,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
|
|||
u32 val = intel_cursor_position(crtc_state, plane_state,
|
||||
true);
|
||||
|
||||
intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(dev_priv, pipe), val);
|
||||
intel_de_write_dsb(display, dsb, CURPOS_ERLY_TPT(display, pipe), val);
|
||||
}
|
||||
|
||||
intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), plane_state->ctl);
|
||||
|
|
@ -653,8 +661,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane->base.dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum pipe pipe = plane->pipe;
|
||||
u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0;
|
||||
|
||||
|
|
@ -680,7 +687,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
|
|||
* CURPOS.
|
||||
*
|
||||
* On other platforms CURPOS always requires the
|
||||
* CURBASE write to arm the update. Additonally
|
||||
* CURBASE write to arm the update. Additionally
|
||||
* a write to any of the cursor register will cancel
|
||||
* an already armed cursor update. Thus leaving out
|
||||
* the CURBASE write after CURPOS could lead to a
|
||||
|
|
@ -692,7 +699,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
|
|||
* the CURCNTR write arms the update.
|
||||
*/
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9)
|
||||
if (DISPLAY_VER(display) >= 9)
|
||||
skl_write_cursor_wm(dsb, plane, crtc_state);
|
||||
|
||||
if (plane_state)
|
||||
|
|
@ -703,18 +710,18 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
|
|||
if (plane->cursor.base != base ||
|
||||
plane->cursor.size != fbc_ctl ||
|
||||
plane->cursor.cntl != cntl) {
|
||||
if (HAS_CUR_FBC(dev_priv))
|
||||
intel_de_write_dsb(display, dsb, CUR_FBC_CTL(dev_priv, pipe), fbc_ctl);
|
||||
intel_de_write_dsb(display, dsb, CURCNTR(dev_priv, pipe), cntl);
|
||||
intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
|
||||
intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
|
||||
if (HAS_CUR_FBC(display))
|
||||
intel_de_write_dsb(display, dsb, CUR_FBC_CTL(display, pipe), fbc_ctl);
|
||||
intel_de_write_dsb(display, dsb, CURCNTR(display, pipe), cntl);
|
||||
intel_de_write_dsb(display, dsb, CURPOS(display, pipe), pos);
|
||||
intel_de_write_dsb(display, dsb, CURBASE(display, pipe), base);
|
||||
|
||||
plane->cursor.base = base;
|
||||
plane->cursor.size = fbc_ctl;
|
||||
plane->cursor.cntl = cntl;
|
||||
} else {
|
||||
intel_de_write_dsb(display, dsb, CURPOS(dev_priv, pipe), pos);
|
||||
intel_de_write_dsb(display, dsb, CURBASE(dev_priv, pipe), base);
|
||||
intel_de_write_dsb(display, dsb, CURPOS(display, pipe), pos);
|
||||
intel_de_write_dsb(display, dsb, CURBASE(display, pipe), base);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -728,7 +735,7 @@ static void i9xx_cursor_disable_arm(struct intel_dsb *dsb,
|
|||
static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
enum intel_display_power_domain power_domain;
|
||||
intel_wakeref_t wakeref;
|
||||
bool ret;
|
||||
|
|
@ -740,24 +747,45 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
|
|||
* display power wells.
|
||||
*/
|
||||
power_domain = POWER_DOMAIN_PIPE(plane->pipe);
|
||||
wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
|
||||
wakeref = intel_display_power_get_if_enabled(display, power_domain);
|
||||
if (!wakeref)
|
||||
return false;
|
||||
|
||||
val = intel_de_read(dev_priv, CURCNTR(dev_priv, plane->pipe));
|
||||
val = intel_de_read(display, CURCNTR(display, plane->pipe));
|
||||
|
||||
ret = val & MCURSOR_MODE_MASK;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv))
|
||||
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
*pipe = plane->pipe;
|
||||
else
|
||||
*pipe = REG_FIELD_GET(MCURSOR_PIPE_SEL_MASK, val);
|
||||
|
||||
intel_display_power_put(dev_priv, power_domain, wakeref);
|
||||
intel_display_power_put(display, power_domain, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void g4x_cursor_capture_error(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
|
||||
error->ctl = intel_de_read(display, CURCNTR(display, crtc->pipe));
|
||||
error->surf = intel_de_read(display, CURBASE(display, crtc->pipe));
|
||||
error->surflive = intel_de_read(display, CURSURFLIVE(display, crtc->pipe));
|
||||
}
|
||||
|
||||
static void i9xx_cursor_capture_error(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
|
||||
error->ctl = intel_de_read(display, CURCNTR(display, crtc->pipe));
|
||||
error->surf = intel_de_read(display, CURBASE(display, crtc->pipe));
|
||||
}
|
||||
|
||||
static bool intel_cursor_format_mod_supported(struct drm_plane *_plane,
|
||||
u32 format, u64 modifier)
|
||||
{
|
||||
|
|
@ -790,7 +818,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
|
|||
{
|
||||
struct intel_plane *plane = to_intel_plane(_plane);
|
||||
struct intel_crtc *crtc = to_intel_crtc(_crtc);
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
struct intel_plane_state *old_plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
struct intel_plane_state *new_plane_state;
|
||||
|
|
@ -865,7 +893,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
|
|||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
ret = intel_plane_pin_fb(new_plane_state);
|
||||
ret = intel_plane_pin_fb(new_plane_state, old_plane_state);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
|
|
@ -894,7 +922,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
|
|||
|
||||
intel_psr_lock(crtc_state);
|
||||
|
||||
if (!drm_WARN_ON(&i915->drm, drm_crtc_vblank_get(&crtc->base))) {
|
||||
if (!drm_WARN_ON(display->drm, drm_crtc_vblank_get(&crtc->base))) {
|
||||
/*
|
||||
* TODO: maybe check if we're still in PSR
|
||||
* and skip the vblank evasion entirely?
|
||||
|
|
@ -960,8 +988,8 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
|
|||
|
||||
static void intel_cursor_add_size_hints_property(struct intel_plane *plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
const struct drm_mode_config *config = &i915->drm.mode_config;
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
const struct drm_mode_config *config = &display->drm->mode_config;
|
||||
struct drm_plane_size_hint hints[4];
|
||||
int size, max_size, num_hints = 0;
|
||||
|
||||
|
|
@ -969,7 +997,7 @@ static void intel_cursor_add_size_hints_property(struct intel_plane *plane)
|
|||
|
||||
/* for simplicity only enumerate the supported square+POT sizes */
|
||||
for (size = 64; size <= max_size; size *= 2) {
|
||||
if (drm_WARN_ON(&i915->drm, num_hints >= ARRAY_SIZE(hints)))
|
||||
if (drm_WARN_ON(display->drm, num_hints >= ARRAY_SIZE(hints)))
|
||||
break;
|
||||
|
||||
hints[num_hints].width = size;
|
||||
|
|
@ -981,7 +1009,7 @@ static void intel_cursor_add_size_hints_property(struct intel_plane *plane)
|
|||
}
|
||||
|
||||
struct intel_plane *
|
||||
intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
||||
intel_cursor_plane_create(struct intel_display *display,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct intel_plane *cursor;
|
||||
|
|
@ -997,7 +1025,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
|||
cursor->id = PLANE_CURSOR;
|
||||
cursor->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, cursor->id);
|
||||
|
||||
if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
|
||||
if (display->platform.i845g || display->platform.i865g) {
|
||||
cursor->max_stride = i845_cursor_max_stride;
|
||||
cursor->min_alignment = i845_cursor_min_alignment;
|
||||
cursor->update_arm = i845_cursor_update_arm;
|
||||
|
|
@ -1007,28 +1035,36 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
|||
} else {
|
||||
cursor->max_stride = i9xx_cursor_max_stride;
|
||||
|
||||
if (IS_I830(dev_priv))
|
||||
if (display->platform.i830)
|
||||
cursor->min_alignment = i830_cursor_min_alignment;
|
||||
else if (IS_I85X(dev_priv))
|
||||
else if (display->platform.i85x)
|
||||
cursor->min_alignment = i85x_cursor_min_alignment;
|
||||
else
|
||||
cursor->min_alignment = i9xx_cursor_min_alignment;
|
||||
|
||||
if (intel_scanout_needs_vtd_wa(display))
|
||||
cursor->vtd_guard = 2;
|
||||
|
||||
cursor->update_arm = i9xx_cursor_update_arm;
|
||||
cursor->disable_arm = i9xx_cursor_disable_arm;
|
||||
cursor->get_hw_state = i9xx_cursor_get_hw_state;
|
||||
cursor->check_plane = i9xx_check_cursor;
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 5 || display->platform.g4x)
|
||||
cursor->capture_error = g4x_cursor_capture_error;
|
||||
else
|
||||
cursor->capture_error = i9xx_cursor_capture_error;
|
||||
|
||||
cursor->cursor.base = ~0;
|
||||
cursor->cursor.cntl = ~0;
|
||||
|
||||
if (IS_I845G(dev_priv) || IS_I865G(dev_priv) || HAS_CUR_FBC(dev_priv))
|
||||
if (display->platform.i845g || display->platform.i865g || HAS_CUR_FBC(display))
|
||||
cursor->cursor.size = ~0;
|
||||
|
||||
modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_NONE);
|
||||
modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_NONE);
|
||||
|
||||
ret = drm_universal_plane_init(&dev_priv->drm, &cursor->base,
|
||||
ret = drm_universal_plane_init(display->drm, &cursor->base,
|
||||
0, &intel_cursor_plane_funcs,
|
||||
intel_cursor_formats,
|
||||
ARRAY_SIZE(intel_cursor_formats),
|
||||
|
|
@ -1041,7 +1077,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 4)
|
||||
if (DISPLAY_VER(display) >= 4)
|
||||
drm_plane_create_rotation_property(&cursor->base,
|
||||
DRM_MODE_ROTATE_0,
|
||||
DRM_MODE_ROTATE_0 |
|
||||
|
|
@ -1049,10 +1085,10 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
|||
|
||||
intel_cursor_add_size_hints_property(cursor);
|
||||
|
||||
zpos = DISPLAY_RUNTIME_INFO(dev_priv)->num_sprites[pipe] + 1;
|
||||
zpos = DISPLAY_RUNTIME_INFO(display)->num_sprites[pipe] + 1;
|
||||
drm_plane_create_zpos_immutable_property(&cursor->base, zpos);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
if (DISPLAY_VER(display) >= 12)
|
||||
drm_plane_enable_fb_damage_clips(&cursor->base);
|
||||
|
||||
intel_plane_helper_add(cursor);
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
#define _INTEL_CURSOR_H_
|
||||
|
||||
enum pipe;
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
struct intel_plane;
|
||||
struct kthread_work;
|
||||
|
||||
struct intel_plane *
|
||||
intel_cursor_plane_create(struct drm_i915_private *dev_priv,
|
||||
intel_cursor_plane_create(struct intel_display *display,
|
||||
enum pipe pipe);
|
||||
|
||||
void intel_cursor_unpin_work(struct kthread_work *base);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "intel_hdmi.h"
|
||||
#include "intel_panel.h"
|
||||
#include "intel_psr.h"
|
||||
#include "intel_snps_hdmi_pll.h"
|
||||
#include "intel_tc.h"
|
||||
|
||||
#define MB_WRITE_COMMITTED true
|
||||
|
|
@ -33,13 +34,13 @@
|
|||
|
||||
bool intel_encoder_is_c10phy(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
||||
if (IS_PANTHERLAKE(i915) && phy == PHY_A)
|
||||
if (display->platform.pantherlake && phy == PHY_A)
|
||||
return true;
|
||||
|
||||
if ((IS_LUNARLAKE(i915) || IS_METEORLAKE(i915)) && phy < PHY_C)
|
||||
if ((display->platform.lunarlake || display->platform.meteorlake) && phy < PHY_C)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -72,10 +73,9 @@ static u8 intel_cx0_get_owned_lane_mask(struct intel_encoder *encoder)
|
|||
static void
|
||||
assert_dc_off(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
bool enabled;
|
||||
|
||||
enabled = intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF);
|
||||
enabled = intel_display_power_is_enabled(display, POWER_DOMAIN_DC_OFF);
|
||||
drm_WARN_ON(display->drm, !enabled);
|
||||
}
|
||||
|
||||
|
|
@ -102,12 +102,12 @@ static void intel_cx0_program_msgbus_timer(struct intel_encoder *encoder)
|
|||
*/
|
||||
static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *encoder)
|
||||
{
|
||||
intel_wakeref_t wakeref;
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
intel_wakeref_t wakeref;
|
||||
|
||||
intel_psr_pause(intel_dp);
|
||||
wakeref = intel_display_power_get(i915, POWER_DOMAIN_DC_OFF);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF);
|
||||
intel_cx0_program_msgbus_timer(encoder);
|
||||
|
||||
return wakeref;
|
||||
|
|
@ -115,11 +115,11 @@ static intel_wakeref_t intel_cx0_phy_transaction_begin(struct intel_encoder *enc
|
|||
|
||||
static void intel_cx0_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
intel_psr_resume(intel_dp);
|
||||
intel_display_power_put(i915, POWER_DOMAIN_DC_OFF, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref);
|
||||
}
|
||||
|
||||
static void intel_clear_response_ready_flag(struct intel_encoder *encoder,
|
||||
|
|
@ -2003,19 +2003,6 @@ static const struct intel_c20pll_state * const mtl_c20_hdmi_tables[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
static int intel_c10_phy_check_hdmi_link_rate(int clock)
|
||||
{
|
||||
const struct intel_c10pll_state * const *tables = mtl_c10_hdmi_tables;
|
||||
int i;
|
||||
|
||||
for (i = 0; tables[i]; i++) {
|
||||
if (clock == tables[i]->clock)
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
return MODE_CLOCK_RANGE;
|
||||
}
|
||||
|
||||
static const struct intel_c10pll_state * const *
|
||||
intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
|
|
@ -2033,21 +2020,25 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
static void intel_cx0pll_update_ssc(struct intel_encoder *encoder,
|
||||
struct intel_cx0pll_state *pll_state, bool is_dp)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll;
|
||||
int i;
|
||||
|
||||
if (intel_crtc_has_dp_encoder(crtc_state)) {
|
||||
if (is_dp) {
|
||||
if (intel_panel_use_ssc(display)) {
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
pll_state->ssc_enabled =
|
||||
(intel_dp->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void intel_c10pll_update_pll(struct intel_encoder *encoder,
|
||||
struct intel_cx0pll_state *pll_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
int i;
|
||||
|
||||
if (pll_state->ssc_enabled)
|
||||
return;
|
||||
|
|
@ -2057,21 +2048,19 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
|
|||
pll_state->c10.pll[i] = 0;
|
||||
}
|
||||
|
||||
static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
static int intel_c10pll_calc_state_from_table(struct intel_encoder *encoder,
|
||||
const struct intel_c10pll_state * const *tables,
|
||||
bool is_dp, int port_clock,
|
||||
struct intel_cx0pll_state *pll_state)
|
||||
{
|
||||
const struct intel_c10pll_state * const *tables;
|
||||
int i;
|
||||
|
||||
tables = intel_c10pll_tables_get(crtc_state, encoder);
|
||||
if (!tables)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; tables[i]; i++) {
|
||||
if (crtc_state->port_clock == tables[i]->clock) {
|
||||
crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
|
||||
intel_c10pll_update_pll(crtc_state, encoder);
|
||||
crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
|
||||
if (port_clock == tables[i]->clock) {
|
||||
pll_state->c10 = *tables[i];
|
||||
intel_cx0pll_update_ssc(encoder, pll_state, is_dp);
|
||||
intel_c10pll_update_pll(encoder, pll_state);
|
||||
pll_state->use_c10 = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2080,6 +2069,34 @@ static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
{
|
||||
const struct intel_c10pll_state * const *tables;
|
||||
int err;
|
||||
|
||||
tables = intel_c10pll_tables_get(crtc_state, encoder);
|
||||
if (!tables)
|
||||
return -EINVAL;
|
||||
|
||||
err = intel_c10pll_calc_state_from_table(encoder, tables,
|
||||
intel_crtc_has_dp_encoder(crtc_state),
|
||||
crtc_state->port_clock,
|
||||
&crtc_state->dpll_hw_state.cx0pll);
|
||||
|
||||
if (err == 0 || !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
|
||||
return err;
|
||||
|
||||
/* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */
|
||||
intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10,
|
||||
crtc_state->port_clock);
|
||||
intel_c10pll_update_pll(encoder,
|
||||
&crtc_state->dpll_hw_state.cx0pll);
|
||||
crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
|
||||
struct intel_c10pll_state *pll_state)
|
||||
{
|
||||
|
|
@ -2107,10 +2124,9 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
|
|||
}
|
||||
|
||||
static void intel_c10_pll_program(struct intel_display *display,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_c10pll_state *pll_state)
|
||||
{
|
||||
const struct intel_c10pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c10;
|
||||
int i;
|
||||
|
||||
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
|
||||
|
|
@ -2173,9 +2189,47 @@ static void intel_c10pll_dump_hw_state(struct intel_display *display,
|
|||
i + 2, hw_state->pll[i + 2], i + 3, hw_state->pll[i + 3]);
|
||||
}
|
||||
|
||||
static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
||||
/*
|
||||
* Some ARLs SoCs have the same drm PCI IDs, so need a helper to differentiate based
|
||||
* on the host bridge device ID to get the correct txx_mics value.
|
||||
*/
|
||||
static bool is_arrowlake_s_by_host_bridge(void)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
u16 host_bridge_pci_dev_id;
|
||||
|
||||
while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev)))
|
||||
host_bridge_pci_dev_id = pdev->device;
|
||||
|
||||
return pdev && IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(host_bridge_pci_dev_id);
|
||||
}
|
||||
|
||||
static u16 intel_c20_hdmi_tmds_tx_cgf_1(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
u16 tx_misc;
|
||||
u16 tx_dcc_cal_dac_ctrl_range = 8;
|
||||
u16 tx_term_ctrl = 2;
|
||||
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
tx_misc = 5;
|
||||
tx_term_ctrl = 4;
|
||||
} else if (display->platform.battlemage) {
|
||||
tx_misc = 0;
|
||||
} else if (display->platform.meteorlake_u ||
|
||||
is_arrowlake_s_by_host_bridge()) {
|
||||
tx_misc = 3;
|
||||
} else {
|
||||
tx_misc = 7;
|
||||
}
|
||||
|
||||
return (C20_PHY_TX_MISC(tx_misc) |
|
||||
C20_PHY_TX_DCC_CAL_RANGE(tx_dcc_cal_dac_ctrl_range) |
|
||||
C20_PHY_TX_DCC_BYPASS | C20_PHY_TX_TERM_CTL(tx_term_ctrl));
|
||||
}
|
||||
|
||||
static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
|
||||
u64 datarate;
|
||||
u64 mpll_tx_clk_div;
|
||||
|
|
@ -2185,7 +2239,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
|||
u64 mpll_multiplier;
|
||||
u64 mpll_fracn_quot;
|
||||
u64 mpll_fracn_rem;
|
||||
u16 tx_misc;
|
||||
u8 mpllb_ana_freq_vco;
|
||||
u8 mpll_div_multiplier;
|
||||
|
||||
|
|
@ -2205,11 +2258,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
|||
mpll_div_multiplier = min_t(u8, div64_u64((vco_freq * 16 + (datarate >> 1)),
|
||||
datarate), 255);
|
||||
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
tx_misc = 0x5;
|
||||
else
|
||||
tx_misc = 0x0;
|
||||
|
||||
if (vco_freq <= DATARATE_3000000000)
|
||||
mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_3;
|
||||
else if (vco_freq <= DATARATE_3500000000)
|
||||
|
|
@ -2221,7 +2269,7 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
|||
|
||||
pll_state->clock = crtc_state->port_clock;
|
||||
pll_state->tx[0] = 0xbe88;
|
||||
pll_state->tx[1] = 0x9800 | C20_PHY_TX_MISC(tx_misc);
|
||||
pll_state->tx[1] = intel_c20_hdmi_tmds_tx_cgf_1(crtc_state);
|
||||
pll_state->tx[2] = 0x0000;
|
||||
pll_state->cmn[0] = 0x0500;
|
||||
pll_state->cmn[1] = 0x0005;
|
||||
|
|
@ -2249,31 +2297,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int intel_c20_phy_check_hdmi_link_rate(int clock)
|
||||
{
|
||||
const struct intel_c20pll_state * const *tables = mtl_c20_hdmi_tables;
|
||||
int i;
|
||||
|
||||
for (i = 0; tables[i]; i++) {
|
||||
if (clock == tables[i]->clock)
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
if (clock >= 25175 && clock <= 594000)
|
||||
return MODE_OK;
|
||||
|
||||
return MODE_CLOCK_RANGE;
|
||||
}
|
||||
|
||||
int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock)
|
||||
{
|
||||
struct intel_digital_port *dig_port = hdmi_to_dig_port(hdmi);
|
||||
|
||||
if (intel_encoder_is_c10phy(&dig_port->base))
|
||||
return intel_c10_phy_check_hdmi_link_rate(clock);
|
||||
return intel_c20_phy_check_hdmi_link_rate(clock);
|
||||
}
|
||||
|
||||
static const struct intel_c20pll_state * const *
|
||||
intel_c20_pll_tables_get(struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
|
|
@ -2322,6 +2345,9 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
|
|||
for (i = 0; tables[i]; i++) {
|
||||
if (crtc_state->port_clock == tables[i]->clock) {
|
||||
crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
|
||||
intel_cx0pll_update_ssc(encoder,
|
||||
&crtc_state->dpll_hw_state.cx0pll,
|
||||
intel_crtc_has_dp_encoder(crtc_state));
|
||||
crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2587,19 +2613,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp)
|
|||
}
|
||||
|
||||
static void intel_c20_pll_program(struct intel_display *display,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
struct intel_encoder *encoder)
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_c20pll_state *pll_state,
|
||||
bool is_dp, int port_clock)
|
||||
{
|
||||
const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
|
||||
bool dp = false;
|
||||
u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
|
||||
u32 clock = crtc_state->port_clock;
|
||||
bool cntx;
|
||||
int i;
|
||||
|
||||
if (intel_crtc_has_dp_encoder(crtc_state))
|
||||
dp = true;
|
||||
|
||||
/* 1. Read current context selection */
|
||||
cntx = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE) & BIT(0);
|
||||
|
||||
|
|
@ -2667,23 +2688,23 @@ static void intel_c20_pll_program(struct intel_display *display,
|
|||
/* 4. Program custom width to match the link protocol */
|
||||
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH,
|
||||
PHY_C20_CUSTOM_WIDTH_MASK,
|
||||
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(clock, dp)),
|
||||
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(port_clock, is_dp)),
|
||||
MB_WRITE_COMMITTED);
|
||||
|
||||
/* 5. For DP or 6. For HDMI */
|
||||
if (dp) {
|
||||
if (is_dp) {
|
||||
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
|
||||
BIT(6) | PHY_C20_CUSTOM_SERDES_MASK,
|
||||
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(clock)),
|
||||
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(port_clock)),
|
||||
MB_WRITE_COMMITTED);
|
||||
} else {
|
||||
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
|
||||
BIT(7) | PHY_C20_CUSTOM_SERDES_MASK,
|
||||
is_hdmi_frl(clock) ? BIT(7) : 0,
|
||||
is_hdmi_frl(port_clock) ? BIT(7) : 0,
|
||||
MB_WRITE_COMMITTED);
|
||||
|
||||
intel_cx0_write(encoder, INTEL_CX0_BOTH_LANES, PHY_C20_VDR_HDMI_RATE,
|
||||
intel_c20_get_hdmi_rate(clock),
|
||||
intel_c20_get_hdmi_rate(port_clock),
|
||||
MB_WRITE_COMMITTED);
|
||||
}
|
||||
|
||||
|
|
@ -2723,7 +2744,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
|
|||
}
|
||||
|
||||
static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_cx0pll_state *pll_state,
|
||||
bool is_dp, int port_clock,
|
||||
bool lane_reversal)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
|
@ -2738,18 +2760,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
|
|||
|
||||
val |= XELPDP_FORWARD_CLOCK_UNGATE;
|
||||
|
||||
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
|
||||
is_hdmi_frl(crtc_state->port_clock))
|
||||
if (!is_dp && is_hdmi_frl(port_clock))
|
||||
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
|
||||
else
|
||||
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
|
||||
|
||||
/* TODO: HDMI FRL */
|
||||
/* DP2.0 10G and 20G rates enable MPLLA*/
|
||||
if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
|
||||
val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
|
||||
if (port_clock == 1000000 || port_clock == 2000000)
|
||||
val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
|
||||
else
|
||||
val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
|
||||
val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
|
||||
|
||||
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
|
||||
XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
|
||||
|
|
@ -2979,8 +3000,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
|
|||
return val;
|
||||
}
|
||||
|
||||
static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
static void __intel_cx0pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_cx0pll_state *pll_state,
|
||||
bool is_dp, int port_clock, int lane_count)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
enum phy phy = intel_encoder_to_phy(encoder);
|
||||
|
|
@ -2994,7 +3016,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
|||
* 1. Program PORT_CLOCK_CTL REGISTER to configure
|
||||
* clock muxes, gating and SSC
|
||||
*/
|
||||
intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
|
||||
intel_program_port_clock_ctl(encoder, pll_state, is_dp, port_clock, lane_reversal);
|
||||
|
||||
/* 2. Bring PHY out of reset. */
|
||||
intel_cx0_phy_lane_reset(encoder, lane_reversal);
|
||||
|
|
@ -3014,15 +3036,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
|||
|
||||
/* 5. Program PHY internal PLL internal registers. */
|
||||
if (intel_encoder_is_c10phy(encoder))
|
||||
intel_c10_pll_program(display, crtc_state, encoder);
|
||||
intel_c10_pll_program(display, encoder, &pll_state->c10);
|
||||
else
|
||||
intel_c20_pll_program(display, crtc_state, encoder);
|
||||
intel_c20_pll_program(display, encoder, &pll_state->c20, is_dp, port_clock);
|
||||
|
||||
/*
|
||||
* 6. Program the enabled and disabled owned PHY lane
|
||||
* transmitters over message bus
|
||||
*/
|
||||
intel_cx0_program_phy_lane(encoder, crtc_state->lane_count, lane_reversal);
|
||||
intel_cx0_program_phy_lane(encoder, lane_count, lane_reversal);
|
||||
|
||||
/*
|
||||
* 7. Follow the Display Voltage Frequency Switching - Sequence
|
||||
|
|
@ -3033,8 +3055,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
|||
* 8. Program DDI_CLK_VALFREQ to match intended DDI
|
||||
* clock frequency.
|
||||
*/
|
||||
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
|
||||
crtc_state->port_clock);
|
||||
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
|
||||
|
||||
/*
|
||||
* 9. Set PORT_CLOCK_CTL register PCLK PLL Request
|
||||
|
|
@ -3061,6 +3082,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
|||
intel_cx0_phy_transaction_end(encoder, wakeref);
|
||||
}
|
||||
|
||||
static void intel_cx0pll_enable(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
__intel_cx0pll_enable(encoder, &crtc_state->dpll_hw_state.cx0pll,
|
||||
intel_crtc_has_dp_encoder(crtc_state),
|
||||
crtc_state->port_clock, crtc_state->lane_count);
|
||||
}
|
||||
|
||||
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
|
@ -3203,12 +3232,11 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder,
|
|||
static u8 cx0_power_control_disable_val(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
|
||||
if (intel_encoder_is_c10phy(encoder))
|
||||
return CX0_P2PG_STATE_DISABLE;
|
||||
|
||||
if ((IS_BATTLEMAGE(i915) && encoder->port == PORT_A) ||
|
||||
if ((display->platform.battlemage && encoder->port == PORT_A) ||
|
||||
(DISPLAY_VER(display) >= 30 && encoder->type == INTEL_OUTPUT_EDP))
|
||||
return CX0_P2PG_STATE_DISABLE;
|
||||
|
||||
|
|
@ -3266,6 +3294,16 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder)
|
|||
intel_cx0_phy_transaction_end(encoder, wakeref);
|
||||
}
|
||||
|
||||
static bool intel_cx0_pll_is_enabled(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
u8 lane = dig_port->lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0;
|
||||
|
||||
return intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)) &
|
||||
intel_cx0_get_pclk_pll_request(lane);
|
||||
}
|
||||
|
||||
static void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
|
@ -3527,3 +3565,54 @@ void intel_cx0pll_state_verify(struct intel_atomic_state *state,
|
|||
else
|
||||
intel_c20pll_state_verify(new_crtc_state, crtc, encoder, &mpll_hw_state.c20);
|
||||
}
|
||||
|
||||
/*
|
||||
* WA 14022081154
|
||||
* The dedicated display PHYs reset to a power state that blocks S0ix, increasing idle
|
||||
* system power. After a system reset (cold boot, S3/4/5, warm reset) if a dedicated
|
||||
* PHY is not being brought up shortly, use these steps to move the PHY to the lowest
|
||||
* power state to save power. For PTL the workaround is needed only for port A. Port B
|
||||
* is not connected.
|
||||
*
|
||||
* 1. Follow the PLL Enable Sequence, using any valid frequency such as DP 1.62 GHz.
|
||||
* This brings lanes out of reset and enables the PLL to allow powerdown to be moved
|
||||
* to the Disable state.
|
||||
* 2. Follow PLL Disable Sequence. This moves powerdown to the Disable state and disables the PLL.
|
||||
*/
|
||||
void intel_cx0_pll_power_save_wa(struct intel_display *display)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
|
||||
if (DISPLAY_VER(display) != 30)
|
||||
return;
|
||||
|
||||
for_each_intel_encoder(display->drm, encoder) {
|
||||
struct intel_cx0pll_state pll_state = {};
|
||||
int port_clock = 162000;
|
||||
|
||||
if (!intel_encoder_is_dig_port(encoder))
|
||||
continue;
|
||||
|
||||
if (!intel_encoder_is_c10phy(encoder))
|
||||
continue;
|
||||
|
||||
if (intel_cx0_pll_is_enabled(encoder))
|
||||
continue;
|
||||
|
||||
if (intel_c10pll_calc_state_from_table(encoder,
|
||||
mtl_c10_edp_tables,
|
||||
true, port_clock,
|
||||
&pll_state) < 0) {
|
||||
drm_WARN_ON(display->drm,
|
||||
"Unable to calc C10 state from the tables\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
drm_dbg_kms(display->drm,
|
||||
"[ENCODER:%d:%s] Applying power saving workaround on disabled PLL\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
|
||||
__intel_cx0pll_enable(encoder, &pll_state, true, port_clock, 4);
|
||||
intel_cx0pll_disable(encoder);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ bool intel_cx0pll_compare_hw_state(const struct intel_cx0pll_state *a,
|
|||
const struct intel_cx0pll_state *b);
|
||||
void intel_cx0_phy_set_signal_levels(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
|
||||
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);
|
||||
void intel_cx0_pll_power_save_wa(struct intel_display *display);
|
||||
|
||||
#endif /* __INTEL_CX0_PHY_H__ */
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@
|
|||
#define XELPDP_TCSS_POWER_REQUEST REG_BIT(5)
|
||||
#define XELPDP_TCSS_POWER_STATE REG_BIT(4)
|
||||
#define XELPDP_PORT_WIDTH_MASK REG_GENMASK(3, 1)
|
||||
#define XELPDP_PORT_WIDTH(val) REG_FIELD_PREP(XELPDP_PORT_WIDTH_MASK, val)
|
||||
#define XELPDP_PORT_WIDTH(width) REG_FIELD_PREP(XELPDP_PORT_WIDTH_MASK, \
|
||||
((width) == 3 ? 4 : (width) - 1))
|
||||
|
||||
#define _XELPDP_PORT_BUF_CTL2(idx) _MMIO(_PICK_EVEN_2RANGES(idx, PORT_TC1, \
|
||||
_XELPDP_PORT_BUF_CTL1_LN0_A, \
|
||||
|
|
@ -218,10 +219,34 @@
|
|||
|
||||
/* C10 Vendor Registers */
|
||||
#define PHY_C10_VDR_PLL(idx) (0xC00 + (idx))
|
||||
#define C10_PLL0_SSC_EN REG_BIT8(0)
|
||||
#define C10_PLL0_DIVCLK_EN REG_BIT8(1)
|
||||
#define C10_PLL0_DIV5CLK_EN REG_BIT8(2)
|
||||
#define C10_PLL0_WORDDIV2_EN REG_BIT8(3)
|
||||
#define C10_PLL0_FRACEN REG_BIT8(4)
|
||||
#define C10_PLL0_PMIX_EN REG_BIT8(5)
|
||||
#define C10_PLL0_ANA_FREQ_VCO_MASK REG_GENMASK8(7, 6)
|
||||
#define C10_PLL1_DIV_MULTIPLIER_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL2_MULTIPLIERL_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL3_MULTIPLIERH_MASK REG_GENMASK8(3, 0)
|
||||
#define C10_PLL8_SSC_UP_SPREAD REG_BIT8(5)
|
||||
#define C10_PLL9_FRACN_DENL_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL10_FRACN_DENH_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL11_FRACN_QUOT_L_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL12_FRACN_QUOT_H_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL13_FRACN_REM_L_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL14_FRACN_REM_H_MASK REG_GENMASK8(7, 0)
|
||||
#define C10_PLL15_TXCLKDIV_MASK REG_GENMASK8(2, 0)
|
||||
#define C10_PLL15_HDMIDIV_MASK REG_GENMASK8(5, 3)
|
||||
#define C10_PLL15_PIXELCLKDIV_MASK REG_GENMASK8(7, 6)
|
||||
#define C10_PLL16_ANA_CPINT REG_GENMASK8(6, 0)
|
||||
#define C10_PLL16_ANA_CPINTGS_L REG_BIT8(7)
|
||||
#define C10_PLL17_ANA_CPINTGS_H_MASK REG_GENMASK8(5, 0)
|
||||
#define C10_PLL17_ANA_CPPROP_L_MASK REG_GENMASK8(7, 6)
|
||||
#define C10_PLL18_ANA_CPPROP_H_MASK REG_GENMASK8(4, 0)
|
||||
#define C10_PLL18_ANA_CPPROPGS_L_MASK REG_GENMASK8(7, 5)
|
||||
#define C10_PLL19_ANA_CPPROPGS_H_MASK REG_GENMASK8(3, 0)
|
||||
#define C10_PLL19_ANA_V2I_MASK REG_GENMASK8(5, 4)
|
||||
|
||||
#define PHY_C10_VDR_CMN(idx) (0xC20 + (idx))
|
||||
#define C10_CMN0_REF_RANGE REG_FIELD_PREP(REG_GENMASK(4, 0), 1)
|
||||
|
|
@ -298,6 +323,12 @@
|
|||
#define C20_PHY_TX_RATE REG_GENMASK(2, 0)
|
||||
#define C20_PHY_TX_MISC_MASK REG_GENMASK16(7, 0)
|
||||
#define C20_PHY_TX_MISC(val) REG_FIELD_PREP16(C20_PHY_TX_MISC_MASK, (val))
|
||||
#define C20_PHY_TX_DCC_CAL_RANGE_MASK REG_GENMASK16(11, 8)
|
||||
#define C20_PHY_TX_DCC_CAL_RANGE(val) \
|
||||
REG_FIELD_PREP16(C20_PHY_TX_DCC_CAL_RANGE_MASK, (val))
|
||||
#define C20_PHY_TX_DCC_BYPASS REG_BIT(12)
|
||||
#define C20_PHY_TX_TERM_CTL_MASK REG_GENMASK16(15, 13)
|
||||
#define C20_PHY_TX_TERM_CTL(val) REG_FIELD_PREP16(C20_PHY_TX_TERM_CTL_MASK, (val))
|
||||
|
||||
#define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \
|
||||
((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,13 +3,13 @@
|
|||
* Copyright © 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_utils.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_ddi.h"
|
||||
#include "intel_ddi_buf_trans.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_dp.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
|
||||
/* HDMI/DVI modes ignore everything but the last 2 items. So we share
|
||||
* them for both DP and FDI transports, allowing those ports to
|
||||
|
|
@ -1407,10 +1407,10 @@ tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state,
|
||||
int *n_entries)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (crtc_state->port_clock > 270000) {
|
||||
if (IS_TIGERLAKE_UY(dev_priv)) {
|
||||
if (display->platform.tigerlake_uy) {
|
||||
return intel_get_buf_trans(&tgl_uy_combo_phy_trans_dp_hbr2,
|
||||
n_entries);
|
||||
} else {
|
||||
|
|
@ -1709,59 +1709,67 @@ mtl_get_c20_buf_trans(struct intel_encoder *encoder,
|
|||
|
||||
void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
|
||||
if (DISPLAY_VER(i915) >= 14) {
|
||||
if (DISPLAY_VER(display) >= 14) {
|
||||
if (intel_encoder_is_c10phy(encoder))
|
||||
encoder->get_buf_trans = mtl_get_c10_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans = mtl_get_c20_buf_trans;
|
||||
} else if (IS_DG2(i915)) {
|
||||
} else if (display->platform.dg2) {
|
||||
encoder->get_buf_trans = dg2_get_snps_buf_trans;
|
||||
} else if (IS_ALDERLAKE_P(i915)) {
|
||||
} else if (display->platform.alderlake_p) {
|
||||
if (intel_encoder_is_combo(encoder))
|
||||
encoder->get_buf_trans = adlp_get_combo_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans = adlp_get_dkl_buf_trans;
|
||||
} else if (IS_ALDERLAKE_S(i915)) {
|
||||
} else if (display->platform.alderlake_s) {
|
||||
encoder->get_buf_trans = adls_get_combo_buf_trans;
|
||||
} else if (IS_ROCKETLAKE(i915)) {
|
||||
} else if (display->platform.rocketlake) {
|
||||
encoder->get_buf_trans = rkl_get_combo_buf_trans;
|
||||
} else if (IS_DG1(i915)) {
|
||||
} else if (display->platform.dg1) {
|
||||
encoder->get_buf_trans = dg1_get_combo_buf_trans;
|
||||
} else if (DISPLAY_VER(i915) >= 12) {
|
||||
} else if (DISPLAY_VER(display) >= 12) {
|
||||
if (intel_encoder_is_combo(encoder))
|
||||
encoder->get_buf_trans = tgl_get_combo_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans = tgl_get_dkl_buf_trans;
|
||||
} else if (DISPLAY_VER(i915) == 11) {
|
||||
if (IS_JASPERLAKE(i915))
|
||||
} else if (DISPLAY_VER(display) == 11) {
|
||||
if (display->platform.jasperlake)
|
||||
encoder->get_buf_trans = jsl_get_combo_buf_trans;
|
||||
else if (IS_ELKHARTLAKE(i915))
|
||||
else if (display->platform.elkhartlake)
|
||||
encoder->get_buf_trans = ehl_get_combo_buf_trans;
|
||||
else if (intel_encoder_is_combo(encoder))
|
||||
encoder->get_buf_trans = icl_get_combo_buf_trans;
|
||||
else
|
||||
encoder->get_buf_trans = icl_get_mg_buf_trans;
|
||||
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
|
||||
} else if (display->platform.geminilake || display->platform.broxton) {
|
||||
encoder->get_buf_trans = bxt_get_buf_trans;
|
||||
} else if (IS_COMETLAKE_ULX(i915) || IS_COFFEELAKE_ULX(i915) || IS_KABYLAKE_ULX(i915)) {
|
||||
} else if (display->platform.cometlake_ulx ||
|
||||
display->platform.coffeelake_ulx ||
|
||||
display->platform.kabylake_ulx) {
|
||||
encoder->get_buf_trans = kbl_y_get_buf_trans;
|
||||
} else if (IS_COMETLAKE_ULT(i915) || IS_COFFEELAKE_ULT(i915) || IS_KABYLAKE_ULT(i915)) {
|
||||
} else if (display->platform.cometlake_ult ||
|
||||
display->platform.coffeelake_ult ||
|
||||
display->platform.kabylake_ult) {
|
||||
encoder->get_buf_trans = kbl_u_get_buf_trans;
|
||||
} else if (IS_COMETLAKE(i915) || IS_COFFEELAKE(i915) || IS_KABYLAKE(i915)) {
|
||||
} else if (display->platform.cometlake ||
|
||||
display->platform.coffeelake ||
|
||||
display->platform.kabylake) {
|
||||
encoder->get_buf_trans = kbl_get_buf_trans;
|
||||
} else if (IS_SKYLAKE_ULX(i915)) {
|
||||
} else if (display->platform.skylake_ulx) {
|
||||
encoder->get_buf_trans = skl_y_get_buf_trans;
|
||||
} else if (IS_SKYLAKE_ULT(i915)) {
|
||||
} else if (display->platform.skylake_ult) {
|
||||
encoder->get_buf_trans = skl_u_get_buf_trans;
|
||||
} else if (IS_SKYLAKE(i915)) {
|
||||
} else if (display->platform.skylake) {
|
||||
encoder->get_buf_trans = skl_get_buf_trans;
|
||||
} else if (IS_BROADWELL(i915)) {
|
||||
} else if (display->platform.broadwell) {
|
||||
encoder->get_buf_trans = bdw_get_buf_trans;
|
||||
} else if (IS_HASWELL(i915)) {
|
||||
} else if (display->platform.haswell) {
|
||||
encoder->get_buf_trans = hsw_get_buf_trans;
|
||||
} else {
|
||||
MISSING_CASE(INTEL_INFO(i915)->platform);
|
||||
struct pci_dev *pdev = to_pci_dev(display->drm->dev);
|
||||
|
||||
MISSING_CASE(pdev->device);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -59,8 +59,6 @@ struct intel_link_m_n;
|
|||
struct intel_plane;
|
||||
struct intel_plane_state;
|
||||
struct intel_power_domain_mask;
|
||||
struct intel_remapped_info;
|
||||
struct intel_rotation_info;
|
||||
struct pci_dev;
|
||||
struct work_struct;
|
||||
|
||||
|
|
@ -413,22 +411,20 @@ enum phy_fia {
|
|||
i)
|
||||
|
||||
int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
|
||||
int intel_atomic_add_affected_planes(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc);
|
||||
u8 intel_calc_active_pipes(struct intel_atomic_state *state,
|
||||
u8 active_pipes);
|
||||
void intel_link_compute_m_n(u16 bpp, int nlanes,
|
||||
int pixel_clock, int link_clock,
|
||||
int bw_overhead,
|
||||
struct intel_link_m_n *m_n);
|
||||
u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
|
||||
u32 intel_plane_fb_max_stride(struct drm_device *drm,
|
||||
u32 pixel_format, u64 modifier);
|
||||
enum drm_mode_status
|
||||
intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
|
||||
intel_mode_valid_max_plane_size(struct intel_display *display,
|
||||
const struct drm_display_mode *mode,
|
||||
int num_joined_pipes);
|
||||
enum drm_mode_status
|
||||
intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915,
|
||||
intel_cpu_transcoder_mode_valid(struct intel_display *display,
|
||||
const struct drm_display_mode *mode);
|
||||
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
|
||||
bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
|
||||
|
|
@ -450,7 +446,6 @@ bool intel_pipe_config_compare(const struct intel_crtc_state *current_config,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
bool fastset);
|
||||
|
||||
void intel_plane_destroy(struct drm_plane *plane);
|
||||
void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state);
|
||||
void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state);
|
||||
void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state);
|
||||
|
|
@ -463,20 +458,13 @@ int vlv_get_cck_clock(struct drm_i915_private *dev_priv,
|
|||
int vlv_get_cck_clock_hpll(struct drm_i915_private *dev_priv,
|
||||
const char *name, u32 reg);
|
||||
void intel_init_display_hooks(struct drm_i915_private *dev_priv);
|
||||
unsigned int intel_fb_xy_to_linear(int x, int y,
|
||||
const struct intel_plane_state *state,
|
||||
int plane);
|
||||
void intel_add_fb_offsets(int *x, int *y,
|
||||
const struct intel_plane_state *state, int plane);
|
||||
unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
|
||||
unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
|
||||
bool intel_has_pending_fb_unpin(struct drm_i915_private *dev_priv);
|
||||
void intel_encoder_destroy(struct drm_encoder *encoder);
|
||||
struct drm_display_mode *
|
||||
intel_encoder_current_mode(struct intel_encoder *encoder);
|
||||
void intel_encoder_get_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *crtc_state);
|
||||
bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy);
|
||||
bool intel_phy_is_combo(struct intel_display *display, enum phy phy);
|
||||
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy);
|
||||
bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy);
|
||||
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
|
||||
|
|
@ -489,9 +477,6 @@ bool intel_encoder_is_tc(struct intel_encoder *encoder);
|
|||
enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder);
|
||||
|
||||
int ilk_get_lanes_required(int target_clock, int link_bw, int bpp);
|
||||
void vlv_wait_port_ready(struct intel_display *display,
|
||||
struct intel_digital_port *dig_port,
|
||||
unsigned int expected_mask);
|
||||
|
||||
bool intel_fuzzy_clock_check(int clock1, int clock2);
|
||||
|
||||
|
|
@ -530,8 +515,6 @@ void ilk_pfit_disable(const struct intel_crtc_state *old_crtc_state);
|
|||
int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc);
|
||||
unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
|
||||
|
||||
bool intel_plane_uses_fence(const struct intel_plane_state *plane_state);
|
||||
|
||||
struct intel_encoder *
|
||||
intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
|
|
@ -571,15 +554,13 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev,
|
|||
int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state,
|
||||
bool nonblock);
|
||||
|
||||
void intel_hpd_poll_fini(struct drm_i915_private *i915);
|
||||
|
||||
/* modesetting asserts */
|
||||
void assert_transcoder(struct drm_i915_private *dev_priv,
|
||||
void assert_transcoder(struct intel_display *display,
|
||||
enum transcoder cpu_transcoder, bool state);
|
||||
#define assert_transcoder_enabled(d, t) assert_transcoder(d, t, true)
|
||||
#define assert_transcoder_disabled(d, t) assert_transcoder(d, t, false)
|
||||
|
||||
bool assert_port_valid(struct drm_i915_private *i915, enum port port);
|
||||
bool assert_port_valid(struct intel_display *display, enum port port);
|
||||
|
||||
/*
|
||||
* Use INTEL_DISPLAY_STATE_WARN(x) (rather than WARN() and WARN_ON()) for hw
|
||||
|
|
@ -596,7 +577,7 @@ bool assert_port_valid(struct drm_i915_private *i915, enum port port);
|
|||
unlikely(__ret_warn_on); \
|
||||
})
|
||||
|
||||
bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915);
|
||||
bool intel_scanout_needs_vtd_wa(struct intel_display *display);
|
||||
int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -68,17 +68,17 @@ static int intel_display_caps(struct seq_file *m, void *data)
|
|||
|
||||
static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
|
||||
spin_lock(&dev_priv->display.fb_tracking.lock);
|
||||
spin_lock(&display->fb_tracking.lock);
|
||||
|
||||
seq_printf(m, "FB tracking busy bits: 0x%08x\n",
|
||||
dev_priv->display.fb_tracking.busy_bits);
|
||||
display->fb_tracking.busy_bits);
|
||||
|
||||
seq_printf(m, "FB tracking flip bits: 0x%08x\n",
|
||||
dev_priv->display.fb_tracking.flip_bits);
|
||||
display->fb_tracking.flip_bits);
|
||||
|
||||
spin_unlock(&dev_priv->display.fb_tracking.lock);
|
||||
spin_unlock(&display->fb_tracking.lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -86,26 +86,27 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
|
|||
static int i915_sr_status(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
intel_wakeref_t wakeref;
|
||||
bool sr_enabled = false;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT);
|
||||
|
||||
if (DISPLAY_VER(dev_priv) >= 9)
|
||||
if (DISPLAY_VER(display) >= 9)
|
||||
/* no global SR status; inspect per-plane WM */;
|
||||
else if (HAS_PCH_SPLIT(dev_priv))
|
||||
sr_enabled = intel_de_read(dev_priv, WM1_LP_ILK) & WM_LP_ENABLE;
|
||||
else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) ||
|
||||
IS_I945G(dev_priv) || IS_I945GM(dev_priv))
|
||||
sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF) & FW_BLC_SELF_EN;
|
||||
else if (IS_I915GM(dev_priv))
|
||||
sr_enabled = intel_de_read(dev_priv, INSTPM) & INSTPM_SELF_EN;
|
||||
else if (IS_PINEVIEW(dev_priv))
|
||||
sr_enabled = intel_de_read(dev_priv, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN;
|
||||
else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
||||
sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
|
||||
sr_enabled = intel_de_read(display, WM1_LP_ILK) & WM_LP_ENABLE;
|
||||
else if (display->platform.i965gm || display->platform.g4x ||
|
||||
display->platform.i945g || display->platform.i945gm)
|
||||
sr_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN;
|
||||
else if (display->platform.i915gm)
|
||||
sr_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN;
|
||||
else if (display->platform.pineview)
|
||||
sr_enabled = intel_de_read(display, DSPFW3(dev_priv)) & PINEVIEW_SELF_REFRESH_EN;
|
||||
else if (display->platform.valleyview || display->platform.cherryview)
|
||||
sr_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref);
|
||||
|
||||
seq_printf(m, "self-refresh: %s\n", str_enabled_disabled(sr_enabled));
|
||||
|
||||
|
|
@ -114,12 +115,12 @@ static int i915_sr_status(struct seq_file *m, void *unused)
|
|||
|
||||
static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct intel_framebuffer *fbdev_fb = NULL;
|
||||
struct drm_framebuffer *drm_fb;
|
||||
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
fbdev_fb = intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev);
|
||||
fbdev_fb = intel_fbdev_framebuffer(display->fbdev.fbdev);
|
||||
if (fbdev_fb) {
|
||||
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
|
||||
fbdev_fb->base.width,
|
||||
|
|
@ -133,8 +134,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
|||
}
|
||||
#endif
|
||||
|
||||
mutex_lock(&dev_priv->drm.mode_config.fb_lock);
|
||||
drm_for_each_fb(drm_fb, &dev_priv->drm) {
|
||||
mutex_lock(&display->drm->mode_config.fb_lock);
|
||||
drm_for_each_fb(drm_fb, display->drm) {
|
||||
struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
|
||||
if (fb == fbdev_fb)
|
||||
continue;
|
||||
|
|
@ -149,7 +150,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
|||
intel_bo_describe(m, intel_fb_bo(&fb->base));
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
mutex_unlock(&dev_priv->drm.mode_config.fb_lock);
|
||||
mutex_unlock(&display->drm->mode_config.fb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -157,8 +158,9 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
|
|||
static int i915_power_domain_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
struct intel_display *display = &i915->display;
|
||||
|
||||
intel_display_power_debug(i915, m);
|
||||
intel_display_power_debug(display, m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -178,14 +180,14 @@ static void intel_encoder_info(struct seq_file *m,
|
|||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_connector *connector;
|
||||
|
||||
seq_printf(m, "\t[ENCODER:%d:%s]: connectors:\n",
|
||||
encoder->base.base.id, encoder->base.name);
|
||||
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_connector_list_iter_begin(display->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
const struct drm_connector_state *conn_state =
|
||||
connector->state;
|
||||
|
|
@ -213,38 +215,6 @@ static void intel_panel_info(struct seq_file *m,
|
|||
intel_seq_print_mode(m, 2, fixed_mode);
|
||||
}
|
||||
|
||||
static void intel_hdcp_info(struct seq_file *m,
|
||||
struct intel_connector *intel_connector,
|
||||
bool remote_req)
|
||||
{
|
||||
bool hdcp_cap = false, hdcp2_cap = false;
|
||||
|
||||
if (!intel_connector->hdcp.shim) {
|
||||
seq_puts(m, "No Connector Support");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (remote_req) {
|
||||
intel_hdcp_get_remote_capability(intel_connector,
|
||||
&hdcp_cap,
|
||||
&hdcp2_cap);
|
||||
} else {
|
||||
hdcp_cap = intel_hdcp_get_capability(intel_connector);
|
||||
hdcp2_cap = intel_hdcp2_get_capability(intel_connector);
|
||||
}
|
||||
|
||||
if (hdcp_cap)
|
||||
seq_puts(m, "HDCP1.4 ");
|
||||
if (hdcp2_cap)
|
||||
seq_puts(m, "HDCP2.2 ");
|
||||
|
||||
if (!hdcp_cap && !hdcp2_cap)
|
||||
seq_puts(m, "None");
|
||||
|
||||
out:
|
||||
seq_puts(m, "\n");
|
||||
}
|
||||
|
||||
static void intel_dp_info(struct seq_file *m, struct intel_connector *connector)
|
||||
{
|
||||
struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
|
||||
|
|
@ -309,12 +279,7 @@ static void intel_connector_info(struct seq_file *m,
|
|||
break;
|
||||
}
|
||||
|
||||
seq_puts(m, "\tHDCP version: ");
|
||||
if (intel_connector->mst_port) {
|
||||
intel_hdcp_info(m, intel_connector, true);
|
||||
seq_puts(m, "\tMST Hub HDCP version: ");
|
||||
}
|
||||
intel_hdcp_info(m, intel_connector, false);
|
||||
intel_hdcp_info(m, intel_connector);
|
||||
|
||||
seq_printf(m, "\tmax bpc: %u\n", connector->display_info.bpc);
|
||||
|
||||
|
|
@ -365,8 +330,8 @@ static const char *plane_visibility(const struct intel_plane_state *plane_state)
|
|||
if (plane_state->uapi.visible)
|
||||
return "visible";
|
||||
|
||||
if (plane_state->planar_slave)
|
||||
return "planar-slave";
|
||||
if (plane_state->is_y_plane)
|
||||
return "Y plane";
|
||||
|
||||
return "hidden";
|
||||
}
|
||||
|
|
@ -399,7 +364,7 @@ static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
|
|||
if (plane_state->planar_linked_plane)
|
||||
seq_printf(m, "\t\tplanar: Linked to [PLANE:%d:%s] as a %s\n",
|
||||
plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,
|
||||
plane_state->planar_slave ? "slave" : "master");
|
||||
plane_state->is_y_plane ? "Y plane" : "UV plane");
|
||||
}
|
||||
|
||||
static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
|
||||
|
|
@ -427,10 +392,10 @@ static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
|
|||
|
||||
static void intel_plane_info(struct seq_file *m, struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct intel_plane *plane;
|
||||
|
||||
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
|
||||
for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
|
||||
seq_printf(m, "\t[PLANE:%d:%s]: type=%s\n",
|
||||
plane->base.base.id, plane->base.name,
|
||||
plane_type(plane->base.type));
|
||||
|
|
@ -573,7 +538,7 @@ static void crtc_updates_add(struct intel_crtc *crtc)
|
|||
|
||||
static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
|
|
@ -607,7 +572,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
|
|||
|
||||
intel_vdsc_state_dump(&p, 1, crtc_state);
|
||||
|
||||
for_each_intel_encoder_mask(&dev_priv->drm, encoder,
|
||||
for_each_intel_encoder_mask(display->drm, encoder,
|
||||
crtc_state->uapi.encoder_mask)
|
||||
intel_encoder_info(m, crtc, encoder);
|
||||
|
||||
|
|
@ -622,6 +587,7 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
|
|||
|
||||
static int i915_display_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_crtc *crtc;
|
||||
struct drm_connector *connector;
|
||||
|
|
@ -630,22 +596,22 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
|||
|
||||
wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
|
||||
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
drm_modeset_lock_all(display->drm);
|
||||
|
||||
seq_printf(m, "CRTC info\n");
|
||||
seq_printf(m, "---------\n");
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc)
|
||||
for_each_intel_crtc(display->drm, crtc)
|
||||
intel_crtc_info(m, crtc);
|
||||
|
||||
seq_printf(m, "\n");
|
||||
seq_printf(m, "Connector info\n");
|
||||
seq_printf(m, "--------------\n");
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_connector_list_iter_begin(display->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter)
|
||||
intel_connector_info(m, connector);
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
drm_modeset_unlock_all(display->drm);
|
||||
|
||||
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
|
||||
|
||||
|
|
@ -654,56 +620,56 @@ static int i915_display_info(struct seq_file *m, void *unused)
|
|||
|
||||
static int i915_display_capabilities(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
|
||||
intel_display_device_info_print(DISPLAY_INFO(i915),
|
||||
DISPLAY_RUNTIME_INFO(i915), &p);
|
||||
intel_display_device_info_print(DISPLAY_INFO(display),
|
||||
DISPLAY_RUNTIME_INFO(display), &p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_shared_dplls_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
struct intel_shared_dpll *pll;
|
||||
int i;
|
||||
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
drm_modeset_lock_all(display->drm);
|
||||
|
||||
drm_printf(&p, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
|
||||
dev_priv->display.dpll.ref_clks.nssc,
|
||||
dev_priv->display.dpll.ref_clks.ssc);
|
||||
display->dpll.ref_clks.nssc,
|
||||
display->dpll.ref_clks.ssc);
|
||||
|
||||
for_each_shared_dpll(dev_priv, pll, i) {
|
||||
for_each_shared_dpll(display, pll, i) {
|
||||
drm_printf(&p, "DPLL%i: %s, id: %i\n", pll->index,
|
||||
pll->info->name, pll->info->id);
|
||||
drm_printf(&p, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
|
||||
pll->state.pipe_mask, pll->active_mask,
|
||||
str_yes_no(pll->on));
|
||||
drm_printf(&p, " tracked hardware state:\n");
|
||||
intel_dpll_dump_hw_state(dev_priv, &p, &pll->state.hw_state);
|
||||
intel_dpll_dump_hw_state(display, &p, &pll->state.hw_state);
|
||||
}
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
drm_modeset_unlock_all(display->drm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i915_ddb_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct skl_ddb_entry *entry;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
if (DISPLAY_VER(dev_priv) < 9)
|
||||
if (DISPLAY_VER(display) < 9)
|
||||
return -ENODEV;
|
||||
|
||||
drm_modeset_lock_all(&dev_priv->drm);
|
||||
drm_modeset_lock_all(display->drm);
|
||||
|
||||
seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
|
@ -723,16 +689,16 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
|
|||
entry->end, skl_ddb_entry_size(entry));
|
||||
}
|
||||
|
||||
drm_modeset_unlock_all(&dev_priv->drm);
|
||||
drm_modeset_unlock_all(display->drm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_lpsp_power_well_enabled(struct drm_i915_private *i915,
|
||||
intel_lpsp_power_well_enabled(struct intel_display *display,
|
||||
enum i915_power_well_id power_well_id)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
intel_wakeref_t wakeref;
|
||||
bool is_enabled;
|
||||
|
||||
|
|
@ -746,15 +712,16 @@ intel_lpsp_power_well_enabled(struct drm_i915_private *i915,
|
|||
|
||||
static int i915_lpsp_status(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct drm_i915_private *i915 = node_to_i915(m->private);
|
||||
bool lpsp_enabled = false;
|
||||
|
||||
if (DISPLAY_VER(i915) >= 13 || IS_DISPLAY_VER(i915, 9, 10)) {
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(i915, SKL_DISP_PW_2);
|
||||
} else if (IS_DISPLAY_VER(i915, 11, 12)) {
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(i915, ICL_DISP_PW_3);
|
||||
if (DISPLAY_VER(display) >= 13 || IS_DISPLAY_VER(display, 9, 10)) {
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(display, SKL_DISP_PW_2);
|
||||
} else if (IS_DISPLAY_VER(display, 11, 12)) {
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(display, ICL_DISP_PW_3);
|
||||
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(i915, HSW_DISP_PW_GLOBAL);
|
||||
lpsp_enabled = !intel_lpsp_power_well_enabled(display, HSW_DISP_PW_GLOBAL);
|
||||
} else {
|
||||
seq_puts(m, "LPSP: not supported\n");
|
||||
return 0;
|
||||
|
|
@ -767,13 +734,13 @@ static int i915_lpsp_status(struct seq_file *m, void *unused)
|
|||
|
||||
static int i915_dp_mst_info(struct seq_file *m, void *unused)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = node_to_i915(m->private);
|
||||
struct intel_display *display = node_to_intel_display(m->private);
|
||||
struct intel_encoder *intel_encoder;
|
||||
struct intel_digital_port *dig_port;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
|
||||
drm_connector_list_iter_begin(display->drm, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
|
||||
continue;
|
||||
|
|
@ -801,7 +768,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
const char __user *ubuf,
|
||||
size_t cnt, loff_t *ppos)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = filp->private_data;
|
||||
struct intel_display *display = filp->private_data;
|
||||
struct intel_crtc *crtc;
|
||||
int ret;
|
||||
bool reset;
|
||||
|
|
@ -813,7 +780,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
if (!reset)
|
||||
return cnt;
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
struct drm_crtc_commit *commit;
|
||||
struct intel_crtc_state *crtc_state;
|
||||
|
||||
|
|
@ -830,7 +797,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
}
|
||||
|
||||
if (!ret && crtc_state->hw.active) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Re-arming FIFO underruns on pipe %c\n",
|
||||
pipe_name(crtc->pipe));
|
||||
|
||||
|
|
@ -843,7 +810,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
intel_fbc_reset_underrun(&dev_priv->display);
|
||||
intel_fbc_reset_underrun(display);
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
|
@ -875,7 +842,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
|
|||
struct drm_minor *minor = i915->drm.primary;
|
||||
|
||||
debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root,
|
||||
to_i915(minor->dev), &i915_fifo_underrun_reset_ops);
|
||||
display, &i915_fifo_underrun_reset_ops);
|
||||
|
||||
drm_debugfs_create_files(intel_display_debugfs_list,
|
||||
ARRAY_SIZE(intel_display_debugfs_list),
|
||||
|
|
@ -893,38 +860,12 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
|
|||
intel_display_debugfs_params(display);
|
||||
}
|
||||
|
||||
static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
int ret;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!connector->base.encoder ||
|
||||
connector->base.status != connector_status_connected) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(m, "%s:%d HDCP version: ", connector->base.name,
|
||||
connector->base.base.id);
|
||||
intel_hdcp_info(m, connector, false);
|
||||
|
||||
out:
|
||||
drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
|
||||
|
||||
static int i915_lpsp_capability_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
int connector_type = connector->base.connector_type;
|
||||
bool lpsp_capable = false;
|
||||
|
||||
|
|
@ -934,19 +875,19 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data)
|
|||
if (connector->base.status != connector_status_connected)
|
||||
return -ENODEV;
|
||||
|
||||
if (DISPLAY_VER(i915) >= 13)
|
||||
if (DISPLAY_VER(display) >= 13)
|
||||
lpsp_capable = encoder->port <= PORT_B;
|
||||
else if (DISPLAY_VER(i915) >= 12)
|
||||
else if (DISPLAY_VER(display) >= 12)
|
||||
/*
|
||||
* Actually TGL can drive LPSP on port till DDI_C
|
||||
* but there is no physical connected DDI_C on TGL sku's,
|
||||
* even driver is not initilizing DDI_C port for gen12.
|
||||
* even driver is not initializing DDI_C port for gen12.
|
||||
*/
|
||||
lpsp_capable = encoder->port <= PORT_B;
|
||||
else if (DISPLAY_VER(i915) == 11)
|
||||
else if (DISPLAY_VER(display) == 11)
|
||||
lpsp_capable = (connector_type == DRM_MODE_CONNECTOR_DSI ||
|
||||
connector_type == DRM_MODE_CONNECTOR_eDP);
|
||||
else if (IS_DISPLAY_VER(i915, 9, 10))
|
||||
else if (IS_DISPLAY_VER(display, 9, 10))
|
||||
lpsp_capable = (encoder->port == PORT_A &&
|
||||
(connector_type == DRM_MODE_CONNECTOR_DSI ||
|
||||
connector_type == DRM_MODE_CONNECTOR_eDP ||
|
||||
|
|
@ -963,7 +904,7 @@ DEFINE_SHOW_ATTRIBUTE(i915_lpsp_capability);
|
|||
static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_dp *intel_dp;
|
||||
struct drm_modeset_acquire_ctx ctx;
|
||||
|
|
@ -975,7 +916,7 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
|
|||
|
||||
do {
|
||||
try_again = false;
|
||||
ret = drm_modeset_lock(&i915->drm.mode_config.connection_mutex,
|
||||
ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex,
|
||||
&ctx);
|
||||
if (ret) {
|
||||
if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) {
|
||||
|
|
@ -1036,7 +977,7 @@ static ssize_t i915_dsc_fec_support_write(struct file *file,
|
|||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
bool dsc_enable = false;
|
||||
|
|
@ -1045,14 +986,14 @@ static ssize_t i915_dsc_fec_support_write(struct file *file,
|
|||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
drm_dbg(&i915->drm,
|
||||
drm_dbg(display->drm,
|
||||
"Copied %zu bytes from user to force DSC\n", len);
|
||||
|
||||
ret = kstrtobool_from_user(ubuf, len, &dsc_enable);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_dbg(&i915->drm, "Got %s for DSC Enable\n",
|
||||
drm_dbg(display->drm, "Got %s for DSC Enable\n",
|
||||
(dsc_enable) ? "true" : "false");
|
||||
intel_dp->force_dsc_en = dsc_enable;
|
||||
|
||||
|
|
@ -1079,7 +1020,7 @@ static const struct file_operations i915_dsc_fec_support_fops = {
|
|||
static int i915_dsc_bpc_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_crtc_state *crtc_state;
|
||||
|
|
@ -1088,7 +1029,7 @@ static int i915_dsc_bpc_show(struct seq_file *m, void *data)
|
|||
if (!encoder)
|
||||
return -ENODEV;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
|
||||
ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1101,7 +1042,7 @@ static int i915_dsc_bpc_show(struct seq_file *m, void *data)
|
|||
crtc_state = to_intel_crtc_state(crtc->state);
|
||||
seq_printf(m, "Input_BPC: %d\n", crtc_state->dsc.config.bits_per_component);
|
||||
|
||||
out: drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
|
||||
out: drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1145,7 +1086,7 @@ static const struct file_operations i915_dsc_bpc_fops = {
|
|||
static int i915_dsc_output_format_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_crtc_state *crtc_state;
|
||||
|
|
@ -1154,7 +1095,7 @@ static int i915_dsc_output_format_show(struct seq_file *m, void *data)
|
|||
if (!encoder)
|
||||
return -ENODEV;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
|
||||
ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1168,7 +1109,7 @@ static int i915_dsc_output_format_show(struct seq_file *m, void *data)
|
|||
seq_printf(m, "DSC_Output_Format: %s\n",
|
||||
intel_output_format_name(crtc_state->output_format));
|
||||
|
||||
out: drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
|
||||
out: drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1212,7 +1153,7 @@ static const struct file_operations i915_dsc_output_format_fops = {
|
|||
static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_crtc *crtc;
|
||||
struct intel_dp *intel_dp;
|
||||
|
|
@ -1221,7 +1162,7 @@ static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data)
|
|||
if (!encoder)
|
||||
return -ENODEV;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
|
||||
ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -1236,7 +1177,7 @@ static int i915_dsc_fractional_bpp_show(struct seq_file *m, void *data)
|
|||
str_yes_no(intel_dp->force_dsc_fractional_bpp_en));
|
||||
|
||||
out:
|
||||
drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
|
||||
drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1247,8 +1188,8 @@ static ssize_t i915_dsc_fractional_bpp_write(struct file *file,
|
|||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct intel_connector *connector = m->private;
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
bool dsc_fractional_bpp_enable = false;
|
||||
int ret;
|
||||
|
|
@ -1256,14 +1197,14 @@ static ssize_t i915_dsc_fractional_bpp_write(struct file *file,
|
|||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
drm_dbg(&i915->drm,
|
||||
drm_dbg(display->drm,
|
||||
"Copied %zu bytes from user to force fractional bpp for DSC\n", len);
|
||||
|
||||
ret = kstrtobool_from_user(ubuf, len, &dsc_fractional_bpp_enable);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_dbg(&i915->drm, "Got %s for DSC Fractional BPP Enable\n",
|
||||
drm_dbg(display->drm, "Got %s for DSC Fractional BPP Enable\n",
|
||||
(dsc_fractional_bpp_enable) ? "true" : "false");
|
||||
intel_dp->force_dsc_fractional_bpp_en = dsc_fractional_bpp_enable;
|
||||
|
||||
|
|
@ -1392,7 +1333,7 @@ static const struct file_operations i915_joiner_fops = {
|
|||
*/
|
||||
void intel_connector_debugfs_add(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct dentry *root = connector->base.debugfs_entry;
|
||||
int connector_type = connector->base.connector_type;
|
||||
|
||||
|
|
@ -1401,19 +1342,13 @@ void intel_connector_debugfs_add(struct intel_connector *connector)
|
|||
return;
|
||||
|
||||
intel_drrs_connector_debugfs_add(connector);
|
||||
intel_hdcp_connector_debugfs_add(connector);
|
||||
intel_pps_connector_debugfs_add(connector);
|
||||
intel_psr_connector_debugfs_add(connector);
|
||||
intel_alpm_lobf_debugfs_add(connector);
|
||||
intel_dp_link_training_debugfs_add(connector);
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
|
||||
connector_type == DRM_MODE_CONNECTOR_HDMIA ||
|
||||
connector_type == DRM_MODE_CONNECTOR_HDMIB) {
|
||||
debugfs_create_file("i915_hdcp_sink_capability", 0444, root,
|
||||
connector, &i915_hdcp_sink_capability_fops);
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(i915) >= 11 &&
|
||||
if (DISPLAY_VER(display) >= 11 &&
|
||||
((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) ||
|
||||
connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
||||
debugfs_create_file("i915_dsc_fec_support", 0644, root,
|
||||
|
|
|
|||
|
|
@ -1357,6 +1357,12 @@ static const struct intel_display_device_info xe2_hpd_display = {
|
|||
BIT(PORT_TC1) | BIT(PORT_TC2) | BIT(PORT_TC3) | BIT(PORT_TC4),
|
||||
};
|
||||
|
||||
static const u16 mtl_u_ids[] = {
|
||||
INTEL_MTL_U_IDS(ID),
|
||||
INTEL_ARL_U_IDS(ID),
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
* Do not initialize the .info member of the platform desc for GMD ID based
|
||||
* platforms. Their display will be probed automatically based on the IP version
|
||||
|
|
@ -1364,6 +1370,13 @@ static const struct intel_display_device_info xe2_hpd_display = {
|
|||
*/
|
||||
static const struct platform_desc mtl_desc = {
|
||||
PLATFORM(meteorlake),
|
||||
.subplatforms = (const struct subplatform_desc[]) {
|
||||
{
|
||||
SUBPLATFORM(meteorlake, u),
|
||||
.pciidlist = mtl_u_ids,
|
||||
},
|
||||
{},
|
||||
}
|
||||
};
|
||||
|
||||
static const struct platform_desc lnl_desc = {
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ struct pci_dev;
|
|||
func(dg2_g12) \
|
||||
/* Display ver 14 (based on GMD ID) */ \
|
||||
func(meteorlake) \
|
||||
func(meteorlake_u) \
|
||||
/* Display ver 20 (based on GMD ID) */ \
|
||||
func(lunarlake) \
|
||||
/* Display ver 14.1 (based on GMD ID) */ \
|
||||
|
|
@ -145,6 +146,7 @@ struct intel_display_platforms {
|
|||
#define HAS_BIGJOINER(__display) (DISPLAY_VER(__display) >= 11 && HAS_DSC(__display))
|
||||
#define HAS_CDCLK_CRAWL(__display) (DISPLAY_INFO(__display)->has_cdclk_crawl)
|
||||
#define HAS_CDCLK_SQUASH(__display) (DISPLAY_INFO(__display)->has_cdclk_squash)
|
||||
#define HAS_CMTG(__display) (!(__display)->platform.dg2 && DISPLAY_VER(__display) >= 13)
|
||||
#define HAS_CUR_FBC(__display) (!HAS_GMCH(__display) && IS_DISPLAY_VER(__display, 7, 13))
|
||||
#define HAS_D12_PLANE_MINIMIZATION(__display) ((__display)->platform.rocketlake || (__display)->platform.alderlake_s)
|
||||
#define HAS_DBUF_OVERLAP_DETECTION(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dbuf_overlap_detection)
|
||||
|
|
@ -233,6 +235,17 @@ struct intel_display_platforms {
|
|||
(drm_WARN_ON(__to_intel_display(__display)->drm, INTEL_DISPLAY_STEP(__display) == STEP_NONE), \
|
||||
INTEL_DISPLAY_STEP(__display) >= (since) && INTEL_DISPLAY_STEP(__display) < (until))
|
||||
|
||||
#define ARLS_HOST_BRIDGE_PCI_ID1 0x7D1C
|
||||
#define ARLS_HOST_BRIDGE_PCI_ID2 0x7D2D
|
||||
#define ARLS_HOST_BRIDGE_PCI_ID3 0x7D2E
|
||||
#define ARLS_HOST_BRIDGE_PCI_ID4 0x7D2F
|
||||
|
||||
#define IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(id) \
|
||||
(((id) == ARLS_HOST_BRIDGE_PCI_ID1) || \
|
||||
((id) == ARLS_HOST_BRIDGE_PCI_ID2) || \
|
||||
((id) == ARLS_HOST_BRIDGE_PCI_ID3) || \
|
||||
((id) == ARLS_HOST_BRIDGE_PCI_ID4))
|
||||
|
||||
struct intel_display_runtime_info {
|
||||
struct intel_display_ip_ver {
|
||||
u16 ver;
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ void intel_display_driver_early_probe(struct intel_display *display)
|
|||
intel_dkl_phy_init(i915);
|
||||
intel_color_init_hooks(display);
|
||||
intel_init_cdclk_hooks(display);
|
||||
intel_audio_hooks_init(i915);
|
||||
intel_audio_hooks_init(display);
|
||||
intel_dpll_init_clock_hook(i915);
|
||||
intel_init_display_hooks(i915);
|
||||
intel_fdi_init_hook(i915);
|
||||
|
|
@ -442,18 +442,18 @@ int intel_display_driver_probe_nogem(struct intel_display *display)
|
|||
INTEL_NUM_PIPES(display) > 1 ? "s" : "");
|
||||
|
||||
for_each_pipe(display, pipe) {
|
||||
ret = intel_crtc_init(i915, pipe);
|
||||
ret = intel_crtc_init(display, pipe);
|
||||
if (ret)
|
||||
goto err_mode_config;
|
||||
}
|
||||
|
||||
intel_plane_possible_crtcs_init(display);
|
||||
intel_shared_dpll_init(i915);
|
||||
intel_shared_dpll_init(display);
|
||||
intel_fdi_pll_freq_update(i915);
|
||||
|
||||
intel_update_czclk(i915);
|
||||
intel_display_driver_init_hw(display);
|
||||
intel_dpll_update_ref_clks(i915);
|
||||
intel_dpll_update_ref_clks(display);
|
||||
|
||||
if (display->cdclk.max_cdclk_freq == 0)
|
||||
intel_update_max_cdclk(display);
|
||||
|
|
@ -544,11 +544,11 @@ void intel_display_driver_register(struct intel_display *display)
|
|||
intel_opregion_register(display);
|
||||
intel_acpi_video_register(display);
|
||||
|
||||
intel_audio_init(i915);
|
||||
intel_audio_init(display);
|
||||
|
||||
intel_display_driver_enable_user_access(display);
|
||||
|
||||
intel_audio_register(i915);
|
||||
intel_audio_register(display);
|
||||
|
||||
intel_display_debugfs_register(i915);
|
||||
|
||||
|
|
@ -636,8 +636,6 @@ void intel_display_driver_remove_nogem(struct intel_display *display)
|
|||
|
||||
void intel_display_driver_unregister(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (!HAS_DISPLAY(display))
|
||||
return;
|
||||
|
||||
|
|
@ -652,7 +650,7 @@ void intel_display_driver_unregister(struct intel_display *display)
|
|||
|
||||
intel_display_driver_disable_user_access(display);
|
||||
|
||||
intel_audio_deinit(i915);
|
||||
intel_audio_deinit(display);
|
||||
|
||||
drm_atomic_helper_shutdown(display->drm);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,8 +11,9 @@
|
|||
#include "intel_display_limits.h"
|
||||
|
||||
enum pipe;
|
||||
struct drm_i915_private;
|
||||
struct drm_crtc;
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
|
||||
void valleyview_enable_display_irqs(struct drm_i915_private *i915);
|
||||
void valleyview_disable_display_irqs(struct drm_i915_private *i915);
|
||||
|
|
@ -64,7 +65,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *i915);
|
|||
void gen11_de_irq_postinstall(struct drm_i915_private *i915);
|
||||
void dg1_de_irq_postinstall(struct drm_i915_private *i915);
|
||||
|
||||
u32 i915_pipestat_enable_mask(struct drm_i915_private *i915, enum pipe pipe);
|
||||
u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe);
|
||||
void i915_enable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask);
|
||||
void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask);
|
||||
void i915_enable_asle_pipestat(struct drm_i915_private *i915);
|
||||
|
|
@ -75,6 +76,9 @@ void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_
|
|||
void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]);
|
||||
void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]);
|
||||
|
||||
void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt);
|
||||
void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt);
|
||||
|
||||
void intel_display_irq_init(struct drm_i915_private *i915);
|
||||
|
||||
void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable);
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ intel_display_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400,
|
|||
|
||||
intel_display_param_named_unsafe(enable_dmc_wl, int, 0400,
|
||||
"Enable DMC wakelock "
|
||||
"(-1=use per-chip default, 0=disabled, 1=enabled) "
|
||||
"(-1=use per-chip default, 0=disabled, 1=enabled, 2=match any register, 3=always locked) "
|
||||
"Default: -1");
|
||||
|
||||
__maybe_unused
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ static bool __intel_display_power_is_enabled(struct intel_display *display,
|
|||
|
||||
/**
|
||||
* intel_display_power_is_enabled - check for a power domain
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to check
|
||||
*
|
||||
* This function can be used to check the hw power domain state. It is mostly
|
||||
|
|
@ -239,10 +239,9 @@ static bool __intel_display_power_is_enabled(struct intel_display *display,
|
|||
* Returns:
|
||||
* True when the power domain is enabled, false otherwise.
|
||||
*/
|
||||
bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
|
||||
bool intel_display_power_is_enabled(struct intel_display *display,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
bool ret;
|
||||
|
||||
|
|
@ -500,7 +499,7 @@ __intel_display_power_get_domain(struct intel_display *display,
|
|||
|
||||
/**
|
||||
* intel_display_power_get - grab a power domain reference
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to reference
|
||||
*
|
||||
* This function grabs a power domain reference for @domain and ensures that the
|
||||
|
|
@ -510,10 +509,10 @@ __intel_display_power_get_domain(struct intel_display *display,
|
|||
* Any power domain reference obtained by this function must have a symmetric
|
||||
* call to intel_display_power_put() to release the reference again.
|
||||
*/
|
||||
intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
|
||||
intel_wakeref_t intel_display_power_get(struct intel_display *display,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
|
||||
|
||||
|
|
@ -526,7 +525,7 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
|
|||
|
||||
/**
|
||||
* intel_display_power_get_if_enabled - grab a reference for an enabled display power domain
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to reference
|
||||
*
|
||||
* This function grabs a power domain reference for @domain and ensures that the
|
||||
|
|
@ -537,10 +536,10 @@ intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
|
|||
* call to intel_display_power_put() to release the reference again.
|
||||
*/
|
||||
intel_wakeref_t
|
||||
intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
|
||||
intel_display_power_get_if_enabled(struct intel_display *display,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
intel_wakeref_t wakeref;
|
||||
bool is_enabled;
|
||||
|
|
@ -696,7 +695,7 @@ intel_display_power_put_async_work(struct work_struct *work)
|
|||
|
||||
/**
|
||||
* __intel_display_power_put_async - release a power domain reference asynchronously
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to reference
|
||||
* @wakeref: wakeref acquired for the reference that is being released
|
||||
* @delay_ms: delay of powering down the power domain
|
||||
|
|
@ -707,12 +706,12 @@ intel_display_power_put_async_work(struct work_struct *work)
|
|||
* The power down is delayed by @delay_ms if this is >= 0, or by a default
|
||||
* 100 ms otherwise.
|
||||
*/
|
||||
void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
void __intel_display_power_put_async(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
struct intel_runtime_pm *rpm = &i915->runtime_pm;
|
||||
intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm);
|
||||
|
|
@ -754,7 +753,7 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
|
|||
|
||||
/**
|
||||
* intel_display_power_flush_work - flushes the async display power disabling work
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Flushes any pending work that was scheduled by a preceding
|
||||
* intel_display_power_put_async() call, completing the disabling of the
|
||||
|
|
@ -764,9 +763,9 @@ void __intel_display_power_put_async(struct drm_i915_private *i915,
|
|||
* function returns; to ensure that the work handler isn't running use
|
||||
* intel_display_power_flush_work_sync() instead.
|
||||
*/
|
||||
void intel_display_power_flush_work(struct drm_i915_private *i915)
|
||||
void intel_display_power_flush_work(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
struct intel_power_domain_mask async_put_mask;
|
||||
intel_wakeref_t work_wakeref;
|
||||
|
|
@ -800,10 +799,9 @@ void intel_display_power_flush_work(struct drm_i915_private *i915)
|
|||
static void
|
||||
intel_display_power_flush_work_sync(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
|
||||
intel_display_power_flush_work(i915);
|
||||
intel_display_power_flush_work(display);
|
||||
cancel_async_put_work(power_domains, true);
|
||||
|
||||
verify_async_put_domains_state(power_domains);
|
||||
|
|
@ -814,7 +812,7 @@ intel_display_power_flush_work_sync(struct intel_display *display)
|
|||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
/**
|
||||
* intel_display_power_put - release a power domain reference
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to reference
|
||||
* @wakeref: wakeref acquired for the reference that is being released
|
||||
*
|
||||
|
|
@ -822,11 +820,11 @@ intel_display_power_flush_work_sync(struct intel_display *display)
|
|||
* intel_display_power_get() and might power down the corresponding hardware
|
||||
* block right away if this is the last reference.
|
||||
*/
|
||||
void intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
void intel_display_power_put(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
__intel_display_power_put(display, domain);
|
||||
intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
|
||||
|
|
@ -834,7 +832,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
|
|||
#else
|
||||
/**
|
||||
* intel_display_power_put_unchecked - release an unchecked power domain reference
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @domain: power domain to reference
|
||||
*
|
||||
* This function drops the power domain reference obtained by
|
||||
|
|
@ -842,13 +840,13 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
|
|||
* block right away if this is the last reference.
|
||||
*
|
||||
* This function is only for the power domain code's internal use to suppress wakeref
|
||||
* tracking when the correspondig debug kconfig option is disabled, should not
|
||||
* tracking when the corresponding debug kconfig option is disabled, should not
|
||||
* be used otherwise.
|
||||
*/
|
||||
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
|
||||
void intel_display_power_put_unchecked(struct intel_display *display,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
__intel_display_power_put(display, domain);
|
||||
intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm);
|
||||
|
|
@ -856,16 +854,15 @@ void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
|
|||
#endif
|
||||
|
||||
void
|
||||
intel_display_power_get_in_set(struct drm_i915_private *i915,
|
||||
intel_display_power_get_in_set(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
intel_wakeref_t __maybe_unused wf;
|
||||
|
||||
drm_WARN_ON(display->drm, test_bit(domain, power_domain_set->mask.bits));
|
||||
|
||||
wf = intel_display_power_get(i915, domain);
|
||||
wf = intel_display_power_get(display, domain);
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
power_domain_set->wakerefs[domain] = wf;
|
||||
#endif
|
||||
|
|
@ -873,16 +870,15 @@ intel_display_power_get_in_set(struct drm_i915_private *i915,
|
|||
}
|
||||
|
||||
bool
|
||||
intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
|
||||
intel_display_power_get_in_set_if_enabled(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
enum intel_display_power_domain domain)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
intel_wakeref_t wf;
|
||||
|
||||
drm_WARN_ON(display->drm, test_bit(domain, power_domain_set->mask.bits));
|
||||
|
||||
wf = intel_display_power_get_if_enabled(i915, domain);
|
||||
wf = intel_display_power_get_if_enabled(display, domain);
|
||||
if (!wf)
|
||||
return false;
|
||||
|
||||
|
|
@ -895,11 +891,10 @@ intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
|
|||
}
|
||||
|
||||
void
|
||||
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
|
||||
intel_display_power_put_mask_in_set(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
struct intel_power_domain_mask *mask)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
enum intel_display_power_domain domain;
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
|
|
@ -911,7 +906,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
|
|||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
wf = fetch_and_zero(&power_domain_set->wakerefs[domain]);
|
||||
#endif
|
||||
intel_display_power_put(i915, domain, wf);
|
||||
intel_display_power_put(display, domain, wf);
|
||||
clear_bit(domain, power_domain_set->mask.bits);
|
||||
}
|
||||
}
|
||||
|
|
@ -999,7 +994,7 @@ static u32 get_allowed_dc_mask(struct intel_display *display, int enable_dc)
|
|||
* intel_power_domains_init - initializes the power domain structures
|
||||
* @display: display device instance
|
||||
*
|
||||
* Initializes the power domain structures for @dev_priv depending upon the
|
||||
* Initializes the power domain structures for @display depending upon the
|
||||
* supported platform.
|
||||
*/
|
||||
int intel_power_domains_init(struct intel_display *display)
|
||||
|
|
@ -1061,10 +1056,9 @@ static void gen9_dbuf_slice_set(struct intel_display *display,
|
|||
slice, str_enable_disable(enable));
|
||||
}
|
||||
|
||||
void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
||||
void gen9_dbuf_slices_update(struct intel_display *display,
|
||||
u8 req_slices)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
u8 slice_mask = DISPLAY_INFO(display)->dbuf.slice_mask;
|
||||
enum dbuf_slice slice;
|
||||
|
|
@ -1095,10 +1089,9 @@ void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
|||
|
||||
static void gen9_dbuf_enable(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u8 slices_mask;
|
||||
|
||||
display->dbuf.enabled_slices = intel_enabled_dbuf_slices_mask(dev_priv);
|
||||
display->dbuf.enabled_slices = intel_enabled_dbuf_slices_mask(display);
|
||||
|
||||
slices_mask = BIT(DBUF_S1) | display->dbuf.enabled_slices;
|
||||
|
||||
|
|
@ -1109,14 +1102,12 @@ static void gen9_dbuf_enable(struct intel_display *display)
|
|||
* Just power up at least 1 slice, we will
|
||||
* figure out later which slices we have and what we need.
|
||||
*/
|
||||
gen9_dbuf_slices_update(dev_priv, slices_mask);
|
||||
gen9_dbuf_slices_update(display, slices_mask);
|
||||
}
|
||||
|
||||
static void gen9_dbuf_disable(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
gen9_dbuf_slices_update(dev_priv, 0);
|
||||
gen9_dbuf_slices_update(display, 0);
|
||||
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
intel_pmdemand_program_dbuf(display, 0);
|
||||
|
|
@ -1126,9 +1117,6 @@ static void gen12_dbuf_slices_config(struct intel_display *display)
|
|||
{
|
||||
enum dbuf_slice slice;
|
||||
|
||||
if (display->platform.alderlake_p)
|
||||
return;
|
||||
|
||||
for_each_dbuf_slice(display, slice)
|
||||
intel_de_rmw(display, DBUF_CTL_S(slice),
|
||||
DBUF_TRACKER_STATE_SERVICE_MASK,
|
||||
|
|
@ -1663,7 +1651,7 @@ static void icl_display_core_init(struct intel_display *display,
|
|||
return;
|
||||
|
||||
/* 2. Initialize all combo phys */
|
||||
intel_combo_phy_init(dev_priv);
|
||||
intel_combo_phy_init(display);
|
||||
|
||||
/*
|
||||
* 3. Enable Power Well 1 (PG1).
|
||||
|
|
@ -1681,7 +1669,7 @@ static void icl_display_core_init(struct intel_display *display,
|
|||
/* 4. Enable CDCLK. */
|
||||
intel_cdclk_init_hw(display);
|
||||
|
||||
if (DISPLAY_VER(display) >= 12)
|
||||
if (DISPLAY_VER(display) == 12 || display->platform.dg2)
|
||||
gen12_dbuf_slices_config(display);
|
||||
|
||||
/* 5. Enable DBUF. */
|
||||
|
|
@ -1726,7 +1714,6 @@ static void icl_display_core_init(struct intel_display *display,
|
|||
|
||||
static void icl_display_core_uninit(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
struct i915_power_well *well;
|
||||
|
||||
|
|
@ -1736,7 +1723,7 @@ static void icl_display_core_uninit(struct intel_display *display)
|
|||
gen9_disable_dc_states(display);
|
||||
intel_dmc_disable_program(display);
|
||||
|
||||
/* 1. Disable all display engine functions -> aready done */
|
||||
/* 1. Disable all display engine functions -> already done */
|
||||
|
||||
/* 2. Disable DBUF */
|
||||
gen9_dbuf_disable(display);
|
||||
|
|
@ -1759,7 +1746,7 @@ static void icl_display_core_uninit(struct intel_display *display)
|
|||
mutex_unlock(&power_domains->lock);
|
||||
|
||||
/* 5. */
|
||||
intel_combo_phy_uninit(dev_priv);
|
||||
intel_combo_phy_uninit(display);
|
||||
}
|
||||
|
||||
static void chv_phy_control_init(struct intel_display *display)
|
||||
|
|
@ -1966,12 +1953,12 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume)
|
|||
*/
|
||||
drm_WARN_ON(display->drm, power_domains->init_wakeref);
|
||||
power_domains->init_wakeref =
|
||||
intel_display_power_get(i915, POWER_DOMAIN_INIT);
|
||||
intel_display_power_get(display, POWER_DOMAIN_INIT);
|
||||
|
||||
/* Disable power support if the user asked so. */
|
||||
if (!display->params.disable_power_well) {
|
||||
drm_WARN_ON(display->drm, power_domains->disable_wakeref);
|
||||
display->power.domains.disable_wakeref = intel_display_power_get(i915,
|
||||
display->power.domains.disable_wakeref = intel_display_power_get(display,
|
||||
POWER_DOMAIN_INIT);
|
||||
}
|
||||
intel_power_domains_sync_hw(display);
|
||||
|
|
@ -1998,7 +1985,7 @@ void intel_power_domains_driver_remove(struct intel_display *display)
|
|||
|
||||
/* Remove the refcount we took to keep power well support disabled. */
|
||||
if (!display->params.disable_power_well)
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT,
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT,
|
||||
fetch_and_zero(&display->power.domains.disable_wakeref));
|
||||
|
||||
intel_display_power_flush_work_sync(display);
|
||||
|
|
@ -2054,11 +2041,10 @@ void intel_power_domains_sanitize_state(struct intel_display *display)
|
|||
*/
|
||||
void intel_power_domains_enable(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
intel_wakeref_t wakeref __maybe_unused =
|
||||
fetch_and_zero(&display->power.domains.init_wakeref);
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_power_domains_verify_state(display);
|
||||
}
|
||||
|
||||
|
|
@ -2071,12 +2057,11 @@ void intel_power_domains_enable(struct intel_display *display)
|
|||
*/
|
||||
void intel_power_domains_disable(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
|
||||
drm_WARN_ON(display->drm, power_domains->init_wakeref);
|
||||
power_domains->init_wakeref =
|
||||
intel_display_power_get(i915, POWER_DOMAIN_INIT);
|
||||
intel_display_power_get(display, POWER_DOMAIN_INIT);
|
||||
|
||||
intel_power_domains_verify_state(display);
|
||||
}
|
||||
|
|
@ -2094,12 +2079,11 @@ void intel_power_domains_disable(struct intel_display *display)
|
|||
*/
|
||||
void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
intel_wakeref_t wakeref __maybe_unused =
|
||||
fetch_and_zero(&power_domains->init_wakeref);
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref);
|
||||
|
||||
/*
|
||||
* In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9
|
||||
|
|
@ -2110,7 +2094,7 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
|
|||
*/
|
||||
if (!(power_domains->allowed_dc_mask & DC_STATE_EN_DC9) && s2idle &&
|
||||
intel_dmc_has_payload(display)) {
|
||||
intel_display_power_flush_work(i915);
|
||||
intel_display_power_flush_work(display);
|
||||
intel_power_domains_verify_state(display);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2120,10 +2104,10 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
|
|||
* power wells if power domains must be deinitialized for suspend.
|
||||
*/
|
||||
if (!display->params.disable_power_well)
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT,
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT,
|
||||
fetch_and_zero(&display->power.domains.disable_wakeref));
|
||||
|
||||
intel_display_power_flush_work(i915);
|
||||
intel_display_power_flush_work(display);
|
||||
intel_power_domains_verify_state(display);
|
||||
|
||||
if (DISPLAY_VER(display) >= 11)
|
||||
|
|
@ -2148,7 +2132,6 @@ void intel_power_domains_suspend(struct intel_display *display, bool s2idle)
|
|||
*/
|
||||
void intel_power_domains_resume(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
|
||||
if (power_domains->display_core_suspended) {
|
||||
|
|
@ -2157,7 +2140,7 @@ void intel_power_domains_resume(struct intel_display *display)
|
|||
} else {
|
||||
drm_WARN_ON(display->drm, power_domains->init_wakeref);
|
||||
power_domains->init_wakeref =
|
||||
intel_display_power_get(i915, POWER_DOMAIN_INIT);
|
||||
intel_display_power_get(display, POWER_DOMAIN_INIT);
|
||||
}
|
||||
|
||||
intel_power_domains_verify_state(display);
|
||||
|
|
@ -2327,9 +2310,8 @@ void intel_display_power_resume(struct intel_display *display)
|
|||
}
|
||||
}
|
||||
|
||||
void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m)
|
||||
void intel_display_power_debug(struct intel_display *display, struct seq_file *m)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
int i;
|
||||
|
||||
|
|
@ -2510,9 +2492,8 @@ intel_port_domains_for_port(struct intel_display *display, enum port port)
|
|||
}
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
|
||||
intel_display_power_ddi_io_domain(struct intel_display *display, enum port port)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(display, port);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID))
|
||||
|
|
@ -2522,9 +2503,8 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
|
|||
}
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port port)
|
||||
intel_display_power_ddi_lanes_domain(struct intel_display *display, enum port port)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(display, port);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID))
|
||||
|
|
@ -2549,9 +2529,8 @@ intel_port_domains_for_aux_ch(struct intel_display *display, enum aux_ch aux_ch)
|
|||
}
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux_ch)
|
||||
intel_display_power_aux_io_domain(struct intel_display *display, enum aux_ch aux_ch)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !domains || domains->aux_io == POWER_DOMAIN_INVALID))
|
||||
|
|
@ -2561,9 +2540,8 @@ intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux
|
|||
}
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch)
|
||||
intel_display_power_legacy_aux_domain(struct intel_display *display, enum aux_ch aux_ch)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID))
|
||||
|
|
@ -2573,9 +2551,8 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch
|
|||
}
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch)
|
||||
intel_display_power_tbt_aux_domain(struct intel_display *display, enum aux_ch aux_ch)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(display, aux_ch);
|
||||
|
||||
if (drm_WARN_ON(display->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID))
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
enum aux_ch;
|
||||
enum port;
|
||||
struct drm_i915_private;
|
||||
struct i915_power_well;
|
||||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
|
|
@ -184,102 +183,102 @@ void intel_display_power_resume(struct intel_display *display);
|
|||
void intel_display_power_set_target_dc_state(struct intel_display *display,
|
||||
u32 state);
|
||||
|
||||
bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
|
||||
bool intel_display_power_is_enabled(struct intel_display *display,
|
||||
enum intel_display_power_domain domain);
|
||||
intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
|
||||
intel_wakeref_t intel_display_power_get(struct intel_display *display,
|
||||
enum intel_display_power_domain domain);
|
||||
intel_wakeref_t
|
||||
intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv,
|
||||
intel_display_power_get_if_enabled(struct intel_display *display,
|
||||
enum intel_display_power_domain domain);
|
||||
void __intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
void __intel_display_power_put_async(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms);
|
||||
void intel_display_power_flush_work(struct drm_i915_private *i915);
|
||||
void intel_display_power_flush_work(struct intel_display *display);
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
|
||||
void intel_display_power_put(struct drm_i915_private *dev_priv,
|
||||
void intel_display_power_put(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref);
|
||||
static inline void
|
||||
intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
intel_display_power_put_async(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, wakeref, -1);
|
||||
__intel_display_power_put_async(display, domain, wakeref, -1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_async_delay(struct drm_i915_private *i915,
|
||||
intel_display_power_put_async_delay(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, wakeref, delay_ms);
|
||||
__intel_display_power_put_async(display, domain, wakeref, delay_ms);
|
||||
}
|
||||
#else
|
||||
void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv,
|
||||
void intel_display_power_put_unchecked(struct intel_display *display,
|
||||
enum intel_display_power_domain domain);
|
||||
|
||||
static inline void
|
||||
intel_display_power_put(struct drm_i915_private *i915,
|
||||
intel_display_power_put(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
intel_display_power_put_unchecked(i915, domain);
|
||||
intel_display_power_put_unchecked(display, domain);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_async(struct drm_i915_private *i915,
|
||||
intel_display_power_put_async(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, -1);
|
||||
__intel_display_power_put_async(display, domain, INTEL_WAKEREF_DEF, -1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_async_delay(struct drm_i915_private *i915,
|
||||
intel_display_power_put_async_delay(struct intel_display *display,
|
||||
enum intel_display_power_domain domain,
|
||||
intel_wakeref_t wakeref,
|
||||
int delay_ms)
|
||||
{
|
||||
__intel_display_power_put_async(i915, domain, INTEL_WAKEREF_DEF, delay_ms);
|
||||
__intel_display_power_put_async(display, domain, INTEL_WAKEREF_DEF, delay_ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
intel_display_power_get_in_set(struct drm_i915_private *i915,
|
||||
intel_display_power_get_in_set(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
enum intel_display_power_domain domain);
|
||||
|
||||
bool
|
||||
intel_display_power_get_in_set_if_enabled(struct drm_i915_private *i915,
|
||||
intel_display_power_get_in_set_if_enabled(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
enum intel_display_power_domain domain);
|
||||
|
||||
void
|
||||
intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
|
||||
intel_display_power_put_mask_in_set(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set,
|
||||
struct intel_power_domain_mask *mask);
|
||||
|
||||
static inline void
|
||||
intel_display_power_put_all_in_set(struct drm_i915_private *i915,
|
||||
intel_display_power_put_all_in_set(struct intel_display *display,
|
||||
struct intel_display_power_domain_set *power_domain_set)
|
||||
{
|
||||
intel_display_power_put_mask_in_set(i915, power_domain_set, &power_domain_set->mask);
|
||||
intel_display_power_put_mask_in_set(display, power_domain_set, &power_domain_set->mask);
|
||||
}
|
||||
|
||||
void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m);
|
||||
void intel_display_power_debug(struct intel_display *display, struct seq_file *m);
|
||||
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port port);
|
||||
intel_display_power_ddi_lanes_domain(struct intel_display *display, enum port port);
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port);
|
||||
intel_display_power_ddi_io_domain(struct intel_display *display, enum port port);
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_aux_io_domain(struct drm_i915_private *i915, enum aux_ch aux_ch);
|
||||
intel_display_power_aux_io_domain(struct intel_display *display, enum aux_ch aux_ch);
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch);
|
||||
intel_display_power_legacy_aux_domain(struct intel_display *display, enum aux_ch aux_ch);
|
||||
enum intel_display_power_domain
|
||||
intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch aux_ch);
|
||||
intel_display_power_tbt_aux_domain(struct intel_display *display, enum aux_ch aux_ch);
|
||||
|
||||
/*
|
||||
* FIXME: We should probably switch this to a 0-based scheme to be consistent
|
||||
|
|
@ -293,15 +292,15 @@ enum dbuf_slice {
|
|||
I915_MAX_DBUF_SLICES
|
||||
};
|
||||
|
||||
void gen9_dbuf_slices_update(struct drm_i915_private *dev_priv,
|
||||
void gen9_dbuf_slices_update(struct intel_display *display,
|
||||
u8 req_slices);
|
||||
|
||||
#define with_intel_display_power(i915, domain, wf) \
|
||||
for ((wf) = intel_display_power_get((i915), (domain)); (wf); \
|
||||
intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL)
|
||||
#define with_intel_display_power(display, domain, wf) \
|
||||
for ((wf) = intel_display_power_get((display), (domain)); (wf); \
|
||||
intel_display_power_put_async((display), (domain), (wf)), (wf) = NULL)
|
||||
|
||||
#define with_intel_display_power_if_enabled(i915, domain, wf) \
|
||||
for ((wf) = intel_display_power_get_if_enabled((i915), (domain)); (wf); \
|
||||
intel_display_power_put_async((i915), (domain), (wf)), (wf) = NULL)
|
||||
#define with_intel_display_power_if_enabled(display, domain, wf) \
|
||||
for ((wf) = intel_display_power_get_if_enabled((display), (domain)); (wf); \
|
||||
intel_display_power_put_async((display), (domain), (wf)), (wf) = NULL)
|
||||
|
||||
#endif /* __INTEL_DISPLAY_POWER_H__ */
|
||||
|
|
|
|||
|
|
@ -507,7 +507,6 @@ static void
|
|||
icl_tc_phy_aux_power_well_enable(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum aux_ch aux_ch = icl_aux_pw_to_ch(power_well);
|
||||
struct intel_digital_port *dig_port = aux_ch_to_digital_port(display, aux_ch);
|
||||
const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
|
||||
|
|
@ -539,7 +538,7 @@ icl_tc_phy_aux_power_well_enable(struct intel_display *display,
|
|||
|
||||
tc_port = TGL_AUX_PW_TO_TC_PORT(i915_power_well_instance(power_well)->hsw.idx);
|
||||
|
||||
if (wait_for(intel_dkl_phy_read(dev_priv, DKL_CMN_UC_DW_27(tc_port)) &
|
||||
if (wait_for(intel_dkl_phy_read(display, DKL_CMN_UC_DW_27(tc_port)) &
|
||||
DKL_CMN_UC_DW27_UC_HEALTH, 1))
|
||||
drm_warn(display->drm,
|
||||
"Timeout waiting TC uC health\n");
|
||||
|
|
@ -962,8 +961,7 @@ static bool gen9_dc_off_power_well_enabled(struct intel_display *display,
|
|||
|
||||
static void gen9_assert_dbuf_enabled(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(dev_priv);
|
||||
u8 hw_enabled_dbuf_slices = intel_enabled_dbuf_slices_mask(display);
|
||||
u8 enabled_dbuf_slices = display->dbuf.enabled_slices;
|
||||
|
||||
drm_WARN(display->drm,
|
||||
|
|
@ -975,7 +973,6 @@ static void gen9_assert_dbuf_enabled(struct intel_display *display)
|
|||
|
||||
void gen9_disable_dc_states(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct i915_power_domains *power_domains = &display->power.domains;
|
||||
struct intel_cdclk_config cdclk_config = {};
|
||||
u32 old_state = power_domains->dc_state;
|
||||
|
|
@ -1015,7 +1012,7 @@ void gen9_disable_dc_states(struct intel_display *display)
|
|||
* PHY's HW context for port B is lost after DC transitions,
|
||||
* so we need to restore it manually.
|
||||
*/
|
||||
intel_combo_phy_init(dev_priv);
|
||||
intel_combo_phy_init(display);
|
||||
}
|
||||
|
||||
static void gen9_dc_off_power_well_enable(struct intel_display *display,
|
||||
|
|
@ -1314,11 +1311,10 @@ static void vlv_dpio_cmn_power_well_enable(struct intel_display *display,
|
|||
static void vlv_dpio_cmn_power_well_disable(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum pipe pipe;
|
||||
|
||||
for_each_pipe(display, pipe)
|
||||
assert_pll_disabled(dev_priv, pipe);
|
||||
assert_pll_disabled(display, pipe);
|
||||
|
||||
/* Assert common reset */
|
||||
intel_de_rmw(display, DPIO_CTL, DPIO_CMNRST, 0);
|
||||
|
|
@ -1500,7 +1496,6 @@ static void chv_dpio_cmn_power_well_enable(struct intel_display *display,
|
|||
static void chv_dpio_cmn_power_well_disable(struct intel_display *display,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum i915_power_well_id id = i915_power_well_instance(power_well)->id;
|
||||
enum dpio_phy phy;
|
||||
|
||||
|
|
@ -1510,11 +1505,11 @@ static void chv_dpio_cmn_power_well_disable(struct intel_display *display,
|
|||
|
||||
if (id == VLV_DISP_PW_DPIO_CMN_BC) {
|
||||
phy = DPIO_PHY0;
|
||||
assert_pll_disabled(dev_priv, PIPE_A);
|
||||
assert_pll_disabled(dev_priv, PIPE_B);
|
||||
assert_pll_disabled(display, PIPE_A);
|
||||
assert_pll_disabled(display, PIPE_B);
|
||||
} else {
|
||||
phy = DPIO_PHY1;
|
||||
assert_pll_disabled(dev_priv, PIPE_C);
|
||||
assert_pll_disabled(display, PIPE_C);
|
||||
}
|
||||
|
||||
display->power.chv_phy_control &= ~PHY_COM_LANE_RESET_DEASSERT(phy);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ struct i915_power_well_instance {
|
|||
/* unique identifier for this power well */
|
||||
enum i915_power_well_id id;
|
||||
/*
|
||||
* Arbitraty data associated with this power well. Platform and power
|
||||
* Arbitrary data associated with this power well. Platform and power
|
||||
* well specific.
|
||||
*/
|
||||
union {
|
||||
|
|
@ -77,7 +77,7 @@ struct i915_power_well_instance {
|
|||
struct {
|
||||
/*
|
||||
* request/status flag index in the power well
|
||||
* constrol/status registers.
|
||||
* control/status registers.
|
||||
*/
|
||||
u8 idx;
|
||||
} hsw;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_clock_gating.h"
|
||||
#include "intel_cx0_phy.h"
|
||||
#include "intel_display_driver.h"
|
||||
#include "intel_display_reset.h"
|
||||
#include "intel_display_types.h"
|
||||
|
|
@ -116,6 +117,7 @@ void intel_display_reset_finish(struct drm_i915_private *i915)
|
|||
intel_pps_unlock_regs_wa(display);
|
||||
intel_display_driver_init_hw(display);
|
||||
intel_clock_gating_init(i915);
|
||||
intel_cx0_pll_power_save_wa(display);
|
||||
intel_hpd_init(i915);
|
||||
|
||||
ret = __intel_display_driver_resume(display, state, ctx);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@
|
|||
*/
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#ifdef I915
|
||||
#define TRACE_SYSTEM i915
|
||||
#else
|
||||
#define TRACE_SYSTEM xe
|
||||
#endif
|
||||
|
||||
#if !defined(__INTEL_DISPLAY_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define __INTEL_DISPLAY_TRACE_H__
|
||||
|
|
@ -21,6 +25,7 @@
|
|||
#include "intel_vblank.h"
|
||||
|
||||
#define __dev_name_display(display) dev_name((display)->drm->dev)
|
||||
#define __dev_name_drm(obj) dev_name((obj)->dev->dev)
|
||||
#define __dev_name_kms(obj) dev_name((obj)->base.dev->dev)
|
||||
|
||||
/*
|
||||
|
|
@ -397,23 +402,24 @@ TRACE_EVENT(intel_plane_async_flip,
|
|||
__entry->async_flip = async_flip;
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, async_flip=%s",
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, async_flip=%s",
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline, str_yes_no(__entry->async_flip))
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_plane_update_noarm,
|
||||
TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc),
|
||||
TP_ARGS(plane, crtc),
|
||||
TP_PROTO(const struct intel_plane_state *plane_state, struct intel_crtc *crtc),
|
||||
TP_ARGS(plane_state, crtc),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_kms(plane))
|
||||
__string(dev, __dev_name_drm(plane_state->uapi.plane))
|
||||
__field(char, pipe_name)
|
||||
__field(u32, frame)
|
||||
__field(u32, scanline)
|
||||
__field(u32, format)
|
||||
__array(int, src, 4)
|
||||
__array(int, dst, 4)
|
||||
__string(name, plane->base.name)
|
||||
__string(name, plane_state->uapi.plane->name)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
|
|
@ -422,29 +428,31 @@ TRACE_EVENT(intel_plane_update_noarm,
|
|||
__entry->pipe_name = pipe_name(crtc->pipe);
|
||||
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src));
|
||||
memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst));
|
||||
__entry->format = plane_state->hw.fb->format->format;
|
||||
memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src));
|
||||
memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst));
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, format=%p4cc, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline,
|
||||
__entry->frame, __entry->scanline, &__entry->format,
|
||||
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
|
||||
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_plane_update_arm,
|
||||
TP_PROTO(struct intel_plane *plane, struct intel_crtc *crtc),
|
||||
TP_ARGS(plane, crtc),
|
||||
TP_PROTO(const struct intel_plane_state *plane_state, struct intel_crtc *crtc),
|
||||
TP_ARGS(plane_state, crtc),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_kms(plane))
|
||||
__string(dev, __dev_name_drm(plane_state->uapi.plane))
|
||||
__field(char, pipe_name)
|
||||
__field(u32, frame)
|
||||
__field(u32, scanline)
|
||||
__field(u32, format)
|
||||
__array(int, src, 4)
|
||||
__array(int, dst, 4)
|
||||
__string(name, plane->base.name)
|
||||
__string(name, plane_state->uapi.plane->name)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
|
|
@ -453,13 +461,14 @@ TRACE_EVENT(intel_plane_update_arm,
|
|||
__entry->pipe_name = pipe_name(crtc->pipe);
|
||||
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
memcpy(__entry->src, &plane->base.state->src, sizeof(__entry->src));
|
||||
memcpy(__entry->dst, &plane->base.state->dst, sizeof(__entry->dst));
|
||||
__entry->format = plane_state->hw.fb->format->format;
|
||||
memcpy(__entry->src, &plane_state->uapi.src, sizeof(__entry->src));
|
||||
memcpy(__entry->dst, &plane_state->uapi.dst, sizeof(__entry->dst));
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u, format=%p4cc, " DRM_RECT_FP_FMT " -> " DRM_RECT_FMT,
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline,
|
||||
__entry->frame, __entry->scanline, &__entry->format,
|
||||
DRM_RECT_FP_ARG((const struct drm_rect *)__entry->src),
|
||||
DRM_RECT_ARG((const struct drm_rect *)__entry->dst))
|
||||
);
|
||||
|
|
@ -484,11 +493,110 @@ TRACE_EVENT(intel_plane_disable_arm,
|
|||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u",
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline)
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_plane_scaler_update_arm,
|
||||
TP_PROTO(struct intel_plane *plane,
|
||||
int scaler_id, int x, int y, int w, int h),
|
||||
TP_ARGS(plane, scaler_id, x, y, w, h),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_kms(plane))
|
||||
__field(char, pipe_name)
|
||||
__field(int, scaler_id)
|
||||
__field(u32, frame)
|
||||
__field(u32, scanline)
|
||||
__field(int, x)
|
||||
__field(int, y)
|
||||
__field(int, w)
|
||||
__field(int, h)
|
||||
__string(name, plane->base.name)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
struct intel_display *display = to_intel_display(plane);
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
|
||||
__assign_str(dev);
|
||||
__assign_str(name);
|
||||
__entry->pipe_name = pipe_name(crtc->pipe);
|
||||
__entry->scaler_id = scaler_id;
|
||||
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
__entry->x = x;
|
||||
__entry->y = y;
|
||||
__entry->w = w;
|
||||
__entry->h = h;
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, scaler %d, plane %s, frame=%u, scanline=%u, " DRM_RECT_FMT,
|
||||
__get_str(dev), __entry->pipe_name, __entry->scaler_id,
|
||||
__get_str(name), __entry->frame, __entry->scanline,
|
||||
__entry->w, __entry->h, __entry->x, __entry->y)
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_pipe_scaler_update_arm,
|
||||
TP_PROTO(struct intel_crtc *crtc, int scaler_id,
|
||||
int x, int y, int w, int h),
|
||||
TP_ARGS(crtc, scaler_id, x, y, w, h),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_kms(crtc))
|
||||
__field(char, pipe_name)
|
||||
__field(int, scaler_id)
|
||||
__field(u32, frame)
|
||||
__field(u32, scanline)
|
||||
__field(int, x)
|
||||
__field(int, y)
|
||||
__field(int, w)
|
||||
__field(int, h)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(dev);
|
||||
__entry->pipe_name = pipe_name(crtc->pipe);
|
||||
__entry->scaler_id = scaler_id;
|
||||
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
__entry->x = x;
|
||||
__entry->y = y;
|
||||
__entry->w = w;
|
||||
__entry->h = h;
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, scaler %d frame=%u, scanline=%u, " DRM_RECT_FMT,
|
||||
__get_str(dev), __entry->pipe_name, __entry->scaler_id,
|
||||
__entry->frame, __entry->scanline,
|
||||
__entry->w, __entry->h, __entry->x, __entry->y)
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_scaler_disable_arm,
|
||||
TP_PROTO(struct intel_crtc *crtc, int scaler_id),
|
||||
TP_ARGS(crtc, scaler_id),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(dev, __dev_name_kms(crtc))
|
||||
__field(char, pipe_name)
|
||||
__field(int, scaler_id)
|
||||
__field(u32, frame)
|
||||
__field(u32, scanline)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(dev);
|
||||
__entry->pipe_name = pipe_name(crtc->pipe);
|
||||
__entry->scaler_id = scaler_id;
|
||||
__entry->frame = intel_crtc_get_vblank_counter(crtc);
|
||||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, scaler %d, frame=%u, scanline=%u",
|
||||
__get_str(dev), __entry->pipe_name, __entry->scaler_id,
|
||||
__entry->frame, __entry->scanline)
|
||||
);
|
||||
|
||||
TRACE_EVENT(intel_fbc_activate,
|
||||
TP_PROTO(struct intel_plane *plane),
|
||||
TP_ARGS(plane),
|
||||
|
|
@ -512,7 +620,7 @@ TRACE_EVENT(intel_fbc_activate,
|
|||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u",
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline)
|
||||
);
|
||||
|
|
@ -540,7 +648,7 @@ TRACE_EVENT(intel_fbc_deactivate,
|
|||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u",
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline)
|
||||
);
|
||||
|
|
@ -568,7 +676,7 @@ TRACE_EVENT(intel_fbc_nuke,
|
|||
__entry->scanline = intel_get_crtc_scanline(crtc);
|
||||
),
|
||||
|
||||
TP_printk("dev %s, pipe %c, plane %s, frame=%u, scanline=%u",
|
||||
TP_printk("dev %s, pipe %c, %s, frame=%u, scanline=%u",
|
||||
__get_str(dev), __entry->pipe_name, __get_str(name),
|
||||
__entry->frame, __entry->scanline)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ struct intel_framebuffer {
|
|||
struct i915_address_space *dpt_vm;
|
||||
|
||||
unsigned int min_alignment;
|
||||
unsigned int vtd_guard;
|
||||
};
|
||||
|
||||
enum intel_hotplug_state {
|
||||
|
|
@ -412,6 +413,7 @@ struct intel_panel {
|
|||
union {
|
||||
struct {
|
||||
struct drm_edp_backlight_info info;
|
||||
bool luminance_control_support;
|
||||
} vesa;
|
||||
struct {
|
||||
bool sdr_uses_aux;
|
||||
|
|
@ -494,6 +496,8 @@ struct intel_hdcp {
|
|||
enum transcoder cpu_transcoder;
|
||||
/* Only used for DP MST stream encryption */
|
||||
enum transcoder stream_transcoder;
|
||||
/* Used to force HDCP 1.4 bypassing HDCP 2.x */
|
||||
bool force_hdcp14;
|
||||
};
|
||||
|
||||
struct intel_connector {
|
||||
|
|
@ -638,6 +642,9 @@ struct intel_plane_state {
|
|||
/* Plane state to display black pixels when pxp is borked */
|
||||
bool force_black;
|
||||
|
||||
/* Acting as Y plane for another UV plane? */
|
||||
bool is_y_plane;
|
||||
|
||||
/* plane control register */
|
||||
u32 ctl;
|
||||
|
||||
|
|
@ -677,16 +684,6 @@ struct intel_plane_state {
|
|||
*/
|
||||
struct intel_plane *planar_linked_plane;
|
||||
|
||||
/*
|
||||
* planar_slave:
|
||||
* If set don't update use the linked plane's state for updating
|
||||
* this plane during atomic commit with the update_slave() callback.
|
||||
*
|
||||
* It's also used by the watermark code to ignore wm calculations on
|
||||
* this plane. They're calculated by the linked plane's wm code.
|
||||
*/
|
||||
u32 planar_slave;
|
||||
|
||||
struct drm_intel_sprite_colorkey ckey;
|
||||
|
||||
struct drm_rect psr2_sel_fetch_area;
|
||||
|
|
@ -711,6 +708,8 @@ struct intel_initial_plane_config {
|
|||
struct intel_scaler {
|
||||
u32 mode;
|
||||
bool in_use;
|
||||
int hscale;
|
||||
int vscale;
|
||||
};
|
||||
|
||||
struct intel_crtc_scaler_state {
|
||||
|
|
@ -732,7 +731,7 @@ struct intel_crtc_scaler_state {
|
|||
*
|
||||
* intel_atomic_setup_scalers will setup available scalers to users
|
||||
* requesting scalers. It will gracefully fail if request exceeds
|
||||
* avilability.
|
||||
* availability.
|
||||
*/
|
||||
#define SKL_CRTC_INDEX 31
|
||||
unsigned scaler_users;
|
||||
|
|
@ -1095,6 +1094,7 @@ struct intel_crtc_state {
|
|||
|
||||
int max_link_bpp_x16; /* in 1/16 bpp units */
|
||||
int pipe_bpp; /* in 1 bpp units */
|
||||
int min_hblank;
|
||||
struct intel_link_m_n dp_m_n;
|
||||
|
||||
/* m2_n2 for eDP downclock */
|
||||
|
|
@ -1113,7 +1113,7 @@ struct intel_crtc_state {
|
|||
u16 su_y_granularity;
|
||||
|
||||
/*
|
||||
* Frequence the dpll for the port should run at. Differs from the
|
||||
* Frequency the dpll for the port should run at. Differs from the
|
||||
* adjusted dotclock e.g. for DP or 10/12bpc hdmi mode. This is also
|
||||
* already multiplied by pixel_multiplier.
|
||||
*/
|
||||
|
|
@ -1439,12 +1439,17 @@ struct intel_crtc {
|
|||
bool block_dc_for_vblank;
|
||||
};
|
||||
|
||||
struct intel_plane_error {
|
||||
u32 ctl, surf, surflive;
|
||||
};
|
||||
|
||||
struct intel_plane {
|
||||
struct drm_plane base;
|
||||
enum i9xx_plane_id i9xx_plane;
|
||||
enum plane_id id;
|
||||
enum pipe pipe;
|
||||
bool need_async_flip_toggle_wa;
|
||||
u8 vtd_guard;
|
||||
u32 frontbuffer_bit;
|
||||
|
||||
struct {
|
||||
|
|
@ -1474,6 +1479,7 @@ struct intel_plane {
|
|||
unsigned int (*max_stride)(struct intel_plane *plane,
|
||||
u32 pixel_format, u64 modifier,
|
||||
unsigned int rotation);
|
||||
bool (*can_async_flip)(u64 modifier);
|
||||
/* Write all non-self arming plane registers */
|
||||
void (*update_noarm)(struct intel_dsb *dsb,
|
||||
struct intel_plane *plane,
|
||||
|
|
@ -1488,6 +1494,9 @@ struct intel_plane {
|
|||
void (*disable_arm)(struct intel_dsb *dsb,
|
||||
struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state);
|
||||
void (*capture_error)(struct intel_crtc *crtc,
|
||||
struct intel_plane *plane,
|
||||
struct intel_plane_error *error);
|
||||
bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
|
||||
int (*check_plane)(struct intel_crtc_state *crtc_state,
|
||||
struct intel_plane_state *plane_state);
|
||||
|
|
@ -1979,24 +1988,12 @@ static inline bool intel_encoder_is_hdmi(struct intel_encoder *encoder)
|
|||
}
|
||||
}
|
||||
|
||||
static inline struct intel_lspcon *
|
||||
enc_to_intel_lspcon(struct intel_encoder *encoder)
|
||||
{
|
||||
return &enc_to_dig_port(encoder)->lspcon;
|
||||
}
|
||||
|
||||
static inline struct intel_digital_port *
|
||||
dp_to_dig_port(struct intel_dp *intel_dp)
|
||||
{
|
||||
return container_of(intel_dp, struct intel_digital_port, dp);
|
||||
}
|
||||
|
||||
static inline struct intel_lspcon *
|
||||
dp_to_lspcon(struct intel_dp *intel_dp)
|
||||
{
|
||||
return &dp_to_dig_port(intel_dp)->lspcon;
|
||||
}
|
||||
|
||||
static inline struct intel_digital_port *
|
||||
hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,20 +20,20 @@ void intel_dkl_phy_init(struct drm_i915_private *i915)
|
|||
}
|
||||
|
||||
static void
|
||||
dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
dkl_phy_set_hip_idx(struct intel_display *display, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
enum tc_port tc_port = DKL_REG_TC_PORT(reg);
|
||||
|
||||
drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
|
||||
drm_WARN_ON(display->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
|
||||
|
||||
intel_de_write(i915,
|
||||
intel_de_write(display,
|
||||
HIP_INDEX_REG(tc_port),
|
||||
HIP_INDEX_VAL(tc_port, reg.bank_idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_read - read a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @display: intel_display device instance
|
||||
* @reg: Dekel PHY register
|
||||
*
|
||||
* Read the @reg Dekel PHY register.
|
||||
|
|
@ -41,42 +41,42 @@ dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
|||
* Returns the read value.
|
||||
*/
|
||||
u32
|
||||
intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
spin_lock(&display->dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
val = intel_de_read(i915, DKL_REG_MMIO(reg));
|
||||
dkl_phy_set_hip_idx(display, reg);
|
||||
val = intel_de_read(display, DKL_REG_MMIO(reg));
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
spin_unlock(&display->dkl.phy_lock);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_write - write a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @display: intel_display device instance
|
||||
* @reg: Dekel PHY register
|
||||
* @val: value to write
|
||||
*
|
||||
* Write @val to the @reg Dekel PHY register.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val)
|
||||
intel_dkl_phy_write(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 val)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
spin_lock(&display->dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_write(i915, DKL_REG_MMIO(reg), val);
|
||||
dkl_phy_set_hip_idx(display, reg);
|
||||
intel_de_write(display, DKL_REG_MMIO(reg), val);
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
spin_unlock(&display->dkl.phy_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_rmw - read-modify-write a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
* @reg: Dekel PHY register
|
||||
* @clear: mask to clear
|
||||
* @set: mask to set
|
||||
|
|
@ -85,30 +85,30 @@ intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg,
|
|||
* this value back to the register if the value differs from the read one.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
|
||||
intel_dkl_phy_rmw(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
spin_lock(&display->dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set);
|
||||
dkl_phy_set_hip_idx(display, reg);
|
||||
intel_de_rmw(display, DKL_REG_MMIO(reg), clear, set);
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
spin_unlock(&display->dkl.phy_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register
|
||||
* @i915: i915 device instance
|
||||
* @display: display device instance
|
||||
* @reg: Dekel PHY register
|
||||
*
|
||||
* Read the @reg Dekel PHY register without returning the read value.
|
||||
*/
|
||||
void
|
||||
intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
|
||||
intel_dkl_phy_posting_read(struct intel_display *display, struct intel_dkl_phy_reg reg)
|
||||
{
|
||||
spin_lock(&i915->display.dkl.phy_lock);
|
||||
spin_lock(&display->dkl.phy_lock);
|
||||
|
||||
dkl_phy_set_hip_idx(i915, reg);
|
||||
intel_de_posting_read(i915, DKL_REG_MMIO(reg));
|
||||
dkl_phy_set_hip_idx(display, reg);
|
||||
intel_de_posting_read(display, DKL_REG_MMIO(reg));
|
||||
|
||||
spin_unlock(&i915->display.dkl.phy_lock);
|
||||
spin_unlock(&display->dkl.phy_lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,16 @@
|
|||
#include "intel_dkl_phy_regs.h"
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_display;
|
||||
|
||||
void intel_dkl_phy_init(struct drm_i915_private *i915);
|
||||
u32
|
||||
intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
|
||||
intel_dkl_phy_read(struct intel_display *display, struct intel_dkl_phy_reg reg);
|
||||
void
|
||||
intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val);
|
||||
intel_dkl_phy_write(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 val);
|
||||
void
|
||||
intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set);
|
||||
intel_dkl_phy_rmw(struct intel_display *display, struct intel_dkl_phy_reg reg, u32 clear, u32 set);
|
||||
void
|
||||
intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
|
||||
intel_dkl_phy_posting_read(struct intel_display *display, struct intel_dkl_phy_reg reg);
|
||||
|
||||
#endif /* __INTEL_DKL_PHY_H__ */
|
||||
|
|
|
|||
|
|
@ -992,19 +992,16 @@ static int parse_dmc_fw(struct intel_dmc *dmc, const struct firmware *fw)
|
|||
|
||||
static void intel_dmc_runtime_pm_get(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
drm_WARN_ON(display->drm, display->dmc.wakeref);
|
||||
display->dmc.wakeref = intel_display_power_get(i915, POWER_DOMAIN_INIT);
|
||||
display->dmc.wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT);
|
||||
}
|
||||
|
||||
static void intel_dmc_runtime_pm_put(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
intel_wakeref_t wakeref __maybe_unused =
|
||||
fetch_and_zero(&display->dmc.wakeref);
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_INIT, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_INIT, wakeref);
|
||||
}
|
||||
|
||||
static const char *dmc_fallback_path(struct intel_display *display)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "intel_de.h"
|
||||
#include "intel_dmc.h"
|
||||
#include "intel_dmc_regs.h"
|
||||
#include "intel_dmc_wl.h"
|
||||
|
||||
|
|
@ -50,12 +49,24 @@
|
|||
#define DMC_WAKELOCK_CTL_TIMEOUT_US 5000
|
||||
#define DMC_WAKELOCK_HOLD_TIME 50
|
||||
|
||||
/*
|
||||
* Possible non-negative values for the enable_dmc_wl param.
|
||||
*/
|
||||
enum {
|
||||
ENABLE_DMC_WL_DISABLED,
|
||||
ENABLE_DMC_WL_ENABLED,
|
||||
ENABLE_DMC_WL_ANY_REGISTER,
|
||||
ENABLE_DMC_WL_ALWAYS_LOCKED,
|
||||
ENABLE_DMC_WL_MAX,
|
||||
};
|
||||
|
||||
struct intel_dmc_wl_range {
|
||||
u32 start;
|
||||
u32 end;
|
||||
};
|
||||
|
||||
static const struct intel_dmc_wl_range powered_off_ranges[] = {
|
||||
{ .start = 0x44400, .end = 0x4447f }, /* PIPE interrupt registers */
|
||||
{ .start = 0x60000, .end = 0x7ffff },
|
||||
{},
|
||||
};
|
||||
|
|
@ -90,6 +101,7 @@ static const struct intel_dmc_wl_range xe3lpd_dc5_dc6_dmc_ranges[] = {
|
|||
{ .start = 0x42088 }, /* CHICKEN_MISC_3 */
|
||||
{ .start = 0x46160 }, /* CMTG_CLK_SEL */
|
||||
{ .start = 0x8f000, .end = 0x8ffff }, /* Main DMC registers */
|
||||
{ .start = 0x45230 }, /* INITIATE_PM_DMD_REQ */
|
||||
|
||||
{},
|
||||
};
|
||||
|
|
@ -230,10 +242,15 @@ static bool intel_dmc_wl_reg_in_range(i915_reg_t reg,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool intel_dmc_wl_check_range(i915_reg_t reg, u32 dc_state)
|
||||
static bool intel_dmc_wl_check_range(struct intel_display *display,
|
||||
i915_reg_t reg,
|
||||
u32 dc_state)
|
||||
{
|
||||
const struct intel_dmc_wl_range *ranges;
|
||||
|
||||
if (display->params.enable_dmc_wl == ENABLE_DMC_WL_ANY_REGISTER)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Check that the offset is in one of the ranges for which
|
||||
* registers are powered off during DC states.
|
||||
|
|
@ -265,20 +282,48 @@ static bool intel_dmc_wl_check_range(i915_reg_t reg, u32 dc_state)
|
|||
|
||||
static bool __intel_dmc_wl_supported(struct intel_display *display)
|
||||
{
|
||||
return display->params.enable_dmc_wl && intel_dmc_has_payload(display);
|
||||
return display->params.enable_dmc_wl;
|
||||
}
|
||||
|
||||
static void intel_dmc_wl_sanitize_param(struct intel_display *display)
|
||||
{
|
||||
if (!HAS_DMC_WAKELOCK(display))
|
||||
display->params.enable_dmc_wl = 0;
|
||||
else if (display->params.enable_dmc_wl >= 0)
|
||||
display->params.enable_dmc_wl = !!display->params.enable_dmc_wl;
|
||||
else
|
||||
display->params.enable_dmc_wl = DISPLAY_VER(display) >= 30;
|
||||
const char *desc;
|
||||
|
||||
drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d\n",
|
||||
display->params.enable_dmc_wl);
|
||||
if (!HAS_DMC_WAKELOCK(display)) {
|
||||
display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED;
|
||||
} else if (display->params.enable_dmc_wl < 0) {
|
||||
if (DISPLAY_VER(display) >= 30)
|
||||
display->params.enable_dmc_wl = ENABLE_DMC_WL_ENABLED;
|
||||
else
|
||||
display->params.enable_dmc_wl = ENABLE_DMC_WL_DISABLED;
|
||||
} else if (display->params.enable_dmc_wl >= ENABLE_DMC_WL_MAX) {
|
||||
display->params.enable_dmc_wl = ENABLE_DMC_WL_ENABLED;
|
||||
}
|
||||
|
||||
drm_WARN_ON(display->drm,
|
||||
display->params.enable_dmc_wl < 0 ||
|
||||
display->params.enable_dmc_wl >= ENABLE_DMC_WL_MAX);
|
||||
|
||||
switch (display->params.enable_dmc_wl) {
|
||||
case ENABLE_DMC_WL_DISABLED:
|
||||
desc = "disabled";
|
||||
break;
|
||||
case ENABLE_DMC_WL_ENABLED:
|
||||
desc = "enabled";
|
||||
break;
|
||||
case ENABLE_DMC_WL_ANY_REGISTER:
|
||||
desc = "match any register";
|
||||
break;
|
||||
case ENABLE_DMC_WL_ALWAYS_LOCKED:
|
||||
desc = "always locked";
|
||||
break;
|
||||
default:
|
||||
desc = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
drm_dbg_kms(display->drm, "Sanitized enable_dmc_wl value: %d (%s)\n",
|
||||
display->params.enable_dmc_wl, desc);
|
||||
}
|
||||
|
||||
void intel_dmc_wl_init(struct intel_display *display)
|
||||
|
|
@ -292,7 +337,8 @@ void intel_dmc_wl_init(struct intel_display *display)
|
|||
|
||||
INIT_DELAYED_WORK(&wl->work, intel_dmc_wl_work);
|
||||
spin_lock_init(&wl->lock);
|
||||
refcount_set(&wl->refcount, 0);
|
||||
refcount_set(&wl->refcount,
|
||||
display->params.enable_dmc_wl == ENABLE_DMC_WL_ALWAYS_LOCKED ? 1 : 0);
|
||||
}
|
||||
|
||||
/* Must only be called as part of enabling dynamic DC states. */
|
||||
|
|
@ -398,7 +444,8 @@ void intel_dmc_wl_get(struct intel_display *display, i915_reg_t reg)
|
|||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state))
|
||||
if (i915_mmio_reg_valid(reg) &&
|
||||
!intel_dmc_wl_check_range(display, reg, wl->dc_state))
|
||||
goto out_unlock;
|
||||
|
||||
if (!wl->enabled) {
|
||||
|
|
@ -430,7 +477,8 @@ void intel_dmc_wl_put(struct intel_display *display, i915_reg_t reg)
|
|||
|
||||
spin_lock_irqsave(&wl->lock, flags);
|
||||
|
||||
if (i915_mmio_reg_valid(reg) && !intel_dmc_wl_check_range(reg, wl->dc_state))
|
||||
if (i915_mmio_reg_valid(reg) &&
|
||||
!intel_dmc_wl_check_range(display, reg, wl->dc_state))
|
||||
goto out_unlock;
|
||||
|
||||
if (WARN_RATELIMIT(!refcount_read(&wl->refcount),
|
||||
|
|
|
|||
|
|
@ -1075,7 +1075,7 @@ static bool source_can_output(struct intel_dp *intel_dp,
|
|||
/*
|
||||
* No YCbCr output support on gmch platforms.
|
||||
* Also, ILK doesn't seem capable of DP YCbCr output.
|
||||
* The displayed image is severly corrupted. SNB+ is fine.
|
||||
* The displayed image is severely corrupted. SNB+ is fine.
|
||||
*/
|
||||
return !HAS_GMCH(display) && !display->platform.ironlake;
|
||||
|
||||
|
|
@ -1396,7 +1396,6 @@ intel_dp_mode_valid(struct drm_connector *_connector,
|
|||
struct intel_display *display = to_intel_display(_connector->dev);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
|
||||
const struct drm_display_mode *fixed_mode;
|
||||
int target_clock = mode->clock;
|
||||
int max_rate, mode_rate, max_lanes, max_link_clock;
|
||||
|
|
@ -1407,7 +1406,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
|
|||
bool dsc = false;
|
||||
int num_joined_pipes;
|
||||
|
||||
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
|
||||
status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
|
|
@ -1496,7 +1495,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
|
|||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes);
|
||||
return intel_mode_valid_max_plane_size(display, mode, num_joined_pipes);
|
||||
}
|
||||
|
||||
bool intel_dp_source_supports_tps3(struct intel_display *display)
|
||||
|
|
@ -1926,7 +1925,7 @@ static bool intel_dp_dsc_supports_format(const struct intel_connector *connector
|
|||
return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format);
|
||||
}
|
||||
|
||||
static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_clock,
|
||||
static bool is_bw_sufficient_for_dsc_config(int dsc_bpp_x16, u32 link_clock,
|
||||
u32 lane_count, u32 mode_clock,
|
||||
enum intel_output_format output_format,
|
||||
int timeslots)
|
||||
|
|
@ -1934,15 +1933,16 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_cloc
|
|||
u32 available_bw, required_bw;
|
||||
|
||||
available_bw = (link_clock * lane_count * timeslots * 16) / 8;
|
||||
required_bw = compressed_bppx16 * (intel_dp_mode_to_fec_clock(mode_clock));
|
||||
required_bw = dsc_bpp_x16 * (intel_dp_mode_to_fec_clock(mode_clock));
|
||||
|
||||
return available_bw > required_bw;
|
||||
}
|
||||
|
||||
static int dsc_compute_link_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct link_config_limits *limits,
|
||||
u16 compressed_bppx16,
|
||||
struct drm_connector_state *conn_state,
|
||||
const struct link_config_limits *limits,
|
||||
int dsc_bpp_x16,
|
||||
int timeslots)
|
||||
{
|
||||
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
|
|
@ -1957,15 +1957,37 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
|
|||
for (lane_count = limits->min_lane_count;
|
||||
lane_count <= limits->max_lane_count;
|
||||
lane_count <<= 1) {
|
||||
if (!is_bw_sufficient_for_dsc_config(compressed_bppx16, link_rate,
|
||||
lane_count, adjusted_mode->clock,
|
||||
pipe_config->output_format,
|
||||
timeslots))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* FIXME: intel_dp_mtp_tu_compute_config() requires
|
||||
* ->lane_count and ->port_clock set before we know
|
||||
* they'll work. If we end up failing altogether,
|
||||
* they'll remain in crtc state. This shouldn't matter,
|
||||
* as we'd then bail out from compute config, but it's
|
||||
* just ugly.
|
||||
*/
|
||||
pipe_config->lane_count = lane_count;
|
||||
pipe_config->port_clock = link_rate;
|
||||
|
||||
if (drm_dp_is_uhbr_rate(link_rate)) {
|
||||
int ret;
|
||||
|
||||
ret = intel_dp_mtp_tu_compute_config(intel_dp,
|
||||
pipe_config,
|
||||
conn_state,
|
||||
dsc_bpp_x16,
|
||||
dsc_bpp_x16,
|
||||
0, true);
|
||||
if (ret)
|
||||
continue;
|
||||
} else {
|
||||
if (!is_bw_sufficient_for_dsc_config(dsc_bpp_x16, link_rate,
|
||||
lane_count, adjusted_mode->clock,
|
||||
pipe_config->output_format,
|
||||
timeslots))
|
||||
continue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2055,111 +2077,66 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp)
|
|||
}
|
||||
|
||||
/*
|
||||
* From a list of valid compressed bpps try different compressed bpp and find a
|
||||
* suitable link configuration that can support it.
|
||||
* Note: for pre-13 display you still need to check the validity of each step.
|
||||
*/
|
||||
static int
|
||||
icl_dsc_compute_link_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct link_config_limits *limits,
|
||||
int dsc_max_bpp,
|
||||
int dsc_min_bpp,
|
||||
int pipe_bpp,
|
||||
int timeslots)
|
||||
static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector)
|
||||
{
|
||||
int i, ret;
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
u8 incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
|
||||
|
||||
/* Compressed BPP should be less than the Input DSC bpp */
|
||||
dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
|
||||
if (DISPLAY_VER(display) < 14 || !incr)
|
||||
return fxp_q4_from_int(1);
|
||||
|
||||
for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) {
|
||||
if (valid_dsc_bpp[i] < dsc_min_bpp ||
|
||||
valid_dsc_bpp[i] > dsc_max_bpp)
|
||||
continue;
|
||||
/* fxp q4 */
|
||||
return fxp_q4_from_int(1) / incr;
|
||||
}
|
||||
|
||||
ret = dsc_compute_link_config(intel_dp,
|
||||
pipe_config,
|
||||
limits,
|
||||
valid_dsc_bpp[i] << 4,
|
||||
timeslots);
|
||||
if (ret == 0) {
|
||||
pipe_config->dsc.compressed_bpp_x16 =
|
||||
fxp_q4_from_int(valid_dsc_bpp[i]);
|
||||
return 0;
|
||||
}
|
||||
/* Note: This is not universally usable! */
|
||||
static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int i;
|
||||
|
||||
if (DISPLAY_VER(display) >= 13) {
|
||||
if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
if (fxp_q4_to_frac(bpp_x16))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) {
|
||||
if (fxp_q4_to_int(bpp_x16) == valid_dsc_bpp[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* From XE_LPD onwards we supports compression bpps in steps of 1 up to
|
||||
* uncompressed bpp-1. So we start from max compressed bpp and see if any
|
||||
* link configuration is able to support that compressed bpp, if not we
|
||||
* step down and check for lower compressed bpp.
|
||||
* Find the max compressed BPP we can find a link configuration for. The BPPs to
|
||||
* try depend on the source (platform) and sink.
|
||||
*/
|
||||
static int
|
||||
xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
|
||||
const struct intel_connector *connector,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct link_config_limits *limits,
|
||||
int dsc_max_bpp,
|
||||
int dsc_min_bpp,
|
||||
int pipe_bpp,
|
||||
int timeslots)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
|
||||
u16 compressed_bppx16;
|
||||
u8 bppx16_step;
|
||||
int ret;
|
||||
|
||||
if (DISPLAY_VER(display) < 14 || bppx16_incr <= 1)
|
||||
bppx16_step = 16;
|
||||
else
|
||||
bppx16_step = 16 / bppx16_incr;
|
||||
|
||||
/* Compressed BPP should be less than the Input DSC bpp */
|
||||
dsc_max_bpp = min(dsc_max_bpp << 4, (pipe_bpp << 4) - bppx16_step);
|
||||
dsc_min_bpp = dsc_min_bpp << 4;
|
||||
|
||||
for (compressed_bppx16 = dsc_max_bpp;
|
||||
compressed_bppx16 >= dsc_min_bpp;
|
||||
compressed_bppx16 -= bppx16_step) {
|
||||
if (intel_dp->force_dsc_fractional_bpp_en &&
|
||||
!fxp_q4_to_frac(compressed_bppx16))
|
||||
continue;
|
||||
ret = dsc_compute_link_config(intel_dp,
|
||||
pipe_config,
|
||||
limits,
|
||||
compressed_bppx16,
|
||||
timeslots);
|
||||
if (ret == 0) {
|
||||
pipe_config->dsc.compressed_bpp_x16 = compressed_bppx16;
|
||||
if (intel_dp->force_dsc_fractional_bpp_en &&
|
||||
fxp_q4_to_frac(compressed_bppx16))
|
||||
drm_dbg_kms(display->drm,
|
||||
"Forcing DSC fractional bpp\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
|
||||
const struct intel_connector *connector,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct link_config_limits *limits,
|
||||
struct drm_connector_state *conn_state,
|
||||
const struct link_config_limits *limits,
|
||||
int pipe_bpp,
|
||||
int timeslots)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
const struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
||||
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
|
||||
int output_bpp;
|
||||
int dsc_min_bpp;
|
||||
int dsc_max_bpp;
|
||||
int min_bpp_x16, max_bpp_x16, bpp_step_x16;
|
||||
int dsc_joiner_max_bpp;
|
||||
int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config);
|
||||
int bpp_x16;
|
||||
int ret;
|
||||
|
||||
dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16);
|
||||
|
||||
|
|
@ -2168,11 +2145,38 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
|
|||
num_joined_pipes);
|
||||
dsc_max_bpp = min(dsc_joiner_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16));
|
||||
|
||||
if (DISPLAY_VER(display) >= 13)
|
||||
return xelpd_dsc_compute_link_config(intel_dp, connector, pipe_config, limits,
|
||||
dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
|
||||
return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
|
||||
dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
|
||||
/* FIXME: remove the round trip via integers */
|
||||
min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp);
|
||||
max_bpp_x16 = fxp_q4_from_int(dsc_max_bpp);
|
||||
|
||||
bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector);
|
||||
|
||||
/* Compressed BPP should be less than the Input DSC bpp */
|
||||
output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
|
||||
max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16);
|
||||
|
||||
for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) {
|
||||
if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16))
|
||||
continue;
|
||||
|
||||
ret = dsc_compute_link_config(intel_dp,
|
||||
pipe_config,
|
||||
conn_state,
|
||||
limits,
|
||||
bpp_x16,
|
||||
timeslots);
|
||||
if (ret == 0) {
|
||||
pipe_config->dsc.compressed_bpp_x16 = bpp_x16;
|
||||
if (intel_dp->force_dsc_fractional_bpp_en &&
|
||||
fxp_q4_to_frac(bpp_x16))
|
||||
drm_dbg_kms(display->drm,
|
||||
"Forcing DSC fractional bpp\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int intel_dp_dsc_min_src_input_bpc(void)
|
||||
|
|
@ -2182,7 +2186,7 @@ int intel_dp_dsc_min_src_input_bpc(void)
|
|||
}
|
||||
|
||||
static
|
||||
bool is_dsc_pipe_bpp_sufficient(struct link_config_limits *limits,
|
||||
bool is_dsc_pipe_bpp_sufficient(const struct link_config_limits *limits,
|
||||
int pipe_bpp)
|
||||
{
|
||||
return pipe_bpp >= limits->pipe.min_bpp &&
|
||||
|
|
@ -2191,7 +2195,7 @@ bool is_dsc_pipe_bpp_sufficient(struct link_config_limits *limits,
|
|||
|
||||
static
|
||||
int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
|
||||
struct link_config_limits *limits)
|
||||
const struct link_config_limits *limits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
int forced_bpp;
|
||||
|
|
@ -2217,13 +2221,11 @@ int intel_dp_force_dsc_pipe_bpp(struct intel_dp *intel_dp,
|
|||
static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits,
|
||||
const struct link_config_limits *limits,
|
||||
int timeslots)
|
||||
{
|
||||
const struct intel_connector *connector =
|
||||
to_intel_connector(conn_state->connector);
|
||||
int dsc_max_bpp;
|
||||
int dsc_min_bpp;
|
||||
u8 dsc_bpc[3] = {};
|
||||
int forced_bpp, pipe_bpp;
|
||||
int num_bpc, i, ret;
|
||||
|
|
@ -2231,7 +2233,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
|||
forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, limits);
|
||||
|
||||
if (forced_bpp) {
|
||||
ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config,
|
||||
ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state,
|
||||
limits, forced_bpp, timeslots);
|
||||
if (ret == 0) {
|
||||
pipe_config->pipe_bpp = forced_bpp;
|
||||
|
|
@ -2239,9 +2241,6 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
|||
}
|
||||
}
|
||||
|
||||
dsc_max_bpp = limits->pipe.max_bpp;
|
||||
dsc_min_bpp = limits->pipe.min_bpp;
|
||||
|
||||
/*
|
||||
* Get the maximum DSC bpc that will be supported by any valid
|
||||
* link configuration and compressed bpp.
|
||||
|
|
@ -2249,11 +2248,10 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
|||
num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc);
|
||||
for (i = 0; i < num_bpc; i++) {
|
||||
pipe_bpp = dsc_bpc[i] * 3;
|
||||
if (pipe_bpp < dsc_min_bpp)
|
||||
break;
|
||||
if (pipe_bpp > dsc_max_bpp)
|
||||
if (pipe_bpp < limits->pipe.min_bpp || pipe_bpp > limits->pipe.max_bpp)
|
||||
continue;
|
||||
ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config,
|
||||
|
||||
ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state,
|
||||
limits, pipe_bpp, timeslots);
|
||||
if (ret == 0) {
|
||||
pipe_config->pipe_bpp = pipe_bpp;
|
||||
|
|
@ -2267,7 +2265,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
|||
static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits)
|
||||
const struct link_config_limits *limits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_connector *connector =
|
||||
|
|
@ -2332,9 +2330,8 @@ static void intel_dp_fec_compute_config(struct intel_dp *intel_dp,
|
|||
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits,
|
||||
int timeslots,
|
||||
bool compute_pipe_bpp)
|
||||
const struct link_config_limits *limits,
|
||||
int timeslots)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
const struct intel_connector *connector =
|
||||
|
|
@ -2342,6 +2339,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
|||
const struct drm_display_mode *adjusted_mode =
|
||||
&pipe_config->hw.adjusted_mode;
|
||||
int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config);
|
||||
bool is_mst = intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST);
|
||||
int ret;
|
||||
|
||||
intel_dp_fec_compute_config(intel_dp, pipe_config);
|
||||
|
|
@ -2350,12 +2348,10 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
|||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* compute pipe bpp is set to false for DP MST DSC case
|
||||
* and compressed_bpp is calculated same time once
|
||||
* vpci timeslots are allocated, because overall bpp
|
||||
* calculation procedure is bit different for MST case.
|
||||
* Link parameters, pipe bpp and compressed bpp have already been
|
||||
* figured out for DP MST DSC.
|
||||
*/
|
||||
if (compute_pipe_bpp) {
|
||||
if (!is_mst) {
|
||||
if (intel_dp_is_edp(intel_dp))
|
||||
ret = intel_edp_dsc_compute_pipe_bpp(intel_dp, pipe_config,
|
||||
conn_state, limits);
|
||||
|
|
@ -2518,9 +2514,6 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
|
|||
limits->min_rate = intel_dp_min_link_rate(intel_dp);
|
||||
limits->max_rate = intel_dp_max_link_rate(intel_dp);
|
||||
|
||||
/* FIXME 128b/132b SST+DSC support missing */
|
||||
if (!is_mst && dsc)
|
||||
limits->max_rate = min(limits->max_rate, 810000);
|
||||
limits->min_rate = min(limits->min_rate, limits->max_rate);
|
||||
|
||||
limits->min_lane_count = intel_dp_min_lane_count(intel_dp);
|
||||
|
|
@ -2640,9 +2633,9 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
|
|||
if (!ret && intel_dp_is_uhbr(pipe_config))
|
||||
ret = intel_dp_mtp_tu_compute_config(intel_dp,
|
||||
pipe_config,
|
||||
pipe_config->pipe_bpp,
|
||||
pipe_config->pipe_bpp,
|
||||
conn_state,
|
||||
fxp_q4_from_int(pipe_config->pipe_bpp),
|
||||
fxp_q4_from_int(pipe_config->pipe_bpp),
|
||||
0, false);
|
||||
if (ret)
|
||||
dsc_needed = true;
|
||||
|
|
@ -2666,7 +2659,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
|
|||
return -EINVAL;
|
||||
|
||||
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
|
||||
conn_state, &limits, 64, true);
|
||||
conn_state, &limits, 64);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -2831,15 +2824,14 @@ static void intel_dp_compute_as_sdp(struct intel_dp *intel_dp,
|
|||
as_sdp->sdp_type = DP_SDP_ADAPTIVE_SYNC;
|
||||
as_sdp->length = 0x9;
|
||||
as_sdp->duration_incr_ms = 0;
|
||||
as_sdp->vtotal = intel_vrr_vmin_vtotal(crtc_state);
|
||||
|
||||
if (crtc_state->cmrr.enable) {
|
||||
as_sdp->mode = DP_AS_SDP_FAVT_TRR_REACHED;
|
||||
as_sdp->vtotal = adjusted_mode->vtotal;
|
||||
as_sdp->target_rr = drm_mode_vrefresh(adjusted_mode);
|
||||
as_sdp->target_rr_divider = true;
|
||||
} else {
|
||||
as_sdp->mode = DP_AS_SDP_AVT_DYNAMIC_VTOTAL;
|
||||
as_sdp->vtotal = adjusted_mode->vtotal;
|
||||
as_sdp->target_rr = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -3064,15 +3056,6 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
|
|||
intel_dp_is_uhbr(pipe_config);
|
||||
}
|
||||
|
||||
static void intel_dp_queue_modeset_retry_work(struct intel_connector *connector)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
|
||||
drm_connector_get(&connector->base);
|
||||
if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work))
|
||||
drm_connector_put(&connector->base);
|
||||
}
|
||||
|
||||
void
|
||||
intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
|
|
@ -3089,7 +3072,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
|
|||
intel_dp->needs_modeset_retry = true;
|
||||
|
||||
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
|
||||
intel_dp_queue_modeset_retry_work(intel_dp->attached_connector);
|
||||
intel_connector_queue_modeset_retry_work(intel_dp->attached_connector);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -3099,7 +3082,7 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state,
|
|||
continue;
|
||||
|
||||
if (connector->mst_port == intel_dp)
|
||||
intel_dp_queue_modeset_retry_work(connector);
|
||||
intel_connector_queue_modeset_retry_work(connector);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3526,9 +3509,9 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
|
|||
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, mode);
|
||||
} else {
|
||||
struct intel_lspcon *lspcon = dp_to_lspcon(intel_dp);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
|
||||
lspcon_resume(dp_to_dig_port(intel_dp));
|
||||
intel_lspcon_resume(dig_port);
|
||||
|
||||
/* Write the source OUI as early as possible */
|
||||
intel_dp_init_source_oui(intel_dp);
|
||||
|
|
@ -3544,8 +3527,8 @@ void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode)
|
|||
msleep(1);
|
||||
}
|
||||
|
||||
if (ret == 1 && lspcon->active)
|
||||
lspcon_wait_pcon_mode(lspcon);
|
||||
if (ret == 1 && intel_lspcon_active(dig_port))
|
||||
intel_lspcon_wait_pcon_mode(dig_port);
|
||||
}
|
||||
|
||||
if (ret != 1)
|
||||
|
|
@ -5395,7 +5378,7 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
|
|||
if (drm_WARN_ON(display->drm, intel_dp_is_edp(intel_dp)))
|
||||
return connector_status_connected;
|
||||
|
||||
lspcon_resume(dig_port);
|
||||
intel_lspcon_resume(dig_port);
|
||||
|
||||
if (!intel_dp_get_dpcd(intel_dp))
|
||||
return connector_status_disconnected;
|
||||
|
|
@ -5477,13 +5460,13 @@ void intel_digital_port_unlock(struct intel_encoder *encoder)
|
|||
*/
|
||||
bool intel_digital_port_connected_locked(struct intel_encoder *encoder)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
|
||||
bool is_glitch_free = intel_tc_port_handles_hpd_glitches(dig_port);
|
||||
bool is_connected = false;
|
||||
intel_wakeref_t wakeref;
|
||||
|
||||
with_intel_display_power(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref) {
|
||||
with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) {
|
||||
unsigned long wait_expires = jiffies + msecs_to_jiffies_timeout(4);
|
||||
|
||||
do {
|
||||
|
|
@ -5595,7 +5578,7 @@ intel_dp_update_420(struct intel_dp *intel_dp)
|
|||
intel_dp->downstream_ports);
|
||||
/* on-board LSPCON always assumed to support 4:4:4->4:2:0 conversion */
|
||||
intel_dp->dfp.ycbcr_444_to_420 =
|
||||
dp_to_dig_port(intel_dp)->lspcon.active ||
|
||||
intel_lspcon_active(dp_to_dig_port(intel_dp)) ||
|
||||
drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd,
|
||||
intel_dp->downstream_ports);
|
||||
intel_dp->dfp.rgb_to_ycbcr =
|
||||
|
|
@ -5869,7 +5852,6 @@ intel_dp_connector_register(struct drm_connector *connector)
|
|||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct intel_lspcon *lspcon = &dig_port->lspcon;
|
||||
int ret;
|
||||
|
||||
ret = intel_connector_register(connector);
|
||||
|
|
@ -5891,9 +5873,8 @@ intel_dp_connector_register(struct drm_connector *connector)
|
|||
* ToDo: Clean this up to handle lspcon init and resume more
|
||||
* efficiently and streamlined.
|
||||
*/
|
||||
if (lspcon_init(dig_port)) {
|
||||
lspcon_detect_hdr_capability(lspcon);
|
||||
if (lspcon->hdr_supported)
|
||||
if (intel_lspcon_init(dig_port)) {
|
||||
if (intel_lspcon_detect_hdr_capability(dig_port))
|
||||
drm_connector_attach_hdr_output_metadata_property(connector);
|
||||
}
|
||||
|
||||
|
|
@ -6495,35 +6476,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void intel_dp_modeset_retry_work_fn(struct work_struct *work)
|
||||
{
|
||||
struct intel_connector *connector = container_of(work, typeof(*connector),
|
||||
modeset_retry_work);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
|
||||
drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.base.id,
|
||||
connector->base.name);
|
||||
|
||||
/* Grab the locks before changing connector property*/
|
||||
mutex_lock(&display->drm->mode_config.mutex);
|
||||
/* Set connector link status to BAD and send a Uevent to notify
|
||||
* userspace to do a modeset.
|
||||
*/
|
||||
drm_connector_set_link_status_property(&connector->base,
|
||||
DRM_MODE_LINK_STATUS_BAD);
|
||||
mutex_unlock(&display->drm->mode_config.mutex);
|
||||
/* Send Hotplug uevent so userspace can reprobe */
|
||||
drm_kms_helper_connector_hotplug_event(&connector->base);
|
||||
|
||||
drm_connector_put(&connector->base);
|
||||
}
|
||||
|
||||
void intel_dp_init_modeset_retry_work(struct intel_connector *connector)
|
||||
{
|
||||
INIT_WORK(&connector->modeset_retry_work,
|
||||
intel_dp_modeset_retry_work_fn);
|
||||
}
|
||||
|
||||
bool
|
||||
intel_dp_init_connector(struct intel_digital_port *dig_port,
|
||||
struct intel_connector *connector)
|
||||
|
|
@ -6532,13 +6484,9 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
|
|||
struct intel_dp *intel_dp = &dig_port->dp;
|
||||
struct intel_encoder *encoder = &dig_port->base;
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
enum port port = encoder->port;
|
||||
int type;
|
||||
|
||||
/* Initialize the work for modeset in case of link train failure */
|
||||
intel_dp_init_modeset_retry_work(connector);
|
||||
|
||||
if (drm_WARN(dev, dig_port->max_lanes < 1,
|
||||
"Not enough lanes (%d) for DP on [ENCODER:%d:%s]\n",
|
||||
dig_port->max_lanes, encoder->base.base.id,
|
||||
|
|
@ -6632,7 +6580,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
|
|||
return true;
|
||||
|
||||
fail:
|
||||
intel_display_power_flush_work(dev_priv);
|
||||
intel_display_power_flush_work(display);
|
||||
drm_connector_cleanup(&connector->base);
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -75,9 +75,8 @@ int intel_dp_compute_config(struct intel_encoder *encoder,
|
|||
int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits,
|
||||
int timeslots,
|
||||
bool recompute_pipe_bpp);
|
||||
const struct link_config_limits *limits,
|
||||
int timeslots);
|
||||
void intel_dp_audio_compute_config(struct intel_encoder *encoder,
|
||||
struct intel_crtc_state *pipe_config,
|
||||
struct drm_connector_state *conn_state);
|
||||
|
|
|
|||
|
|
@ -243,7 +243,6 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
|
|||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct intel_encoder *encoder = &dig_port->base;
|
||||
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
|
||||
i915_reg_t ch_ctl, ch_data[5];
|
||||
u32 aux_clock_divider;
|
||||
enum intel_display_power_domain aux_domain;
|
||||
|
|
@ -272,7 +271,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
|
|||
|
||||
aux_domain = intel_aux_power_domain(dig_port);
|
||||
|
||||
aux_wakeref = intel_display_power_get(i915, aux_domain);
|
||||
aux_wakeref = intel_display_power_get(display, aux_domain);
|
||||
pps_wakeref = intel_pps_lock(intel_dp);
|
||||
|
||||
/*
|
||||
|
|
@ -432,7 +431,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp,
|
|||
intel_pps_vdd_off_unlocked(intel_dp, false);
|
||||
|
||||
intel_pps_unlock(intel_dp, pps_wakeref);
|
||||
intel_display_power_put_async(i915, aux_domain, aux_wakeref);
|
||||
intel_display_power_put_async(display, aux_domain, aux_wakeref);
|
||||
out_unlock:
|
||||
intel_digital_port_unlock(encoder);
|
||||
|
||||
|
|
|
|||
|
|
@ -451,9 +451,54 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
|
|||
/* VESA backlight callbacks */
|
||||
static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, enum pipe unused)
|
||||
{
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
u8 buf[3];
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
|
||||
if (panel->backlight.edp.vesa.luminance_control_support) {
|
||||
ret = drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, buf,
|
||||
sizeof(buf));
|
||||
if (ret < 0) {
|
||||
drm_err(intel_dp->aux.drm_dev,
|
||||
"[CONNECTOR:%d:%s] Failed to read Luminance from DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
val |= buf[0] | buf[1] << 8 | buf[2] << 16;
|
||||
return val / 1000;
|
||||
}
|
||||
|
||||
return connector->panel.backlight.level;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_dp_aux_vesa_set_luminance(struct intel_connector *connector, u32 level)
|
||||
{
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
u8 buf[3];
|
||||
int ret;
|
||||
|
||||
level = level * 1000;
|
||||
level &= 0xffffff;
|
||||
buf[0] = (level & 0x0000ff);
|
||||
buf[1] = (level & 0x00ff00) >> 8;
|
||||
buf[2] = (level & 0xff0000) >> 16;
|
||||
|
||||
ret = drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
|
||||
buf, sizeof(buf));
|
||||
if (ret != sizeof(buf)) {
|
||||
drm_err(intel_dp->aux.drm_dev,
|
||||
"%s: Failed to set VESA Aux Luminance: %d\n",
|
||||
intel_dp->aux.name, ret);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level)
|
||||
{
|
||||
|
|
@ -461,6 +506,11 @@ intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u3
|
|||
struct intel_panel *panel = &connector->panel;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
|
||||
if (panel->backlight.edp.vesa.luminance_control_support) {
|
||||
if (!intel_dp_aux_vesa_set_luminance(connector, level))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!panel->backlight.edp.vesa.info.aux_set) {
|
||||
const u32 pwm_level = intel_backlight_level_to_pwm(connector, level);
|
||||
|
||||
|
|
@ -477,6 +527,18 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
|
|||
struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
int ret;
|
||||
|
||||
if (panel->backlight.edp.vesa.luminance_control_support) {
|
||||
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
|
||||
DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE);
|
||||
|
||||
if (ret == 1)
|
||||
return;
|
||||
|
||||
if (!intel_dp_aux_vesa_set_luminance(connector, level))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!panel->backlight.edp.vesa.info.aux_enable) {
|
||||
u32 pwm_level;
|
||||
|
|
@ -500,6 +562,9 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state
|
|||
struct intel_panel *panel = &connector->panel;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
|
||||
|
||||
if (panel->backlight.edp.vesa.luminance_control_support)
|
||||
return;
|
||||
|
||||
drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
|
||||
|
||||
if (!panel->backlight.edp.vesa.info.aux_enable)
|
||||
|
|
@ -510,56 +575,75 @@ static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state
|
|||
static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct drm_luminance_range_info *luminance_range =
|
||||
&connector->base.display_info.luminance_range;
|
||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
u16 current_level;
|
||||
u8 current_mode;
|
||||
int ret;
|
||||
|
||||
ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
|
||||
panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
|
||||
¤t_level, ¤t_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable));
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set));
|
||||
|
||||
if (!panel->backlight.edp.vesa.info.aux_set || !panel->backlight.edp.vesa.info.aux_enable) {
|
||||
ret = panel->backlight.pwm_funcs->setup(connector, pipe);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n",
|
||||
connector->base.base.id, connector->base.name, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (panel->backlight.edp.vesa.info.aux_set) {
|
||||
panel->backlight.max = panel->backlight.edp.vesa.info.max;
|
||||
panel->backlight.min = 0;
|
||||
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
|
||||
panel->backlight.level = current_level;
|
||||
panel->backlight.enabled = panel->backlight.level != 0;
|
||||
if (panel->backlight.edp.vesa.luminance_control_support) {
|
||||
if (luminance_range->max_luminance) {
|
||||
panel->backlight.max = luminance_range->max_luminance;
|
||||
panel->backlight.min = luminance_range->min_luminance;
|
||||
} else {
|
||||
panel->backlight.level = panel->backlight.max;
|
||||
panel->backlight.enabled = false;
|
||||
panel->backlight.max = 512;
|
||||
panel->backlight.min = 0;
|
||||
}
|
||||
panel->backlight.level = intel_dp_aux_vesa_get_backlight(connector, 0);
|
||||
panel->backlight.enabled = panel->backlight.level != 0;
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX VESA Nits backlight level is controlled through DPCD\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
} else {
|
||||
panel->backlight.max = panel->backlight.pwm_level_max;
|
||||
panel->backlight.min = panel->backlight.pwm_level_min;
|
||||
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) {
|
||||
panel->backlight.level = panel->backlight.pwm_funcs->get(connector, pipe);
|
||||
panel->backlight.enabled = panel->backlight.pwm_enabled;
|
||||
ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
|
||||
panel->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
|
||||
¤t_level, ¤t_mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX VESA backlight enable is controlled through %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_enable));
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX VESA backlight level is controlled through %s\n",
|
||||
connector->base.base.id, connector->base.name,
|
||||
dpcd_vs_pwm_str(panel->backlight.edp.vesa.info.aux_set));
|
||||
|
||||
if (!panel->backlight.edp.vesa.info.aux_set ||
|
||||
!panel->backlight.edp.vesa.info.aux_enable) {
|
||||
ret = panel->backlight.pwm_funcs->setup(connector, pipe);
|
||||
if (ret < 0) {
|
||||
drm_err(display->drm,
|
||||
"[CONNECTOR:%d:%s] Failed to setup PWM backlight controls for eDP backlight: %d\n",
|
||||
connector->base.base.id, connector->base.name, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (panel->backlight.edp.vesa.info.aux_set) {
|
||||
panel->backlight.max = panel->backlight.edp.vesa.info.max;
|
||||
panel->backlight.min = 0;
|
||||
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
|
||||
panel->backlight.level = current_level;
|
||||
panel->backlight.enabled = panel->backlight.level != 0;
|
||||
} else {
|
||||
panel->backlight.level = panel->backlight.max;
|
||||
panel->backlight.enabled = false;
|
||||
}
|
||||
} else {
|
||||
panel->backlight.level = panel->backlight.max;
|
||||
panel->backlight.enabled = false;
|
||||
panel->backlight.max = panel->backlight.pwm_level_max;
|
||||
panel->backlight.min = panel->backlight.pwm_level_min;
|
||||
if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_PWM) {
|
||||
panel->backlight.level =
|
||||
panel->backlight.pwm_funcs->get(connector, pipe);
|
||||
panel->backlight.enabled = panel->backlight.pwm_enabled;
|
||||
} else {
|
||||
panel->backlight.level = panel->backlight.max;
|
||||
panel->backlight.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -575,6 +659,15 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
|
||||
if ((intel_dp->edp_dpcd[3] & DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"[CONNECTOR:%d:%s] AUX Luminance Based Backlight Control Supported!\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
panel->backlight.edp.vesa.luminance_control_support = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
|
|
@ -604,6 +697,7 @@ static const struct intel_panel_bl_funcs intel_dp_vesa_bl_funcs = {
|
|||
int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
struct drm_device *dev = connector->base.dev;
|
||||
struct intel_panel *panel = &connector->panel;
|
||||
bool try_intel_interface = false, try_vesa_interface = false;
|
||||
|
|
@ -640,6 +734,10 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
break;
|
||||
}
|
||||
|
||||
/* For eDP 1.5 and above we are supposed to use VESA interface for brightness control */
|
||||
if (intel_dp->edp_dpcd[0] >= DP_EDP_15)
|
||||
try_vesa_interface = true;
|
||||
|
||||
/*
|
||||
* Since Intel has their own backlight control interface, the majority of machines out there
|
||||
* using DPCD backlight controls with Intel GPUs will be using this interface as opposed to
|
||||
|
|
@ -653,7 +751,8 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
|
|||
* backlight interface at all. This means that the only sensible way for us to detect both
|
||||
* interfaces is to probe for Intel's first, and VESA's second.
|
||||
*/
|
||||
if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector)) {
|
||||
if (try_intel_interface && intel_dp_aux_supports_hdr_backlight(connector) &&
|
||||
intel_dp->edp_dpcd[0] <= DP_EDP_14b) {
|
||||
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Using Intel proprietary eDP backlight controls\n",
|
||||
connector->base.base.id, connector->base.name);
|
||||
panel->backlight.funcs = &intel_dp_hdr_bl_funcs;
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@ intel_dp_prepare_link_train(struct intel_dp *intel_dp,
|
|||
/*
|
||||
* WaEdpLinkRateDataReload
|
||||
*
|
||||
* Parade PS8461E MUX (used on varius TGL+ laptops) needs
|
||||
* Parade PS8461E MUX (used on various TGL+ laptops) needs
|
||||
* to snoop the link rates reported by the sink when we
|
||||
* use LINK_RATE_SET in order to operate in jitter cleaning
|
||||
* mode (as opposed to redriver mode). Unfortunately it
|
||||
|
|
@ -1642,7 +1642,7 @@ void intel_dp_start_link_train(struct intel_atomic_state *state,
|
|||
/*
|
||||
* Ignore the link failure in CI
|
||||
*
|
||||
* In fixed enviroments like CI, sometimes unexpected long HPDs are
|
||||
* In fixed environments like CI, sometimes unexpected long HPDs are
|
||||
* generated by the displays. If ignore_long_hpd flag is set, such long
|
||||
* HPDs are ignored. And probably as a consequence of these ignored
|
||||
* long HPDs, subsequent link trainings are failed resulting into CI
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state,
|
|||
&crtc_state->hw.adjusted_mode;
|
||||
|
||||
if (!intel_dp_is_uhbr(crtc_state) || DISPLAY_VER(display) >= 20 || !dsc)
|
||||
return INT_MAX;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* DSC->DPT interface width:
|
||||
|
|
@ -209,22 +209,56 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec
|
|||
num_joined_pipes);
|
||||
}
|
||||
|
||||
static void intel_dp_mst_compute_min_hblank(struct intel_crtc_state *crtc_state,
|
||||
int bpp_x16)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8;
|
||||
int hblank;
|
||||
|
||||
if (DISPLAY_VER(display) < 20)
|
||||
return;
|
||||
|
||||
/* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */
|
||||
hblank = DIV_ROUND_UP((DIV_ROUND_UP
|
||||
(adjusted_mode->htotal - adjusted_mode->hdisplay, 4) * bpp_x16),
|
||||
symbol_size);
|
||||
|
||||
crtc_state->min_hblank = hblank;
|
||||
}
|
||||
|
||||
int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
int max_bpp, int min_bpp,
|
||||
struct drm_connector_state *conn_state,
|
||||
int step, bool dsc)
|
||||
int min_bpp_x16, int max_bpp_x16, int bpp_step_x16, bool dsc)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct drm_atomic_state *state = crtc_state->uapi.state;
|
||||
struct drm_dp_mst_topology_state *mst_state = NULL;
|
||||
struct intel_connector *connector =
|
||||
to_intel_connector(conn_state->connector);
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->hw.adjusted_mode;
|
||||
fixed20_12 pbn_div;
|
||||
int bpp, slots = -EINVAL;
|
||||
bool is_mst = intel_dp->is_mst;
|
||||
int bpp_x16, slots = -EINVAL;
|
||||
int dsc_slice_count = 0;
|
||||
int max_dpt_bpp;
|
||||
int max_dpt_bpp_x16;
|
||||
|
||||
/* shouldn't happen, sanity check */
|
||||
drm_WARN_ON(display->drm, !dsc && (fxp_q4_to_frac(min_bpp_x16) ||
|
||||
fxp_q4_to_frac(max_bpp_x16) ||
|
||||
fxp_q4_to_frac(bpp_step_x16)));
|
||||
|
||||
if (is_mst) {
|
||||
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
|
||||
if (IS_ERR(mst_state))
|
||||
return PTR_ERR(mst_state);
|
||||
|
||||
mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock,
|
||||
crtc_state->lane_count);
|
||||
}
|
||||
|
||||
if (dsc) {
|
||||
if (!intel_dp_supports_fec(intel_dp, connector, crtc_state))
|
||||
|
|
@ -233,18 +267,15 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state);
|
||||
}
|
||||
|
||||
pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock,
|
||||
crtc_state->lane_count);
|
||||
|
||||
max_dpt_bpp = intel_dp_mst_max_dpt_bpp(crtc_state, dsc);
|
||||
if (max_bpp > max_dpt_bpp) {
|
||||
drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (%d -> %d)\n",
|
||||
max_bpp, max_dpt_bpp);
|
||||
max_bpp = max_dpt_bpp;
|
||||
max_dpt_bpp_x16 = fxp_q4_from_int(intel_dp_mst_max_dpt_bpp(crtc_state, dsc));
|
||||
if (max_dpt_bpp_x16 && max_bpp_x16 > max_dpt_bpp_x16) {
|
||||
drm_dbg_kms(display->drm, "Limiting bpp to max DPT bpp (" FXP_Q4_FMT " -> " FXP_Q4_FMT ")\n",
|
||||
FXP_Q4_ARGS(max_bpp_x16), FXP_Q4_ARGS(max_dpt_bpp_x16));
|
||||
max_bpp_x16 = max_dpt_bpp_x16;
|
||||
}
|
||||
|
||||
drm_dbg_kms(display->drm, "Looking for slots in range min bpp %d max bpp %d\n",
|
||||
min_bpp, max_bpp);
|
||||
drm_dbg_kms(display->drm, "Looking for slots in range min bpp " FXP_Q4_FMT " max bpp " FXP_Q4_FMT "\n",
|
||||
FXP_Q4_ARGS(min_bpp_x16), FXP_Q4_ARGS(max_bpp_x16));
|
||||
|
||||
if (dsc) {
|
||||
dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state);
|
||||
|
|
@ -255,23 +286,27 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
}
|
||||
}
|
||||
|
||||
for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
|
||||
for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) {
|
||||
int local_bw_overhead;
|
||||
int link_bpp_x16;
|
||||
|
||||
drm_dbg_kms(display->drm, "Trying bpp %d\n", bpp);
|
||||
drm_dbg_kms(display->drm, "Trying bpp " FXP_Q4_FMT "\n", FXP_Q4_ARGS(bpp_x16));
|
||||
|
||||
link_bpp_x16 = fxp_q4_from_int(dsc ? bpp :
|
||||
intel_dp_output_bpp(crtc_state->output_format, bpp));
|
||||
link_bpp_x16 = dsc ? bpp_x16 :
|
||||
fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format,
|
||||
fxp_q4_to_int(bpp_x16)));
|
||||
|
||||
local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state,
|
||||
false, dsc_slice_count, link_bpp_x16);
|
||||
|
||||
intel_dp_mst_compute_min_hblank(crtc_state, link_bpp_x16);
|
||||
|
||||
intel_dp_mst_compute_m_n(crtc_state,
|
||||
local_bw_overhead,
|
||||
link_bpp_x16,
|
||||
&crtc_state->dp_m_n);
|
||||
|
||||
if (intel_dp->is_mst) {
|
||||
if (is_mst) {
|
||||
int remote_bw_overhead;
|
||||
int remote_tu;
|
||||
fixed20_12 pbn;
|
||||
|
|
@ -296,7 +331,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
pbn.full = dfixed_const(intel_dp_mst_calc_pbn(adjusted_mode->crtc_clock,
|
||||
link_bpp_x16,
|
||||
remote_bw_overhead));
|
||||
remote_tu = DIV_ROUND_UP(pbn.full, pbn_div.full);
|
||||
remote_tu = DIV_ROUND_UP(pbn.full, mst_state->pbn_div.full);
|
||||
|
||||
/*
|
||||
* Aligning the TUs ensures that symbols consisting of multiple
|
||||
|
|
@ -314,7 +349,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
* allocated for the whole path and the TUs allocated for the
|
||||
* first branch device's link also applies here.
|
||||
*/
|
||||
pbn.full = remote_tu * pbn_div.full;
|
||||
pbn.full = remote_tu * mst_state->pbn_div.full;
|
||||
|
||||
drm_WARN_ON(display->drm, remote_tu < crtc_state->dp_m_n.tu);
|
||||
crtc_state->dp_m_n.tu = remote_tu;
|
||||
|
|
@ -343,7 +378,7 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
}
|
||||
|
||||
/* Allow using zero step to indicate one try */
|
||||
if (!step)
|
||||
if (!bpp_step_x16)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -354,65 +389,42 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
|||
}
|
||||
|
||||
if (!dsc)
|
||||
crtc_state->pipe_bpp = bpp;
|
||||
crtc_state->pipe_bpp = fxp_q4_to_int(bpp_x16);
|
||||
else
|
||||
crtc_state->dsc.compressed_bpp_x16 = fxp_q4_from_int(bpp);
|
||||
crtc_state->dsc.compressed_bpp_x16 = bpp_x16;
|
||||
|
||||
drm_dbg_kms(display->drm, "Got %d slots for pipe bpp %d dsc %d\n",
|
||||
slots, bpp, dsc);
|
||||
drm_dbg_kms(display->drm, "Got %d slots for pipe bpp " FXP_Q4_FMT " dsc %d\n",
|
||||
slots, FXP_Q4_ARGS(bpp_x16), dsc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
int max_bpp, int min_bpp,
|
||||
struct link_config_limits *limits,
|
||||
struct drm_connector_state *conn_state,
|
||||
int step, bool dsc)
|
||||
{
|
||||
struct drm_atomic_state *state = crtc_state->uapi.state;
|
||||
struct drm_dp_mst_topology_state *mst_state;
|
||||
|
||||
mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
|
||||
if (IS_ERR(mst_state))
|
||||
return PTR_ERR(mst_state);
|
||||
|
||||
crtc_state->lane_count = limits->max_lane_count;
|
||||
crtc_state->port_clock = limits->max_rate;
|
||||
|
||||
mst_state->pbn_div = drm_dp_get_vc_payload_bw(crtc_state->port_clock,
|
||||
crtc_state->lane_count);
|
||||
|
||||
return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state,
|
||||
max_bpp, min_bpp,
|
||||
conn_state, step, dsc);
|
||||
}
|
||||
|
||||
static int mst_stream_compute_link_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits)
|
||||
const struct link_config_limits *limits)
|
||||
{
|
||||
crtc_state->lane_count = limits->max_lane_count;
|
||||
crtc_state->port_clock = limits->max_rate;
|
||||
|
||||
/*
|
||||
* FIXME: allocate the BW according to link_bpp, which in the case of
|
||||
* YUV420 is only half of the pipe bpp value.
|
||||
*/
|
||||
return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state,
|
||||
fxp_q4_to_int(limits->link.max_bpp_x16),
|
||||
fxp_q4_to_int(limits->link.min_bpp_x16),
|
||||
limits,
|
||||
conn_state, 2 * 3, false);
|
||||
return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state,
|
||||
limits->link.min_bpp_x16,
|
||||
limits->link.max_bpp_x16,
|
||||
fxp_q4_from_int(2 * 3), false);
|
||||
}
|
||||
|
||||
static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state,
|
||||
struct link_config_limits *limits)
|
||||
const struct link_config_limits *limits)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_connector *connector = to_intel_connector(conn_state->connector);
|
||||
int i, num_bpc;
|
||||
int num_bpc;
|
||||
u8 dsc_bpc[3] = {};
|
||||
int min_bpp, max_bpp, sink_min_bpp, sink_max_bpp;
|
||||
int min_compressed_bpp, max_compressed_bpp;
|
||||
|
|
@ -426,15 +438,8 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp,
|
|||
drm_dbg_kms(display->drm, "DSC Source supported min bpp %d max bpp %d\n",
|
||||
min_bpp, max_bpp);
|
||||
|
||||
sink_max_bpp = dsc_bpc[0] * 3;
|
||||
sink_min_bpp = sink_max_bpp;
|
||||
|
||||
for (i = 1; i < num_bpc; i++) {
|
||||
if (sink_min_bpp > dsc_bpc[i] * 3)
|
||||
sink_min_bpp = dsc_bpc[i] * 3;
|
||||
if (sink_max_bpp < dsc_bpc[i] * 3)
|
||||
sink_max_bpp = dsc_bpc[i] * 3;
|
||||
}
|
||||
sink_min_bpp = min_array(dsc_bpc, num_bpc) * 3;
|
||||
sink_max_bpp = max_array(dsc_bpc, num_bpc) * 3;
|
||||
|
||||
drm_dbg_kms(display->drm, "DSC Sink supported min bpp %d max bpp %d\n",
|
||||
sink_min_bpp, sink_max_bpp);
|
||||
|
|
@ -459,9 +464,13 @@ static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp,
|
|||
min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(display, min_compressed_bpp,
|
||||
crtc_state->pipe_bpp);
|
||||
|
||||
return mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp,
|
||||
min_compressed_bpp, limits,
|
||||
conn_state, 1, true);
|
||||
crtc_state->lane_count = limits->max_lane_count;
|
||||
crtc_state->port_clock = limits->max_rate;
|
||||
|
||||
return intel_dp_mtp_tu_compute_config(intel_dp, crtc_state, conn_state,
|
||||
fxp_q4_from_int(min_compressed_bpp),
|
||||
fxp_q4_from_int(max_compressed_bpp),
|
||||
fxp_q4_from_int(1), true);
|
||||
}
|
||||
|
||||
static int mst_stream_update_slots(struct intel_dp *intel_dp,
|
||||
|
|
@ -683,7 +692,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
|
|||
|
||||
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
|
||||
conn_state, &limits,
|
||||
pipe_config->dp_m_n.tu, false);
|
||||
pipe_config->dp_m_n.tu);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
|
@ -841,7 +850,7 @@ static int intel_dp_mst_check_bw(struct intel_atomic_state *state,
|
|||
* @state must be recomputed with the updated @limits.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 if the confugration is valid
|
||||
* - 0 if the configuration is valid
|
||||
* - %-EAGAIN, if the configuration is invalid and @limits got updated
|
||||
* with fallback values with which the configuration of all CRTCs in
|
||||
* @state must be recomputed
|
||||
|
|
@ -947,33 +956,32 @@ mst_connector_atomic_topology_check(struct intel_connector *connector,
|
|||
}
|
||||
|
||||
static int
|
||||
mst_connector_atomic_check(struct drm_connector *connector,
|
||||
mst_connector_atomic_check(struct drm_connector *_connector,
|
||||
struct drm_atomic_state *_state)
|
||||
{
|
||||
struct intel_atomic_state *state = to_intel_atomic_state(_state);
|
||||
struct intel_connector *intel_connector =
|
||||
to_intel_connector(connector);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
int ret;
|
||||
|
||||
ret = intel_digital_connector_atomic_check(connector, &state->base);
|
||||
ret = intel_digital_connector_atomic_check(&connector->base, &state->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mst_connector_atomic_topology_check(intel_connector, state);
|
||||
ret = mst_connector_atomic_topology_check(connector, state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (intel_connector_needs_modeset(state, connector)) {
|
||||
if (intel_connector_needs_modeset(state, &connector->base)) {
|
||||
ret = intel_dp_tunnel_atomic_check_state(state,
|
||||
intel_connector->mst_port,
|
||||
intel_connector);
|
||||
connector->mst_port,
|
||||
connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return drm_dp_atomic_release_time_slots(&state->base,
|
||||
&intel_connector->mst_port->mst_mgr,
|
||||
intel_connector->port);
|
||||
&connector->mst_port->mst_mgr,
|
||||
connector->port);
|
||||
}
|
||||
|
||||
static void mst_stream_disable(struct intel_atomic_state *state,
|
||||
|
|
@ -986,6 +994,7 @@ static void mst_stream_disable(struct intel_atomic_state *state,
|
|||
struct intel_dp *intel_dp = to_primary_dp(encoder);
|
||||
struct intel_connector *connector =
|
||||
to_intel_connector(old_conn_state->connector);
|
||||
enum transcoder trans = old_crtc_state->cpu_transcoder;
|
||||
|
||||
drm_dbg_kms(display->drm, "active links %d\n",
|
||||
intel_dp->active_mst_links);
|
||||
|
|
@ -996,6 +1005,9 @@ static void mst_stream_disable(struct intel_atomic_state *state,
|
|||
intel_hdcp_disable(intel_mst->connector);
|
||||
|
||||
intel_dp_sink_disable_decompression(state, connector, old_crtc_state);
|
||||
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0);
|
||||
}
|
||||
|
||||
static void mst_stream_post_disable(struct intel_atomic_state *state,
|
||||
|
|
@ -1224,11 +1236,10 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state,
|
|||
static void enable_bs_jitter_was(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
|
||||
u32 clear = 0;
|
||||
u32 set = 0;
|
||||
|
||||
if (!IS_ALDERLAKE_P(i915))
|
||||
if (!display->platform.alderlake_p)
|
||||
return;
|
||||
|
||||
if (!IS_DISPLAY_STEP(display, STEP_D0, STEP_FOREVER))
|
||||
|
|
@ -1269,7 +1280,7 @@ static void mst_stream_enable(struct intel_atomic_state *state,
|
|||
enum transcoder trans = pipe_config->cpu_transcoder;
|
||||
bool first_mst_stream = intel_dp->active_mst_links == 1;
|
||||
struct intel_crtc *pipe_crtc;
|
||||
int ret, i;
|
||||
int ret, i, min_hblank;
|
||||
|
||||
drm_WARN_ON(display->drm, pipe_config->has_pch_encoder);
|
||||
|
||||
|
|
@ -1284,6 +1295,29 @@ static void mst_stream_enable(struct intel_atomic_state *state,
|
|||
TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff));
|
||||
}
|
||||
|
||||
if (DISPLAY_VER(display) >= 20) {
|
||||
/*
|
||||
* adjust the BlankingStart/BlankingEnd framing control from
|
||||
* the calculated value
|
||||
*/
|
||||
min_hblank = pipe_config->min_hblank - 2;
|
||||
|
||||
/* Maximum value to be programmed is limited to 0x10 */
|
||||
min_hblank = min(0x10, min_hblank);
|
||||
|
||||
/*
|
||||
* Minimum hblank accepted for 128b/132b would be 5 and for
|
||||
* 8b/10b would be 3 symbol count
|
||||
*/
|
||||
if (intel_dp_is_uhbr(pipe_config))
|
||||
min_hblank = max(min_hblank, 5);
|
||||
else
|
||||
min_hblank = max(min_hblank, 3);
|
||||
|
||||
intel_de_write(display, DP_MIN_HBLANK_CTL(trans),
|
||||
min_hblank);
|
||||
}
|
||||
|
||||
enable_bs_jitter_was(pipe_config);
|
||||
|
||||
intel_ddi_enable_transcoder_func(encoder, pipe_config);
|
||||
|
|
@ -1353,23 +1387,23 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder,
|
|||
return intel_dp_initial_fastset_check(primary_encoder, crtc_state);
|
||||
}
|
||||
|
||||
static int mst_connector_get_ddc_modes(struct drm_connector *connector)
|
||||
static int mst_connector_get_ddc_modes(struct drm_connector *_connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_dp *intel_dp = connector->mst_port;
|
||||
const struct drm_edid *drm_edid;
|
||||
int ret;
|
||||
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
return intel_connector_update_modes(connector, NULL);
|
||||
if (drm_connector_is_unregistered(&connector->base))
|
||||
return intel_connector_update_modes(&connector->base, NULL);
|
||||
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return drm_edid_connector_add_modes(connector);
|
||||
return drm_edid_connector_add_modes(&connector->base);
|
||||
|
||||
drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst_mgr, intel_connector->port);
|
||||
drm_edid = drm_dp_mst_edid_read(&connector->base, &intel_dp->mst_mgr, connector->port);
|
||||
|
||||
ret = intel_connector_update_modes(connector, drm_edid);
|
||||
ret = intel_connector_update_modes(&connector->base, drm_edid);
|
||||
|
||||
drm_edid_free(drm_edid);
|
||||
|
||||
|
|
@ -1377,32 +1411,29 @@ static int mst_connector_get_ddc_modes(struct drm_connector *connector)
|
|||
}
|
||||
|
||||
static int
|
||||
mst_connector_late_register(struct drm_connector *connector)
|
||||
mst_connector_late_register(struct drm_connector *_connector)
|
||||
{
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
int ret;
|
||||
|
||||
ret = drm_dp_mst_connector_late_register(connector,
|
||||
intel_connector->port);
|
||||
ret = drm_dp_mst_connector_late_register(&connector->base, connector->port);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = intel_connector_register(connector);
|
||||
ret = intel_connector_register(&connector->base);
|
||||
if (ret < 0)
|
||||
drm_dp_mst_connector_early_unregister(connector,
|
||||
intel_connector->port);
|
||||
drm_dp_mst_connector_early_unregister(&connector->base, connector->port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mst_connector_early_unregister(struct drm_connector *connector)
|
||||
mst_connector_early_unregister(struct drm_connector *_connector)
|
||||
{
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
|
||||
intel_connector_unregister(connector);
|
||||
drm_dp_mst_connector_early_unregister(connector,
|
||||
intel_connector->port);
|
||||
intel_connector_unregister(&connector->base);
|
||||
drm_dp_mst_connector_early_unregister(&connector->base, connector->port);
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs mst_connector_funcs = {
|
||||
|
|
@ -1416,23 +1447,24 @@ static const struct drm_connector_funcs mst_connector_funcs = {
|
|||
.atomic_duplicate_state = intel_digital_connector_duplicate_state,
|
||||
};
|
||||
|
||||
static int mst_connector_get_modes(struct drm_connector *connector)
|
||||
static int mst_connector_get_modes(struct drm_connector *_connector)
|
||||
{
|
||||
return mst_connector_get_ddc_modes(connector);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
|
||||
return mst_connector_get_ddc_modes(&connector->base);
|
||||
}
|
||||
|
||||
static int
|
||||
mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
||||
mst_connector_mode_valid_ctx(struct drm_connector *_connector,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_modeset_acquire_ctx *ctx,
|
||||
enum drm_mode_status *status)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_dp *intel_dp = connector->mst_port;
|
||||
struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
|
||||
struct drm_dp_mst_port *port = intel_connector->port;
|
||||
struct drm_dp_mst_port *port = connector->port;
|
||||
const int min_bpp = 18;
|
||||
int max_dotclk = display->cdclk.max_dotclk_freq;
|
||||
int max_rate, mode_rate, max_lanes, max_link_clock;
|
||||
|
|
@ -1443,12 +1475,12 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
|||
int target_clock = mode->clock;
|
||||
int num_joined_pipes;
|
||||
|
||||
if (drm_connector_is_unregistered(connector)) {
|
||||
if (drm_connector_is_unregistered(&connector->base)) {
|
||||
*status = MODE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
|
||||
*status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (*status != MODE_OK)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1481,7 +1513,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
|||
* corresponding link capabilities of the sink) in case the
|
||||
* stream is uncompressed for it by the last branch device.
|
||||
*/
|
||||
num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, intel_connector,
|
||||
num_joined_pipes = intel_dp_num_joined_pipes(intel_dp, connector,
|
||||
mode->hdisplay, target_clock);
|
||||
max_dotclk *= num_joined_pipes;
|
||||
|
||||
|
|
@ -1495,14 +1527,14 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (intel_dp_has_dsc(intel_connector)) {
|
||||
if (intel_dp_has_dsc(connector)) {
|
||||
/*
|
||||
* TBD pass the connector BPC,
|
||||
* for now U8_MAX so that max BPC on that platform would be picked
|
||||
*/
|
||||
int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_connector, U8_MAX);
|
||||
int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);
|
||||
|
||||
if (drm_dp_sink_supports_fec(intel_connector->dp.fec_capability)) {
|
||||
if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) {
|
||||
dsc_max_compressed_bpp =
|
||||
intel_dp_dsc_get_max_compressed_bpp(display,
|
||||
max_link_clock,
|
||||
|
|
@ -1513,7 +1545,7 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
|||
INTEL_OUTPUT_FORMAT_RGB,
|
||||
pipe_bpp, 64);
|
||||
dsc_slice_count =
|
||||
intel_dp_dsc_get_slice_count(intel_connector,
|
||||
intel_dp_dsc_get_slice_count(connector,
|
||||
target_clock,
|
||||
mode->hdisplay,
|
||||
num_joined_pipes);
|
||||
|
|
@ -1532,44 +1564,44 @@ mst_connector_mode_valid_ctx(struct drm_connector *connector,
|
|||
return 0;
|
||||
}
|
||||
|
||||
*status = intel_mode_valid_max_plane_size(dev_priv, mode, num_joined_pipes);
|
||||
*status = intel_mode_valid_max_plane_size(display, mode, num_joined_pipes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_encoder *
|
||||
mst_connector_atomic_best_encoder(struct drm_connector *connector,
|
||||
mst_connector_atomic_best_encoder(struct drm_connector *_connector,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state,
|
||||
connector);
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct drm_connector_state *connector_state =
|
||||
drm_atomic_get_new_connector_state(state, &connector->base);
|
||||
struct intel_dp *intel_dp = connector->mst_port;
|
||||
struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc);
|
||||
|
||||
return &intel_dp->mst_encoders[crtc->pipe]->base.base;
|
||||
}
|
||||
|
||||
static int
|
||||
mst_connector_detect_ctx(struct drm_connector *connector,
|
||||
mst_connector_detect_ctx(struct drm_connector *_connector,
|
||||
struct drm_modeset_acquire_ctx *ctx, bool force)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct intel_dp *intel_dp = intel_connector->mst_port;
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_dp *intel_dp = connector->mst_port;
|
||||
|
||||
if (!intel_display_device_enabled(display))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
if (drm_connector_is_unregistered(&connector->base))
|
||||
return connector_status_disconnected;
|
||||
|
||||
if (!intel_display_driver_check_access(display))
|
||||
return connector->status;
|
||||
return connector->base.status;
|
||||
|
||||
intel_dp_flush_connector_commits(intel_connector);
|
||||
intel_dp_flush_connector_commits(connector);
|
||||
|
||||
return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr,
|
||||
intel_connector->port);
|
||||
return drm_dp_mst_detect_port(&connector->base, ctx, &intel_dp->mst_mgr,
|
||||
connector->port);
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs mst_connector_helper_funcs = {
|
||||
|
|
@ -1605,29 +1637,30 @@ static bool mst_connector_get_hw_state(struct intel_connector *connector)
|
|||
}
|
||||
|
||||
static int mst_topology_add_connector_properties(struct intel_dp *intel_dp,
|
||||
struct drm_connector *connector,
|
||||
struct drm_connector *_connector,
|
||||
const char *pathprop)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
|
||||
drm_object_attach_property(&connector->base,
|
||||
drm_object_attach_property(&connector->base.base,
|
||||
display->drm->mode_config.path_property, 0);
|
||||
drm_object_attach_property(&connector->base,
|
||||
drm_object_attach_property(&connector->base.base,
|
||||
display->drm->mode_config.tile_property, 0);
|
||||
|
||||
intel_attach_force_audio_property(connector);
|
||||
intel_attach_broadcast_rgb_property(connector);
|
||||
intel_attach_force_audio_property(&connector->base);
|
||||
intel_attach_broadcast_rgb_property(&connector->base);
|
||||
|
||||
/*
|
||||
* Reuse the prop from the SST connector because we're
|
||||
* not allowed to create new props after device registration.
|
||||
*/
|
||||
connector->max_bpc_property =
|
||||
connector->base.max_bpc_property =
|
||||
intel_dp->attached_connector->base.max_bpc_property;
|
||||
if (connector->max_bpc_property)
|
||||
drm_connector_attach_max_bpc_property(connector, 6, 12);
|
||||
if (connector->base.max_bpc_property)
|
||||
drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
|
||||
|
||||
return drm_connector_set_path_property(connector, pathprop);
|
||||
return drm_connector_set_path_property(&connector->base, pathprop);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1700,62 +1733,58 @@ mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||
struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
|
||||
struct intel_display *display = to_intel_display(intel_dp);
|
||||
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
|
||||
struct intel_connector *intel_connector;
|
||||
struct drm_connector *connector;
|
||||
struct intel_connector *connector;
|
||||
enum pipe pipe;
|
||||
int ret;
|
||||
|
||||
intel_connector = intel_connector_alloc();
|
||||
if (!intel_connector)
|
||||
connector = intel_connector_alloc();
|
||||
if (!connector)
|
||||
return NULL;
|
||||
|
||||
connector = &intel_connector->base;
|
||||
|
||||
intel_connector->get_hw_state = mst_connector_get_hw_state;
|
||||
intel_connector->sync_state = intel_dp_connector_sync_state;
|
||||
intel_connector->mst_port = intel_dp;
|
||||
intel_connector->port = port;
|
||||
connector->get_hw_state = mst_connector_get_hw_state;
|
||||
connector->sync_state = intel_dp_connector_sync_state;
|
||||
connector->mst_port = intel_dp;
|
||||
connector->port = port;
|
||||
drm_dp_mst_get_port_malloc(port);
|
||||
|
||||
intel_dp_init_modeset_retry_work(intel_connector);
|
||||
|
||||
ret = drm_connector_dynamic_init(display->drm, connector, &mst_connector_funcs,
|
||||
ret = drm_connector_dynamic_init(display->drm, &connector->base, &mst_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_DisplayPort, NULL);
|
||||
if (ret) {
|
||||
drm_dp_mst_put_port_malloc(port);
|
||||
intel_connector_free(intel_connector);
|
||||
return NULL;
|
||||
}
|
||||
if (ret)
|
||||
goto err_put_port;
|
||||
|
||||
intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port);
|
||||
intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector);
|
||||
intel_connector->dp.dsc_hblank_expansion_quirk =
|
||||
detect_dsc_hblank_expansion_quirk(intel_connector);
|
||||
connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port);
|
||||
intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, connector);
|
||||
connector->dp.dsc_hblank_expansion_quirk =
|
||||
detect_dsc_hblank_expansion_quirk(connector);
|
||||
|
||||
drm_connector_helper_add(connector, &mst_connector_helper_funcs);
|
||||
drm_connector_helper_add(&connector->base, &mst_connector_helper_funcs);
|
||||
|
||||
for_each_pipe(display, pipe) {
|
||||
struct drm_encoder *enc =
|
||||
&intel_dp->mst_encoders[pipe]->base.base;
|
||||
|
||||
ret = drm_connector_attach_encoder(&intel_connector->base, enc);
|
||||
ret = drm_connector_attach_encoder(&connector->base, enc);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_cleanup_connector;
|
||||
}
|
||||
|
||||
ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop);
|
||||
ret = mst_topology_add_connector_properties(intel_dp, &connector->base, pathprop);
|
||||
if (ret)
|
||||
goto err;
|
||||
goto err_cleanup_connector;
|
||||
|
||||
ret = intel_dp_hdcp_init(dig_port, intel_connector);
|
||||
ret = intel_dp_hdcp_init(dig_port, connector);
|
||||
if (ret)
|
||||
drm_dbg_kms(display->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
|
||||
connector->name, connector->base.id);
|
||||
connector->base.name, connector->base.base.id);
|
||||
|
||||
return connector;
|
||||
return &connector->base;
|
||||
|
||||
err_cleanup_connector:
|
||||
drm_connector_cleanup(&connector->base);
|
||||
err_put_port:
|
||||
drm_dp_mst_put_port_malloc(port);
|
||||
intel_connector_free(connector);
|
||||
|
||||
err:
|
||||
drm_connector_cleanup(connector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2060,7 +2089,7 @@ bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
|
|||
* @intel_dp: DP port object
|
||||
*
|
||||
* Prepare an MST link for topology probing, programming the target
|
||||
* link parameters to DPCD. This step is a requirement of the enumaration
|
||||
* link parameters to DPCD. This step is a requirement of the enumeration
|
||||
* of path resources during probing.
|
||||
*/
|
||||
void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp)
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp);
|
|||
|
||||
int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp,
|
||||
struct intel_crtc_state *crtc_state,
|
||||
int max_bpp, int min_bpp,
|
||||
struct drm_connector_state *conn_state,
|
||||
int step, bool dsc);
|
||||
int min_bpp_x16, int max_bpp_x16, int bpp_step_x16, bool dsc);
|
||||
|
||||
#endif /* __INTEL_DP_MST_H__ */
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
|
|||
/*
|
||||
* FIXME: Ideally pattern should come from DPCD 0x250. As
|
||||
* current firmware of DPR-100 could not set it, so hardcoding
|
||||
* now for complaince test.
|
||||
* now for compliance test.
|
||||
*/
|
||||
drm_dbg_kms(display->drm,
|
||||
"Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n");
|
||||
|
|
@ -275,7 +275,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
|
|||
/*
|
||||
* FIXME: Ideally pattern should come from DPCD 0x24A. As
|
||||
* current firmware of DPR-100 could not set it, so hardcoding
|
||||
* now for complaince test.
|
||||
* now for compliance test.
|
||||
*/
|
||||
drm_dbg_kms(display->drm,
|
||||
"Set HBR2 compliance Phy Test Pattern\n");
|
||||
|
|
|
|||
|
|
@ -647,7 +647,7 @@ void intel_dp_tunnel_atomic_clear_stream_bw(struct intel_atomic_state *state,
|
|||
* @state must be recomputed with the updated @limits.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 if the confugration is valid
|
||||
* - 0 if the configuration is valid
|
||||
* - %-EAGAIN, if the configuration is invalid and @limits got updated
|
||||
* with fallback values with which the configuration of all CRTCs in
|
||||
* @state must be recomputed
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ struct intel_dp;
|
|||
struct intel_encoder;
|
||||
struct intel_link_bw_limits;
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)
|
||||
#if (IS_ENABLED(CONFIG_DRM_I915_DP_TUNNEL) && defined(I915)) || \
|
||||
(IS_ENABLED(CONFIG_DRM_XE_DP_TUNNEL) && !defined(I915))
|
||||
|
||||
int intel_dp_tunnel_detect(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx);
|
||||
void intel_dp_tunnel_disconnect(struct intel_dp *intel_dp);
|
||||
|
|
@ -127,6 +128,6 @@ intel_dp_tunnel_mgr_init(struct intel_display *display)
|
|||
|
||||
static inline void intel_dp_tunnel_mgr_cleanup(struct intel_display *display) {}
|
||||
|
||||
#endif /* CONFIG_DRM_I915_DP_TUNNEL */
|
||||
#endif /* CONFIG_DRM_I915_DP_TUNNEL || CONFIG_DRM_XE_DP_TUNNEL */
|
||||
|
||||
#endif /* __INTEL_DP_TUNNEL_H__ */
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
* VLV, CHV and BXT have slightly peculiar display PHYs for driving DP/HDMI
|
||||
* ports. DPIO is the name given to such a display PHY. These PHYs
|
||||
* don't follow the standard programming model using direct MMIO
|
||||
* registers, and instead their registers must be accessed trough IOSF
|
||||
* registers, and instead their registers must be accessed through IOSF
|
||||
* sideband. VLV has one such PHY for driving ports B and C, and CHV
|
||||
* adds another PHY for driving port D. Each PHY responds to specific
|
||||
* IOSF-SB port.
|
||||
|
|
@ -1156,3 +1156,37 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
|
|||
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1_GRP(ch), 0x00e00060);
|
||||
vlv_dpio_put(dev_priv);
|
||||
}
|
||||
|
||||
void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
unsigned int expected_mask)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(encoder);
|
||||
u32 port_mask;
|
||||
i915_reg_t dpll_reg;
|
||||
|
||||
switch (encoder->port) {
|
||||
default:
|
||||
MISSING_CASE(encoder->port);
|
||||
fallthrough;
|
||||
case PORT_B:
|
||||
port_mask = DPLL_PORTB_READY_MASK;
|
||||
dpll_reg = DPLL(display, 0);
|
||||
break;
|
||||
case PORT_C:
|
||||
port_mask = DPLL_PORTC_READY_MASK;
|
||||
dpll_reg = DPLL(display, 0);
|
||||
expected_mask <<= 4;
|
||||
break;
|
||||
case PORT_D:
|
||||
port_mask = DPLL_PORTD_READY_MASK;
|
||||
dpll_reg = DPIO_PHY_STATUS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (intel_de_wait(display, dpll_reg, port_mask, expected_mask, 1000))
|
||||
drm_WARN(display->drm, 1,
|
||||
"timed out waiting for [ENCODER:%d:%s] port ready: got 0x%x, expected 0x%x\n",
|
||||
encoder->base.base.id, encoder->base.name,
|
||||
intel_de_read(display, dpll_reg) & port_mask,
|
||||
expected_mask);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state);
|
||||
void vlv_phy_reset_lanes(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state);
|
||||
void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
unsigned int expected_mask);
|
||||
#else
|
||||
static inline void bxt_port_to_phy_channel(struct intel_display *display, enum port port,
|
||||
enum dpio_phy *phy, enum dpio_channel *ch)
|
||||
|
|
@ -170,6 +172,10 @@ static inline void vlv_phy_reset_lanes(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *old_crtc_state)
|
||||
{
|
||||
}
|
||||
static inline void vlv_wait_port_ready(struct intel_encoder *encoder,
|
||||
unsigned int expected_mask)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_DPIO_PHY_H__ */
|
||||
|
|
|
|||
|
|
@ -1843,7 +1843,7 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state)
|
|||
enum pipe pipe = crtc->pipe;
|
||||
int i;
|
||||
|
||||
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, crtc_state->cpu_transcoder);
|
||||
|
||||
/* PLL is protected by panel, make sure we can write it */
|
||||
if (i9xx_has_pps(dev_priv))
|
||||
|
|
@ -2024,7 +2024,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state)
|
|||
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, crtc_state->cpu_transcoder);
|
||||
|
||||
/* PLL is protected by panel, make sure we can write it */
|
||||
assert_pps_unlocked(display, pipe);
|
||||
|
|
@ -2171,7 +2171,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state)
|
|||
const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, crtc_state->cpu_transcoder);
|
||||
|
||||
/* PLL is protected by panel, make sure we can write it */
|
||||
assert_pps_unlocked(display, pipe);
|
||||
|
|
@ -2253,36 +2253,38 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|||
|
||||
void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
u32 val;
|
||||
|
||||
/* Make sure the pipe isn't still relying on us */
|
||||
assert_transcoder_disabled(dev_priv, (enum transcoder)pipe);
|
||||
assert_transcoder_disabled(display, (enum transcoder)pipe);
|
||||
|
||||
val = DPLL_INTEGRATED_REF_CLK_VLV |
|
||||
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
|
||||
if (pipe != PIPE_A)
|
||||
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
|
||||
|
||||
intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
|
||||
intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
|
||||
intel_de_write(display, DPLL(display, pipe), val);
|
||||
intel_de_posting_read(display, DPLL(display, pipe));
|
||||
}
|
||||
|
||||
void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
enum dpio_channel ch = vlv_pipe_to_channel(pipe);
|
||||
enum dpio_phy phy = vlv_pipe_to_phy(pipe);
|
||||
u32 val;
|
||||
|
||||
/* Make sure the pipe isn't still relying on us */
|
||||
assert_transcoder_disabled(dev_priv, (enum transcoder)pipe);
|
||||
assert_transcoder_disabled(display, (enum transcoder)pipe);
|
||||
|
||||
val = DPLL_SSC_REF_CLK_CHV |
|
||||
DPLL_REF_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS;
|
||||
if (pipe != PIPE_A)
|
||||
val |= DPLL_INTEGRATED_CRI_CLK_VLV;
|
||||
|
||||
intel_de_write(dev_priv, DPLL(dev_priv, pipe), val);
|
||||
intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
|
||||
intel_de_write(display, DPLL(display, pipe), val);
|
||||
intel_de_posting_read(display, DPLL(display, pipe));
|
||||
|
||||
vlv_dpio_get(dev_priv);
|
||||
|
||||
|
|
@ -2296,19 +2298,19 @@ void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
|
||||
void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc_state);
|
||||
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
/* Don't disable pipe or pipe PLLs if needed */
|
||||
if (IS_I830(dev_priv))
|
||||
if (display->platform.i830)
|
||||
return;
|
||||
|
||||
/* Make sure the pipe isn't still relying on us */
|
||||
assert_transcoder_disabled(dev_priv, crtc_state->cpu_transcoder);
|
||||
assert_transcoder_disabled(display, crtc_state->cpu_transcoder);
|
||||
|
||||
intel_de_write(dev_priv, DPLL(dev_priv, pipe), DPLL_VGA_MODE_DIS);
|
||||
intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe));
|
||||
intel_de_write(display, DPLL(display, pipe), DPLL_VGA_MODE_DIS);
|
||||
intel_de_posting_read(display, DPLL(display, pipe));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2329,10 +2331,9 @@ void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe)
|
|||
}
|
||||
|
||||
/* Only for pre-ILK configs */
|
||||
static void assert_pll(struct drm_i915_private *dev_priv,
|
||||
static void assert_pll(struct intel_display *display,
|
||||
enum pipe pipe, bool state)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
bool cur_state;
|
||||
|
||||
cur_state = intel_de_read(display, DPLL(display, pipe)) & DPLL_VCO_ENABLE;
|
||||
|
|
@ -2341,12 +2342,12 @@ static void assert_pll(struct drm_i915_private *dev_priv,
|
|||
str_on_off(state), str_on_off(cur_state));
|
||||
}
|
||||
|
||||
void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)
|
||||
void assert_pll_enabled(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
assert_pll(i915, pipe, true);
|
||||
assert_pll(display, pipe, true);
|
||||
}
|
||||
|
||||
void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe)
|
||||
void assert_pll_disabled(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
assert_pll(i915, pipe, false);
|
||||
assert_pll(display, pipe, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ struct drm_i915_private;
|
|||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_display;
|
||||
struct intel_dpll_hw_state;
|
||||
enum pipe;
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state);
|
|||
void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state);
|
||||
void chv_crtc_clock_get(struct intel_crtc_state *crtc_state);
|
||||
|
||||
void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_pll_enabled(struct intel_display *display, enum pipe pipe);
|
||||
void assert_pll_disabled(struct intel_display *display, enum pipe pipe);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -30,12 +30,11 @@
|
|||
#include "intel_display_power.h"
|
||||
#include "intel_wakeref.h"
|
||||
|
||||
#define for_each_shared_dpll(__i915, __pll, __i) \
|
||||
for ((__i) = 0; (__i) < (__i915)->display.dpll.num_shared_dpll && \
|
||||
((__pll) = &(__i915)->display.dpll.shared_dplls[(__i)]) ; (__i)++)
|
||||
#define for_each_shared_dpll(__display, __pll, __i) \
|
||||
for ((__i) = 0; (__i) < (__display)->dpll.num_shared_dpll && \
|
||||
((__pll) = &(__display)->dpll.shared_dplls[(__i)]) ; (__i)++)
|
||||
|
||||
enum tc_port;
|
||||
struct drm_i915_private;
|
||||
struct drm_printer;
|
||||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
|
|
@ -318,7 +317,7 @@ struct dpll_info {
|
|||
const struct intel_shared_dpll_funcs *funcs;
|
||||
|
||||
/**
|
||||
* @id: unique indentifier for this DPLL
|
||||
* @id: unique identifier for this DPLL
|
||||
*/
|
||||
enum intel_dpll_id id;
|
||||
|
||||
|
|
@ -390,9 +389,9 @@ struct intel_shared_dpll {
|
|||
|
||||
/* shared dpll functions */
|
||||
struct intel_shared_dpll *
|
||||
intel_get_shared_dpll_by_id(struct drm_i915_private *i915,
|
||||
intel_get_shared_dpll_by_id(struct intel_display *display,
|
||||
enum intel_dpll_id id);
|
||||
void assert_shared_dpll(struct drm_i915_private *i915,
|
||||
void assert_shared_dpll(struct intel_display *display,
|
||||
struct intel_shared_dpll *pll,
|
||||
bool state);
|
||||
#define assert_shared_dpll_enabled(d, p) assert_shared_dpll(d, p, true)
|
||||
|
|
@ -413,24 +412,24 @@ void icl_set_active_port_dpll(struct intel_crtc_state *crtc_state,
|
|||
void intel_update_active_dpll(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc,
|
||||
struct intel_encoder *encoder);
|
||||
int intel_dpll_get_freq(struct drm_i915_private *i915,
|
||||
int intel_dpll_get_freq(struct intel_display *display,
|
||||
const struct intel_shared_dpll *pll,
|
||||
const struct intel_dpll_hw_state *dpll_hw_state);
|
||||
bool intel_dpll_get_hw_state(struct drm_i915_private *i915,
|
||||
bool intel_dpll_get_hw_state(struct intel_display *display,
|
||||
struct intel_shared_dpll *pll,
|
||||
struct intel_dpll_hw_state *dpll_hw_state);
|
||||
void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state);
|
||||
void intel_shared_dpll_swap_state(struct intel_atomic_state *state);
|
||||
void intel_shared_dpll_init(struct drm_i915_private *i915);
|
||||
void intel_dpll_update_ref_clks(struct drm_i915_private *i915);
|
||||
void intel_dpll_readout_hw_state(struct drm_i915_private *i915);
|
||||
void intel_dpll_sanitize_state(struct drm_i915_private *i915);
|
||||
void intel_shared_dpll_init(struct intel_display *display);
|
||||
void intel_dpll_update_ref_clks(struct intel_display *display);
|
||||
void intel_dpll_readout_hw_state(struct intel_display *display);
|
||||
void intel_dpll_sanitize_state(struct intel_display *display);
|
||||
|
||||
void intel_dpll_dump_hw_state(struct drm_i915_private *i915,
|
||||
void intel_dpll_dump_hw_state(struct intel_display *display,
|
||||
struct drm_printer *p,
|
||||
const struct intel_dpll_hw_state *dpll_hw_state);
|
||||
bool intel_dpll_compare_hw_state(struct drm_i915_private *i915,
|
||||
bool intel_dpll_compare_hw_state(struct intel_display *display,
|
||||
const struct intel_dpll_hw_state *a,
|
||||
const struct intel_dpll_hw_state *b);
|
||||
enum intel_dpll_id icl_tc_port_to_pll_id(enum tc_port tc_port);
|
||||
|
|
|
|||
|
|
@ -109,38 +109,32 @@ static bool pre_commit_is_vrr_active(struct intel_atomic_state *state,
|
|||
return old_crtc_state->vrr.enable && !intel_crtc_vrr_disabling(state, crtc);
|
||||
}
|
||||
|
||||
static const struct intel_crtc_state *
|
||||
pre_commit_crtc_state(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
static int dsb_vblank_delay(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
const struct intel_crtc_state *old_crtc_state =
|
||||
intel_atomic_get_old_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *new_crtc_state =
|
||||
intel_atomic_get_new_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
|
||||
/*
|
||||
* During fastsets/etc. the transcoder is still
|
||||
* running with the old timings at this point.
|
||||
*/
|
||||
if (intel_crtc_needs_modeset(new_crtc_state))
|
||||
return new_crtc_state;
|
||||
if (pre_commit_is_vrr_active(state, crtc))
|
||||
/*
|
||||
* When the push is sent during vblank it will trigger
|
||||
* on the next scanline, hence we have up to one extra
|
||||
* scanline until the delayed vblank occurs after
|
||||
* TRANS_PUSH has been written.
|
||||
*/
|
||||
return intel_vrr_vblank_delay(crtc_state) + 1;
|
||||
else
|
||||
return old_crtc_state;
|
||||
}
|
||||
|
||||
static int dsb_vblank_delay(const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
return intel_mode_vblank_start(&crtc_state->hw.adjusted_mode) -
|
||||
intel_mode_vdisplay(&crtc_state->hw.adjusted_mode);
|
||||
return intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode);
|
||||
}
|
||||
|
||||
static int dsb_vtotal(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
|
||||
if (pre_commit_is_vrr_active(state, crtc))
|
||||
return crtc_state->vrr.vmax;
|
||||
return intel_vrr_vmax_vtotal(crtc_state);
|
||||
else
|
||||
return intel_mode_vtotal(&crtc_state->hw.adjusted_mode);
|
||||
}
|
||||
|
|
@ -148,7 +142,8 @@ static int dsb_vtotal(struct intel_atomic_state *state,
|
|||
static int dsb_dewake_scanline_start(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
struct drm_i915_private *i915 = to_i915(state->base.dev);
|
||||
unsigned int latency = skl_watermark_max_latency(i915, 0);
|
||||
|
||||
|
|
@ -159,7 +154,8 @@ static int dsb_dewake_scanline_start(struct intel_atomic_state *state,
|
|||
static int dsb_dewake_scanline_end(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
|
||||
return intel_mode_vdisplay(&crtc_state->hw.adjusted_mode);
|
||||
}
|
||||
|
|
@ -167,23 +163,33 @@ static int dsb_dewake_scanline_end(struct intel_atomic_state *state,
|
|||
static int dsb_scanline_to_hw(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc, int scanline)
|
||||
{
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
int vtotal = dsb_vtotal(state, crtc);
|
||||
|
||||
return (scanline + vtotal - intel_crtc_scanline_offset(crtc_state)) % vtotal;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bspec suggests that we should always set DSB_SKIP_WAITS_EN. We have approach
|
||||
* different from what is explained in Bspec on how flip is considered being
|
||||
* complete. We are waiting for vblank in DSB and generate interrupt when it
|
||||
* happens and this interrupt is considered as indication of completion -> we
|
||||
* definitely do not want to skip vblank wait. We also have concern what comes
|
||||
* to skipping vblank evasion. I.e. arming registers are latched before we have
|
||||
* managed writing them. Due to these reasons we are not setting
|
||||
* DSB_SKIP_WAITS_EN.
|
||||
*/
|
||||
static u32 dsb_chicken(struct intel_atomic_state *state,
|
||||
struct intel_crtc *crtc)
|
||||
{
|
||||
if (pre_commit_is_vrr_active(state, crtc))
|
||||
return DSB_SKIP_WAITS_EN |
|
||||
DSB_CTRL_WAIT_SAFE_WINDOW |
|
||||
return DSB_CTRL_WAIT_SAFE_WINDOW |
|
||||
DSB_CTRL_NO_WAIT_VBLANK |
|
||||
DSB_INST_WAIT_SAFE_WINDOW |
|
||||
DSB_INST_NO_WAIT_VBLANK;
|
||||
else
|
||||
return DSB_SKIP_WAITS_EN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool assert_dsb_has_room(struct intel_dsb *dsb)
|
||||
|
|
@ -378,7 +384,8 @@ void intel_dsb_interrupt(struct intel_dsb *dsb)
|
|||
|
||||
void intel_dsb_wait_usec(struct intel_dsb *dsb, int count)
|
||||
{
|
||||
intel_dsb_emit(dsb, count,
|
||||
/* +1 to make sure we never wait less time than asked for */
|
||||
intel_dsb_emit(dsb, count + 1,
|
||||
DSB_OPCODE_WAIT_USEC << DSB_OPCODE_SHIFT);
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +468,25 @@ void intel_dsb_wait_scanline_out(struct intel_atomic_state *state,
|
|||
start, end);
|
||||
}
|
||||
|
||||
void intel_dsb_poll(struct intel_dsb *dsb,
|
||||
i915_reg_t reg, u32 mask, u32 val,
|
||||
int wait_us, int count)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
intel_dsb_reg_write(dsb, DSB_POLLMASK(pipe, dsb->id), mask);
|
||||
intel_dsb_reg_write(dsb, DSB_POLLFUNC(pipe, dsb->id),
|
||||
DSB_POLL_ENABLE |
|
||||
DSB_POLL_WAIT(wait_us) | DSB_POLL_COUNT(count));
|
||||
|
||||
intel_dsb_noop(dsb, 5);
|
||||
|
||||
intel_dsb_emit(dsb, val,
|
||||
(DSB_OPCODE_POLL << DSB_OPCODE_SHIFT) |
|
||||
i915_mmio_reg_offset(reg));
|
||||
}
|
||||
|
||||
static void intel_dsb_align_tail(struct intel_dsb *dsb)
|
||||
{
|
||||
u32 aligned_tail, tail;
|
||||
|
|
@ -532,13 +558,27 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state,
|
|||
struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
/* FIXME calibrate sensibly */
|
||||
int latency = intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 20);
|
||||
int vblank_delay = dsb_vblank_delay(crtc_state);
|
||||
int start, end;
|
||||
|
||||
/*
|
||||
* PIPEDSL is reading as 0 when in SRDENT(PSR1) or DEEP_SLEEP(PSR2). On
|
||||
* wake-up scanline counting starts from vblank_start - 1. We don't know
|
||||
* if wake-up is already ongoing when evasion starts. In worst case
|
||||
* PIPEDSL could start reading valid value right after checking the
|
||||
* scanline. In this scenario we wouldn't have enough time to write all
|
||||
* registers. To tackle this evade scanline 0 as well. As a drawback we
|
||||
* have 1 frame delay in flip when waking up.
|
||||
*/
|
||||
if (crtc_state->has_psr)
|
||||
intel_dsb_emit_wait_dsl(dsb, DSB_OPCODE_WAIT_DSL_OUT, 0, 0);
|
||||
|
||||
if (pre_commit_is_vrr_active(state, crtc)) {
|
||||
int vblank_delay = intel_vrr_vblank_delay(crtc_state);
|
||||
|
||||
end = intel_vrr_vmin_vblank_start(crtc_state);
|
||||
start = end - vblank_delay - latency;
|
||||
intel_dsb_wait_scanline_out(state, dsb, start, end);
|
||||
|
|
@ -547,6 +587,8 @@ void intel_dsb_vblank_evade(struct intel_atomic_state *state,
|
|||
start = end - vblank_delay - latency;
|
||||
intel_dsb_wait_scanline_out(state, dsb, start, end);
|
||||
} else {
|
||||
int vblank_delay = intel_mode_vblank_delay(&crtc_state->hw.adjusted_mode);
|
||||
|
||||
end = intel_mode_vblank_start(&crtc_state->hw.adjusted_mode);
|
||||
start = end - vblank_delay - latency;
|
||||
intel_dsb_wait_scanline_out(state, dsb, start, end);
|
||||
|
|
@ -624,9 +666,10 @@ void intel_dsb_wait_vblank_delay(struct intel_atomic_state *state,
|
|||
struct intel_dsb *dsb)
|
||||
{
|
||||
struct intel_crtc *crtc = dsb->crtc;
|
||||
const struct intel_crtc_state *crtc_state = pre_commit_crtc_state(state, crtc);
|
||||
const struct intel_crtc_state *crtc_state =
|
||||
intel_pre_commit_crtc_state(state, crtc);
|
||||
int usecs = intel_scanlines_to_usecs(&crtc_state->hw.adjusted_mode,
|
||||
dsb_vblank_delay(crtc_state)) + 1;
|
||||
dsb_vblank_delay(state, crtc));
|
||||
|
||||
intel_dsb_wait_usec(dsb, usecs);
|
||||
}
|
||||
|
|
@ -825,7 +868,7 @@ void intel_dsb_irq_handler(struct intel_display *display,
|
|||
|
||||
if (crtc->dsb_event) {
|
||||
/*
|
||||
* Update vblank counter/timestmap in case it
|
||||
* Update vblank counter/timestamp in case it
|
||||
* hasn't been done yet for this frame.
|
||||
*/
|
||||
drm_crtc_accurate_vblank_count(&crtc->base);
|
||||
|
|
@ -838,7 +881,16 @@ void intel_dsb_irq_handler(struct intel_display *display,
|
|||
}
|
||||
|
||||
errors = tmp & dsb_error_int_status(display);
|
||||
if (errors)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d error interrupt: 0x%x\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id, errors);
|
||||
if (errors & DSB_ATS_FAULT_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d ATS fault\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
if (errors & DSB_GTT_FAULT_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d GTT fault\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
if (errors & DSB_RSPTIMEOUT_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d response timeout\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
if (errors & DSB_POLL_ERR_INT_STATUS)
|
||||
drm_err(display->drm, "[CRTC:%d:%s] DSB %d poll error\n",
|
||||
crtc->base.base.id, crtc->base.name, dsb_id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ void intel_dsb_wait_scanline_out(struct intel_atomic_state *state,
|
|||
int lower, int upper);
|
||||
void intel_dsb_vblank_evade(struct intel_atomic_state *state,
|
||||
struct intel_dsb *dsb);
|
||||
void intel_dsb_poll(struct intel_dsb *dsb,
|
||||
i915_reg_t reg, u32 mask, u32 val,
|
||||
int wait_us, int count);
|
||||
void intel_dsb_chain(struct intel_atomic_state *state,
|
||||
struct intel_dsb *dsb,
|
||||
struct intel_dsb *chained_dsb,
|
||||
|
|
|
|||
|
|
@ -60,14 +60,14 @@ int intel_dsi_get_modes(struct drm_connector *connector)
|
|||
enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_fixed_mode(intel_connector, mode);
|
||||
int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
|
||||
int max_dotclk = display->cdclk.max_dotclk_freq;
|
||||
enum drm_mode_status status;
|
||||
|
||||
drm_dbg_kms(&dev_priv->drm, "\n");
|
||||
drm_dbg_kms(display->drm, "\n");
|
||||
|
||||
status = intel_panel_mode_valid(intel_connector, mode);
|
||||
if (status != MODE_OK)
|
||||
|
|
@ -76,7 +76,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
|
|||
if (fixed_mode->clock > max_dotclk)
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, 1);
|
||||
return intel_mode_valid_max_plane_size(display, mode, 1);
|
||||
}
|
||||
|
||||
struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
|
||||
|
|
|
|||
|
|
@ -582,7 +582,7 @@ static const fn_mipi_elem_exec exec_elem[] = {
|
|||
|
||||
/*
|
||||
* MIPI Sequence from VBT #53 parsing logic
|
||||
* We have already separated each seqence during bios parsing
|
||||
* We have already separated each sequence during bios parsing
|
||||
* Following is generic execution function for any sequence
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -219,16 +219,16 @@ static enum drm_mode_status
|
|||
intel_dvo_mode_valid(struct drm_connector *_connector,
|
||||
const struct drm_display_mode *mode)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(_connector->dev);
|
||||
struct intel_connector *connector = to_intel_connector(_connector);
|
||||
struct drm_i915_private *i915 = to_i915(connector->base.dev);
|
||||
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
|
||||
const struct drm_display_mode *fixed_mode =
|
||||
intel_panel_fixed_mode(connector, mode);
|
||||
int max_dotclk = to_i915(connector->base.dev)->display.cdclk.max_dotclk_freq;
|
||||
int max_dotclk = display->cdclk.max_dotclk_freq;
|
||||
int target_clock = mode->clock;
|
||||
enum drm_mode_status status;
|
||||
|
||||
status = intel_cpu_transcoder_mode_valid(i915, mode);
|
||||
status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
|
|
@ -524,7 +524,7 @@ void intel_dvo_init(struct drm_i915_private *i915)
|
|||
return;
|
||||
}
|
||||
|
||||
assert_port_valid(i915, intel_dvo->dev.port);
|
||||
assert_port_valid(display, intel_dvo->dev.port);
|
||||
|
||||
encoder->type = INTEL_OUTPUT_DVO;
|
||||
encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct intel_dvo_dev_ops {
|
|||
* Turn on/off output.
|
||||
*
|
||||
* Because none of our dvo drivers support an intermediate power levels,
|
||||
* we don't expose this in the interfac.
|
||||
* we don't expose this in the interface.
|
||||
*/
|
||||
void (*dpms)(struct intel_dvo_device *dvo, bool enable);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include "intel_fb_bo.h"
|
||||
#include "intel_frontbuffer.h"
|
||||
|
||||
#define check_array_bounds(i915, a, i) drm_WARN_ON(&(i915)->drm, (i) >= ARRAY_SIZE(a))
|
||||
#define check_array_bounds(display, a, i) drm_WARN_ON((display)->drm, (i) >= ARRAY_SIZE(a))
|
||||
|
||||
/*
|
||||
* From the Sky Lake PRM:
|
||||
|
|
@ -539,11 +539,13 @@ static bool check_modifier_display_ver_range(const struct intel_modifier_desc *m
|
|||
display_ver_from <= md->display_ver.until;
|
||||
}
|
||||
|
||||
static bool plane_has_modifier(struct drm_i915_private *i915,
|
||||
static bool plane_has_modifier(struct intel_display *display,
|
||||
u8 plane_caps,
|
||||
const struct intel_modifier_desc *md)
|
||||
{
|
||||
if (!IS_DISPLAY_VER(i915, md->display_ver.from, md->display_ver.until))
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (!IS_DISPLAY_VER(display, md->display_ver.from, md->display_ver.until))
|
||||
return false;
|
||||
|
||||
if (!plane_caps_contain_all(plane_caps, md->plane_caps))
|
||||
|
|
@ -570,14 +572,14 @@ static bool plane_has_modifier(struct drm_i915_private *i915,
|
|||
|
||||
/**
|
||||
* intel_fb_plane_get_modifiers: Get the modifiers for the given platform and plane capabilities
|
||||
* @i915: i915 device instance
|
||||
* @display: display instance
|
||||
* @plane_caps: capabilities for the plane the modifiers are queried for
|
||||
*
|
||||
* Returns:
|
||||
* Returns the list of modifiers allowed by the @i915 platform and @plane_caps.
|
||||
* Returns the list of modifiers allowed by the @display platform and @plane_caps.
|
||||
* The caller must free the returned buffer.
|
||||
*/
|
||||
u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915,
|
||||
u64 *intel_fb_plane_get_modifiers(struct intel_display *display,
|
||||
u8 plane_caps)
|
||||
{
|
||||
u64 *list, *p;
|
||||
|
|
@ -585,17 +587,17 @@ u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) {
|
||||
if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i]))
|
||||
if (plane_has_modifier(display, plane_caps, &intel_modifiers[i]))
|
||||
count++;
|
||||
}
|
||||
|
||||
list = kmalloc_array(count, sizeof(*list), GFP_KERNEL);
|
||||
if (drm_WARN_ON(&i915->drm, !list))
|
||||
if (drm_WARN_ON(display->drm, !list))
|
||||
return NULL;
|
||||
|
||||
p = list;
|
||||
for (i = 0; i < ARRAY_SIZE(intel_modifiers); i++) {
|
||||
if (plane_has_modifier(i915, plane_caps, &intel_modifiers[i]))
|
||||
if (plane_has_modifier(display, plane_caps, &intel_modifiers[i]))
|
||||
*p++ = intel_modifiers[i].modifier;
|
||||
}
|
||||
*p++ = DRM_FORMAT_MOD_INVALID;
|
||||
|
|
@ -751,33 +753,34 @@ static unsigned int gen12_ccs_aux_stride(struct intel_framebuffer *fb, int ccs_p
|
|||
int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
|
||||
{
|
||||
const struct intel_modifier_desc *md = lookup_modifier(fb->modifier);
|
||||
struct drm_i915_private *i915 = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
|
||||
if (md->ccs.packed_aux_planes | md->ccs.planar_aux_planes)
|
||||
return main_to_ccs_plane(fb, main_plane);
|
||||
else if (DISPLAY_VER(i915) < 11 &&
|
||||
else if (DISPLAY_VER(display) < 11 &&
|
||||
format_is_yuv_semiplanar(md, fb->format))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int intel_tile_size(const struct drm_i915_private *i915)
|
||||
unsigned int intel_tile_size(struct intel_display *display)
|
||||
{
|
||||
return DISPLAY_VER(i915) == 2 ? 2048 : 4096;
|
||||
return DISPLAY_VER(display) == 2 ? 2048 : 4096;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
unsigned int cpp = fb->format->cpp[color_plane];
|
||||
|
||||
switch (fb->modifier) {
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
return intel_tile_size(dev_priv);
|
||||
return intel_tile_size(display);
|
||||
case I915_FORMAT_MOD_X_TILED:
|
||||
if (DISPLAY_VER(dev_priv) == 2)
|
||||
if (DISPLAY_VER(display) == 2)
|
||||
return 128;
|
||||
else
|
||||
return 512;
|
||||
|
|
@ -807,7 +810,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
|
|||
return 64;
|
||||
fallthrough;
|
||||
case I915_FORMAT_MOD_Y_TILED:
|
||||
if (DISPLAY_VER(dev_priv) == 2 || HAS_128_BYTE_Y_TILING(dev_priv))
|
||||
if (DISPLAY_VER(display) == 2 || HAS_128_BYTE_Y_TILING(i915))
|
||||
return 128;
|
||||
else
|
||||
return 512;
|
||||
|
|
@ -838,7 +841,9 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
|
|||
|
||||
unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane)
|
||||
{
|
||||
return intel_tile_size(to_i915(fb->dev)) /
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
|
||||
return intel_tile_size(display) /
|
||||
intel_tile_width_bytes(fb, color_plane);
|
||||
}
|
||||
|
||||
|
|
@ -890,15 +895,17 @@ intel_fb_align_height(const struct drm_framebuffer *fb,
|
|||
return ALIGN(height, tile_height);
|
||||
}
|
||||
|
||||
bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier)
|
||||
bool intel_fb_modifier_uses_dpt(struct intel_display *display, u64 modifier)
|
||||
{
|
||||
return HAS_DPT(i915) && modifier != DRM_FORMAT_MOD_LINEAR;
|
||||
return HAS_DPT(display) && modifier != DRM_FORMAT_MOD_LINEAR;
|
||||
}
|
||||
|
||||
bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
|
||||
{
|
||||
return to_i915(fb->dev)->display.params.enable_dpt &&
|
||||
intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
|
||||
return display->params.enable_dpt &&
|
||||
intel_fb_modifier_uses_dpt(display, fb->modifier);
|
||||
}
|
||||
|
||||
void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
|
||||
|
|
@ -1007,16 +1014,16 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
|
|||
unsigned int pitch,
|
||||
u32 old_offset, u32 new_offset)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
unsigned int cpp = fb->format->cpp[color_plane];
|
||||
|
||||
drm_WARN_ON(&i915->drm, new_offset > old_offset);
|
||||
drm_WARN_ON(display->drm, new_offset > old_offset);
|
||||
|
||||
if (!is_surface_linear(fb, color_plane)) {
|
||||
unsigned int tile_size, tile_width, tile_height;
|
||||
unsigned int pitch_tiles;
|
||||
|
||||
tile_size = intel_tile_size(i915);
|
||||
tile_size = intel_tile_size(display);
|
||||
intel_tile_dims(fb, color_plane, &tile_width, &tile_height);
|
||||
|
||||
if (drm_rotation_90_or_270(rotation)) {
|
||||
|
|
@ -1042,13 +1049,13 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
|
|||
* the x/y offsets.
|
||||
*/
|
||||
u32 intel_plane_adjust_aligned_offset(int *x, int *y,
|
||||
const struct intel_plane_state *state,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane,
|
||||
u32 old_offset, u32 new_offset)
|
||||
{
|
||||
return intel_adjust_aligned_offset(x, y, state->hw.fb, color_plane,
|
||||
state->hw.rotation,
|
||||
state->view.color_plane[color_plane].mapping_stride,
|
||||
return intel_adjust_aligned_offset(x, y, plane_state->hw.fb, color_plane,
|
||||
plane_state->hw.rotation,
|
||||
plane_state->view.color_plane[color_plane].mapping_stride,
|
||||
old_offset, new_offset);
|
||||
}
|
||||
|
||||
|
|
@ -1066,7 +1073,7 @@ u32 intel_plane_adjust_aligned_offset(int *x, int *y,
|
|||
* used. This is why the user has to pass in the pitch since it
|
||||
* is specified in the rotated orientation.
|
||||
*/
|
||||
static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
|
||||
static u32 intel_compute_aligned_offset(struct intel_display *display,
|
||||
int *x, int *y,
|
||||
const struct drm_framebuffer *fb,
|
||||
int color_plane,
|
||||
|
|
@ -1081,7 +1088,7 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
|
|||
unsigned int tile_size, tile_width, tile_height;
|
||||
unsigned int tile_rows, tiles, pitch_tiles;
|
||||
|
||||
tile_size = intel_tile_size(i915);
|
||||
tile_size = intel_tile_size(display);
|
||||
intel_tile_dims(fb, color_plane, &tile_width, &tile_height);
|
||||
|
||||
if (drm_rotation_90_or_270(rotation)) {
|
||||
|
|
@ -1122,17 +1129,17 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *i915,
|
|||
}
|
||||
|
||||
u32 intel_plane_compute_aligned_offset(int *x, int *y,
|
||||
const struct intel_plane_state *state,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(state->uapi.plane);
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
const struct drm_framebuffer *fb = state->hw.fb;
|
||||
unsigned int rotation = state->hw.rotation;
|
||||
unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
unsigned int pitch = plane_state->view.color_plane[color_plane].mapping_stride;
|
||||
unsigned int alignment = plane->min_alignment(plane, fb, color_plane);
|
||||
|
||||
return intel_compute_aligned_offset(i915, x, y, fb, color_plane,
|
||||
return intel_compute_aligned_offset(display, x, y, fb, color_plane,
|
||||
pitch, rotation, alignment);
|
||||
}
|
||||
|
||||
|
|
@ -1141,16 +1148,16 @@ static int intel_fb_offset_to_xy(int *x, int *y,
|
|||
const struct drm_framebuffer *fb,
|
||||
int color_plane)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
unsigned int height, alignment, unused;
|
||||
|
||||
if (fb->modifier != DRM_FORMAT_MOD_LINEAR)
|
||||
alignment = intel_tile_size(i915);
|
||||
alignment = intel_tile_size(display);
|
||||
else
|
||||
alignment = 0;
|
||||
|
||||
if (alignment != 0 && fb->offsets[color_plane] % alignment) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Misaligned offset 0x%08x for color plane %d\n",
|
||||
fb->offsets[color_plane], color_plane);
|
||||
return -EINVAL;
|
||||
|
|
@ -1162,7 +1169,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
|
|||
/* Catch potential overflows early */
|
||||
if (check_add_overflow(mul_u32_u32(height, fb->pitches[color_plane]),
|
||||
fb->offsets[color_plane], &unused)) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"Bad offset 0x%08x or pitch %d for color plane %d\n",
|
||||
fb->offsets[color_plane], fb->pitches[color_plane],
|
||||
color_plane);
|
||||
|
|
@ -1182,7 +1189,7 @@ static int intel_fb_offset_to_xy(int *x, int *y,
|
|||
|
||||
static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane, int x, int y)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
const struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
||||
int main_plane;
|
||||
int hsub, vsub;
|
||||
|
|
@ -1216,13 +1223,12 @@ static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane
|
|||
* x/y offsets must match between CCS and the main surface.
|
||||
*/
|
||||
if (main_x != ccs_x || main_y != ccs_y) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
"Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
|
||||
main_x, main_y,
|
||||
ccs_x, ccs_y,
|
||||
intel_fb->normal_view.color_plane[main_plane].x,
|
||||
intel_fb->normal_view.color_plane[main_plane].y,
|
||||
x, y);
|
||||
drm_dbg_kms(display->drm,
|
||||
"Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
|
||||
main_x, main_y, ccs_x, ccs_y,
|
||||
intel_fb->normal_view.color_plane[main_plane].x,
|
||||
intel_fb->normal_view.color_plane[main_plane].y,
|
||||
x, y);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -1231,8 +1237,8 @@ static int intel_fb_check_ccs_xy(const struct drm_framebuffer *fb, int ccs_plane
|
|||
|
||||
static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *i915 = to_i915(plane->base.dev);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
int i;
|
||||
|
||||
|
|
@ -1246,7 +1252,7 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
|
|||
* Would also need to deal with the fence POT alignment
|
||||
* and gen2 2KiB GTT tile size.
|
||||
*/
|
||||
if (DISPLAY_VER(i915) < 4)
|
||||
if (DISPLAY_VER(display) < 4)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
@ -1258,7 +1264,7 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
|
|||
|
||||
/* Linear needs a page aligned stride for remapping */
|
||||
if (fb->modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
unsigned int alignment = intel_tile_size(i915) - 1;
|
||||
unsigned int alignment = intel_tile_size(display) - 1;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (fb->pitches[i] & alignment)
|
||||
|
|
@ -1271,12 +1277,22 @@ static bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
|
|||
|
||||
bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->base.dev);
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
|
||||
return (IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) &&
|
||||
return (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) &&
|
||||
intel_fb_uses_dpt(&fb->base);
|
||||
}
|
||||
|
||||
bool intel_plane_uses_fence(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
||||
|
||||
return DISPLAY_VER(dev_priv) < 4 ||
|
||||
(plane->fbc && !plane_state->no_fbc_reason &&
|
||||
plane_state->view.gtt.type == I915_GTT_VIEW_NORMAL);
|
||||
}
|
||||
|
||||
static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation)
|
||||
{
|
||||
if (drm_rotation_90_or_270(rotation))
|
||||
|
|
@ -1318,12 +1334,13 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
|
|||
static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int color_plane,
|
||||
int plane_width, int *x, int *y)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
struct drm_gem_object *obj = intel_fb_bo(&fb->base);
|
||||
int ret;
|
||||
|
||||
ret = intel_fb_offset_to_xy(x, y, &fb->base, color_plane);
|
||||
if (ret) {
|
||||
drm_dbg_kms(fb->base.dev,
|
||||
drm_dbg_kms(display->drm,
|
||||
"bad fb plane %d offset: 0x%x\n",
|
||||
color_plane, fb->base.offsets[color_plane]);
|
||||
return ret;
|
||||
|
|
@ -1344,7 +1361,7 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co
|
|||
*/
|
||||
if (color_plane == 0 && intel_bo_is_tiled(obj) &&
|
||||
(*x + plane_width) * fb->base.format->cpp[color_plane] > fb->base.pitches[color_plane]) {
|
||||
drm_dbg_kms(fb->base.dev,
|
||||
drm_dbg_kms(display->drm,
|
||||
"bad fb plane %d offset: 0x%x\n",
|
||||
color_plane, fb->base.offsets[color_plane]);
|
||||
return -EINVAL;
|
||||
|
|
@ -1355,11 +1372,11 @@ static int convert_plane_offset_to_xy(const struct intel_framebuffer *fb, int co
|
|||
|
||||
static u32 calc_plane_aligned_offset(const struct intel_framebuffer *fb, int color_plane, int *x, int *y)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->base.dev);
|
||||
unsigned int tile_size = intel_tile_size(i915);
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
unsigned int tile_size = intel_tile_size(display);
|
||||
u32 offset;
|
||||
|
||||
offset = intel_compute_aligned_offset(i915, x, y, &fb->base, color_plane,
|
||||
offset = intel_compute_aligned_offset(display, x, y, &fb->base, color_plane,
|
||||
fb->base.pitches[color_plane],
|
||||
DRM_MODE_ROTATE_0,
|
||||
tile_size);
|
||||
|
|
@ -1410,10 +1427,10 @@ plane_view_scanout_stride(const struct intel_framebuffer *fb, int color_plane,
|
|||
unsigned int tile_width,
|
||||
unsigned int src_stride_tiles, unsigned int dst_stride_tiles)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->base.dev);
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
unsigned int stride_tiles;
|
||||
|
||||
if ((IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14) &&
|
||||
if ((display->platform.alderlake_p || DISPLAY_VER(display) >= 14) &&
|
||||
src_stride_tiles < dst_stride_tiles)
|
||||
stride_tiles = src_stride_tiles;
|
||||
else
|
||||
|
|
@ -1443,23 +1460,23 @@ plane_view_linear_tiles(const struct intel_framebuffer *fb, int color_plane,
|
|||
const struct fb_plane_view_dims *dims,
|
||||
int x, int y)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->base.dev);
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
unsigned int size;
|
||||
|
||||
size = (y + dims->height) * fb->base.pitches[color_plane] +
|
||||
x * fb->base.format->cpp[color_plane];
|
||||
|
||||
return DIV_ROUND_UP(size, intel_tile_size(i915));
|
||||
return DIV_ROUND_UP(size, intel_tile_size(display));
|
||||
}
|
||||
|
||||
#define assign_chk_ovf(i915, var, val) ({ \
|
||||
drm_WARN_ON(&(i915)->drm, overflows_type(val, var)); \
|
||||
#define assign_chk_ovf(display, var, val) ({ \
|
||||
drm_WARN_ON((display)->drm, overflows_type(val, var)); \
|
||||
(var) = (val); \
|
||||
})
|
||||
|
||||
#define assign_bfld_chk_ovf(i915, var, val) ({ \
|
||||
#define assign_bfld_chk_ovf(display, var, val) ({ \
|
||||
(var) = (val); \
|
||||
drm_WARN_ON(&(i915)->drm, (var) != (val)); \
|
||||
drm_WARN_ON((display)->drm, (var) != (val)); \
|
||||
(var); \
|
||||
})
|
||||
|
||||
|
|
@ -1468,38 +1485,38 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
u32 obj_offset, u32 gtt_offset, int x, int y,
|
||||
struct intel_fb_view *view)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->base.dev);
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
struct intel_remapped_plane_info *remap_info = &view->gtt.remapped.plane[color_plane];
|
||||
struct i915_color_plane_view *color_plane_info = &view->color_plane[color_plane];
|
||||
unsigned int tile_width = dims->tile_width;
|
||||
unsigned int tile_height = dims->tile_height;
|
||||
unsigned int tile_size = intel_tile_size(i915);
|
||||
unsigned int tile_size = intel_tile_size(display);
|
||||
struct drm_rect r;
|
||||
u32 size = 0;
|
||||
|
||||
assign_bfld_chk_ovf(i915, remap_info->offset, obj_offset);
|
||||
assign_bfld_chk_ovf(display, remap_info->offset, obj_offset);
|
||||
|
||||
if (intel_fb_is_gen12_ccs_aux_plane(&fb->base, color_plane)) {
|
||||
remap_info->linear = 1;
|
||||
|
||||
assign_chk_ovf(i915, remap_info->size,
|
||||
assign_chk_ovf(display, remap_info->size,
|
||||
plane_view_linear_tiles(fb, color_plane, dims, x, y));
|
||||
} else {
|
||||
remap_info->linear = 0;
|
||||
|
||||
assign_chk_ovf(i915, remap_info->src_stride,
|
||||
assign_chk_ovf(display, remap_info->src_stride,
|
||||
plane_view_src_stride_tiles(fb, color_plane, dims));
|
||||
assign_chk_ovf(i915, remap_info->width,
|
||||
assign_chk_ovf(display, remap_info->width,
|
||||
plane_view_width_tiles(fb, color_plane, dims, x));
|
||||
assign_chk_ovf(i915, remap_info->height,
|
||||
assign_chk_ovf(display, remap_info->height,
|
||||
plane_view_height_tiles(fb, color_plane, dims, y));
|
||||
}
|
||||
|
||||
if (view->gtt.type == I915_GTT_VIEW_ROTATED) {
|
||||
drm_WARN_ON(&i915->drm, remap_info->linear);
|
||||
check_array_bounds(i915, view->gtt.rotated.plane, color_plane);
|
||||
drm_WARN_ON(display->drm, remap_info->linear);
|
||||
check_array_bounds(display, view->gtt.rotated.plane, color_plane);
|
||||
|
||||
assign_chk_ovf(i915, remap_info->dst_stride,
|
||||
assign_chk_ovf(display, remap_info->dst_stride,
|
||||
plane_view_dst_stride_tiles(fb, color_plane, remap_info->height));
|
||||
|
||||
/* rotate the x/y offsets to match the GTT view */
|
||||
|
|
@ -1520,9 +1537,9 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
/* rotate the tile dimensions to match the GTT view */
|
||||
swap(tile_width, tile_height);
|
||||
} else {
|
||||
drm_WARN_ON(&i915->drm, view->gtt.type != I915_GTT_VIEW_REMAPPED);
|
||||
drm_WARN_ON(display->drm, view->gtt.type != I915_GTT_VIEW_REMAPPED);
|
||||
|
||||
check_array_bounds(i915, view->gtt.remapped.plane, color_plane);
|
||||
check_array_bounds(display, view->gtt.remapped.plane, color_plane);
|
||||
|
||||
if (view->gtt.remapped.plane_alignment) {
|
||||
u32 aligned_offset = ALIGN(gtt_offset,
|
||||
|
|
@ -1556,7 +1573,7 @@ static u32 calc_plane_remap_info(const struct intel_framebuffer *fb, int color_p
|
|||
|
||||
dst_stride = plane_view_dst_stride_tiles(fb, color_plane, dst_stride);
|
||||
|
||||
assign_chk_ovf(i915, remap_info->dst_stride, dst_stride);
|
||||
assign_chk_ovf(display, remap_info->dst_stride, dst_stride);
|
||||
color_plane_info->mapping_stride = dst_stride *
|
||||
tile_width *
|
||||
fb->base.format->cpp[color_plane];
|
||||
|
|
@ -1614,20 +1631,23 @@ calc_plane_normal_size(const struct intel_framebuffer *fb, int color_plane,
|
|||
return tiles;
|
||||
}
|
||||
|
||||
static void intel_fb_view_init(struct drm_i915_private *i915, struct intel_fb_view *view,
|
||||
static void intel_fb_view_init(struct intel_display *display,
|
||||
struct intel_fb_view *view,
|
||||
enum i915_gtt_view_type view_type)
|
||||
{
|
||||
memset(view, 0, sizeof(*view));
|
||||
view->gtt.type = view_type;
|
||||
|
||||
if (view_type == I915_GTT_VIEW_REMAPPED &&
|
||||
(IS_ALDERLAKE_P(i915) || DISPLAY_VER(i915) >= 14))
|
||||
(display->platform.alderlake_p || DISPLAY_VER(display) >= 14))
|
||||
view->gtt.remapped.plane_alignment = SZ_2M / PAGE_SIZE;
|
||||
}
|
||||
|
||||
bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
|
||||
{
|
||||
if (DISPLAY_VER(to_i915(fb->base.dev)) >= 13)
|
||||
struct intel_display *display = to_intel_display(fb->base.dev);
|
||||
|
||||
if (DISPLAY_VER(display) >= 13)
|
||||
return false;
|
||||
|
||||
return fb->base.modifier == I915_FORMAT_MOD_Y_TILED ||
|
||||
|
|
@ -1636,11 +1656,11 @@ bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb)
|
|||
|
||||
static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
struct intel_plane *plane;
|
||||
unsigned int min_alignment = 0;
|
||||
|
||||
for_each_intel_plane(&i915->drm, plane) {
|
||||
for_each_intel_plane(display->drm, plane) {
|
||||
unsigned int plane_min_alignment;
|
||||
|
||||
if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
|
||||
|
|
@ -1648,7 +1668,7 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
|
|||
|
||||
plane_min_alignment = plane->min_alignment(plane, fb, 0);
|
||||
|
||||
drm_WARN_ON(&i915->drm, plane_min_alignment &&
|
||||
drm_WARN_ON(display->drm, plane_min_alignment &&
|
||||
!is_power_of_2(plane_min_alignment));
|
||||
|
||||
if (intel_plane_needs_physical(plane))
|
||||
|
|
@ -1660,25 +1680,41 @@ static unsigned int intel_fb_min_alignment(const struct drm_framebuffer *fb)
|
|||
return min_alignment;
|
||||
}
|
||||
|
||||
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb)
|
||||
static unsigned int intel_fb_vtd_guard(const struct drm_framebuffer *fb)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
struct intel_plane *plane;
|
||||
unsigned int vtd_guard = 0;
|
||||
|
||||
for_each_intel_plane(display->drm, plane) {
|
||||
if (!drm_plane_has_format(&plane->base, fb->format->format, fb->modifier))
|
||||
continue;
|
||||
|
||||
vtd_guard = max_t(unsigned int, vtd_guard, plane->vtd_guard);
|
||||
}
|
||||
|
||||
return vtd_guard;
|
||||
}
|
||||
|
||||
int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb)
|
||||
{
|
||||
struct drm_gem_object *obj = intel_fb_bo(&fb->base);
|
||||
u32 gtt_offset_rotated = 0;
|
||||
u32 gtt_offset_remapped = 0;
|
||||
unsigned int max_size = 0;
|
||||
int i, num_planes = fb->base.format->num_planes;
|
||||
unsigned int tile_size = intel_tile_size(i915);
|
||||
unsigned int tile_size = intel_tile_size(display);
|
||||
|
||||
intel_fb_view_init(i915, &fb->normal_view, I915_GTT_VIEW_NORMAL);
|
||||
intel_fb_view_init(display, &fb->normal_view, I915_GTT_VIEW_NORMAL);
|
||||
|
||||
drm_WARN_ON(&i915->drm,
|
||||
drm_WARN_ON(display->drm,
|
||||
intel_fb_supports_90_270_rotation(fb) &&
|
||||
intel_fb_needs_pot_stride_remap(fb));
|
||||
|
||||
if (intel_fb_supports_90_270_rotation(fb))
|
||||
intel_fb_view_init(i915, &fb->rotated_view, I915_GTT_VIEW_ROTATED);
|
||||
intel_fb_view_init(display, &fb->rotated_view, I915_GTT_VIEW_ROTATED);
|
||||
if (intel_fb_needs_pot_stride_remap(fb))
|
||||
intel_fb_view_init(i915, &fb->remapped_view, I915_GTT_VIEW_REMAPPED);
|
||||
intel_fb_view_init(display, &fb->remapped_view, I915_GTT_VIEW_REMAPPED);
|
||||
|
||||
for (i = 0; i < num_planes; i++) {
|
||||
struct fb_plane_view_dims view_dims;
|
||||
|
|
@ -1694,10 +1730,24 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
|
|||
* arithmetic related to alignment and offset calculation.
|
||||
*/
|
||||
if (is_gen12_ccs_cc_plane(&fb->base, i)) {
|
||||
if (IS_ALIGNED(fb->base.offsets[i], 64))
|
||||
continue;
|
||||
else
|
||||
unsigned int end;
|
||||
|
||||
if (!IS_ALIGNED(fb->base.offsets[i], 64)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"fb misaligned clear color plane %d offset (0x%x)\n",
|
||||
i, fb->base.offsets[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (check_add_overflow(fb->base.offsets[i], 64, &end)) {
|
||||
drm_dbg_kms(display->drm,
|
||||
"fb bad clear color plane %d offset (0x%x)\n",
|
||||
i, fb->base.offsets[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
max_size = max(max_size, DIV_ROUND_UP(end, tile_size));
|
||||
continue;
|
||||
}
|
||||
|
||||
intel_fb_plane_dims(fb, i, &width, &height);
|
||||
|
|
@ -1736,21 +1786,52 @@ int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *
|
|||
}
|
||||
|
||||
if (mul_u32_u32(max_size, tile_size) > obj->size) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"fb too big for bo (need %llu bytes, have %zu bytes)\n",
|
||||
mul_u32_u32(max_size, tile_size), obj->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fb->min_alignment = intel_fb_min_alignment(&fb->base);
|
||||
fb->vtd_guard = intel_fb_vtd_guard(&fb->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb,
|
||||
const struct intel_fb_view *view,
|
||||
unsigned int rotation)
|
||||
{
|
||||
unsigned int vtd_guard;
|
||||
int color_plane;
|
||||
|
||||
vtd_guard = to_intel_framebuffer(fb)->vtd_guard;
|
||||
if (!vtd_guard)
|
||||
return 0;
|
||||
|
||||
for (color_plane = 0; color_plane < fb->format->num_planes; color_plane++) {
|
||||
unsigned int stride, tile;
|
||||
|
||||
if (intel_fb_is_ccs_aux_plane(fb, color_plane) ||
|
||||
is_gen12_ccs_cc_plane(fb, color_plane))
|
||||
continue;
|
||||
|
||||
stride = view->color_plane[color_plane].mapping_stride;
|
||||
|
||||
if (drm_rotation_90_or_270(rotation))
|
||||
tile = intel_tile_height(fb, color_plane);
|
||||
else
|
||||
tile = intel_tile_width_bytes(fb, color_plane);
|
||||
|
||||
vtd_guard = max(vtd_guard, DIV_ROUND_UP(stride, tile));
|
||||
}
|
||||
|
||||
return vtd_guard;
|
||||
}
|
||||
|
||||
static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct drm_i915_private *i915 =
|
||||
to_i915(plane_state->uapi.plane->dev);
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
|
|
@ -1759,7 +1840,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
|
|||
unsigned int src_w, src_h;
|
||||
u32 gtt_offset = 0;
|
||||
|
||||
intel_fb_view_init(i915, &plane_state->view,
|
||||
intel_fb_view_init(display, &plane_state->view,
|
||||
drm_rotation_90_or_270(rotation) ? I915_GTT_VIEW_ROTATED :
|
||||
I915_GTT_VIEW_REMAPPED);
|
||||
|
||||
|
|
@ -1768,7 +1849,7 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
|
|||
src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
|
||||
src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
|
||||
|
||||
drm_WARN_ON(&i915->drm, intel_fb_is_ccs_modifier(fb->modifier));
|
||||
drm_WARN_ON(display->drm, intel_fb_is_ccs_modifier(fb->modifier));
|
||||
|
||||
/* Make src coordinates relative to the viewport */
|
||||
drm_rect_translate(&plane_state->uapi.src,
|
||||
|
|
@ -1810,6 +1891,42 @@ static void intel_plane_remap_gtt(struct intel_plane_state *plane_state)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info)
|
||||
{
|
||||
unsigned int size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++)
|
||||
size += rot_info->plane[i].dst_stride * rot_info->plane[i].width;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info)
|
||||
{
|
||||
unsigned int size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
|
||||
unsigned int plane_size;
|
||||
|
||||
if (rem_info->plane[i].linear)
|
||||
plane_size = rem_info->plane[i].size;
|
||||
else
|
||||
plane_size = rem_info->plane[i].dst_stride * rem_info->plane[i].height;
|
||||
|
||||
if (plane_size == 0)
|
||||
continue;
|
||||
|
||||
if (rem_info->plane_alignment)
|
||||
size = ALIGN(size, rem_info->plane_alignment);
|
||||
|
||||
size += plane_size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation,
|
||||
struct intel_fb_view *view)
|
||||
{
|
||||
|
|
@ -1821,8 +1938,39 @@ void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotatio
|
|||
*view = fb->normal_view;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the x/y offsets into a linear offset.
|
||||
* Only valid with 0/180 degree rotation, which is fine since linear
|
||||
* offset is only used with linear buffers on pre-hsw and tiled buffers
|
||||
* with gen2/3, and 90/270 degree rotations isn't supported on any of them.
|
||||
*/
|
||||
u32 intel_fb_xy_to_linear(int x, int y,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
unsigned int cpp = fb->format->cpp[color_plane];
|
||||
unsigned int pitch = plane_state->view.color_plane[color_plane].mapping_stride;
|
||||
|
||||
return y * pitch + x * cpp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the x/y offsets derived from fb->offsets[] to the user
|
||||
* specified plane src x/y offsets. The resulting x/y offsets
|
||||
* specify the start of scanout from the beginning of the gtt mapping.
|
||||
*/
|
||||
void intel_add_fb_offsets(int *x, int *y,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane)
|
||||
|
||||
{
|
||||
*x += plane_state->view.color_plane[color_plane].x;
|
||||
*y += plane_state->view.color_plane[color_plane].y;
|
||||
}
|
||||
|
||||
static
|
||||
u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
|
||||
u32 intel_fb_max_stride(struct intel_display *display,
|
||||
u32 pixel_format, u64 modifier)
|
||||
{
|
||||
/*
|
||||
|
|
@ -1831,10 +1979,10 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
|
|||
*
|
||||
* The new CCS hash mode makes remapping impossible
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) < 4 || intel_fb_is_ccs_modifier(modifier) ||
|
||||
intel_fb_modifier_uses_dpt(dev_priv, modifier))
|
||||
return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier);
|
||||
else if (DISPLAY_VER(dev_priv) >= 7)
|
||||
if (DISPLAY_VER(display) < 4 || intel_fb_is_ccs_modifier(modifier) ||
|
||||
intel_fb_modifier_uses_dpt(display, modifier))
|
||||
return intel_plane_fb_max_stride(display->drm, pixel_format, modifier);
|
||||
else if (DISPLAY_VER(display) >= 7)
|
||||
return 256 * 1024;
|
||||
else
|
||||
return 128 * 1024;
|
||||
|
|
@ -1843,11 +1991,11 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv,
|
|||
static unsigned int
|
||||
intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(fb->dev);
|
||||
struct intel_display *display = to_intel_display(fb->dev);
|
||||
unsigned int tile_width;
|
||||
|
||||
if (is_surface_linear(fb, color_plane)) {
|
||||
unsigned int max_stride = intel_plane_fb_max_stride(dev_priv,
|
||||
unsigned int max_stride = intel_plane_fb_max_stride(display->drm,
|
||||
fb->format->format,
|
||||
fb->modifier);
|
||||
|
||||
|
|
@ -1857,7 +2005,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
|||
*/
|
||||
if (fb->pitches[color_plane] > max_stride &&
|
||||
!intel_fb_is_ccs_modifier(fb->modifier))
|
||||
return intel_tile_size(dev_priv);
|
||||
return intel_tile_size(display);
|
||||
else
|
||||
return 64;
|
||||
}
|
||||
|
|
@ -1868,7 +2016,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
|||
* On TGL the surface stride must be 4 tile aligned, mapped by
|
||||
* one 64 byte cacheline on the CCS AUX surface.
|
||||
*/
|
||||
if (DISPLAY_VER(dev_priv) >= 12)
|
||||
if (DISPLAY_VER(display) >= 12)
|
||||
tile_width *= 4;
|
||||
/*
|
||||
* Display WA #0531: skl,bxt,kbl,glk
|
||||
|
|
@ -1879,7 +2027,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
|||
* require the entire fb to accommodate that to avoid
|
||||
* potential runtime errors at plane configuration time.
|
||||
*/
|
||||
else if ((DISPLAY_VER(dev_priv) == 9 || IS_GEMINILAKE(dev_priv)) &&
|
||||
else if ((DISPLAY_VER(display) == 9 || display->platform.geminilake) &&
|
||||
color_plane == 0 && fb->width > 3840)
|
||||
tile_width *= 4;
|
||||
}
|
||||
|
|
@ -1888,6 +2036,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
|
|||
|
||||
static int intel_plane_check_stride(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(plane_state);
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct drm_framebuffer *fb = plane_state->hw.fb;
|
||||
unsigned int rotation = plane_state->hw.rotation;
|
||||
|
|
@ -1909,7 +2058,7 @@ static int intel_plane_check_stride(const struct intel_plane_state *plane_state)
|
|||
fb->modifier, rotation);
|
||||
|
||||
if (stride > max_stride) {
|
||||
drm_dbg_kms(plane->base.dev,
|
||||
drm_dbg_kms(display->drm,
|
||||
"[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
|
||||
fb->base.id, stride,
|
||||
plane->base.base.id, plane->base.name, max_stride);
|
||||
|
|
@ -2058,13 +2207,13 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
struct drm_gem_object *obj,
|
||||
struct drm_mode_fb_cmd2 *mode_cmd)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(obj->dev);
|
||||
struct intel_display *display = to_intel_display(obj->dev);
|
||||
struct drm_framebuffer *fb = &intel_fb->base;
|
||||
u32 max_stride;
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
|
||||
ret = intel_fb_bo_framebuffer_init(intel_fb, obj, mode_cmd);
|
||||
ret = intel_fb_bo_framebuffer_init(fb, obj, mode_cmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -2075,19 +2224,19 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (!drm_any_plane_has_format(&dev_priv->drm,
|
||||
if (!drm_any_plane_has_format(display->drm,
|
||||
mode_cmd->pixel_format,
|
||||
mode_cmd->modifier[0])) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"unsupported pixel format %p4cc / modifier 0x%llx\n",
|
||||
&mode_cmd->pixel_format, mode_cmd->modifier[0]);
|
||||
goto err_frontbuffer_put;
|
||||
}
|
||||
|
||||
max_stride = intel_fb_max_stride(dev_priv, mode_cmd->pixel_format,
|
||||
max_stride = intel_fb_max_stride(display, mode_cmd->pixel_format,
|
||||
mode_cmd->modifier[0]);
|
||||
if (mode_cmd->pitches[0] > max_stride) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"%s pitch (%u) must be at most %d\n",
|
||||
mode_cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR ?
|
||||
"tiled" : "linear",
|
||||
|
|
@ -2097,26 +2246,25 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
|
||||
/* FIXME need to adjust LINOFF/TILEOFF accordingly. */
|
||||
if (mode_cmd->offsets[0] != 0) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane 0 offset (0x%08x) must be 0\n",
|
||||
mode_cmd->offsets[0]);
|
||||
goto err_frontbuffer_put;
|
||||
}
|
||||
|
||||
drm_helper_mode_fill_fb_struct(&dev_priv->drm, fb, mode_cmd);
|
||||
drm_helper_mode_fill_fb_struct(display->drm, fb, mode_cmd);
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
unsigned int stride_alignment;
|
||||
|
||||
if (mode_cmd->handles[i] != mode_cmd->handles[0]) {
|
||||
drm_dbg_kms(&dev_priv->drm, "bad plane %d handle\n",
|
||||
i);
|
||||
drm_dbg_kms(display->drm, "bad plane %d handle\n", i);
|
||||
goto err_frontbuffer_put;
|
||||
}
|
||||
|
||||
stride_alignment = intel_fb_stride_alignment(fb, i);
|
||||
if (fb->pitches[i] & (stride_alignment - 1)) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"plane %d pitch (%d) must be at least %u byte aligned\n",
|
||||
i, fb->pitches[i], stride_alignment);
|
||||
goto err_frontbuffer_put;
|
||||
|
|
@ -2126,10 +2274,9 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
unsigned int ccs_aux_stride = gen12_ccs_aux_stride(intel_fb, i);
|
||||
|
||||
if (fb->pitches[i] != ccs_aux_stride) {
|
||||
drm_dbg_kms(&dev_priv->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"ccs aux plane %d pitch (%d) must be %d\n",
|
||||
i,
|
||||
fb->pitches[i], ccs_aux_stride);
|
||||
i, fb->pitches[i], ccs_aux_stride);
|
||||
goto err_frontbuffer_put;
|
||||
}
|
||||
}
|
||||
|
|
@ -2137,7 +2284,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
fb->obj[i] = obj;
|
||||
}
|
||||
|
||||
ret = intel_fill_fb_info(dev_priv, intel_fb);
|
||||
ret = intel_fill_fb_info(display, intel_fb);
|
||||
if (ret)
|
||||
goto err_frontbuffer_put;
|
||||
|
||||
|
|
@ -2146,7 +2293,7 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
|
||||
vm = intel_dpt_create(intel_fb);
|
||||
if (IS_ERR(vm)) {
|
||||
drm_dbg_kms(&dev_priv->drm, "failed to create DPT\n");
|
||||
drm_dbg_kms(display->drm, "failed to create DPT\n");
|
||||
ret = PTR_ERR(vm);
|
||||
goto err_frontbuffer_put;
|
||||
}
|
||||
|
|
@ -2154,9 +2301,9 @@ int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
intel_fb->dpt_vm = vm;
|
||||
}
|
||||
|
||||
ret = drm_framebuffer_init(&dev_priv->drm, fb, &intel_fb_funcs);
|
||||
ret = drm_framebuffer_init(display->drm, fb, &intel_fb_funcs);
|
||||
if (ret) {
|
||||
drm_err(&dev_priv->drm, "framebuffer init failed %d\n", ret);
|
||||
drm_err(display->drm, "framebuffer init failed %d\n", ret);
|
||||
goto err_free_dpt;
|
||||
}
|
||||
|
||||
|
|
@ -2180,9 +2327,8 @@ intel_user_framebuffer_create(struct drm_device *dev,
|
|||
struct drm_framebuffer *fb;
|
||||
struct drm_gem_object *obj;
|
||||
struct drm_mode_fb_cmd2 mode_cmd = *user_mode_cmd;
|
||||
struct drm_i915_private *i915 = to_i915(dev);
|
||||
|
||||
obj = intel_fb_bo_lookup_valid_bo(i915, filp, &mode_cmd);
|
||||
obj = intel_fb_bo_lookup_valid_bo(dev, filp, &mode_cmd);
|
||||
if (IS_ERR(obj))
|
||||
return ERR_CAST(obj);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,14 @@ struct drm_device;
|
|||
struct drm_file;
|
||||
struct drm_framebuffer;
|
||||
struct drm_gem_object;
|
||||
struct drm_i915_gem_object;
|
||||
struct drm_i915_private;
|
||||
struct drm_mode_fb_cmd2;
|
||||
struct intel_display;
|
||||
struct intel_fb_view;
|
||||
struct intel_framebuffer;
|
||||
struct intel_plane;
|
||||
struct intel_plane_state;
|
||||
struct intel_remapped_info;
|
||||
struct intel_rotation_info;
|
||||
|
||||
#define INTEL_PLANE_CAP_NONE 0
|
||||
#define INTEL_PLANE_CAP_CCS_RC BIT(0)
|
||||
|
|
@ -41,7 +42,7 @@ bool intel_fb_is_tile4_modifier(u64 modifier);
|
|||
bool intel_fb_is_ccs_aux_plane(const struct drm_framebuffer *fb, int color_plane);
|
||||
int intel_fb_rc_ccs_cc_plane(const struct drm_framebuffer *fb);
|
||||
|
||||
u64 *intel_fb_plane_get_modifiers(struct drm_i915_private *i915,
|
||||
u64 *intel_fb_plane_get_modifiers(struct intel_display *display,
|
||||
u8 plane_caps);
|
||||
bool intel_fb_plane_supports_modifier(struct intel_plane *plane, u64 modifier);
|
||||
|
||||
|
|
@ -58,7 +59,7 @@ int main_to_ccs_plane(const struct drm_framebuffer *fb, int main_plane);
|
|||
int skl_ccs_to_main_plane(const struct drm_framebuffer *fb, int ccs_plane);
|
||||
int skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane);
|
||||
|
||||
unsigned int intel_tile_size(const struct drm_i915_private *i915);
|
||||
unsigned int intel_tile_size(struct intel_display *display);
|
||||
unsigned int intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane);
|
||||
unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane);
|
||||
unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane);
|
||||
|
|
@ -70,21 +71,35 @@ void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
|
|||
int color_plane);
|
||||
|
||||
u32 intel_plane_adjust_aligned_offset(int *x, int *y,
|
||||
const struct intel_plane_state *state,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane,
|
||||
u32 old_offset, u32 new_offset);
|
||||
u32 intel_plane_compute_aligned_offset(int *x, int *y,
|
||||
const struct intel_plane_state *state,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane);
|
||||
|
||||
bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb);
|
||||
bool intel_plane_uses_fence(const struct intel_plane_state *plane_state);
|
||||
bool intel_fb_supports_90_270_rotation(const struct intel_framebuffer *fb);
|
||||
|
||||
int intel_fill_fb_info(struct drm_i915_private *i915, struct intel_framebuffer *fb);
|
||||
unsigned int intel_rotation_info_size(const struct intel_rotation_info *rot_info);
|
||||
unsigned int intel_remapped_info_size(const struct intel_remapped_info *rem_info);
|
||||
|
||||
int intel_fill_fb_info(struct intel_display *display, struct intel_framebuffer *fb);
|
||||
void intel_fb_fill_view(const struct intel_framebuffer *fb, unsigned int rotation,
|
||||
struct intel_fb_view *view);
|
||||
unsigned int intel_fb_view_vtd_guard(const struct drm_framebuffer *fb,
|
||||
const struct intel_fb_view *view,
|
||||
unsigned int rotation);
|
||||
int intel_plane_compute_gtt(struct intel_plane_state *plane_state);
|
||||
|
||||
unsigned int intel_fb_xy_to_linear(int x, int y,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane);
|
||||
void intel_add_fb_offsets(int *x, int *y,
|
||||
const struct intel_plane_state *plane_state,
|
||||
int color_plane);
|
||||
|
||||
int intel_framebuffer_init(struct intel_framebuffer *ifb,
|
||||
struct drm_gem_object *obj,
|
||||
struct drm_mode_fb_cmd2 *mode_cmd);
|
||||
|
|
@ -96,7 +111,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
|
|||
struct drm_file *filp,
|
||||
const struct drm_mode_fb_cmd2 *user_mode_cmd);
|
||||
|
||||
bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier);
|
||||
bool intel_fb_modifier_uses_dpt(struct intel_display *display, u64 modifier);
|
||||
bool intel_fb_uses_dpt(const struct drm_framebuffer *fb);
|
||||
|
||||
unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "gem/i915_gem_object.h"
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_fb.h"
|
||||
#include "intel_fb_bo.h"
|
||||
|
||||
|
|
@ -16,12 +17,12 @@ void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj)
|
|||
/* Nothing to do for i915 */
|
||||
}
|
||||
|
||||
int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb,
|
||||
struct drm_gem_object *_obj,
|
||||
struct drm_mode_fb_cmd2 *mode_cmd)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
|
||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||
struct intel_display *display = to_intel_display(obj->base.dev);
|
||||
unsigned int tiling, stride;
|
||||
|
||||
i915_gem_object_lock(obj, NULL);
|
||||
|
|
@ -36,7 +37,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
*/
|
||||
if (tiling != I915_TILING_NONE &&
|
||||
tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"tiling_mode doesn't match fb modifier\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
if (tiling == I915_TILING_X) {
|
||||
mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
|
||||
} else if (tiling == I915_TILING_Y) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"No Y tiling for legacy addfb\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -54,9 +55,9 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
* gen2/3 display engine uses the fence if present,
|
||||
* so the tiling mode must match the fb modifier exactly.
|
||||
*/
|
||||
if (DISPLAY_VER(i915) < 4 &&
|
||||
if (DISPLAY_VER(display) < 4 &&
|
||||
tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"tiling_mode must match fb modifier exactly on gen2/3\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -66,7 +67,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
* the fb pitch and fence stride match.
|
||||
*/
|
||||
if (tiling != I915_TILING_NONE && mode_cmd->pitches[0] != stride) {
|
||||
drm_dbg_kms(&i915->drm,
|
||||
drm_dbg_kms(display->drm,
|
||||
"pitch (%d) must match tiling stride (%d)\n",
|
||||
mode_cmd->pitches[0], stride);
|
||||
return -EINVAL;
|
||||
|
|
@ -76,10 +77,11 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
|||
}
|
||||
|
||||
struct drm_gem_object *
|
||||
intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
|
||||
intel_fb_bo_lookup_valid_bo(struct drm_device *drm,
|
||||
struct drm_file *filp,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(drm);
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
||||
obj = i915_gem_object_lookup(filp, mode_cmd->handles[0]);
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@
|
|||
#ifndef __INTEL_FB_BO_H__
|
||||
#define __INTEL_FB_BO_H__
|
||||
|
||||
struct drm_device;
|
||||
struct drm_file;
|
||||
struct drm_framebuffer;
|
||||
struct drm_gem_object;
|
||||
struct drm_i915_private;
|
||||
struct drm_mode_fb_cmd2;
|
||||
struct intel_framebuffer;
|
||||
|
||||
void intel_fb_bo_framebuffer_fini(struct drm_gem_object *obj);
|
||||
|
||||
int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
|
||||
int intel_fb_bo_framebuffer_init(struct drm_framebuffer *fb,
|
||||
struct drm_gem_object *obj,
|
||||
struct drm_mode_fb_cmd2 *mode_cmd);
|
||||
|
||||
struct drm_gem_object *
|
||||
intel_fb_bo_lookup_valid_bo(struct drm_i915_private *i915,
|
||||
intel_fb_bo_lookup_valid_bo(struct drm_device *drm,
|
||||
struct drm_file *filp,
|
||||
const struct drm_mode_fb_cmd2 *user_mode_cmd);
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
|
|||
const struct i915_gtt_view *view,
|
||||
unsigned int alignment,
|
||||
unsigned int phys_alignment,
|
||||
unsigned int vtd_guard,
|
||||
bool uses_fence,
|
||||
unsigned long *out_flags)
|
||||
{
|
||||
|
|
@ -126,14 +127,6 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
|
|||
if (drm_WARN_ON(dev, alignment && !is_power_of_2(alignment)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Note that the w/a also requires 64 PTE of padding following the
|
||||
* bo. We currently fill all unused PTE with the shadow page and so
|
||||
* we should always have valid PTE following the scanout preventing
|
||||
* the VT-d warning.
|
||||
*/
|
||||
if (intel_scanout_needs_vtd_wa(dev_priv) && alignment < 256 * 1024)
|
||||
alignment = 256 * 1024;
|
||||
|
||||
/*
|
||||
* Global gtt pte registers are special registers which actually forward
|
||||
* writes to a chunk of system memory. Which means that there is no risk
|
||||
|
|
@ -170,7 +163,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
|
|||
goto err;
|
||||
|
||||
vma = i915_gem_object_pin_to_display_plane(obj, &ww, alignment,
|
||||
view, pinctl);
|
||||
vtd_guard, view, pinctl);
|
||||
if (IS_ERR(vma)) {
|
||||
ret = PTR_ERR(vma);
|
||||
goto err_unpin;
|
||||
|
|
@ -252,7 +245,16 @@ intel_plane_fb_min_phys_alignment(const struct intel_plane_state *plane_state)
|
|||
return plane->min_alignment(plane, fb, 0);
|
||||
}
|
||||
|
||||
int intel_plane_pin_fb(struct intel_plane_state *plane_state)
|
||||
static unsigned int
|
||||
intel_plane_fb_vtd_guard(const struct intel_plane_state *plane_state)
|
||||
{
|
||||
return intel_fb_view_vtd_guard(plane_state->hw.fb,
|
||||
&plane_state->view,
|
||||
plane_state->hw.rotation);
|
||||
}
|
||||
|
||||
int intel_plane_pin_fb(struct intel_plane_state *plane_state,
|
||||
const struct intel_plane_state *old_plane_state)
|
||||
{
|
||||
struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
|
||||
const struct intel_framebuffer *fb =
|
||||
|
|
@ -263,6 +265,7 @@ int intel_plane_pin_fb(struct intel_plane_state *plane_state)
|
|||
vma = intel_fb_pin_to_ggtt(&fb->base, &plane_state->view.gtt,
|
||||
intel_plane_fb_min_alignment(plane_state),
|
||||
intel_plane_fb_min_phys_alignment(plane_state),
|
||||
intel_plane_fb_vtd_guard(plane_state),
|
||||
intel_plane_uses_fence(plane_state),
|
||||
&plane_state->flags);
|
||||
if (IS_ERR(vma))
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb,
|
|||
const struct i915_gtt_view *view,
|
||||
unsigned int alignment,
|
||||
unsigned int phys_alignment,
|
||||
unsigned int vtd_guard,
|
||||
bool uses_fence,
|
||||
unsigned long *out_flags);
|
||||
|
||||
void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags);
|
||||
|
||||
int intel_plane_pin_fb(struct intel_plane_state *plane_state);
|
||||
int intel_plane_pin_fb(struct intel_plane_state *new_plane_state,
|
||||
const struct intel_plane_state *old_plane_state);
|
||||
void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -177,9 +177,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||
struct intel_framebuffer *fb = ifbdev->fb;
|
||||
struct drm_device *dev = helper->dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
const struct i915_gtt_view view = {
|
||||
.type = I915_GTT_VIEW_NORMAL,
|
||||
};
|
||||
intel_wakeref_t wakeref;
|
||||
struct fb_info *info;
|
||||
struct i915_vma *vma;
|
||||
|
|
@ -226,8 +223,10 @@ static int intelfb_create(struct drm_fb_helper *helper,
|
|||
* This also validates that any existing fb inherited from the
|
||||
* BIOS is suitable for own access.
|
||||
*/
|
||||
vma = intel_fb_pin_to_ggtt(&fb->base, &view,
|
||||
vma = intel_fb_pin_to_ggtt(&fb->base, &fb->normal_view.gtt,
|
||||
fb->min_alignment, 0,
|
||||
intel_fb_view_vtd_guard(&fb->base, &fb->normal_view,
|
||||
DRM_MODE_ROTATE_0),
|
||||
false, &flags);
|
||||
if (IS_ERR(vma)) {
|
||||
ret = PTR_ERR(vma);
|
||||
|
|
@ -695,3 +694,8 @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev)
|
|||
|
||||
return to_intel_framebuffer(fbdev->helper.fb);
|
||||
}
|
||||
|
||||
struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev)
|
||||
{
|
||||
return fbdev ? fbdev->vma : NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ struct intel_framebuffer;
|
|||
void intel_fbdev_setup(struct drm_i915_private *dev_priv);
|
||||
void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous);
|
||||
struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev);
|
||||
struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev);
|
||||
|
||||
#else
|
||||
static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
|
|
@ -30,6 +32,12 @@ static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbd
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __INTEL_FBDEV_H__ */
|
||||
|
|
|
|||
|
|
@ -80,14 +80,13 @@ void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe)
|
|||
assert_fdi_rx(i915, pipe, false);
|
||||
}
|
||||
|
||||
void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915,
|
||||
void assert_fdi_tx_pll_enabled(struct intel_display *display,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
bool cur_state;
|
||||
|
||||
/* ILK FDI PLL is always enabled */
|
||||
if (IS_IRONLAKE(i915))
|
||||
if (display->platform.ironlake)
|
||||
return;
|
||||
|
||||
/* On Haswell, DDI ports are responsible for the FDI PLL setup */
|
||||
|
|
@ -99,10 +98,9 @@ void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915,
|
|||
"FDI TX PLL assertion failure, should be active but is disabled\n");
|
||||
}
|
||||
|
||||
static void assert_fdi_rx_pll(struct drm_i915_private *i915,
|
||||
static void assert_fdi_rx_pll(struct intel_display *display,
|
||||
enum pipe pipe, bool state)
|
||||
{
|
||||
struct intel_display *display = &i915->display;
|
||||
bool cur_state;
|
||||
|
||||
cur_state = intel_de_read(display, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE;
|
||||
|
|
@ -111,14 +109,14 @@ static void assert_fdi_rx_pll(struct drm_i915_private *i915,
|
|||
str_on_off(state), str_on_off(cur_state));
|
||||
}
|
||||
|
||||
void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)
|
||||
void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
assert_fdi_rx_pll(i915, pipe, true);
|
||||
assert_fdi_rx_pll(display, pipe, true);
|
||||
}
|
||||
|
||||
void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe)
|
||||
void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe)
|
||||
{
|
||||
assert_fdi_rx_pll(i915, pipe, false);
|
||||
assert_fdi_rx_pll(display, pipe, false);
|
||||
}
|
||||
|
||||
void intel_fdi_link_train(struct intel_crtc *crtc,
|
||||
|
|
@ -390,7 +388,7 @@ static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state,
|
|||
* @state must be recomputed with the updated @limits.
|
||||
*
|
||||
* Returns:
|
||||
* - 0 if the confugration is valid
|
||||
* - 0 if the configuration is valid
|
||||
* - %-EAGAIN, if the configuration is invalid and @limits got updated
|
||||
* with fallback values with which the configuration of all CRTCs
|
||||
* in @state must be recomputed
|
||||
|
|
@ -513,6 +511,7 @@ void intel_fdi_normal_train(struct intel_crtc *crtc)
|
|||
static void ilk_fdi_link_train(struct intel_crtc *crtc,
|
||||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_device *dev = crtc->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
|
@ -527,7 +526,7 @@ static void ilk_fdi_link_train(struct intel_crtc *crtc,
|
|||
intel_de_read(dev_priv, PIPE_DATA_M1(dev_priv, pipe)) & TU_SIZE_MASK);
|
||||
|
||||
/* FDI needs bits from pipe first */
|
||||
assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder);
|
||||
assert_transcoder_enabled(display, crtc_state->cpu_transcoder);
|
||||
|
||||
/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
|
||||
for train result */
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ struct drm_i915_private;
|
|||
struct intel_atomic_state;
|
||||
struct intel_crtc;
|
||||
struct intel_crtc_state;
|
||||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
struct intel_link_bw_limits;
|
||||
|
||||
|
|
@ -41,8 +42,8 @@ void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe);
|
|||
void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe);
|
||||
void assert_fdi_tx_pll_enabled(struct intel_display *display, enum pipe pipe);
|
||||
void assert_fdi_rx_pll_enabled(struct intel_display *display, enum pipe pipe);
|
||||
void assert_fdi_rx_pll_disabled(struct intel_display *display, enum pipe pipe);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -55,16 +55,15 @@
|
|||
* The code also supports underrun detection on the PCH transcoder.
|
||||
*/
|
||||
|
||||
static bool ivb_can_enable_err_int(struct drm_device *dev)
|
||||
static bool ivb_can_enable_err_int(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc;
|
||||
enum pipe pipe;
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
for_each_pipe(display, pipe) {
|
||||
crtc = intel_crtc_for_pipe(display, pipe);
|
||||
|
||||
if (crtc->cpu_fifo_underrun_disabled)
|
||||
|
|
@ -74,16 +73,15 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool cpt_can_enable_serr_int(struct drm_device *dev)
|
||||
static bool cpt_can_enable_serr_int(struct intel_display *display)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum pipe pipe;
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
for_each_pipe(dev_priv, pipe) {
|
||||
for_each_pipe(display, pipe) {
|
||||
crtc = intel_crtc_for_pipe(display, pipe);
|
||||
|
||||
if (crtc->pch_fifo_underrun_disabled)
|
||||
|
|
@ -97,48 +95,48 @@ static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
i915_reg_t reg = PIPESTAT(dev_priv, crtc->pipe);
|
||||
i915_reg_t reg = PIPESTAT(display, crtc->pipe);
|
||||
u32 enable_mask;
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if ((intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
|
||||
if ((intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
|
||||
return;
|
||||
|
||||
enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
|
||||
intel_de_write(dev_priv, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
|
||||
intel_de_posting_read(dev_priv, reg);
|
||||
enable_mask = i915_pipestat_enable_mask(display, crtc->pipe);
|
||||
intel_de_write(display, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
|
||||
intel_de_posting_read(display, reg);
|
||||
|
||||
trace_intel_cpu_fifo_underrun(display, crtc->pipe);
|
||||
drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe));
|
||||
drm_err(display->drm, "pipe %c underrun\n", pipe_name(crtc->pipe));
|
||||
}
|
||||
|
||||
static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void i9xx_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe,
|
||||
bool enable, bool old)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
i915_reg_t reg = PIPESTAT(dev_priv, pipe);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
i915_reg_t reg = PIPESTAT(display, pipe);
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if (enable) {
|
||||
u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
|
||||
u32 enable_mask = i915_pipestat_enable_mask(display, pipe);
|
||||
|
||||
intel_de_write(dev_priv, reg,
|
||||
intel_de_write(display, reg,
|
||||
enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
|
||||
intel_de_posting_read(dev_priv, reg);
|
||||
intel_de_posting_read(display, reg);
|
||||
} else {
|
||||
if (old && intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS)
|
||||
drm_err(&dev_priv->drm, "pipe %c underrun\n",
|
||||
if (old && intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS)
|
||||
drm_err(display->drm, "pipe %c underrun\n",
|
||||
pipe_name(pipe));
|
||||
}
|
||||
}
|
||||
|
||||
static void ilk_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void ilk_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 bit = (pipe == PIPE_A) ?
|
||||
DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN;
|
||||
|
||||
|
|
@ -153,30 +151,30 @@ static void ivb_check_fifo_underruns(struct intel_crtc *crtc)
|
|||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
u32 err_int = intel_de_read(dev_priv, GEN7_ERR_INT);
|
||||
u32 err_int = intel_de_read(display, GEN7_ERR_INT);
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0)
|
||||
return;
|
||||
|
||||
intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
|
||||
intel_de_posting_read(dev_priv, GEN7_ERR_INT);
|
||||
intel_de_write(display, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
|
||||
intel_de_posting_read(display, GEN7_ERR_INT);
|
||||
|
||||
trace_intel_cpu_fifo_underrun(display, pipe);
|
||||
drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe));
|
||||
drm_err(display->drm, "fifo underrun on pipe %c\n", pipe_name(pipe));
|
||||
}
|
||||
|
||||
static void ivb_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void ivb_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable,
|
||||
bool old)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
if (enable) {
|
||||
intel_de_write(dev_priv, GEN7_ERR_INT,
|
||||
intel_de_write(display, GEN7_ERR_INT,
|
||||
ERR_INT_FIFO_UNDERRUN(pipe));
|
||||
|
||||
if (!ivb_can_enable_err_int(dev))
|
||||
if (!ivb_can_enable_err_int(display))
|
||||
return;
|
||||
|
||||
ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
|
||||
|
|
@ -184,18 +182,18 @@ static void ivb_set_fifo_underrun_reporting(struct drm_device *dev,
|
|||
ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
|
||||
|
||||
if (old &&
|
||||
intel_de_read(dev_priv, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
|
||||
drm_err(&dev_priv->drm,
|
||||
intel_de_read(display, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
|
||||
drm_err(display->drm,
|
||||
"uncleared fifo underrun on pipe %c\n",
|
||||
pipe_name(pipe));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void bdw_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (enable)
|
||||
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
|
||||
|
|
@ -203,11 +201,11 @@ static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
|
|||
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
|
||||
}
|
||||
|
||||
static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void ibx_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pch_transcoder,
|
||||
bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
u32 bit = (pch_transcoder == PIPE_A) ?
|
||||
SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
|
||||
|
||||
|
|
@ -222,53 +220,52 @@ static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
|
|||
struct intel_display *display = to_intel_display(crtc);
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
enum pipe pch_transcoder = crtc->pipe;
|
||||
u32 serr_int = intel_de_read(dev_priv, SERR_INT);
|
||||
u32 serr_int = intel_de_read(display, SERR_INT);
|
||||
|
||||
lockdep_assert_held(&dev_priv->irq_lock);
|
||||
|
||||
if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
|
||||
return;
|
||||
|
||||
intel_de_write(dev_priv, SERR_INT,
|
||||
intel_de_write(display, SERR_INT,
|
||||
SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
|
||||
intel_de_posting_read(dev_priv, SERR_INT);
|
||||
intel_de_posting_read(display, SERR_INT);
|
||||
|
||||
trace_intel_pch_fifo_underrun(display, pch_transcoder);
|
||||
drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n",
|
||||
drm_err(display->drm, "pch fifo underrun on pch transcoder %c\n",
|
||||
pipe_name(pch_transcoder));
|
||||
}
|
||||
|
||||
static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static void cpt_set_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pch_transcoder,
|
||||
bool enable, bool old)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
|
||||
if (enable) {
|
||||
intel_de_write(dev_priv, SERR_INT,
|
||||
intel_de_write(display, SERR_INT,
|
||||
SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
|
||||
|
||||
if (!cpt_can_enable_serr_int(dev))
|
||||
if (!cpt_can_enable_serr_int(display))
|
||||
return;
|
||||
|
||||
ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
|
||||
} else {
|
||||
ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
|
||||
|
||||
if (old && intel_de_read(dev_priv, SERR_INT) &
|
||||
if (old && intel_de_read(display, SERR_INT) &
|
||||
SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
|
||||
drm_err(&dev_priv->drm,
|
||||
drm_err(display->drm,
|
||||
"uncleared pch fifo underrun on pch transcoder %c\n",
|
||||
pipe_name(pch_transcoder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
|
||||
static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
bool old;
|
||||
|
||||
|
|
@ -277,21 +274,21 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
|
|||
old = !crtc->cpu_fifo_underrun_disabled;
|
||||
crtc->cpu_fifo_underrun_disabled = !enable;
|
||||
|
||||
if (HAS_GMCH(dev_priv))
|
||||
i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
|
||||
else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
|
||||
ilk_set_fifo_underrun_reporting(dev, pipe, enable);
|
||||
else if (DISPLAY_VER(dev_priv) == 7)
|
||||
ivb_set_fifo_underrun_reporting(dev, pipe, enable, old);
|
||||
else if (DISPLAY_VER(dev_priv) >= 8)
|
||||
bdw_set_fifo_underrun_reporting(dev, pipe, enable);
|
||||
if (HAS_GMCH(display))
|
||||
i9xx_set_fifo_underrun_reporting(display, pipe, enable, old);
|
||||
else if (display->platform.ironlake || display->platform.sandybridge)
|
||||
ilk_set_fifo_underrun_reporting(display, pipe, enable);
|
||||
else if (DISPLAY_VER(display) == 7)
|
||||
ivb_set_fifo_underrun_reporting(display, pipe, enable, old);
|
||||
else if (DISPLAY_VER(display) >= 8)
|
||||
bdw_set_fifo_underrun_reporting(display, pipe, enable);
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state
|
||||
* @dev_priv: i915 device instance
|
||||
* intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrun reporting state
|
||||
* @display: display device instance
|
||||
* @pipe: (CPU) pipe to set state for
|
||||
* @enable: whether underruns should be reported or not
|
||||
*
|
||||
|
|
@ -305,15 +302,15 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
|
|||
*
|
||||
* Returns the previous state of underrun reporting.
|
||||
*/
|
||||
bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
||||
bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
unsigned long flags;
|
||||
bool ret;
|
||||
|
||||
spin_lock_irqsave(&dev_priv->irq_lock, flags);
|
||||
ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe,
|
||||
enable);
|
||||
ret = __intel_set_cpu_fifo_underrun_reporting(display, pipe, enable);
|
||||
spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
|
||||
|
||||
return ret;
|
||||
|
|
@ -321,7 +318,7 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
|||
|
||||
/**
|
||||
* intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
|
||||
* @enable: whether underruns should be reported or not
|
||||
*
|
||||
|
|
@ -333,13 +330,12 @@ bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
|||
*
|
||||
* Returns the previous state of underrun reporting.
|
||||
*/
|
||||
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
||||
bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pch_transcoder,
|
||||
bool enable)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct intel_crtc *crtc =
|
||||
intel_crtc_for_pipe(display, pch_transcoder);
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pch_transcoder);
|
||||
unsigned long flags;
|
||||
bool old;
|
||||
|
||||
|
|
@ -358,11 +354,11 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
|||
crtc->pch_fifo_underrun_disabled = !enable;
|
||||
|
||||
if (HAS_PCH_IBX(dev_priv))
|
||||
ibx_set_fifo_underrun_reporting(&dev_priv->drm,
|
||||
ibx_set_fifo_underrun_reporting(display,
|
||||
pch_transcoder,
|
||||
enable);
|
||||
else
|
||||
cpt_set_fifo_underrun_reporting(&dev_priv->drm,
|
||||
cpt_set_fifo_underrun_reporting(display,
|
||||
pch_transcoder,
|
||||
enable, old);
|
||||
|
||||
|
|
@ -372,17 +368,16 @@ bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
|||
|
||||
/**
|
||||
* intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @pipe: (CPU) pipe to set state for
|
||||
*
|
||||
* This handles a CPU fifo underrun interrupt, generating an underrun warning
|
||||
* into dmesg if underrun reporting is enabled and then disables the underrun
|
||||
* interrupt to avoid an irq storm.
|
||||
*/
|
||||
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
|
||||
void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
|
||||
enum pipe pipe)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe);
|
||||
|
||||
/* We may be called too early in init, thanks BIOS! */
|
||||
|
|
@ -390,63 +385,62 @@ void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
|
|||
return;
|
||||
|
||||
/* GMCH can't disable fifo underruns, filter them. */
|
||||
if (HAS_GMCH(dev_priv) &&
|
||||
if (HAS_GMCH(display) &&
|
||||
crtc->cpu_fifo_underrun_disabled)
|
||||
return;
|
||||
|
||||
if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
|
||||
if (intel_set_cpu_fifo_underrun_reporting(display, pipe, false)) {
|
||||
trace_intel_cpu_fifo_underrun(display, pipe);
|
||||
|
||||
drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
|
||||
drm_err(display->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
|
||||
}
|
||||
|
||||
intel_fbc_handle_fifo_underrun_irq(&dev_priv->display);
|
||||
intel_fbc_handle_fifo_underrun_irq(display);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
* @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
|
||||
*
|
||||
* This handles a PCH fifo underrun interrupt, generating an underrun warning
|
||||
* into dmesg if underrun reporting is enabled and then disables the underrun
|
||||
* interrupt to avoid an irq storm.
|
||||
*/
|
||||
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
|
||||
void intel_pch_fifo_underrun_irq_handler(struct intel_display *display,
|
||||
enum pipe pch_transcoder)
|
||||
{
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
|
||||
if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
|
||||
if (intel_set_pch_fifo_underrun_reporting(display, pch_transcoder,
|
||||
false)) {
|
||||
trace_intel_pch_fifo_underrun(display, pch_transcoder);
|
||||
drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n",
|
||||
drm_err(display->drm, "PCH transcoder %c FIFO underrun\n",
|
||||
pipe_name(pch_transcoder));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_check_cpu_fifo_underruns - check for CPU fifo underruns immediately
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared
|
||||
* error interrupt may have been disabled, and so CPU fifo underruns won't
|
||||
* necessarily raise an interrupt, and on GMCH platforms where underruns never
|
||||
* raise an interrupt.
|
||||
*/
|
||||
void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
|
||||
void intel_check_cpu_fifo_underruns(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
if (crtc->cpu_fifo_underrun_disabled)
|
||||
continue;
|
||||
|
||||
if (HAS_GMCH(dev_priv))
|
||||
if (HAS_GMCH(display))
|
||||
i9xx_check_fifo_underruns(crtc);
|
||||
else if (DISPLAY_VER(dev_priv) == 7)
|
||||
else if (DISPLAY_VER(display) == 7)
|
||||
ivb_check_fifo_underruns(crtc);
|
||||
}
|
||||
|
||||
|
|
@ -455,19 +449,20 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
|
|||
|
||||
/**
|
||||
* intel_check_pch_fifo_underruns - check for PCH fifo underruns immediately
|
||||
* @dev_priv: i915 device instance
|
||||
* @display: display device instance
|
||||
*
|
||||
* Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared
|
||||
* error interrupt may have been disabled, and so PCH fifo underruns won't
|
||||
* necessarily raise an interrupt.
|
||||
*/
|
||||
void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
|
||||
void intel_check_pch_fifo_underruns(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
struct intel_crtc *crtc;
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
|
||||
for_each_intel_crtc(&dev_priv->drm, crtc) {
|
||||
for_each_intel_crtc(display->drm, crtc) {
|
||||
if (crtc->pch_fifo_underrun_disabled)
|
||||
continue;
|
||||
|
||||
|
|
@ -478,10 +473,12 @@ void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
|
|||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
}
|
||||
|
||||
void intel_init_fifo_underrun_reporting(struct drm_i915_private *i915,
|
||||
void intel_init_fifo_underrun_reporting(struct intel_display *display,
|
||||
struct intel_crtc *crtc,
|
||||
bool enable)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
crtc->cpu_fifo_underrun_disabled = !enable;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_i915_private;
|
||||
struct intel_crtc;
|
||||
enum pipe;
|
||||
struct intel_crtc;
|
||||
struct intel_display;
|
||||
|
||||
void intel_init_fifo_underrun_reporting(struct drm_i915_private *i915,
|
||||
void intel_init_fifo_underrun_reporting(struct intel_display *display,
|
||||
struct intel_crtc *crtc, bool enable);
|
||||
bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
||||
bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pipe, bool enable);
|
||||
bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
|
||||
bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display,
|
||||
enum pipe pch_transcoder,
|
||||
bool enable);
|
||||
void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
|
||||
void intel_cpu_fifo_underrun_irq_handler(struct intel_display *display,
|
||||
enum pipe pipe);
|
||||
void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
|
||||
void intel_pch_fifo_underrun_irq_handler(struct intel_display *display,
|
||||
enum pipe pch_transcoder);
|
||||
void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
|
||||
void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);
|
||||
void intel_check_cpu_fifo_underruns(struct intel_display *display);
|
||||
void intel_check_pch_fifo_underruns(struct intel_display *display);
|
||||
|
||||
#endif /* __INTEL_FIFO_UNDERRUN_H__ */
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ static void intel_frontbuffer_flush_work(struct work_struct *work)
|
|||
* @front: GEM object to flush
|
||||
*
|
||||
* This function is targeted for our dirty callback for queueing flush when
|
||||
* dma fence is signales
|
||||
* dma fence is signals
|
||||
*/
|
||||
void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -761,11 +761,10 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
|||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct intel_display *display = bus->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
intel_wakeref_t wakeref;
|
||||
int ret;
|
||||
|
||||
wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
|
||||
|
||||
if (bus->force_bit) {
|
||||
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
|
||||
|
|
@ -777,7 +776,7 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
|||
bus->force_bit |= GMBUS_FORCE_BIT_RETRY;
|
||||
}
|
||||
|
||||
intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -786,7 +785,6 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
|||
{
|
||||
struct intel_gmbus *bus = to_intel_gmbus(adapter);
|
||||
struct intel_display *display = bus->display;
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
u8 cmd = DRM_HDCP_DDC_AKSV;
|
||||
u8 buf[DRM_HDCP_KSV_LEN] = {};
|
||||
struct i2c_msg msgs[] = {
|
||||
|
|
@ -806,7 +804,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
|||
intel_wakeref_t wakeref;
|
||||
int ret;
|
||||
|
||||
wakeref = intel_display_power_get(i915, POWER_DOMAIN_GMBUS);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
|
||||
mutex_lock(&display->gmbus.mutex);
|
||||
|
||||
/*
|
||||
|
|
@ -817,7 +815,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter)
|
|||
ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT);
|
||||
|
||||
mutex_unlock(&display->gmbus.mutex);
|
||||
intel_display_power_put(i915, POWER_DOMAIN_GMBUS, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/component.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
|
|
@ -208,7 +209,7 @@ int intel_hdcp_read_valid_bksv(struct intel_digital_port *dig_port,
|
|||
}
|
||||
|
||||
/* Is HDCP1.4 capable on Platform and Sink */
|
||||
bool intel_hdcp_get_capability(struct intel_connector *connector)
|
||||
static bool intel_hdcp_get_capability(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_digital_port *dig_port;
|
||||
const struct intel_hdcp_shim *shim = connector->hdcp.shim;
|
||||
|
|
@ -264,7 +265,7 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector)
|
|||
}
|
||||
|
||||
/* Is HDCP2.2 capable on Platform and Sink */
|
||||
bool intel_hdcp2_get_capability(struct intel_connector *connector)
|
||||
static bool intel_hdcp2_get_capability(struct intel_connector *connector)
|
||||
{
|
||||
struct intel_hdcp *hdcp = &connector->hdcp;
|
||||
bool capable = false;
|
||||
|
|
@ -278,9 +279,9 @@ bool intel_hdcp2_get_capability(struct intel_connector *connector)
|
|||
return capable;
|
||||
}
|
||||
|
||||
void intel_hdcp_get_remote_capability(struct intel_connector *connector,
|
||||
bool *hdcp_capable,
|
||||
bool *hdcp2_capable)
|
||||
static void intel_hdcp_get_remote_capability(struct intel_connector *connector,
|
||||
bool *hdcp_capable,
|
||||
bool *hdcp2_capable)
|
||||
{
|
||||
struct intel_hdcp *hdcp = &connector->hdcp;
|
||||
|
||||
|
|
@ -342,7 +343,7 @@ static bool hdcp_key_loadable(struct intel_display *display)
|
|||
* On HSW and BDW, Display HW loads the Key as soon as Display resumes.
|
||||
* On all BXT+, SW can load the keys only when the PW#1 is turned on.
|
||||
*/
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915))
|
||||
if (display->platform.haswell || display->platform.broadwell)
|
||||
id = HSW_DISP_PW_GLOBAL;
|
||||
else
|
||||
id = SKL_DISP_PW_1;
|
||||
|
|
@ -353,7 +354,7 @@ static bool hdcp_key_loadable(struct intel_display *display)
|
|||
|
||||
/*
|
||||
* Another req for hdcp key loadability is enabled state of pll for
|
||||
* cdclk. Without active crtc we wont land here. So we are assuming that
|
||||
* cdclk. Without active crtc we won't land here. So we are assuming that
|
||||
* cdclk is already on.
|
||||
*/
|
||||
|
||||
|
|
@ -381,7 +382,7 @@ static int intel_hdcp_load_keys(struct intel_display *display)
|
|||
* On HSW and BDW HW loads the HDCP1.4 Key when Display comes
|
||||
* out of reset. So if Key is not already loaded, its an error state.
|
||||
*/
|
||||
if (IS_HASWELL(i915) || IS_BROADWELL(i915))
|
||||
if (display->platform.haswell || display->platform.broadwell)
|
||||
if (!(intel_de_read(display, HDCP_KEY_STATUS) & HDCP_KEY_LOAD_DONE))
|
||||
return -ENXIO;
|
||||
|
||||
|
|
@ -393,7 +394,7 @@ static int intel_hdcp_load_keys(struct intel_display *display)
|
|||
* process from other platforms. These platforms use the GT Driver
|
||||
* Mailbox interface.
|
||||
*/
|
||||
if (DISPLAY_VER(display) == 9 && !IS_BROXTON(i915)) {
|
||||
if (DISPLAY_VER(display) == 9 && !display->platform.broxton) {
|
||||
ret = snb_pcode_write(&i915->uncore, SKL_PCODE_LOAD_HDCP_KEYS, 1);
|
||||
if (ret) {
|
||||
drm_err(display->drm,
|
||||
|
|
@ -1550,9 +1551,9 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
|
|||
* with a 50ms delay if not hdcp2 capable for DP/DPMST encoders
|
||||
* (dock decides to stop advertising hdcp2 capability for some reason).
|
||||
* The reason being that during suspend resume dock usually keeps the
|
||||
* HDCP2 registers inaccesible causing AUX error. This wouldn't be a
|
||||
* HDCP2 registers inaccessible causing AUX error. This wouldn't be a
|
||||
* big problem if the userspace just kept retrying with some delay while
|
||||
* it continues to play low value content but most userpace applications
|
||||
* it continues to play low value content but most userspace applications
|
||||
* end up throwing an error when it receives one from KMD. This makes
|
||||
* sure we give the dock and the sink devices to complete its power cycle
|
||||
* and then try HDCP authentication. The values of 10 and delay of 50ms
|
||||
|
|
@ -2338,18 +2339,16 @@ static int initialize_hdcp_port_data(struct intel_connector *connector,
|
|||
|
||||
static bool is_hdcp2_supported(struct intel_display *display)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(display->drm);
|
||||
|
||||
if (intel_hdcp_gsc_cs_required(display))
|
||||
return true;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP))
|
||||
return false;
|
||||
|
||||
return (DISPLAY_VER(display) >= 10 ||
|
||||
IS_KABYLAKE(i915) ||
|
||||
IS_COFFEELAKE(i915) ||
|
||||
IS_COMETLAKE(i915));
|
||||
return DISPLAY_VER(display) >= 10 ||
|
||||
display->platform.kabylake ||
|
||||
display->platform.coffeelake ||
|
||||
display->platform.cometlake;
|
||||
}
|
||||
|
||||
void intel_hdcp_component_init(struct intel_display *display)
|
||||
|
|
@ -2473,13 +2472,16 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
|
|||
* Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
|
||||
* is capable of HDCP2.2, it is preferred to use HDCP2.2.
|
||||
*/
|
||||
if (intel_hdcp2_get_capability(connector)) {
|
||||
if (!hdcp->force_hdcp14 && intel_hdcp2_get_capability(connector)) {
|
||||
ret = _intel_hdcp2_enable(state, connector);
|
||||
if (!ret)
|
||||
check_link_interval =
|
||||
DRM_HDCP2_CHECK_PERIOD_MS;
|
||||
}
|
||||
|
||||
if (hdcp->force_hdcp14)
|
||||
drm_dbg_kms(display->drm, "Forcing HDCP 1.4\n");
|
||||
|
||||
/*
|
||||
* When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will
|
||||
* be attempted.
|
||||
|
|
@ -2573,7 +2575,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
|
|||
|
||||
/*
|
||||
* During the HDCP encryption session if Type change is requested,
|
||||
* disable the HDCP and reenable it with new TYPE value.
|
||||
* disable the HDCP and re-enable it with new TYPE value.
|
||||
*/
|
||||
if (conn_state->content_protection ==
|
||||
DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
|
||||
|
|
@ -2616,6 +2618,15 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
|
|||
_intel_hdcp_enable(state, encoder, crtc_state, conn_state);
|
||||
}
|
||||
|
||||
void intel_hdcp_cancel_works(struct intel_connector *connector)
|
||||
{
|
||||
if (!connector->hdcp.shim)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&connector->hdcp.check_work);
|
||||
cancel_work_sync(&connector->hdcp.prop_work);
|
||||
}
|
||||
|
||||
void intel_hdcp_component_fini(struct intel_display *display)
|
||||
{
|
||||
mutex_lock(&display->hdcp.hdcp_mutex);
|
||||
|
|
@ -2731,3 +2742,153 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
|
|||
|
||||
queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 0);
|
||||
}
|
||||
|
||||
static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connector,
|
||||
bool remote_req)
|
||||
{
|
||||
bool hdcp_cap = false, hdcp2_cap = false;
|
||||
|
||||
if (!connector->hdcp.shim) {
|
||||
seq_puts(m, "No Connector Support");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (remote_req) {
|
||||
intel_hdcp_get_remote_capability(connector, &hdcp_cap, &hdcp2_cap);
|
||||
} else {
|
||||
hdcp_cap = intel_hdcp_get_capability(connector);
|
||||
hdcp2_cap = intel_hdcp2_get_capability(connector);
|
||||
}
|
||||
|
||||
if (hdcp_cap)
|
||||
seq_puts(m, "HDCP1.4 ");
|
||||
if (hdcp2_cap)
|
||||
seq_puts(m, "HDCP2.2 ");
|
||||
|
||||
if (!hdcp_cap && !hdcp2_cap)
|
||||
seq_puts(m, "None");
|
||||
|
||||
out:
|
||||
seq_puts(m, "\n");
|
||||
}
|
||||
|
||||
void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector)
|
||||
{
|
||||
seq_puts(m, "\tHDCP version: ");
|
||||
if (connector->mst_port) {
|
||||
__intel_hdcp_info(m, connector, true);
|
||||
seq_puts(m, "\tMST Hub HDCP version: ");
|
||||
}
|
||||
__intel_hdcp_info(m, connector, false);
|
||||
}
|
||||
|
||||
static int intel_hdcp_sink_capability_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
int ret;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!connector->base.encoder ||
|
||||
connector->base.status != connector_status_connected) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(m, "%s:%d HDCP version: ", connector->base.name,
|
||||
connector->base.base.id);
|
||||
__intel_hdcp_info(m, connector, false);
|
||||
|
||||
out:
|
||||
drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(intel_hdcp_sink_capability);
|
||||
|
||||
static ssize_t intel_hdcp_force_14_write(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *m = file->private_data;
|
||||
struct intel_connector *connector = m->private;
|
||||
struct intel_hdcp *hdcp = &connector->hdcp;
|
||||
bool force_hdcp14 = false;
|
||||
int ret;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
ret = kstrtobool_from_user(ubuf, len, &force_hdcp14);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
hdcp->force_hdcp14 = force_hdcp14;
|
||||
*offp += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int intel_hdcp_force_14_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct intel_connector *connector = m->private;
|
||||
struct intel_display *display = to_intel_display(connector);
|
||||
struct intel_encoder *encoder = intel_attached_encoder(connector);
|
||||
struct intel_hdcp *hdcp = &connector->hdcp;
|
||||
struct drm_crtc *crtc;
|
||||
int ret;
|
||||
|
||||
if (!encoder)
|
||||
return -ENODEV;
|
||||
|
||||
ret = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
crtc = connector->base.state->crtc;
|
||||
if (connector->base.status != connector_status_connected || !crtc) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(m, "%s\n",
|
||||
str_yes_no(hdcp->force_hdcp14));
|
||||
out:
|
||||
drm_modeset_unlock(&display->drm->mode_config.connection_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int intel_hdcp_force_14_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
return single_open(file, intel_hdcp_force_14_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations intel_hdcp_force_14_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = intel_hdcp_force_14_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = intel_hdcp_force_14_write
|
||||
};
|
||||
|
||||
void intel_hdcp_connector_debugfs_add(struct intel_connector *connector)
|
||||
{
|
||||
struct dentry *root = connector->base.debugfs_entry;
|
||||
int connector_type = connector->base.connector_type;
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
|
||||
connector_type == DRM_MODE_CONNECTOR_HDMIA ||
|
||||
connector_type == DRM_MODE_CONNECTOR_HDMIB) {
|
||||
debugfs_create_file("i915_hdcp_sink_capability", 0444, root,
|
||||
connector, &intel_hdcp_sink_capability_fops);
|
||||
debugfs_create_file("i915_force_hdcp14", 0644, root,
|
||||
connector, &intel_hdcp_force_14_fops);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ struct intel_digital_port;
|
|||
struct intel_display;
|
||||
struct intel_encoder;
|
||||
struct intel_hdcp_shim;
|
||||
struct seq_file;
|
||||
enum port;
|
||||
enum transcoder;
|
||||
|
||||
void intel_hdcp_atomic_check(struct drm_connector *connector,
|
||||
struct drm_connector_state *old_state,
|
||||
|
|
@ -33,19 +33,18 @@ void intel_hdcp_enable(struct intel_atomic_state *state,
|
|||
const struct intel_crtc_state *pipe_config,
|
||||
const struct drm_connector_state *conn_state);
|
||||
int intel_hdcp_disable(struct intel_connector *connector);
|
||||
void intel_hdcp_cancel_works(struct intel_connector *connector);
|
||||
void intel_hdcp_update_pipe(struct intel_atomic_state *state,
|
||||
struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state);
|
||||
bool is_hdcp_supported(struct intel_display *display, enum port port);
|
||||
bool intel_hdcp_get_capability(struct intel_connector *connector);
|
||||
bool intel_hdcp2_get_capability(struct intel_connector *connector);
|
||||
void intel_hdcp_get_remote_capability(struct intel_connector *connector,
|
||||
bool *hdcp_capable,
|
||||
bool *hdcp2_capable);
|
||||
void intel_hdcp_component_init(struct intel_display *display);
|
||||
void intel_hdcp_component_fini(struct intel_display *display);
|
||||
void intel_hdcp_cleanup(struct intel_connector *connector);
|
||||
void intel_hdcp_handle_cp_irq(struct intel_connector *connector);
|
||||
|
||||
void intel_hdcp_info(struct seq_file *m, struct intel_connector *connector);
|
||||
void intel_hdcp_connector_debugfs_add(struct intel_connector *connector);
|
||||
|
||||
#endif /* __INTEL_HDCP_H__ */
|
||||
|
|
|
|||
|
|
@ -1909,18 +1909,6 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
|
|||
if (intel_encoder_is_tc(encoder) && clock > 500000 && clock < 532800)
|
||||
return MODE_CLOCK_RANGE;
|
||||
|
||||
/*
|
||||
* SNPS PHYs' MPLLB table-based programming can only handle a fixed
|
||||
* set of link rates.
|
||||
*
|
||||
* FIXME: We will hopefully get an algorithmic way of programming
|
||||
* the MPLLB for HDMI in the future.
|
||||
*/
|
||||
if (DISPLAY_VER(display) >= 14)
|
||||
return intel_cx0_phy_check_hdmi_link_rate(hdmi, clock);
|
||||
else if (IS_DG2(dev_priv))
|
||||
return intel_snps_phy_check_hdmi_link_rate(clock);
|
||||
|
||||
return MODE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2027,7 +2015,6 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
|
|||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector));
|
||||
struct drm_i915_private *dev_priv = to_i915(display->drm);
|
||||
enum drm_mode_status status;
|
||||
int clock = mode->clock;
|
||||
int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
|
||||
|
|
@ -2035,7 +2022,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
|
|||
bool ycbcr_420_only;
|
||||
enum intel_output_format sink_format;
|
||||
|
||||
status = intel_cpu_transcoder_mode_valid(dev_priv, mode);
|
||||
status = intel_cpu_transcoder_mode_valid(display, mode);
|
||||
if (status != MODE_OK)
|
||||
return status;
|
||||
|
||||
|
|
@ -2080,7 +2067,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
|
|||
return status;
|
||||
}
|
||||
|
||||
return intel_mode_valid_max_plane_size(dev_priv, mode, 1);
|
||||
return intel_mode_valid_max_plane_size(display, mode, 1);
|
||||
}
|
||||
|
||||
bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state,
|
||||
|
|
@ -2503,14 +2490,13 @@ static bool
|
|||
intel_hdmi_set_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
|
||||
struct i2c_adapter *ddc = connector->ddc;
|
||||
intel_wakeref_t wakeref;
|
||||
const struct drm_edid *drm_edid;
|
||||
bool connected = false;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
|
||||
|
||||
drm_edid = drm_edid_read_ddc(connector, ddc);
|
||||
|
||||
|
|
@ -2533,7 +2519,7 @@ intel_hdmi_set_edid(struct drm_connector *connector)
|
|||
connected = true;
|
||||
}
|
||||
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
cec_notifier_set_phys_addr(intel_hdmi->cec_notifier,
|
||||
connector->display_info.source_physical_address);
|
||||
|
|
@ -2546,7 +2532,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
|
|||
{
|
||||
struct intel_display *display = to_intel_display(connector->dev);
|
||||
enum drm_connector_status status = connector_status_disconnected;
|
||||
struct drm_i915_private *dev_priv = to_i915(connector->dev);
|
||||
struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector));
|
||||
struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base;
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -2560,7 +2545,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
|
|||
if (!intel_display_driver_check_access(display))
|
||||
return connector->status;
|
||||
|
||||
wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
|
||||
wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS);
|
||||
|
||||
if (DISPLAY_VER(display) >= 11 &&
|
||||
!intel_digital_port_connected(encoder))
|
||||
|
|
@ -2572,7 +2557,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
|
|||
status = connector_status_connected;
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref);
|
||||
intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref);
|
||||
|
||||
if (status != connector_status_connected)
|
||||
cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
|
||||
|
|
|
|||
|
|
@ -62,4 +62,13 @@ int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
|
|||
int hdmi_max_slices, int hdmi_throughput);
|
||||
int intel_hdmi_dsc_get_slice_height(int vactive);
|
||||
|
||||
void hsw_write_infoframe(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
unsigned int type,
|
||||
const void *frame, ssize_t len);
|
||||
void hsw_read_infoframe(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
unsigned int type,
|
||||
void *frame, ssize_t len);
|
||||
|
||||
#endif /* __INTEL_HDMI_H__ */
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@
|
|||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_irq.h"
|
||||
#include "intel_connector.h"
|
||||
#include "intel_display_power.h"
|
||||
#include "intel_display_types.h"
|
||||
#include "intel_hdcp.h"
|
||||
#include "intel_hotplug.h"
|
||||
#include "intel_hotplug_irq.h"
|
||||
|
||||
|
|
@ -82,15 +84,13 @@
|
|||
|
||||
/**
|
||||
* intel_hpd_pin_default - return default pin associated with certain port.
|
||||
* @dev_priv: private driver data pointer
|
||||
* @port: the hpd port to get associated pin
|
||||
*
|
||||
* It is only valid and used by digital port encoder.
|
||||
*
|
||||
* Return pin that is associatade with @port.
|
||||
*/
|
||||
enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
|
||||
enum port port)
|
||||
enum hpd_pin intel_hpd_pin_default(enum port port)
|
||||
{
|
||||
return HPD_PORT_A + port - PORT_A;
|
||||
}
|
||||
|
|
@ -732,6 +732,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
struct drm_i915_private *dev_priv =
|
||||
container_of(work, struct drm_i915_private,
|
||||
display.hotplug.poll_init_work);
|
||||
struct intel_display *display = &dev_priv->display;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct intel_connector *connector;
|
||||
intel_wakeref_t wakeref;
|
||||
|
|
@ -747,7 +748,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
* and so risk an endless loop of this same sequence.
|
||||
*/
|
||||
if (!enabled) {
|
||||
wakeref = intel_display_power_get(dev_priv,
|
||||
wakeref = intel_display_power_get(display,
|
||||
POWER_DOMAIN_DISPLAY_CORE);
|
||||
drm_WARN_ON(&dev_priv->drm,
|
||||
READ_ONCE(dev_priv->display.hotplug.poll_enabled));
|
||||
|
|
@ -789,7 +790,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
if (!enabled) {
|
||||
i915_hpd_poll_detect_connectors(dev_priv);
|
||||
|
||||
intel_display_power_put(dev_priv,
|
||||
intel_display_power_put(display,
|
||||
POWER_DOMAIN_DISPLAY_CORE,
|
||||
wakeref);
|
||||
}
|
||||
|
|
@ -806,7 +807,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
|
|||
* of the powerwells.
|
||||
*
|
||||
* Since this function can get called in contexts where we're already holding
|
||||
* dev->mode_config.mutex, we do the actual hotplug enabling in a seperate
|
||||
* dev->mode_config.mutex, we do the actual hotplug enabling in a separate
|
||||
* worker.
|
||||
*
|
||||
* Also see: intel_hpd_init() and intel_hpd_poll_disable().
|
||||
|
|
@ -823,7 +824,7 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
|
|||
|
||||
/*
|
||||
* We might already be holding dev->mode_config.mutex, so do this in a
|
||||
* seperate worker
|
||||
* separate worker
|
||||
* As well, there's no issue if we race here since we always reschedule
|
||||
* this worker anyway
|
||||
*/
|
||||
|
|
@ -844,7 +845,7 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv)
|
|||
* of the powerwells.
|
||||
*
|
||||
* Since this function can get called in contexts where we're already holding
|
||||
* dev->mode_config.mutex, we do the actual hotplug enabling in a seperate
|
||||
* dev->mode_config.mutex, we do the actual hotplug enabling in a separate
|
||||
* worker.
|
||||
*
|
||||
* Also used during driver init to initialize connector->polled
|
||||
|
|
@ -865,6 +866,20 @@ void intel_hpd_poll_disable(struct drm_i915_private *dev_priv)
|
|||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
}
|
||||
|
||||
void intel_hpd_poll_fini(struct drm_i915_private *i915)
|
||||
{
|
||||
struct intel_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
|
||||
/* Kill all the work that may have been queued by hpd. */
|
||||
drm_connector_list_iter_begin(&i915->drm, &conn_iter);
|
||||
for_each_intel_connector_iter(connector, &conn_iter) {
|
||||
intel_connector_cancel_modeset_retry_work(connector);
|
||||
intel_hdcp_cancel_works(connector);
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
}
|
||||
|
||||
void intel_hpd_init_early(struct drm_i915_private *i915)
|
||||
{
|
||||
INIT_DELAYED_WORK(&i915->display.hotplug.hotplug_work,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ enum port;
|
|||
|
||||
void intel_hpd_poll_enable(struct drm_i915_private *dev_priv);
|
||||
void intel_hpd_poll_disable(struct drm_i915_private *dev_priv);
|
||||
void intel_hpd_poll_fini(struct drm_i915_private *i915);
|
||||
enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder,
|
||||
struct intel_connector *connector);
|
||||
void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
|
||||
|
|
@ -24,8 +25,7 @@ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port);
|
|||
void intel_hpd_init(struct drm_i915_private *dev_priv);
|
||||
void intel_hpd_init_early(struct drm_i915_private *i915);
|
||||
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
|
||||
enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
|
||||
enum port port);
|
||||
enum hpd_pin intel_hpd_pin_default(enum port port);
|
||||
bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
|
||||
void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
|
||||
void intel_hpd_debugfs_register(struct drm_i915_private *i915);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user