Message ID | 20210204134015.419036-1-gwan-gyeong.mun@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v15,1/2] drm/i915/display: Support PSR Multiple Instances | expand |
On Thu, 2021-02-04 at 15:40 +0200, Gwan-gyeong Mun wrote: > It is a preliminary work for supporting multiple EDP PSR and > DP PanelReplay. And it refactors singleton PSR to Multi Transcoder > supportable PSR. > And this moves and renames the i915_psr structure of drm_i915_private's to > intel_dp's intel_psr structure. > It also causes changes in PSR interrupt handling routine for supporting > multiple transcoders. But it does not change the scenario and timing of > enabling and disabling PSR. And it not support multiple pipes with > a single transcoder PSR case yet. > > v2: Fix indentation and add comments > v3: Remove Blank line > v4: Rebased > v5: Rebased and Addressed Anshuman's review comment. > - Move calling of intel_psr_init() to intel_dp_init_connector() > v6: Address Anshuman's review comments > - Remove wrong comments and add comments for a limit of supporting of > a single pipe PSR > v7: Update intel_psr_compute_config() for supporting multiple transcoder > PSR on BDW+ > v8: Address Anshuman's review comments > - Replace DRM_DEBUG_KMS with drm_dbg_kms() / DRM_WARN with drm_warn() > v9: Fix commit message > v10: Rebased > v11: Address Jose's review comment. > - Reorder calling order of intel_psr2_program_trans_man_trk_ctl(). > - In order to reduce changes keep the old name for drm_i915_private. > - Change restrictions of multiple instances of PSR. > v12: Address Jose's review comment. > - Change the calling of intel_psr2_program_trans_man_trk_ctl() into > commit_pipe_config(). > - Change a checking order of CAN_PSR() and connector_status to original > on i915_psr_sink_status_show(). > - Drop unneeded intel_dp_update_pipe() function. > - In order to wait a specific encoder which belong to crtc_state on > intel_psr_wait_for_idle(), add checking of encoder. > - Add an whitespace to comments. > v13: Rebased and Address Jose's review comment. > - Add and use for_each_intel_psr_enabled_encoder() macro. > - In order to use correct frontbuffer_bit for each pipe, > fix intel_psr_invalidate() and intel_psr_flush(). > - Remove redundant or unneeded codes. > - Update comments. > v14: Address Jose's review comment > - Add and use for_each_intel_encoder_can_psr() macro and > for_each_intel_encoder_mask_can_psr() macro. > - Add source_support member variable into intel_psr structure. > - Update CAN_PSR() macro that checks source_support. > - Move encoder's PSR availity check to psr_init() from > psr_compute_config(). > - Remove redundant or unneeded codes. > v15: Remove wrong mutex lock/unlock of PSR from > intel_psr2_program_trans_man_trk_ctl() There is a couple of minor issues yet but we can fix that on top. Reviewed-by: José Roberto de Souza <jose.souza@intel.com> > > Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> > Cc: José Roberto de Souza <jose.souza@intel.com> > Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> > Cc: Anshuman Gupta <anshuman.gupta@intel.com> > Reviewed-by: Anshuman Gupta <anshuman.gupta@intel.com> > --- > drivers/gpu/drm/i915/display/intel_display.c | 2 - > drivers/gpu/drm/i915/display/intel_display.h | 9 + > .../drm/i915/display/intel_display_debugfs.c | 95 ++- > .../drm/i915/display/intel_display_types.h | 51 ++ > drivers/gpu/drm/i915/display/intel_dp.c | 10 +- > drivers/gpu/drm/i915/display/intel_psr.c | 600 ++++++++++-------- > drivers/gpu/drm/i915/display/intel_psr.h | 10 +- > drivers/gpu/drm/i915/display/intel_sprite.c | 6 +- > drivers/gpu/drm/i915/i915_drv.h | 38 -- > drivers/gpu/drm/i915/i915_irq.c | 42 +- > 10 files changed, 487 insertions(+), 376 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c > index aca964f7ba72..92c14f3f0abf 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -14145,8 +14145,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) > intel_dvo_init(dev_priv); > } > > > - intel_psr_init(dev_priv); > - > for_each_intel_encoder(&dev_priv->drm, encoder) { > encoder->base.possible_crtcs = > intel_encoder_possible_crtcs(encoder); > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h > index 64ffa34544a7..c72e41b61349 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.h > +++ b/drivers/gpu/drm/i915/display/intel_display.h > @@ -417,10 +417,19 @@ enum phy_fia { > for_each_if((encoder_mask) & \ > drm_encoder_mask(&intel_encoder->base)) > > > +#define for_each_intel_encoder_mask_can_psr(dev, intel_encoder, encoder_mask) \ > + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ > + for_each_if(((encoder_mask) & drm_encoder_mask(&(intel_encoder)->base)) && \ > + intel_encoder_can_psr(intel_encoder)) > + > #define for_each_intel_dp(dev, intel_encoder) \ > for_each_intel_encoder(dev, intel_encoder) \ > for_each_if(intel_encoder_is_dp(intel_encoder)) > > > +#define for_each_intel_encoder_can_psr(dev, intel_encoder) \ > + for_each_intel_encoder((dev), (intel_encoder)) \ > + for_each_if(intel_encoder_can_psr(intel_encoder)) > + > #define for_each_intel_connector_iter(intel_connector, iter) \ > while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter)))) > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c > index d62b18d5ecd8..b1bda1f5ef16 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c > @@ -249,12 +249,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) > "sink internal error", > }; > struct drm_connector *connector = m->private; > - struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_dp *intel_dp = > intel_attached_dp(to_intel_connector(connector)); > int ret; > > > - if (!CAN_PSR(dev_priv)) { > + if (!CAN_PSR(intel_dp)) { > seq_puts(m, "PSR Unsupported\n"); > return -ENODEV; > } > @@ -280,12 +279,13 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) > DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status); > > > static void > -psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) > +psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) > { > - u32 val, status_val; > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > const char *status = "unknown"; > + u32 val, status_val; > > > - if (dev_priv->psr.psr2_enabled) { > + if (intel_dp->psr.psr2_enabled) { > static const char * const live_status[] = { > "IDLE", > "CAPTURE", > @@ -300,7 +300,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) > "TG_ON" > }; > val = intel_de_read(dev_priv, > - EDP_PSR2_STATUS(dev_priv->psr.transcoder)); > + EDP_PSR2_STATUS(intel_dp->psr.transcoder)); > status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >> > EDP_PSR2_STATUS_STATE_SHIFT; > if (status_val < ARRAY_SIZE(live_status)) > @@ -317,7 +317,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) > "SRDENT_ON", > }; > val = intel_de_read(dev_priv, > - EDP_PSR_STATUS(dev_priv->psr.transcoder)); > + EDP_PSR_STATUS(intel_dp->psr.transcoder)); > status_val = (val & EDP_PSR_STATUS_STATE_MASK) >> > EDP_PSR_STATUS_STATE_SHIFT; > if (status_val < ARRAY_SIZE(live_status)) > @@ -327,21 +327,18 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) > seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val); > } > > > -static int i915_edp_psr_status(struct seq_file *m, void *data) > +static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) > { > - struct drm_i915_private *dev_priv = node_to_i915(m->private); > - struct i915_psr *psr = &dev_priv->psr; > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + struct intel_psr *psr = &intel_dp->psr; > intel_wakeref_t wakeref; > const char *status; > bool enabled; > u32 val; > > > - if (!HAS_PSR(dev_priv)) > - return -ENODEV; > - > seq_printf(m, "Sink support: %s", yesno(psr->sink_support)); > - if (psr->dp) > - seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]); > + if (psr->sink_support) > + seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]); > seq_puts(m, "\n"); > > > if (!psr->sink_support) > @@ -365,16 +362,16 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) > > > if (psr->psr2_enabled) { > val = intel_de_read(dev_priv, > - EDP_PSR2_CTL(dev_priv->psr.transcoder)); > + EDP_PSR2_CTL(intel_dp->psr.transcoder)); > enabled = val & EDP_PSR2_ENABLE; > } else { > val = intel_de_read(dev_priv, > - EDP_PSR_CTL(dev_priv->psr.transcoder)); > + EDP_PSR_CTL(intel_dp->psr.transcoder)); > enabled = val & EDP_PSR_ENABLE; > } > seq_printf(m, "Source PSR ctl: %s [0x%08x]\n", > enableddisabled(enabled), val); > - psr_source_status(dev_priv, m); > + psr_source_status(intel_dp, m); > seq_printf(m, "Busy frontbuffer bits: 0x%08x\n", > psr->busy_frontbuffer_bits); > > > @@ -383,7 +380,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) > */ > if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { > val = intel_de_read(dev_priv, > - EDP_PSR_PERF_CNT(dev_priv->psr.transcoder)); > + EDP_PSR_PERF_CNT(intel_dp->psr.transcoder)); > val &= EDP_PSR_PERF_CNT_MASK; > seq_printf(m, "Performance counter: %u\n", val); > } > @@ -404,7 +401,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) > */ > for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) { > val = intel_de_read(dev_priv, > - PSR2_SU_STATUS(dev_priv->psr.transcoder, frame)); > + PSR2_SU_STATUS(intel_dp->psr.transcoder, frame)); > su_frames_val[frame / 3] = val; > } > > > @@ -430,23 +427,50 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) > return 0; > } > > > +static int i915_edp_psr_status(struct seq_file *m, void *data) > +{ > + struct drm_i915_private *dev_priv = node_to_i915(m->private); > + struct intel_dp *intel_dp = NULL; > + struct intel_encoder *encoder; > + > + if (!HAS_PSR(dev_priv)) > + return -ENODEV; > + > + /* Find the first EDP which supports PSR */ > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + intel_dp = enc_to_intel_dp(encoder); > + break; > + } > + > + if (!intel_dp) > + return -ENODEV; > + > + return intel_psr_status(m, intel_dp); > +} > + > static int > i915_edp_psr_debug_set(void *data, u64 val) > { > struct drm_i915_private *dev_priv = data; > + struct intel_encoder *encoder; > intel_wakeref_t wakeref; > - int ret; > + int ret = -ENODEV; > > > - if (!CAN_PSR(dev_priv)) > - return -ENODEV; > + if (!HAS_PSR(dev_priv)) > + return ret; > > > - drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val); > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > > - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); > + drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val); > > > - ret = intel_psr_debug_set(dev_priv, val); > + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); > > > - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); > + // TODO: split to each transcoder's PSR debug state > + ret = intel_psr_debug_set(intel_dp, val); > + > + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); > + } > > > return ret; > } > @@ -455,12 +479,20 @@ static int > i915_edp_psr_debug_get(void *data, u64 *val) > { > struct drm_i915_private *dev_priv = data; > + struct intel_encoder *encoder; > > > - if (!CAN_PSR(dev_priv)) > + if (!HAS_PSR(dev_priv)) > return -ENODEV; > > > - *val = READ_ONCE(dev_priv->psr.debug); > - return 0; > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + > + // TODO: split to each transcoder's PSR debug state > + *val = READ_ONCE(intel_dp->psr.debug); > + return 0; > + } > + > + return -ENODEV; > } > > > DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops, > @@ -1233,9 +1265,6 @@ static void drrs_status_per_crtc(struct seq_file *m, > /* disable_drrs() will make drrs->dp NULL */ > if (!drrs->dp) { > seq_puts(m, "Idleness DRRS: Disabled\n"); > - if (dev_priv->psr.enabled) > - seq_puts(m, > - "\tAs PSR is enabled, DRRS is not enabled\n"); > mutex_unlock(&drrs->mutex); > return; > } > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h > index 39397748b4b0..307ff4b771f4 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1415,6 +1415,43 @@ struct intel_pps { > struct edp_power_seq pps_delays; > }; > > > +struct intel_psr { > + /* Mutex for PSR state of the transcoder */ > + struct mutex lock; > + > +#define I915_PSR_DEBUG_MODE_MASK 0x0f > +#define I915_PSR_DEBUG_DEFAULT 0x00 > +#define I915_PSR_DEBUG_DISABLE 0x01 > +#define I915_PSR_DEBUG_ENABLE 0x02 > +#define I915_PSR_DEBUG_FORCE_PSR1 0x03 > +#define I915_PSR_DEBUG_IRQ 0x10 > + > + u32 debug; > + bool sink_support; > + bool source_support; > + bool enabled; > + enum pipe pipe; > + enum transcoder transcoder; > + bool active; > + struct work_struct work; > + unsigned int busy_frontbuffer_bits; > + bool sink_psr2_support; > + bool link_standby; > + bool colorimetry_support; > + bool psr2_enabled; > + bool psr2_sel_fetch_enabled; > + u8 sink_sync_latency; > + ktime_t last_entry_attempt; > + ktime_t last_exit; > + bool sink_not_reliable; > + bool irq_aux_error; > + u16 su_x_granularity; > + bool dc3co_enabled; > + u32 dc3co_exit_delay; > + struct delayed_work dc3co_work; > + struct drm_dp_vsc_sdp vsc; > +}; > + > struct intel_dp { > i915_reg_t output_reg; > u32 DP; > @@ -1517,6 +1554,8 @@ struct intel_dp { > bool hobl_active; > > > struct intel_dp_pcon_frl frl; > + > + struct intel_psr psr; > }; > > > enum lspcon_vendor { > @@ -1753,6 +1792,18 @@ dp_to_i915(struct intel_dp *intel_dp) > return to_i915(dp_to_dig_port(intel_dp)->base.base.dev); > } > > > +#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) && \ > + (intel_dp)->psr.sink_support && \ > + (intel_dp)->psr.source_support) > + > +static inline bool intel_encoder_can_psr(struct intel_encoder *encoder) > +{ > + if (!intel_encoder_is_dp(encoder)) > + return false; > + > + return CAN_PSR(enc_to_intel_dp(encoder)); > +} > + > static inline struct intel_digital_port * > hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) > { > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c > index a338720cee2e..96789fbd4c06 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -1663,12 +1663,10 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, > const struct drm_connector_state *conn_state, > struct drm_dp_vsc_sdp *vsc) > { > - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - > vsc->sdp_type = DP_SDP_VSC; > > > - if (dev_priv->psr.psr2_enabled) { > - if (dev_priv->psr.colorimetry_support && > + if (intel_dp->psr.psr2_enabled) { > + if (intel_dp->psr.colorimetry_support && > intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { > /* [PSR2, +Colorimetry] */ > intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, > @@ -2359,7 +2357,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, > return false; > } > > > - if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) { > + if (CAN_PSR(intel_dp) && intel_dp_is_edp(intel_dp)) { > drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n"); > crtc_state->uapi.mode_changed = true; > return false; > @@ -6641,6 +6639,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, > intel_dp->frl.is_trained = false; > intel_dp->frl.trained_rate_gbps = 0; > > > + intel_psr_init(intel_dp); > + > return true; > > > fail: > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c > index 2c365b778f74..bf48eb4e1a84 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -80,9 +80,11 @@ > * use page flips. > */ > > > -static bool psr_global_enabled(struct drm_i915_private *i915) > +static bool psr_global_enabled(struct intel_dp *intel_dp) > { > - switch (i915->psr.debug & I915_PSR_DEBUG_MODE_MASK) { > + struct drm_i915_private *i915 = dp_to_i915(intel_dp); > + > + switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) { > case I915_PSR_DEBUG_DEFAULT: > return i915->params.enable_psr; > case I915_PSR_DEBUG_DISABLE: > @@ -92,9 +94,9 @@ static bool psr_global_enabled(struct drm_i915_private *i915) > } > } > > > -static bool psr2_global_enabled(struct drm_i915_private *dev_priv) > +static bool psr2_global_enabled(struct intel_dp *intel_dp) > { > - switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) { > + switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) { > case I915_PSR_DEBUG_DISABLE: > case I915_PSR_DEBUG_FORCE_PSR1: > return false; > @@ -103,11 +105,12 @@ static bool psr2_global_enabled(struct drm_i915_private *dev_priv) > } > } > > > -static void psr_irq_control(struct drm_i915_private *dev_priv) > +static void psr_irq_control(struct intel_dp *intel_dp) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > enum transcoder trans_shift; > - u32 mask, val; > i915_reg_t imr_reg; > + u32 mask, val; > > > /* > * gen12+ has registers relative to transcoder and one per transcoder > @@ -116,14 +119,14 @@ static void psr_irq_control(struct drm_i915_private *dev_priv) > */ > if (INTEL_GEN(dev_priv) >= 12) { > trans_shift = 0; > - imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder); > + imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder); > } else { > - trans_shift = dev_priv->psr.transcoder; > + trans_shift = intel_dp->psr.transcoder; > imr_reg = EDP_PSR_IMR; > } > > > mask = EDP_PSR_ERROR(trans_shift); > - if (dev_priv->psr.debug & I915_PSR_DEBUG_IRQ) > + if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ) > mask |= EDP_PSR_POST_EXIT(trans_shift) | > EDP_PSR_PRE_ENTRY(trans_shift); > > > @@ -172,30 +175,31 @@ static void psr_event_print(struct drm_i915_private *i915, > drm_dbg_kms(&i915->drm, "\tPSR disabled\n"); > } > > > -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) > +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir) > { > - enum transcoder cpu_transcoder = dev_priv->psr.transcoder; > + enum transcoder cpu_transcoder = intel_dp->psr.transcoder; > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + ktime_t time_ns = ktime_get(); > enum transcoder trans_shift; > i915_reg_t imr_reg; > - ktime_t time_ns = ktime_get(); > > > if (INTEL_GEN(dev_priv) >= 12) { > trans_shift = 0; > - imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder); > + imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder); > } else { > - trans_shift = dev_priv->psr.transcoder; > + trans_shift = intel_dp->psr.transcoder; > imr_reg = EDP_PSR_IMR; > } > > > if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) { > - dev_priv->psr.last_entry_attempt = time_ns; > + intel_dp->psr.last_entry_attempt = time_ns; > drm_dbg_kms(&dev_priv->drm, > "[transcoder %s] PSR entry attempt in 2 vblanks\n", > transcoder_name(cpu_transcoder)); > } > > > if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) { > - dev_priv->psr.last_exit = time_ns; > + intel_dp->psr.last_exit = time_ns; > drm_dbg_kms(&dev_priv->drm, > "[transcoder %s] PSR exit completed\n", > transcoder_name(cpu_transcoder)); > @@ -203,7 +207,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) > if (INTEL_GEN(dev_priv) >= 9) { > u32 val = intel_de_read(dev_priv, > PSR_EVENT(cpu_transcoder)); > - bool psr2_enabled = dev_priv->psr.psr2_enabled; > + bool psr2_enabled = intel_dp->psr.psr2_enabled; > > > intel_de_write(dev_priv, PSR_EVENT(cpu_transcoder), > val); > @@ -217,7 +221,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) > drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n", > transcoder_name(cpu_transcoder)); > > > - dev_priv->psr.irq_aux_error = true; > + intel_dp->psr.irq_aux_error = true; > > > /* > * If this interruption is not masked it will keep > @@ -231,7 +235,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) > val |= EDP_PSR_ERROR(trans_shift); > intel_de_write(dev_priv, imr_reg, val); > > > - schedule_work(&dev_priv->psr.work); > + schedule_work(&intel_dp->psr.work); > } > } > > > @@ -292,12 +296,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) > struct drm_i915_private *dev_priv = > to_i915(dp_to_dig_port(intel_dp)->base.base.dev); > > > - if (dev_priv->psr.dp) { > - drm_warn(&dev_priv->drm, > - "More than one eDP panel found, PSR support should be extended\n"); > - return; > - } > - > drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd, > sizeof(intel_dp->psr_dpcd)); > > > @@ -318,12 +316,10 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) > return; > } > > > - dev_priv->psr.sink_support = true; > - dev_priv->psr.sink_sync_latency = > + intel_dp->psr.sink_support = true; > + intel_dp->psr.sink_sync_latency = > intel_dp_get_sink_sync_latency(intel_dp); > > > - dev_priv->psr.dp = intel_dp; > - > if (INTEL_GEN(dev_priv) >= 9 && > (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) { > bool y_req = intel_dp->psr_dpcd[1] & > @@ -341,14 +337,14 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) > * Y-coordinate requirement panels we would need to enable > * GTC first. > */ > - dev_priv->psr.sink_psr2_support = y_req && alpm; > + intel_dp->psr.sink_psr2_support = y_req && alpm; > drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n", > - dev_priv->psr.sink_psr2_support ? "" : "not "); > + intel_dp->psr.sink_psr2_support ? "" : "not "); > > > - if (dev_priv->psr.sink_psr2_support) { > - dev_priv->psr.colorimetry_support = > + if (intel_dp->psr.sink_psr2_support) { > + intel_dp->psr.colorimetry_support = > intel_dp_get_colorimetry_status(intel_dp); > - dev_priv->psr.su_x_granularity = > + intel_dp->psr.su_x_granularity = > intel_dp_get_su_x_granulartiy(intel_dp); > } > } > @@ -374,7 +370,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) > BUILD_BUG_ON(sizeof(aux_msg) > 20); > for (i = 0; i < sizeof(aux_msg); i += 4) > intel_de_write(dev_priv, > - EDP_PSR_AUX_DATA(dev_priv->psr.transcoder, i >> 2), > + EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2), > intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); > > > aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); > @@ -385,7 +381,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) > > > /* Select only valid bits for SRD_AUX_CTL */ > aux_ctl &= psr_aux_mask; > - intel_de_write(dev_priv, EDP_PSR_AUX_CTL(dev_priv->psr.transcoder), > + intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder), > aux_ctl); > } > > > @@ -395,14 +391,14 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp) > u8 dpcd_val = DP_PSR_ENABLE; > > > /* Enable ALPM at sink for psr2 */ > - if (dev_priv->psr.psr2_enabled) { > + if (intel_dp->psr.psr2_enabled) { > drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, > DP_ALPM_ENABLE | > DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE); > > > dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS; > } else { > - if (dev_priv->psr.link_standby) > + if (intel_dp->psr.link_standby) > dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE; > > > if (INTEL_GEN(dev_priv) >= 8) > @@ -465,7 +461,7 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) > * off-by-one issue that HW has in some cases. > */ > idle_frames = max(6, dev_priv->vbt.psr.idle_frames); > - idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); > + idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1); > > > if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf)) > idle_frames = 0xf; > @@ -485,7 +481,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) > if (IS_HASWELL(dev_priv)) > val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; > > > - if (dev_priv->psr.link_standby) > + if (intel_dp->psr.link_standby) > val |= EDP_PSR_LINK_STANDBY; > > > val |= intel_psr1_get_tp_time(intel_dp); > @@ -493,9 +489,9 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) > if (INTEL_GEN(dev_priv) >= 8) > val |= EDP_PSR_CRC_ENABLE; > > > - val |= (intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & > + val |= (intel_de_read(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder)) & > EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK); > - intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), val); > + intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), val); > } > > > static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) > @@ -530,7 +526,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) > if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) > val |= EDP_Y_COORDINATE_ENABLE; > > > - val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv->psr.sink_sync_latency + 1); > + val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1); > val |= intel_psr2_get_tp_time(intel_dp); > > > if (INTEL_GEN(dev_priv) >= 12) { > @@ -549,7 +545,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) > val |= EDP_PSR2_FAST_WAKE(7); > } > > > - if (dev_priv->psr.psr2_sel_fetch_enabled) { > + if (intel_dp->psr.psr2_sel_fetch_enabled) { > /* WA 1408330847 */ > if (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) || > IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)) > @@ -558,20 +554,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) > DIS_RAM_BYPASS_PSR2_MAN_TRACK); > > > intel_de_write(dev_priv, > - PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), > + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), > PSR2_MAN_TRK_CTL_ENABLE); > } else if (HAS_PSR2_SEL_FETCH(dev_priv)) { > intel_de_write(dev_priv, > - PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0); > + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0); > } > > > /* > * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is > * recommending keep this bit unset while PSR2 is enabled. > */ > - intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), 0); > + intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), 0); > > > - intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val); > + intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val); > } > > > static bool > @@ -594,55 +590,58 @@ static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate) > drm_mode_vrefresh(&cstate->hw.adjusted_mode)); > } > > > -static void psr2_program_idle_frames(struct drm_i915_private *dev_priv, > +static void psr2_program_idle_frames(struct intel_dp *intel_dp, > u32 idle_frames) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > u32 val; > > > idle_frames <<= EDP_PSR2_IDLE_FRAME_SHIFT; > - val = intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)); > + val = intel_de_read(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder)); > val &= ~EDP_PSR2_IDLE_FRAME_MASK; > val |= idle_frames; > - intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val); > + intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val); > } > > > -static void tgl_psr2_enable_dc3co(struct drm_i915_private *dev_priv) > +static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp) > { > - psr2_program_idle_frames(dev_priv, 0); > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + > + psr2_program_idle_frames(intel_dp, 0); > intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO); > } > > > -static void tgl_psr2_disable_dc3co(struct drm_i915_private *dev_priv) > +static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp) > { > - struct intel_dp *intel_dp = dev_priv->psr.dp; > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > > > intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); > - psr2_program_idle_frames(dev_priv, psr_compute_idle_frames(intel_dp)); > + psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp)); > } > > > static void tgl_dc3co_disable_work(struct work_struct *work) > { > - struct drm_i915_private *dev_priv = > - container_of(work, typeof(*dev_priv), psr.dc3co_work.work); > + struct intel_dp *intel_dp = > + container_of(work, typeof(*intel_dp), psr.dc3co_work.work); > > > - mutex_lock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > /* If delayed work is pending, it is not idle */ > - if (delayed_work_pending(&dev_priv->psr.dc3co_work)) > + if (delayed_work_pending(&intel_dp->psr.dc3co_work)) > goto unlock; > > > - tgl_psr2_disable_dc3co(dev_priv); > + tgl_psr2_disable_dc3co(intel_dp); > unlock: > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > } > > > -static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv) > +static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp) > { > - if (!dev_priv->psr.dc3co_enabled) > + if (!intel_dp->psr.dc3co_enabled) > return; > > > - cancel_delayed_work(&dev_priv->psr.dc3co_work); > + cancel_delayed_work(&intel_dp->psr.dc3co_work); > /* Before PSR2 exit disallow dc3co*/ > - tgl_psr2_disable_dc3co(dev_priv); > + tgl_psr2_disable_dc3co(intel_dp); > } > > > static void > @@ -715,7 +714,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, > int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay; > int psr_max_h = 0, psr_max_v = 0, max_bpp = 0; > > > - if (!dev_priv->psr.sink_psr2_support) > + if (!intel_dp->psr.sink_psr2_support) > return false; > > > if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) { > @@ -725,7 +724,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, > return false; > } > > > - if (!psr2_global_enabled(dev_priv)) { > + if (!psr2_global_enabled(intel_dp)) { > drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n"); > return false; > } > @@ -774,10 +773,10 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, > * only need to validate the SU block width is a multiple of > * x granularity. > */ > - if (crtc_hdisplay % dev_priv->psr.su_x_granularity) { > + if (crtc_hdisplay % intel_dp->psr.su_x_granularity) { > drm_dbg_kms(&dev_priv->drm, > "PSR2 not enabled, hdisplay(%d) not multiple of %d\n", > - crtc_hdisplay, dev_priv->psr.su_x_granularity); > + crtc_hdisplay, intel_dp->psr.su_x_granularity); > return false; > } > > > @@ -806,7 +805,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, > void intel_psr_compute_config(struct intel_dp *intel_dp, > struct intel_crtc_state *crtc_state) > { > - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > const struct drm_display_mode *adjusted_mode = > &crtc_state->hw.adjusted_mode; > @@ -819,30 +817,15 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, > if (crtc_state->vrr.enable) > return; > > > - if (!CAN_PSR(dev_priv)) > + if (!CAN_PSR(intel_dp)) > return; > > > - if (intel_dp != dev_priv->psr.dp) > - return; > - > - if (!psr_global_enabled(dev_priv)) { > + if (!psr_global_enabled(intel_dp)) { > drm_dbg_kms(&dev_priv->drm, "PSR disabled by flag\n"); > return; > } > > > - /* > - * HSW spec explicitly says PSR is tied to port A. > - * BDW+ platforms have a instance of PSR registers per transcoder but > - * for now it only supports one instance of PSR, so lets keep it > - * hardcoded to PORT_A > - */ > - if (dig_port->base.port != PORT_A) { > - drm_dbg_kms(&dev_priv->drm, > - "PSR condition failed: Port not supported\n"); > - return; > - } > - > - if (dev_priv->psr.sink_not_reliable) { > + if (intel_dp->psr.sink_not_reliable) { > drm_dbg_kms(&dev_priv->drm, > "PSR sink implementation is not reliable\n"); > return; > @@ -878,23 +861,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, > static void intel_psr_activate(struct intel_dp *intel_dp) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + enum transcoder transcoder = intel_dp->psr.transcoder; > > > - if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) > + if (transcoder_has_psr2(dev_priv, transcoder)) > drm_WARN_ON(&dev_priv->drm, > - intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)) & EDP_PSR2_ENABLE); > + intel_de_read(dev_priv, EDP_PSR2_CTL(transcoder)) & EDP_PSR2_ENABLE); > > > drm_WARN_ON(&dev_priv->drm, > - intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & EDP_PSR_ENABLE); > - drm_WARN_ON(&dev_priv->drm, dev_priv->psr.active); > - lockdep_assert_held(&dev_priv->psr.lock); > + intel_de_read(dev_priv, EDP_PSR_CTL(transcoder)) & EDP_PSR_ENABLE); > + drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active); > + lockdep_assert_held(&intel_dp->psr.lock); > > > /* psr1 and psr2 are mutually exclusive.*/ > - if (dev_priv->psr.psr2_enabled) > + if (intel_dp->psr.psr2_enabled) > hsw_activate_psr2(intel_dp); > else > hsw_activate_psr1(intel_dp); > > > - dev_priv->psr.active = true; > + intel_dp->psr.active = true; > } > > > static void intel_psr_enable_source(struct intel_dp *intel_dp, > @@ -910,7 +894,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, > if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) > hsw_psr_setup_aux(intel_dp); > > > - if (dev_priv->psr.psr2_enabled && (IS_GEN(dev_priv, 9) && > + if (intel_dp->psr.psr2_enabled && (IS_GEN(dev_priv, 9) && > !IS_GEMINILAKE(dev_priv))) { > i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder); > u32 chicken = intel_de_read(dev_priv, reg); > @@ -934,10 +918,10 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, > if (INTEL_GEN(dev_priv) < 11) > mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE; > > > - intel_de_write(dev_priv, EDP_PSR_DEBUG(dev_priv->psr.transcoder), > + intel_de_write(dev_priv, EDP_PSR_DEBUG(intel_dp->psr.transcoder), > mask); > > > - psr_irq_control(dev_priv); > + psr_irq_control(intel_dp); > > > if (crtc_state->dc3co_exitline) { > u32 val; > @@ -955,30 +939,30 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, > > > if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv)) > intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING, > - dev_priv->psr.psr2_sel_fetch_enabled ? > + intel_dp->psr.psr2_sel_fetch_enabled ? > IGNORE_PSR2_HW_TRACKING : 0); > } > > > -static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, > +static void intel_psr_enable_locked(struct intel_dp *intel_dp, > const struct intel_crtc_state *crtc_state, > const struct drm_connector_state *conn_state) > { > - struct intel_dp *intel_dp = dev_priv->psr.dp; > struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > struct intel_encoder *encoder = &dig_port->base; > u32 val; > > > - drm_WARN_ON(&dev_priv->drm, dev_priv->psr.enabled); > + drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled); > > > - dev_priv->psr.psr2_enabled = crtc_state->has_psr2; > - dev_priv->psr.busy_frontbuffer_bits = 0; > - dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; > - dev_priv->psr.dc3co_enabled = !!crtc_state->dc3co_exitline; > - dev_priv->psr.transcoder = crtc_state->cpu_transcoder; > + intel_dp->psr.psr2_enabled = crtc_state->has_psr2; > + intel_dp->psr.busy_frontbuffer_bits = 0; > + intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; > + intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline; > + intel_dp->psr.transcoder = crtc_state->cpu_transcoder; > /* DC5/DC6 requires at least 6 idle frames */ > val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6); > - dev_priv->psr.dc3co_exit_delay = val; > - dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch; > + intel_dp->psr.dc3co_exit_delay = val; > + intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch; > > > /* > * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR > @@ -990,27 +974,27 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, > */ > if (INTEL_GEN(dev_priv) >= 12) { > val = intel_de_read(dev_priv, > - TRANS_PSR_IIR(dev_priv->psr.transcoder)); > + TRANS_PSR_IIR(intel_dp->psr.transcoder)); > val &= EDP_PSR_ERROR(0); > } else { > val = intel_de_read(dev_priv, EDP_PSR_IIR); > - val &= EDP_PSR_ERROR(dev_priv->psr.transcoder); > + val &= EDP_PSR_ERROR(intel_dp->psr.transcoder); > } > if (val) { > - dev_priv->psr.sink_not_reliable = true; > + intel_dp->psr.sink_not_reliable = true; > drm_dbg_kms(&dev_priv->drm, > "PSR interruption error set, not enabling PSR\n"); > return; > } > > > drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n", > - dev_priv->psr.psr2_enabled ? "2" : "1"); > + intel_dp->psr.psr2_enabled ? "2" : "1"); > intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state, > - &dev_priv->psr.vsc); > - intel_write_dp_vsc_sdp(encoder, crtc_state, &dev_priv->psr.vsc); > + &intel_dp->psr.vsc); > + intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc); > intel_psr_enable_sink(intel_dp); > intel_psr_enable_source(intel_dp, crtc_state); > - dev_priv->psr.enabled = true; > + intel_dp->psr.enabled = true; > > > intel_psr_activate(intel_dp); > } > @@ -1029,7 +1013,7 @@ void intel_psr_enable(struct intel_dp *intel_dp, > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > > > - if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp) > + if (!CAN_PSR(intel_dp)) > return; > > > if (!crtc_state->has_psr) > @@ -1037,46 +1021,47 @@ void intel_psr_enable(struct intel_dp *intel_dp, > > > drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp); > > > - mutex_lock(&dev_priv->psr.lock); > - intel_psr_enable_locked(dev_priv, crtc_state, conn_state); > - mutex_unlock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > + intel_psr_enable_locked(intel_dp, crtc_state, conn_state); > + mutex_unlock(&intel_dp->psr.lock); > } > > > -static void intel_psr_exit(struct drm_i915_private *dev_priv) > +static void intel_psr_exit(struct intel_dp *intel_dp) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > u32 val; > > > - if (!dev_priv->psr.active) { > - if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) { > + if (!intel_dp->psr.active) { > + if (transcoder_has_psr2(dev_priv, intel_dp->psr.transcoder)) { > val = intel_de_read(dev_priv, > - EDP_PSR2_CTL(dev_priv->psr.transcoder)); > + EDP_PSR2_CTL(intel_dp->psr.transcoder)); > drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE); > } > > > val = intel_de_read(dev_priv, > - EDP_PSR_CTL(dev_priv->psr.transcoder)); > + EDP_PSR_CTL(intel_dp->psr.transcoder)); > drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE); > > > return; > } > > > - if (dev_priv->psr.psr2_enabled) { > - tgl_disallow_dc3co_on_psr2_exit(dev_priv); > + if (intel_dp->psr.psr2_enabled) { > + tgl_disallow_dc3co_on_psr2_exit(intel_dp); > val = intel_de_read(dev_priv, > - EDP_PSR2_CTL(dev_priv->psr.transcoder)); > + EDP_PSR2_CTL(intel_dp->psr.transcoder)); > drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE)); > val &= ~EDP_PSR2_ENABLE; > intel_de_write(dev_priv, > - EDP_PSR2_CTL(dev_priv->psr.transcoder), val); > + EDP_PSR2_CTL(intel_dp->psr.transcoder), val); > } else { > val = intel_de_read(dev_priv, > - EDP_PSR_CTL(dev_priv->psr.transcoder)); > + EDP_PSR_CTL(intel_dp->psr.transcoder)); > drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR_ENABLE)); > val &= ~EDP_PSR_ENABLE; > intel_de_write(dev_priv, > - EDP_PSR_CTL(dev_priv->psr.transcoder), val); > + EDP_PSR_CTL(intel_dp->psr.transcoder), val); > } > - dev_priv->psr.active = false; > + intel_dp->psr.active = false; > } > > > static void intel_psr_disable_locked(struct intel_dp *intel_dp) > @@ -1085,21 +1070,21 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) > i915_reg_t psr_status; > u32 psr_status_mask; > > > - lockdep_assert_held(&dev_priv->psr.lock); > + lockdep_assert_held(&intel_dp->psr.lock); > > > - if (!dev_priv->psr.enabled) > + if (!intel_dp->psr.enabled) > return; > > > drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n", > - dev_priv->psr.psr2_enabled ? "2" : "1"); > + intel_dp->psr.psr2_enabled ? "2" : "1"); > > > - intel_psr_exit(dev_priv); > + intel_psr_exit(intel_dp); > > > - if (dev_priv->psr.psr2_enabled) { > - psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder); > + if (intel_dp->psr.psr2_enabled) { > + psr_status = EDP_PSR2_STATUS(intel_dp->psr.transcoder); > psr_status_mask = EDP_PSR2_STATUS_STATE_MASK; > } else { > - psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder); > + psr_status = EDP_PSR_STATUS(intel_dp->psr.transcoder); > psr_status_mask = EDP_PSR_STATUS_STATE_MASK; > } > > > @@ -1109,7 +1094,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) > drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n"); > > > /* WA 1408330847 */ > - if (dev_priv->psr.psr2_sel_fetch_enabled && > + if (intel_dp->psr.psr2_sel_fetch_enabled && > (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) || > IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))) > intel_de_rmw(dev_priv, CHICKEN_PAR1_1, > @@ -1118,10 +1103,10 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) > /* Disable PSR on Sink */ > drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); > > > - if (dev_priv->psr.psr2_enabled) > + if (intel_dp->psr.psr2_enabled) > drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0); > > > - dev_priv->psr.enabled = false; > + intel_dp->psr.enabled = false; > } > > > /** > @@ -1139,20 +1124,22 @@ void intel_psr_disable(struct intel_dp *intel_dp, > if (!old_crtc_state->has_psr) > return; > > > - if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(dev_priv))) > + if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(intel_dp))) > return; > > > - mutex_lock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > > > intel_psr_disable_locked(intel_dp); > > > - mutex_unlock(&dev_priv->psr.lock); > - cancel_work_sync(&dev_priv->psr.work); > - cancel_delayed_work_sync(&dev_priv->psr.dc3co_work); > + mutex_unlock(&intel_dp->psr.lock); > + cancel_work_sync(&intel_dp->psr.work); > + cancel_delayed_work_sync(&intel_dp->psr.dc3co_work); > } > > > -static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) > +static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + > if (IS_TIGERLAKE(dev_priv)) > /* > * Writes to CURSURFLIVE in TGL are causing IOMMU errors and > @@ -1166,7 +1153,7 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) > * So using this workaround until this issue is root caused > * and a better fix is found. > */ > - intel_psr_exit(dev_priv); > + intel_psr_exit(intel_dp); > else if (INTEL_GEN(dev_priv) >= 9) > /* > * Display WA #0884: skl+ > @@ -1177,13 +1164,13 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) > * but it makes more sense write to the current active > * pipe. > */ > - intel_de_write(dev_priv, CURSURFLIVE(dev_priv->psr.pipe), 0); > + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); > else > /* > * A write to CURSURFLIVE do not cause HW tracking to exit PSR > * on older gens so doing the manual exit instead. > */ > - intel_psr_exit(dev_priv); > + intel_psr_exit(intel_dp); > } > > > void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, > @@ -1231,16 +1218,24 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, > > > void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) > { > - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > - struct i915_psr *psr = &dev_priv->psr; > + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); > + struct intel_encoder *encoder; > > > if (!HAS_PSR2_SEL_FETCH(dev_priv) || > !crtc_state->enable_psr2_sel_fetch) > return; > > > - intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder), > - crtc_state->psr2_man_track_ctl); > + for_each_intel_encoder_mask_can_psr(&dev_priv->drm, encoder, > + crtc_state->uapi.encoder_mask) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + > + if (!intel_dp->psr.enabled) > + continue; > + > + intel_de_write(dev_priv, > + PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder), > + crtc_state->psr2_man_track_ctl); > + } > } > > > static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, > @@ -1435,13 +1430,13 @@ void intel_psr_update(struct intel_dp *intel_dp, > const struct drm_connector_state *conn_state) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - struct i915_psr *psr = &dev_priv->psr; > + struct intel_psr *psr = &intel_dp->psr; > bool enable, psr2_enable; > > > - if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp) > + if (!CAN_PSR(intel_dp)) > return; > > > - mutex_lock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > > > enable = crtc_state->has_psr; > psr2_enable = crtc_state->has_psr2; > @@ -1449,15 +1444,15 @@ void intel_psr_update(struct intel_dp *intel_dp, > if (enable == psr->enabled && psr2_enable == psr->psr2_enabled) { > /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ > if (crtc_state->crc_enabled && psr->enabled) > - psr_force_hw_tracking_exit(dev_priv); > + psr_force_hw_tracking_exit(intel_dp); > else if (INTEL_GEN(dev_priv) < 9 && psr->enabled) { > /* > * Activate PSR again after a force exit when enabling > * CRC in older gens > */ > - if (!dev_priv->psr.active && > - !dev_priv->psr.busy_frontbuffer_bits) > - schedule_work(&dev_priv->psr.work); > + if (!intel_dp->psr.active && > + !intel_dp->psr.busy_frontbuffer_bits) > + schedule_work(&intel_dp->psr.work); > } > > > goto unlock; > @@ -1467,34 +1462,23 @@ void intel_psr_update(struct intel_dp *intel_dp, > intel_psr_disable_locked(intel_dp); > > > if (enable) > - intel_psr_enable_locked(dev_priv, crtc_state, conn_state); > + intel_psr_enable_locked(intel_dp, crtc_state, conn_state); > > > unlock: > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > } > > > /** > - * intel_psr_wait_for_idle - wait for PSR1 to idle > - * @new_crtc_state: new CRTC state > + * psr_wait_for_idle - wait for PSR1 to idle > + * @intel_dp: Intel DP > * @out_value: PSR status in case of failure > * > - * This function is expected to be called from pipe_update_start() where it is > - * not expected to race with PSR enable or disable. > - * > * Returns: 0 on success or -ETIMEOUT if PSR status does not idle. > + * > */ > -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, > - u32 *out_value) > +static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value) > { > - struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); > - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > - > - if (!dev_priv->psr.enabled || !new_crtc_state->has_psr) > - return 0; > - > - /* FIXME: Update this for PSR2 if we need to wait for idle */ > - if (READ_ONCE(dev_priv->psr.psr2_enabled)) > - return 0; > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > > > /* > * From bspec: Panel Self Refresh (BDW+) > @@ -1502,32 +1486,68 @@ int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, > * exit training time + 1.5 ms of aux channel handshake. 50 ms is > * defensive enough to cover everything. > */ > - > return __intel_wait_for_register(&dev_priv->uncore, > - EDP_PSR_STATUS(dev_priv->psr.transcoder), > + EDP_PSR_STATUS(intel_dp->psr.transcoder), > EDP_PSR_STATUS_STATE_MASK, > EDP_PSR_STATUS_STATE_IDLE, 2, 50, > out_value); > } > > > -static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) > +/** > + * intel_psr_wait_for_idle - wait for PSR1 to idle > + * @new_crtc_state: new CRTC state > + * > + * This function is expected to be called from pipe_update_start() where it is > + * not expected to race with PSR enable or disable. > + */ > +void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) > +{ > + struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev); > + struct intel_encoder *encoder; > + > + if (!new_crtc_state->has_psr) > + return; > + > + for_each_intel_encoder_mask_can_psr(&dev_priv->drm, encoder, > + new_crtc_state->uapi.encoder_mask) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + u32 psr_status; > + > + mutex_lock(&intel_dp->psr.lock); > + if (!intel_dp->psr.enabled || > + (intel_dp->psr.enabled && intel_dp->psr.psr2_enabled)) { > + mutex_unlock(&intel_dp->psr.lock); > + continue; > + } > + > + /* when the PSR1 is enabled */ > + if (psr_wait_for_idle(intel_dp, &psr_status)) > + drm_err(&dev_priv->drm, > + "PSR idle timed out 0x%x, atomic update may fail\n", > + psr_status); > + mutex_unlock(&intel_dp->psr.lock); > + } > +} > + > +static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > i915_reg_t reg; > u32 mask; > int err; > > > - if (!dev_priv->psr.enabled) > + if (!intel_dp->psr.enabled) > return false; > > > - if (dev_priv->psr.psr2_enabled) { > - reg = EDP_PSR2_STATUS(dev_priv->psr.transcoder); > + if (intel_dp->psr.psr2_enabled) { > + reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder); > mask = EDP_PSR2_STATUS_STATE_MASK; > } else { > - reg = EDP_PSR_STATUS(dev_priv->psr.transcoder); > + reg = EDP_PSR_STATUS(intel_dp->psr.transcoder); > mask = EDP_PSR_STATUS_STATE_MASK; > } > > > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > > > err = intel_de_wait_for_clear(dev_priv, reg, mask, 50); > if (err) > @@ -1535,8 +1555,8 @@ static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) > "Timed out waiting for PSR Idle for re-enable\n"); > > > /* After the unlocked wait, verify that PSR is still wanted! */ > - mutex_lock(&dev_priv->psr.lock); > - return err == 0 && dev_priv->psr.enabled; > + mutex_lock(&intel_dp->psr.lock); > + return err == 0 && intel_dp->psr.enabled; > } > > > static int intel_psr_fastset_force(struct drm_i915_private *dev_priv) > @@ -1602,8 +1622,9 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv) > return err; > } > > > -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) > +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val) > { > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > const u32 mode = val & I915_PSR_DEBUG_MODE_MASK; > u32 old_mode; > int ret; > @@ -1614,21 +1635,21 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) > return -EINVAL; > } > > > - ret = mutex_lock_interruptible(&dev_priv->psr.lock); > + ret = mutex_lock_interruptible(&intel_dp->psr.lock); > if (ret) > return ret; > > > - old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK; > - dev_priv->psr.debug = val; > + old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK; > + intel_dp->psr.debug = val; > > > /* > * Do it right away if it's already enabled, otherwise it will be done > * when enabling the source. > */ > - if (dev_priv->psr.enabled) > - psr_irq_control(dev_priv); > + if (intel_dp->psr.enabled) > + psr_irq_control(intel_dp); > > > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > > > if (old_mode != mode) > ret = intel_psr_fastset_force(dev_priv); > @@ -1636,28 +1657,28 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) > return ret; > } > > > -static void intel_psr_handle_irq(struct drm_i915_private *dev_priv) > +static void intel_psr_handle_irq(struct intel_dp *intel_dp) > { > - struct i915_psr *psr = &dev_priv->psr; > + struct intel_psr *psr = &intel_dp->psr; > > > - intel_psr_disable_locked(psr->dp); > + intel_psr_disable_locked(intel_dp); > psr->sink_not_reliable = true; > /* let's make sure that sink is awaken */ > - drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0); > + drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); > } > > > static void intel_psr_work(struct work_struct *work) > { > - struct drm_i915_private *dev_priv = > - container_of(work, typeof(*dev_priv), psr.work); > + struct intel_dp *intel_dp = > + container_of(work, typeof(*intel_dp), psr.work); > > > - mutex_lock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > > > - if (!dev_priv->psr.enabled) > + if (!intel_dp->psr.enabled) > goto unlock; > > > - if (READ_ONCE(dev_priv->psr.irq_aux_error)) > - intel_psr_handle_irq(dev_priv); > + if (READ_ONCE(intel_dp->psr.irq_aux_error)) > + intel_psr_handle_irq(intel_dp); > > > /* > * We have to make sure PSR is ready for re-enable > @@ -1665,7 +1686,7 @@ static void intel_psr_work(struct work_struct *work) > * PSR might take some time to get fully disabled > * and be ready for re-enable. > */ > - if (!__psr_wait_for_idle_locked(dev_priv)) > + if (!__psr_wait_for_idle_locked(intel_dp)) > goto unlock; > > > /* > @@ -1673,12 +1694,12 @@ static void intel_psr_work(struct work_struct *work) > * recheck. Since psr_flush first clears this and then reschedules we > * won't ever miss a flush when bailing out here. > */ > - if (dev_priv->psr.busy_frontbuffer_bits || dev_priv->psr.active) > + if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active) > goto unlock; > > > - intel_psr_activate(dev_priv->psr.dp); > + intel_psr_activate(intel_dp); > unlock: > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > } > > > /** > @@ -1697,27 +1718,31 @@ static void intel_psr_work(struct work_struct *work) > void intel_psr_invalidate(struct drm_i915_private *dev_priv, > unsigned frontbuffer_bits, enum fb_op_origin origin) > { > - if (!CAN_PSR(dev_priv)) > - return; > + struct intel_encoder *encoder; > > > if (origin == ORIGIN_FLIP) > return; > > > - mutex_lock(&dev_priv->psr.lock); > - if (!dev_priv->psr.enabled) { > - mutex_unlock(&dev_priv->psr.lock); > - return; > - } > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + unsigned int pipe_frontbuffer_bits = frontbuffer_bits; > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > > - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); > - dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; > + mutex_lock(&intel_dp->psr.lock); > + if (!intel_dp->psr.enabled) { > + mutex_unlock(&intel_dp->psr.lock); > + continue; > + } > > > - if (frontbuffer_bits) > - intel_psr_exit(dev_priv); > + pipe_frontbuffer_bits &= > + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe); > + intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits; > > > - mutex_unlock(&dev_priv->psr.lock); > -} > + if (pipe_frontbuffer_bits) > + intel_psr_exit(intel_dp); > > > + mutex_unlock(&intel_dp->psr.lock); > + } > +} > /* > * When we will be completely rely on PSR2 S/W tracking in future, > * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP > @@ -1725,15 +1750,15 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, > * accordingly in future. > */ > static void > -tgl_dc3co_flush(struct drm_i915_private *dev_priv, > - unsigned int frontbuffer_bits, enum fb_op_origin origin) > +tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, > + enum fb_op_origin origin) > { > - mutex_lock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > > > - if (!dev_priv->psr.dc3co_enabled) > + if (!intel_dp->psr.dc3co_enabled) > goto unlock; > > > - if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active) > + if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active) > goto unlock; > > > /* > @@ -1741,15 +1766,15 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv, > * when delayed work schedules that means display has been idle. > */ > if (!(frontbuffer_bits & > - INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe))) > + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe))) > goto unlock; > > > - tgl_psr2_enable_dc3co(dev_priv); > - mod_delayed_work(system_wq, &dev_priv->psr.dc3co_work, > - dev_priv->psr.dc3co_exit_delay); > + tgl_psr2_enable_dc3co(intel_dp); > + mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work, > + intel_dp->psr.dc3co_exit_delay); > > > unlock: > - mutex_unlock(&dev_priv->psr.lock); > + mutex_unlock(&intel_dp->psr.lock); > } > > > /** > @@ -1768,47 +1793,73 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv, > void intel_psr_flush(struct drm_i915_private *dev_priv, > unsigned frontbuffer_bits, enum fb_op_origin origin) > { > - if (!CAN_PSR(dev_priv)) > - return; > + struct intel_encoder *encoder; > > > - if (origin == ORIGIN_FLIP) { > - tgl_dc3co_flush(dev_priv, frontbuffer_bits, origin); > - return; > - } > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + unsigned int pipe_frontbuffer_bits = frontbuffer_bits; > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > > - mutex_lock(&dev_priv->psr.lock); > - if (!dev_priv->psr.enabled) { > - mutex_unlock(&dev_priv->psr.lock); > - return; > - } > + if (origin == ORIGIN_FLIP) { > + tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin); > + continue; > + } > + > + mutex_lock(&intel_dp->psr.lock); > + if (!intel_dp->psr.enabled) { > + mutex_unlock(&intel_dp->psr.lock); > + continue; > + } > > > - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); > - dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; > + pipe_frontbuffer_bits &= > + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe); > + intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits; > > > - /* By definition flush = invalidate + flush */ > - if (frontbuffer_bits) > - psr_force_hw_tracking_exit(dev_priv); > + /* By definition flush = invalidate + flush */ > + if (pipe_frontbuffer_bits) > + psr_force_hw_tracking_exit(intel_dp); > > > - if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) > - schedule_work(&dev_priv->psr.work); > - mutex_unlock(&dev_priv->psr.lock); > + if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) > + schedule_work(&intel_dp->psr.work); > + mutex_unlock(&intel_dp->psr.lock); > + } > } > > > /** > * intel_psr_init - Init basic PSR work and mutex. > - * @dev_priv: i915 device private > + * @intel_dp: Intel DP > * > - * This function is called only once at driver load to initialize basic > - * PSR stuff. > + * This function is called after the initializing connector. > + * (the initializing of connector treats the handling of connector capabilities) > + * And it initializes basic PSR stuff for each DP Encoder. > */ > -void intel_psr_init(struct drm_i915_private *dev_priv) > +void intel_psr_init(struct intel_dp *intel_dp) > { > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + > if (!HAS_PSR(dev_priv)) > return; > > > - if (!dev_priv->psr.sink_support) > + if (!intel_dp->psr.sink_support) > return; > > > + /* > + * HSW spec explicitly says PSR is tied to port A. > + * BDW+ platforms have a instance of PSR registers per transcoder but > + * BDW, GEN9 and GEN11 are not validated by HW team in other transcoder > + * than eDP one. > + * For now it only supports one instance of PSR for BDW, GEN9 and GEN11. > + * So lets keep it hardcoded to PORT_A for BDW, GEN9 and GEN11. > + * But GEN12 supports a instance of PSR registers per transcoder. > + */ > + if (INTEL_GEN(dev_priv) < 12 && dig_port->base.port != PORT_A) { > + drm_dbg_kms(&dev_priv->drm, > + "PSR condition failed: Port not supported\n"); > + return; > + } > + > + intel_dp->psr.source_support = true; > + > if (IS_HASWELL(dev_priv)) > /* > * HSW don't have PSR registers on the same space as transcoder > @@ -1824,14 +1875,14 @@ void intel_psr_init(struct drm_i915_private *dev_priv) > /* Set link_standby x link_off defaults */ > if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) > /* HSW and BDW require workarounds that we don't implement. */ > - dev_priv->psr.link_standby = false; > + intel_dp->psr.link_standby = false; > else if (INTEL_GEN(dev_priv) < 12) > /* For new platforms up to TGL let's respect VBT back again */ > - dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; > + intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link; > > > - INIT_WORK(&dev_priv->psr.work, intel_psr_work); > - INIT_DELAYED_WORK(&dev_priv->psr.dc3co_work, tgl_dc3co_disable_work); > - mutex_init(&dev_priv->psr.lock); > + INIT_WORK(&intel_dp->psr.work, intel_psr_work); > + INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work); > + mutex_init(&intel_dp->psr.lock); > } > > > static int psr_get_status_and_error_status(struct intel_dp *intel_dp, > @@ -1857,7 +1908,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > struct drm_dp_aux *aux = &intel_dp->aux; > - struct i915_psr *psr = &dev_priv->psr; > + struct intel_psr *psr = &intel_dp->psr; > u8 val; > int r; > > > @@ -1884,7 +1935,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp) > static void psr_capability_changed_check(struct intel_dp *intel_dp) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - struct i915_psr *psr = &dev_priv->psr; > + struct intel_psr *psr = &intel_dp->psr; > u8 val; > int r; > > > @@ -1908,18 +1959,18 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp) > void intel_psr_short_pulse(struct intel_dp *intel_dp) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - struct i915_psr *psr = &dev_priv->psr; > + struct intel_psr *psr = &intel_dp->psr; > u8 status, error_status; > const u8 errors = DP_PSR_RFB_STORAGE_ERROR | > DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR | > DP_PSR_LINK_CRC_ERROR; > > > - if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp)) > + if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp)) > return; > > > mutex_lock(&psr->lock); > > > - if (!psr->enabled || psr->dp != intel_dp) > + if (!psr->enabled) > goto exit; > > > if (psr_get_status_and_error_status(intel_dp, &status, &error_status)) { > @@ -1962,15 +2013,14 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) > > > bool intel_psr_enabled(struct intel_dp *intel_dp) > { > - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > bool ret; > > > - if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp)) > + if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp)) > return false; > > > - mutex_lock(&dev_priv->psr.lock); > - ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled); > - mutex_unlock(&dev_priv->psr.lock); > + mutex_lock(&intel_dp->psr.lock); > + ret = intel_dp->psr.enabled; > + mutex_unlock(&intel_dp->psr.lock); > > > return ret; > } > diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h > index 0a517978e8af..0491a49ffd50 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.h > +++ b/drivers/gpu/drm/i915/display/intel_psr.h > @@ -18,7 +18,6 @@ struct intel_atomic_state; > struct intel_plane_state; > struct intel_plane; > > > -#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support) > void intel_psr_init_dpcd(struct intel_dp *intel_dp); > void intel_psr_enable(struct intel_dp *intel_dp, > const struct intel_crtc_state *crtc_state, > @@ -28,20 +27,19 @@ void intel_psr_disable(struct intel_dp *intel_dp, > void intel_psr_update(struct intel_dp *intel_dp, > const struct intel_crtc_state *crtc_state, > const struct drm_connector_state *conn_state); > -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value); > +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value); > void intel_psr_invalidate(struct drm_i915_private *dev_priv, > unsigned frontbuffer_bits, > enum fb_op_origin origin); > void intel_psr_flush(struct drm_i915_private *dev_priv, > unsigned frontbuffer_bits, > enum fb_op_origin origin); > -void intel_psr_init(struct drm_i915_private *dev_priv); > +void intel_psr_init(struct intel_dp *intel_dp); > void intel_psr_compute_config(struct intel_dp *intel_dp, > struct intel_crtc_state *crtc_state); > -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir); > +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); > void intel_psr_short_pulse(struct intel_dp *intel_dp); > -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, > - u32 *out_value); > +void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); > bool intel_psr_enabled(struct intel_dp *intel_dp); > int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, > struct intel_crtc *crtc); > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c > index 402030251c64..26025251b038 100644 > --- a/drivers/gpu/drm/i915/display/intel_sprite.c > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c > @@ -96,7 +96,6 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) > bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && > intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); > DEFINE_WAIT(wait); > - u32 psr_status; > > > if (new_crtc_state->uapi.async_flip) > return; > @@ -122,10 +121,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) > * VBL interrupts will start the PSR exit and prevent a PSR > * re-entry as well. > */ > - if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) > - drm_err(&dev_priv->drm, > - "PSR idle timed out 0x%x, atomic update may fail\n", > - psr_status); > + intel_psr_wait_for_idle(new_crtc_state); > > > local_irq_disable(); > > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index a2fd7e5039b3..b289832f00b1 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -478,42 +478,6 @@ struct i915_drrs { > enum drrs_support_type type; > }; > > > -struct i915_psr { > - struct mutex lock; > - > -#define I915_PSR_DEBUG_MODE_MASK 0x0f > -#define I915_PSR_DEBUG_DEFAULT 0x00 > -#define I915_PSR_DEBUG_DISABLE 0x01 > -#define I915_PSR_DEBUG_ENABLE 0x02 > -#define I915_PSR_DEBUG_FORCE_PSR1 0x03 > -#define I915_PSR_DEBUG_IRQ 0x10 > - > - u32 debug; > - bool sink_support; > - bool enabled; > - struct intel_dp *dp; > - enum pipe pipe; > - enum transcoder transcoder; > - bool active; > - struct work_struct work; > - unsigned busy_frontbuffer_bits; > - bool sink_psr2_support; > - bool link_standby; > - bool colorimetry_support; > - bool psr2_enabled; > - bool psr2_sel_fetch_enabled; > - u8 sink_sync_latency; > - ktime_t last_entry_attempt; > - ktime_t last_exit; > - bool sink_not_reliable; > - bool irq_aux_error; > - u16 su_x_granularity; > - bool dc3co_enabled; > - u32 dc3co_exit_delay; > - struct delayed_work dc3co_work; > - struct drm_dp_vsc_sdp vsc; > -}; > - > #define QUIRK_LVDS_SSC_DISABLE (1<<1) > #define QUIRK_INVERT_BRIGHTNESS (1<<2) > #define QUIRK_BACKLIGHT_PRESENT (1<<3) > @@ -1041,8 +1005,6 @@ struct drm_i915_private { > > > struct i915_power_domains power_domains; > > > - struct i915_psr psr; > - > struct i915_gpu_error gpu_error; > > > struct drm_i915_gem_object *vlv_pctx; > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c > index 0ff3f64c4bb5..98145a7f28a4 100644 > --- a/drivers/gpu/drm/i915/i915_irq.c > +++ b/drivers/gpu/drm/i915/i915_irq.c > @@ -2094,10 +2094,19 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, > ivb_err_int_handler(dev_priv); > > > if (de_iir & DE_EDP_PSR_INT_HSW) { > - u32 psr_iir = intel_uncore_read(&dev_priv->uncore, EDP_PSR_IIR); > + struct intel_encoder *encoder; > > > - intel_psr_irq_handler(dev_priv, psr_iir); > - intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR, psr_iir); > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > + > + u32 psr_iir = intel_uncore_read(&dev_priv->uncore, > + EDP_PSR_IIR); > + > + intel_psr_irq_handler(intel_dp, psr_iir); > + intel_uncore_write(&dev_priv->uncore, > + EDP_PSR_IIR, psr_iir); > + break; > + } > } > > > if (de_iir & DE_AUX_CHANNEL_A_IVB) > @@ -2310,21 +2319,30 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) > } > > > if (iir & GEN8_DE_EDP_PSR) { > + struct intel_encoder *encoder; > u32 psr_iir; > i915_reg_t iir_reg; > > > - if (INTEL_GEN(dev_priv) >= 12) > - iir_reg = TRANS_PSR_IIR(dev_priv->psr.transcoder); > - else > - iir_reg = EDP_PSR_IIR; > + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { > + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); > > > - psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg); > - intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir); > + if (INTEL_GEN(dev_priv) >= 12) > + iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder); > + else > + iir_reg = EDP_PSR_IIR; > > > - if (psr_iir) > - found = true; > + psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg); > + intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir); > > > - intel_psr_irq_handler(dev_priv, psr_iir); > + if (psr_iir) > + found = true; > + > + intel_psr_irq_handler(intel_dp, psr_iir); > + > + /* prior GEN12 only have one EDP PSR */ > + if (INTEL_GEN(dev_priv) < 12) > + break; > + } > } > > > if (!found)
On Fri, 2021-02-05 at 03:08 +0000, Patchwork wrote: > == Series Details == > > Series: series starting with [v15,1/2] drm/i915/display: Support PSR Multiple Instances > URL : https://patchwork.freedesktop.org/series/86701/ > State : success > > == Summary == > > CI Bug Log - changes from CI_DRM_9732_full -> Patchwork_19590_full > ==================================================== > > Summary > ------- > > **SUCCESS** > > No regressions found. > Pushed, thanks for the patches. > > > > > > Possible new issues > ------------------- > > Here are the unknown changes that may have been introduced in Patchwork_19590_full: > > ### Piglit changes ### > > #### Possible regressions #### > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x2_2 (NEW): > - {pig-icl-1065g7}: NOTRUN -> [CRASH][1] > [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/pig-icl-1065g7/spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x2_2.html > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x3 (NEW): > - {pig-icl-1065g7}: NOTRUN -> [INCOMPLETE][2] +7 similar issues > [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/pig-icl-1065g7/spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x3.html > > > > > > New tests > --------- > > New tests have been introduced between CI_DRM_9732_full and Patchwork_19590_full: > > ### New Piglit tests (9) ### > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-ivec4: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat2x4: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat3_2: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x2_2: > - Statuses : 1 crash(s) > - Exec time: [0.53] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-mat4x3: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-uint: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-uvec4: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-uvec4_2: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > * spec@arb_tessellation_shader@execution@tcs-input@tcs-input-vec2: > - Statuses : 1 incomplete(s) > - Exec time: [0.0] s > > > > > > > Known issues > ------------ > > Here are the changes found in Patchwork_19590_full that come from known issues: > > ### IGT changes ### > > #### Issues hit #### > > * igt@gem_create@create-massive: > - shard-tglb: NOTRUN -> [DMESG-WARN][3] ([i915#3002]) > [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb1/igt@gem_create@create-massive.html > > * igt@gem_exec_balancer@hang: > - shard-iclb: [PASS][4] -> [INCOMPLETE][5] ([i915#1895] / [i915#2295] / [i915#3031]) > [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb8/igt@gem_exec_balancer@hang.html > [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb2/igt@gem_exec_balancer@hang.html > > * igt@gem_exec_fair@basic-none@vcs1: > - shard-iclb: NOTRUN -> [FAIL][6] ([i915#2842]) > [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb2/igt@gem_exec_fair@basic-none@vcs1.html > > * igt@gem_exec_fair@basic-pace-share@rcs0: > - shard-glk: [PASS][7] -> [FAIL][8] ([i915#2842]) > [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk8/igt@gem_exec_fair@basic-pace-share@rcs0.html > [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@gem_exec_fair@basic-pace-share@rcs0.html > > * igt@gem_exec_params@secure-non-root: > - shard-tglb: NOTRUN -> [SKIP][9] ([fdo#112283]) > [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gem_exec_params@secure-non-root.html > > * igt@gem_exec_reloc@basic-parallel: > - shard-tglb: NOTRUN -> [TIMEOUT][10] ([i915#1729]) > [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gem_exec_reloc@basic-parallel.html > > * igt@gem_exec_schedule@u-fairslice@rcs0: > - shard-glk: [PASS][11] -> [DMESG-WARN][12] ([i915#1610] / [i915#2803]) > [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk9/igt@gem_exec_schedule@u-fairslice@rcs0.html > [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk4/igt@gem_exec_schedule@u-fairslice@rcs0.html > > * igt@gem_pipe_control_store_loop@reused-buffer: > - shard-glk: [PASS][13] -> [DMESG-WARN][14] ([i915#118] / [i915#95]) > [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk7/igt@gem_pipe_control_store_loop@reused-buffer.html > [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@gem_pipe_control_store_loop@reused-buffer.html > > * igt@gem_userptr_blits@readonly-mmap-unsync@wb: > - shard-tglb: NOTRUN -> [SKIP][15] ([i915#1704]) +3 similar issues > [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb1/igt@gem_userptr_blits@readonly-mmap-unsync@wb.html > > * igt@gem_userptr_blits@readonly-unsync: > - shard-tglb: NOTRUN -> [SKIP][16] ([fdo#110426] / [i915#1704]) > [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gem_userptr_blits@readonly-unsync.html > > * igt@gen3_render_mixed_blits: > - shard-tglb: NOTRUN -> [SKIP][17] ([fdo#109289]) > [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gen3_render_mixed_blits.html > > * igt@gen9_exec_parse@bb-chained: > - shard-tglb: NOTRUN -> [SKIP][18] ([fdo#112306]) > [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gen9_exec_parse@bb-chained.html > > * igt@i915_pm_backlight@bad-brightness: > - shard-glk: NOTRUN -> [SKIP][19] ([fdo#109271]) +51 similar issues > [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@i915_pm_backlight@bad-brightness.html > > * igt@kms_big_fb@y-tiled-8bpp-rotate-270: > - shard-tglb: NOTRUN -> [SKIP][20] ([fdo#111614]) +1 similar issue > [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_big_fb@y-tiled-8bpp-rotate-270.html > > * igt@kms_big_fb@yf-tiled-16bpp-rotate-0: > - shard-tglb: NOTRUN -> [SKIP][21] ([fdo#111615]) > [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_big_fb@yf-tiled-16bpp-rotate-0.html > > * igt@kms_big_joiner@invalid-modeset: > - shard-glk: NOTRUN -> [SKIP][22] ([fdo#109271] / [i915#2705]) > [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk3/igt@kms_big_joiner@invalid-modeset.html > > * igt@kms_chamelium@hdmi-hpd-storm-disable: > - shard-skl: NOTRUN -> [SKIP][23] ([fdo#109271] / [fdo#111827]) +3 similar issues > [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_chamelium@hdmi-hpd-storm-disable.html > > * igt@kms_color_chamelium@pipe-b-ctm-0-5: > - shard-tglb: NOTRUN -> [SKIP][24] ([fdo#109284] / [fdo#111827]) +3 similar issues > [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_color_chamelium@pipe-b-ctm-0-5.html > > * igt@kms_color_chamelium@pipe-d-degamma: > - shard-glk: NOTRUN -> [SKIP][25] ([fdo#109271] / [fdo#111827]) +7 similar issues > [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@kms_color_chamelium@pipe-d-degamma.html > > * igt@kms_cursor_crc@pipe-b-cursor-128x42-random: > - shard-skl: [PASS][26] -> [FAIL][27] ([i915#54]) +7 similar issues > [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl6/igt@kms_cursor_crc@pipe-b-cursor-128x42-random.html > [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl4/igt@kms_cursor_crc@pipe-b-cursor-128x42-random.html > > * igt@kms_cursor_crc@pipe-b-cursor-256x85-onscreen: > - shard-skl: NOTRUN -> [FAIL][28] ([i915#54]) +1 similar issue > [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_cursor_crc@pipe-b-cursor-256x85-onscreen.html > > * igt@kms_cursor_crc@pipe-c-cursor-512x170-offscreen: > - shard-tglb: NOTRUN -> [SKIP][29] ([fdo#109279]) +2 similar issues > [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_cursor_crc@pipe-c-cursor-512x170-offscreen.html > > * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size: > - shard-skl: NOTRUN -> [FAIL][30] ([i915#2346] / [i915#533]) > [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html > > * igt@kms_cursor_legacy@flip-vs-cursor-toggle: > - shard-tglb: [PASS][31] -> [FAIL][32] ([i915#2346]) > [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb7/igt@kms_cursor_legacy@flip-vs-cursor-toggle.html > [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb5/igt@kms_cursor_legacy@flip-vs-cursor-toggle.html > > * igt@kms_cursor_legacy@pipe-d-torture-move: > - shard-skl: NOTRUN -> [SKIP][33] ([fdo#109271]) +43 similar issues > [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl9/igt@kms_cursor_legacy@pipe-d-torture-move.html > > * igt@kms_flip@flip-vs-absolute-wf_vblank-interruptible@c-edp1: > - shard-skl: [PASS][34] -> [FAIL][35] ([i915#2122]) > [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl4/igt@kms_flip@flip-vs-absolute-wf_vblank-interruptible@c-edp1.html > [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl2/igt@kms_flip@flip-vs-absolute-wf_vblank-interruptible@c-edp1.html > > * igt@kms_flip@flip-vs-suspend-interruptible@a-dp1: > - shard-apl: [PASS][36] -> [DMESG-WARN][37] ([i915#180]) +1 similar issue > [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-apl8/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html > [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html > > * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs: > - shard-glk: NOTRUN -> [SKIP][38] ([fdo#109271] / [i915#2672]) > [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk3/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs.html > > * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-mmap-gtt: > - shard-tglb: NOTRUN -> [SKIP][39] ([fdo#111825]) +13 similar issues > [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb1/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-pri-indfb-draw-mmap-gtt.html > > * igt@kms_frontbuffer_tracking@psr-suspend: > - shard-skl: [PASS][40] -> [INCOMPLETE][41] ([i915#123]) > [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl6/igt@kms_frontbuffer_tracking@psr-suspend.html > [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_frontbuffer_tracking@psr-suspend.html > > * igt@kms_hdr@static-toggle: > - shard-tglb: NOTRUN -> [SKIP][42] ([i915#1187]) > [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_hdr@static-toggle.html > > * igt@kms_multipipe_modeset@basic-max-pipe-crc-check: > - shard-tglb: NOTRUN -> [SKIP][43] ([i915#1839]) > [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_multipipe_modeset@basic-max-pipe-crc-check.html > > * igt@kms_pipe_crc_basic@read-crc-pipe-d: > - shard-glk: NOTRUN -> [SKIP][44] ([fdo#109271] / [i915#533]) > [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@kms_pipe_crc_basic@read-crc-pipe-d.html > > * igt@kms_plane_alpha_blend@pipe-c-alpha-7efc: > - shard-skl: NOTRUN -> [FAIL][45] ([fdo#108145] / [i915#265]) > [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl9/igt@kms_plane_alpha_blend@pipe-c-alpha-7efc.html > > * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-5: > - shard-tglb: NOTRUN -> [SKIP][46] ([i915#2920]) > [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-5.html > > * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1: > - shard-skl: NOTRUN -> [SKIP][47] ([fdo#109271] / [i915#658]) +1 similar issue > [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html > > * igt@kms_psr@psr2_primary_mmap_cpu: > - shard-iclb: [PASS][48] -> [SKIP][49] ([fdo#109441]) > [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb2/igt@kms_psr@psr2_primary_mmap_cpu.html > [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb8/igt@kms_psr@psr2_primary_mmap_cpu.html > > * igt@kms_vblank@pipe-c-ts-continuation-suspend: > - shard-skl: [PASS][50] -> [INCOMPLETE][51] ([i915#198]) > [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl9/igt@kms_vblank@pipe-c-ts-continuation-suspend.html > [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl2/igt@kms_vblank@pipe-c-ts-continuation-suspend.html > > * igt@kms_vblank@pipe-d-wait-idle: > - shard-skl: NOTRUN -> [SKIP][52] ([fdo#109271] / [i915#533]) +1 similar issue > [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl7/igt@kms_vblank@pipe-d-wait-idle.html > > * igt@nouveau_crc@pipe-d-ctx-flip-detection: > - shard-tglb: NOTRUN -> [SKIP][53] ([i915#2530]) > [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@nouveau_crc@pipe-d-ctx-flip-detection.html > > * igt@perf@polling-parameterized: > - shard-skl: [PASS][54] -> [FAIL][55] ([i915#1542]) > [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl10/igt@perf@polling-parameterized.html > [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl8/igt@perf@polling-parameterized.html > > * igt@prime_nv_api@nv_self_import_to_different_fd: > - shard-tglb: NOTRUN -> [SKIP][56] ([fdo#109291]) > [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@prime_nv_api@nv_self_import_to_different_fd.html > > * igt@prime_vgem@fence-write-hang: > - shard-tglb: NOTRUN -> [SKIP][57] ([fdo#109295]) > [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@prime_vgem@fence-write-hang.html > > * igt@sysfs_clients@recycle: > - shard-iclb: [PASS][58] -> [FAIL][59] ([i915#3028]) > [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb4/igt@sysfs_clients@recycle.html > [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb4/igt@sysfs_clients@recycle.html > - shard-kbl: [PASS][60] -> [FAIL][61] ([i915#3028]) > [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-kbl7/igt@sysfs_clients@recycle.html > [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-kbl2/igt@sysfs_clients@recycle.html > > > > > > #### Possible fixes #### > > * igt@gem_ctx_persistence@smoketest: > - shard-tglb: [FAIL][62] ([i915#2896]) -> [PASS][63] > [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb3/igt@gem_ctx_persistence@smoketest.html > [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb7/igt@gem_ctx_persistence@smoketest.html > > * igt@gem_exec_fair@basic-none-share@rcs0: > - shard-tglb: [FAIL][64] ([i915#2842]) -> [PASS][65] > [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb5/igt@gem_exec_fair@basic-none-share@rcs0.html > [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb2/igt@gem_exec_fair@basic-none-share@rcs0.html > > * igt@gem_exec_fair@basic-none-vip@rcs0: > - shard-glk: [FAIL][66] ([i915#2842]) -> [PASS][67] > [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk1/igt@gem_exec_fair@basic-none-vip@rcs0.html > [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk4/igt@gem_exec_fair@basic-none-vip@rcs0.html > > * igt@gem_exec_schedule@u-fairslice@vcs0: > - shard-skl: [DMESG-WARN][68] ([i915#1610] / [i915#2803]) -> [PASS][69] +1 similar issue > [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl6/igt@gem_exec_schedule@u-fairslice@vcs0.html > [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl9/igt@gem_exec_schedule@u-fairslice@vcs0.html > > * igt@gen9_exec_parse@allowed-all: > - shard-glk: [DMESG-WARN][70] ([i915#1436] / [i915#716]) -> [PASS][71] > [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk3/igt@gen9_exec_parse@allowed-all.html > [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk3/igt@gen9_exec_parse@allowed-all.html > > * igt@i915_pm_dc@dc6-psr: > - shard-iclb: [FAIL][72] ([i915#454]) -> [PASS][73] > [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb4/igt@i915_pm_dc@dc6-psr.html > [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb7/igt@i915_pm_dc@dc6-psr.html > > * igt@kms_cursor_crc@pipe-c-cursor-128x42-sliding: > - shard-skl: [FAIL][74] ([i915#54]) -> [PASS][75] +4 similar issues > [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl2/igt@kms_cursor_crc@pipe-c-cursor-128x42-sliding.html > [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl8/igt@kms_cursor_crc@pipe-c-cursor-128x42-sliding.html > > * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic: > - shard-hsw: [FAIL][76] ([i915#96]) -> [PASS][77] > [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-hsw8/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html > [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-hsw2/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html > > * igt@kms_flip@flip-vs-suspend-interruptible@c-dp1: > - shard-apl: [DMESG-WARN][78] ([i915#180]) -> [PASS][79] > [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-apl8/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html > [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-apl1/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html > > * igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1: > - shard-skl: [FAIL][80] ([i915#2122]) -> [PASS][81] +1 similar issue > [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl8/igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1.html > [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl3/igt@kms_flip@plain-flip-fb-recreate-interruptible@b-edp1.html > > * igt@kms_psr2_su@frontbuffer: > - shard-iclb: [SKIP][82] ([fdo#109642] / [fdo#111068] / [i915#658]) -> [PASS][83] > [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb5/igt@kms_psr2_su@frontbuffer.html > [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb2/igt@kms_psr2_su@frontbuffer.html > > * igt@kms_psr@psr2_no_drrs: > - shard-iclb: [SKIP][84] ([fdo#109441]) -> [PASS][85] +1 similar issue > [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb8/igt@kms_psr@psr2_no_drrs.html > [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb2/igt@kms_psr@psr2_no_drrs.html > > * igt@kms_vblank@pipe-a-ts-continuation-dpms-suspend: > - shard-glk: [INCOMPLETE][86] -> [PASS][87] > [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk9/igt@kms_vblank@pipe-a-ts-continuation-dpms-suspend.html > [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk2/igt@kms_vblank@pipe-a-ts-continuation-dpms-suspend.html > > * igt@prime_vgem@sync@vcs0: > - shard-tglb: [INCOMPLETE][88] ([i915#409]) -> [PASS][89] > [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb1/igt@prime_vgem@sync@vcs0.html > [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb1/igt@prime_vgem@sync@vcs0.html > > * {igt@sysfs_clients@recycle-many}: > - shard-kbl: [FAIL][90] ([i915#3028]) -> [PASS][91] > [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-kbl7/igt@sysfs_clients@recycle-many.html > [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-kbl1/igt@sysfs_clients@recycle-many.html > > * igt@sysfs_clients@sema-10@vcs0: > - shard-apl: [SKIP][92] ([fdo#109271] / [i915#3026]) -> [PASS][93] > [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-apl7/igt@sysfs_clients@sema-10@vcs0.html > [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-apl3/igt@sysfs_clients@sema-10@vcs0.html > > > > > > #### Warnings #### > > * igt@gem_exec_fair@basic-none-rrul@rcs0: > - shard-iclb: [FAIL][94] ([i915#2852]) -> [FAIL][95] ([i915#2842]) > [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb5/igt@gem_exec_fair@basic-none-rrul@rcs0.html > [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb3/igt@gem_exec_fair@basic-none-rrul@rcs0.html > > * igt@gem_exec_fair@basic-throttle@rcs0: > - shard-iclb: [FAIL][96] ([i915#2849]) -> [FAIL][97] ([i915#2842]) > [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb1/igt@gem_exec_fair@basic-throttle@rcs0.html > [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb3/igt@gem_exec_fair@basic-throttle@rcs0.html > > * igt@i915_pm_rc6_residency@rc6-fence: > - shard-iclb: [WARN][98] ([i915#1804] / [i915#2684]) -> [WARN][99] ([i915#2681] / [i915#2684]) > [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb6/igt@i915_pm_rc6_residency@rc6-fence.html > [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb1/igt@i915_pm_rc6_residency@rc6-fence.html > > * igt@kms_dp_dsc@basic-dsc-enable-edp: > - shard-iclb: [DMESG-WARN][100] ([i915#1226]) -> [SKIP][101] ([fdo#109349]) > [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb2/igt@kms_dp_dsc@basic-dsc-enable-edp.html > [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb8/igt@kms_dp_dsc@basic-dsc-enable-edp.html > > * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1: > - shard-iclb: [SKIP][102] ([i915#658]) -> [SKIP][103] ([i915#2920]) +1 similar issue > [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb5/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html > [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html > > * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3: > - shard-kbl: [SKIP][104] ([fdo#109271] / [i915#658]) -> [SKIP][105] ([fdo#109271]) +18 similar issues > [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-kbl6/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html > [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-kbl6/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html > > * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-5: > - shard-apl: [SKIP][106] ([fdo#109271] / [i915#658]) -> [SKIP][107] ([fdo#109271]) +17 similar issues > [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-apl7/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-5.html > [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-apl3/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-5.html > > * igt@kms_psr2_sf@plane-move-sf-dmg-area-0: > - shard-iclb: [SKIP][108] ([i915#2920]) -> [SKIP][109] ([i915#658]) +3 similar issues > [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html > [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-iclb8/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html > > * igt@kms_psr2_su@frontbuffer: > - shard-glk: [SKIP][110] ([fdo#109271] / [i915#658]) -> [SKIP][111] ([fdo#109271]) +16 similar issues > [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk3/igt@kms_psr2_su@frontbuffer.html > [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk4/igt@kms_psr2_su@frontbuffer.html > > * igt@kms_psr@primary_page_flip: > - shard-hsw: [SKIP][112] ([fdo#109271] / [i915#1072]) -> [SKIP][113] ([fdo#109271]) +38 similar issues > [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-hsw2/igt@kms_psr@primary_page_flip.html > [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-hsw4/igt@kms_psr@primary_page_flip.html > > * igt@runner@aborted: > - shard-glk: ([FAIL][114], [FAIL][115], [FAIL][116], [FAIL][117]) ([i915#2295] / [i915#3002] / [k.org#202321]) -> ([FAIL][118], [FAIL][119], [FAIL][120], [FAIL][121]) ([i915#2295] / [i915#2426] / [i915#3002] / [k.org#202321]) > [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk3/igt@runner@aborted.html > [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk8/igt@runner@aborted.html > [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk1/igt@runner@aborted.html > [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-glk9/igt@runner@aborted.html > [118]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk7/igt@runner@aborted.html > [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk4/igt@runner@aborted.html > [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk9/igt@runner@aborted.html > [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-glk3/igt@runner@aborted.html > - shard-tglb: ([FAIL][122], [FAIL][123], [FAIL][124], [FAIL][125]) ([i915#2295] / [i915#2426] / [i915#2667] / [i915#3002] / [i915#409]) -> ([FAIL][126], [FAIL][127], [FAIL][128]) ([i915#2295] / [i915#2667] / [i915#3002]) > [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb2/igt@runner@aborted.html > [123]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb6/igt@runner@aborted.html > [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb6/igt@runner@aborted.html > [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-tglb1/igt@runner@aborted.html > [126]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb8/igt@runner@aborted.html > [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb1/igt@runner@aborted.html > [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-tglb6/igt@runner@aborted.html > - shard-skl: ([FAIL][129], [FAIL][130], [FAIL][131], [FAIL][132], [FAIL][133]) ([i915#2295] / [i915#2426] / [i915#3002]) -> ([FAIL][134], [FAIL][135], [FAIL][136]) ([i915#2295] / [i915#3002]) > [129]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl6/igt@runner@aborted.html > [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl7/igt@runner@aborted.html > [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl4/igt@runner@aborted.html > [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl2/igt@runner@aborted.html > [133]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9732/shard-skl2/igt@runner@aborted.html > [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl8/igt@runner@aborted.html > [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl8/igt@runner@aborted.html > [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/shard-skl10/igt@runner@aborted.html > > > > > > {name}: This element is suppressed. This means it is ignored when computing > the status of the difference (SUCCESS, WARNING, or FAILURE). > > [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145 > [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271 > [fdo#109279]: https://bugs.freedesktop.org/show_bug.cgi?id=109279 > [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284 > [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289 > [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291 > [fdo#109295]: https://bugs.freedesktop.org/show_bug.cgi?id=109295 > [fdo#109349]: https://bugs.freedesktop.org/show_bug.cgi?id=109349 > [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441 > [fdo#109642]: https://bugs.freedesktop.org/show_bug.cgi?id=109642 > [fdo#110426]: https://bugs.freedesktop.org/show_bug.cgi?id=110426 > [fdo#111068]: https://bugs.freedesktop.org/show_bug.cgi?id=111068 > [fdo#111614]: https://bugs.freedesktop.org/show_bug.cgi?id=111614 > [fdo#111615]: https://bugs.freedesktop.org/show_bug.cgi?id=111615 > [fdo#111825]: https://bugs.freedesktop.org/show_bug.cgi?id=111825 > [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827 > [fdo#112283]: https://bugs.freedesktop.org/show_bug.cgi?id=112283 > [fdo#112306]: https://bugs.freedesktop.org/show_bug.cgi?id=112306 > [i915#1072]: https://gitlab.freedesktop.org/drm/intel/issues/1072 > [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118 > [i915#1187]: https://gitlab.freedesktop.org/drm/intel/issues/1187 > [i915#1226]: https://gitlab.freedesktop.org/drm/intel/issues/1226 > [i915#123]: https://gitlab.freedesktop.org/drm/intel/issues/123 > [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436 > [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542 > [i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610 > [i915#1704]: https://gitlab.freedesktop.org/drm/intel/issues/1704 > [i915#1729]: https://gitlab.freedesktop.org/drm/intel/issues/1729 > [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180 > [i915#1804]: https://gitlab.freedesktop.org/drm/intel/issues/1804 > [i915#1839]: https://gitlab.freedesktop.org/drm/intel/issues/1839 > [i915#1895]: https://gitlab.freedesktop.org/drm/intel/issues/18 > > == Logs == > > For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19590/index.html > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index aca964f7ba72..92c14f3f0abf 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -14145,8 +14145,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) intel_dvo_init(dev_priv); } - intel_psr_init(dev_priv); - for_each_intel_encoder(&dev_priv->drm, encoder) { encoder->base.possible_crtcs = intel_encoder_possible_crtcs(encoder); diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 64ffa34544a7..c72e41b61349 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -417,10 +417,19 @@ enum phy_fia { for_each_if((encoder_mask) & \ drm_encoder_mask(&intel_encoder->base)) +#define for_each_intel_encoder_mask_can_psr(dev, intel_encoder, encoder_mask) \ + list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ + for_each_if(((encoder_mask) & drm_encoder_mask(&(intel_encoder)->base)) && \ + intel_encoder_can_psr(intel_encoder)) + #define for_each_intel_dp(dev, intel_encoder) \ for_each_intel_encoder(dev, intel_encoder) \ for_each_if(intel_encoder_is_dp(intel_encoder)) +#define for_each_intel_encoder_can_psr(dev, intel_encoder) \ + for_each_intel_encoder((dev), (intel_encoder)) \ + for_each_if(intel_encoder_can_psr(intel_encoder)) + #define for_each_intel_connector_iter(intel_connector, iter) \ while ((intel_connector = to_intel_connector(drm_connector_list_iter_next(iter)))) diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index d62b18d5ecd8..b1bda1f5ef16 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -249,12 +249,11 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) "sink internal error", }; struct drm_connector *connector = m->private; - struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); int ret; - if (!CAN_PSR(dev_priv)) { + if (!CAN_PSR(intel_dp)) { seq_puts(m, "PSR Unsupported\n"); return -ENODEV; } @@ -280,12 +279,13 @@ static int i915_psr_sink_status_show(struct seq_file *m, void *data) DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status); static void -psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) +psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) { - u32 val, status_val; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); const char *status = "unknown"; + u32 val, status_val; - if (dev_priv->psr.psr2_enabled) { + if (intel_dp->psr.psr2_enabled) { static const char * const live_status[] = { "IDLE", "CAPTURE", @@ -300,7 +300,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) "TG_ON" }; val = intel_de_read(dev_priv, - EDP_PSR2_STATUS(dev_priv->psr.transcoder)); + EDP_PSR2_STATUS(intel_dp->psr.transcoder)); status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >> EDP_PSR2_STATUS_STATE_SHIFT; if (status_val < ARRAY_SIZE(live_status)) @@ -317,7 +317,7 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) "SRDENT_ON", }; val = intel_de_read(dev_priv, - EDP_PSR_STATUS(dev_priv->psr.transcoder)); + EDP_PSR_STATUS(intel_dp->psr.transcoder)); status_val = (val & EDP_PSR_STATUS_STATE_MASK) >> EDP_PSR_STATUS_STATE_SHIFT; if (status_val < ARRAY_SIZE(live_status)) @@ -327,21 +327,18 @@ psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m) seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val); } -static int i915_edp_psr_status(struct seq_file *m, void *data) +static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = node_to_i915(m->private); - struct i915_psr *psr = &dev_priv->psr; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + struct intel_psr *psr = &intel_dp->psr; intel_wakeref_t wakeref; const char *status; bool enabled; u32 val; - if (!HAS_PSR(dev_priv)) - return -ENODEV; - seq_printf(m, "Sink support: %s", yesno(psr->sink_support)); - if (psr->dp) - seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]); + if (psr->sink_support) + seq_printf(m, " [0x%02x]", intel_dp->psr_dpcd[0]); seq_puts(m, "\n"); if (!psr->sink_support) @@ -365,16 +362,16 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) if (psr->psr2_enabled) { val = intel_de_read(dev_priv, - EDP_PSR2_CTL(dev_priv->psr.transcoder)); + EDP_PSR2_CTL(intel_dp->psr.transcoder)); enabled = val & EDP_PSR2_ENABLE; } else { val = intel_de_read(dev_priv, - EDP_PSR_CTL(dev_priv->psr.transcoder)); + EDP_PSR_CTL(intel_dp->psr.transcoder)); enabled = val & EDP_PSR_ENABLE; } seq_printf(m, "Source PSR ctl: %s [0x%08x]\n", enableddisabled(enabled), val); - psr_source_status(dev_priv, m); + psr_source_status(intel_dp, m); seq_printf(m, "Busy frontbuffer bits: 0x%08x\n", psr->busy_frontbuffer_bits); @@ -383,7 +380,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) */ if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { val = intel_de_read(dev_priv, - EDP_PSR_PERF_CNT(dev_priv->psr.transcoder)); + EDP_PSR_PERF_CNT(intel_dp->psr.transcoder)); val &= EDP_PSR_PERF_CNT_MASK; seq_printf(m, "Performance counter: %u\n", val); } @@ -404,7 +401,7 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) */ for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) { val = intel_de_read(dev_priv, - PSR2_SU_STATUS(dev_priv->psr.transcoder, frame)); + PSR2_SU_STATUS(intel_dp->psr.transcoder, frame)); su_frames_val[frame / 3] = val; } @@ -430,23 +427,50 @@ static int i915_edp_psr_status(struct seq_file *m, void *data) return 0; } +static int i915_edp_psr_status(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_dp *intel_dp = NULL; + struct intel_encoder *encoder; + + if (!HAS_PSR(dev_priv)) + return -ENODEV; + + /* Find the first EDP which supports PSR */ + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + intel_dp = enc_to_intel_dp(encoder); + break; + } + + if (!intel_dp) + return -ENODEV; + + return intel_psr_status(m, intel_dp); +} + static int i915_edp_psr_debug_set(void *data, u64 val) { struct drm_i915_private *dev_priv = data; + struct intel_encoder *encoder; intel_wakeref_t wakeref; - int ret; + int ret = -ENODEV; - if (!CAN_PSR(dev_priv)) - return -ENODEV; + if (!HAS_PSR(dev_priv)) + return ret; - drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val); + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val); - ret = intel_psr_debug_set(dev_priv, val); + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + // TODO: split to each transcoder's PSR debug state + ret = intel_psr_debug_set(intel_dp, val); + + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + } return ret; } @@ -455,12 +479,20 @@ static int i915_edp_psr_debug_get(void *data, u64 *val) { struct drm_i915_private *dev_priv = data; + struct intel_encoder *encoder; - if (!CAN_PSR(dev_priv)) + if (!HAS_PSR(dev_priv)) return -ENODEV; - *val = READ_ONCE(dev_priv->psr.debug); - return 0; + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + // TODO: split to each transcoder's PSR debug state + *val = READ_ONCE(intel_dp->psr.debug); + return 0; + } + + return -ENODEV; } DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops, @@ -1233,9 +1265,6 @@ static void drrs_status_per_crtc(struct seq_file *m, /* disable_drrs() will make drrs->dp NULL */ if (!drrs->dp) { seq_puts(m, "Idleness DRRS: Disabled\n"); - if (dev_priv->psr.enabled) - seq_puts(m, - "\tAs PSR is enabled, DRRS is not enabled\n"); mutex_unlock(&drrs->mutex); return; } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 39397748b4b0..307ff4b771f4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1415,6 +1415,43 @@ struct intel_pps { struct edp_power_seq pps_delays; }; +struct intel_psr { + /* Mutex for PSR state of the transcoder */ + struct mutex lock; + +#define I915_PSR_DEBUG_MODE_MASK 0x0f +#define I915_PSR_DEBUG_DEFAULT 0x00 +#define I915_PSR_DEBUG_DISABLE 0x01 +#define I915_PSR_DEBUG_ENABLE 0x02 +#define I915_PSR_DEBUG_FORCE_PSR1 0x03 +#define I915_PSR_DEBUG_IRQ 0x10 + + u32 debug; + bool sink_support; + bool source_support; + bool enabled; + enum pipe pipe; + enum transcoder transcoder; + bool active; + struct work_struct work; + unsigned int busy_frontbuffer_bits; + bool sink_psr2_support; + bool link_standby; + bool colorimetry_support; + bool psr2_enabled; + bool psr2_sel_fetch_enabled; + u8 sink_sync_latency; + ktime_t last_entry_attempt; + ktime_t last_exit; + bool sink_not_reliable; + bool irq_aux_error; + u16 su_x_granularity; + bool dc3co_enabled; + u32 dc3co_exit_delay; + struct delayed_work dc3co_work; + struct drm_dp_vsc_sdp vsc; +}; + struct intel_dp { i915_reg_t output_reg; u32 DP; @@ -1517,6 +1554,8 @@ struct intel_dp { bool hobl_active; struct intel_dp_pcon_frl frl; + + struct intel_psr psr; }; enum lspcon_vendor { @@ -1753,6 +1792,18 @@ dp_to_i915(struct intel_dp *intel_dp) return to_i915(dp_to_dig_port(intel_dp)->base.base.dev); } +#define CAN_PSR(intel_dp) (HAS_PSR(dp_to_i915(intel_dp)) && \ + (intel_dp)->psr.sink_support && \ + (intel_dp)->psr.source_support) + +static inline bool intel_encoder_can_psr(struct intel_encoder *encoder) +{ + if (!intel_encoder_is_dp(encoder)) + return false; + + return CAN_PSR(enc_to_intel_dp(encoder)); +} + static inline struct intel_digital_port * hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a338720cee2e..96789fbd4c06 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1663,12 +1663,10 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, const struct drm_connector_state *conn_state, struct drm_dp_vsc_sdp *vsc) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - vsc->sdp_type = DP_SDP_VSC; - if (dev_priv->psr.psr2_enabled) { - if (dev_priv->psr.colorimetry_support && + if (intel_dp->psr.psr2_enabled) { + if (intel_dp->psr.colorimetry_support && intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { /* [PSR2, +Colorimetry] */ intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, @@ -2359,7 +2357,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, return false; } - if (CAN_PSR(i915) && intel_dp_is_edp(intel_dp)) { + if (CAN_PSR(intel_dp) && intel_dp_is_edp(intel_dp)) { drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n"); crtc_state->uapi.mode_changed = true; return false; @@ -6641,6 +6639,8 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, intel_dp->frl.is_trained = false; intel_dp->frl.trained_rate_gbps = 0; + intel_psr_init(intel_dp); + return true; fail: diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 2c365b778f74..bf48eb4e1a84 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -80,9 +80,11 @@ * use page flips. */ -static bool psr_global_enabled(struct drm_i915_private *i915) +static bool psr_global_enabled(struct intel_dp *intel_dp) { - switch (i915->psr.debug & I915_PSR_DEBUG_MODE_MASK) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); + + switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) { case I915_PSR_DEBUG_DEFAULT: return i915->params.enable_psr; case I915_PSR_DEBUG_DISABLE: @@ -92,9 +94,9 @@ static bool psr_global_enabled(struct drm_i915_private *i915) } } -static bool psr2_global_enabled(struct drm_i915_private *dev_priv) +static bool psr2_global_enabled(struct intel_dp *intel_dp) { - switch (dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK) { + switch (intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK) { case I915_PSR_DEBUG_DISABLE: case I915_PSR_DEBUG_FORCE_PSR1: return false; @@ -103,11 +105,12 @@ static bool psr2_global_enabled(struct drm_i915_private *dev_priv) } } -static void psr_irq_control(struct drm_i915_private *dev_priv) +static void psr_irq_control(struct intel_dp *intel_dp) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); enum transcoder trans_shift; - u32 mask, val; i915_reg_t imr_reg; + u32 mask, val; /* * gen12+ has registers relative to transcoder and one per transcoder @@ -116,14 +119,14 @@ static void psr_irq_control(struct drm_i915_private *dev_priv) */ if (INTEL_GEN(dev_priv) >= 12) { trans_shift = 0; - imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder); + imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder); } else { - trans_shift = dev_priv->psr.transcoder; + trans_shift = intel_dp->psr.transcoder; imr_reg = EDP_PSR_IMR; } mask = EDP_PSR_ERROR(trans_shift); - if (dev_priv->psr.debug & I915_PSR_DEBUG_IRQ) + if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ) mask |= EDP_PSR_POST_EXIT(trans_shift) | EDP_PSR_PRE_ENTRY(trans_shift); @@ -172,30 +175,31 @@ static void psr_event_print(struct drm_i915_private *i915, drm_dbg_kms(&i915->drm, "\tPSR disabled\n"); } -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir) { - enum transcoder cpu_transcoder = dev_priv->psr.transcoder; + enum transcoder cpu_transcoder = intel_dp->psr.transcoder; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + ktime_t time_ns = ktime_get(); enum transcoder trans_shift; i915_reg_t imr_reg; - ktime_t time_ns = ktime_get(); if (INTEL_GEN(dev_priv) >= 12) { trans_shift = 0; - imr_reg = TRANS_PSR_IMR(dev_priv->psr.transcoder); + imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder); } else { - trans_shift = dev_priv->psr.transcoder; + trans_shift = intel_dp->psr.transcoder; imr_reg = EDP_PSR_IMR; } if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) { - dev_priv->psr.last_entry_attempt = time_ns; + intel_dp->psr.last_entry_attempt = time_ns; drm_dbg_kms(&dev_priv->drm, "[transcoder %s] PSR entry attempt in 2 vblanks\n", transcoder_name(cpu_transcoder)); } if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) { - dev_priv->psr.last_exit = time_ns; + intel_dp->psr.last_exit = time_ns; drm_dbg_kms(&dev_priv->drm, "[transcoder %s] PSR exit completed\n", transcoder_name(cpu_transcoder)); @@ -203,7 +207,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) if (INTEL_GEN(dev_priv) >= 9) { u32 val = intel_de_read(dev_priv, PSR_EVENT(cpu_transcoder)); - bool psr2_enabled = dev_priv->psr.psr2_enabled; + bool psr2_enabled = intel_dp->psr.psr2_enabled; intel_de_write(dev_priv, PSR_EVENT(cpu_transcoder), val); @@ -217,7 +221,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n", transcoder_name(cpu_transcoder)); - dev_priv->psr.irq_aux_error = true; + intel_dp->psr.irq_aux_error = true; /* * If this interruption is not masked it will keep @@ -231,7 +235,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir) val |= EDP_PSR_ERROR(trans_shift); intel_de_write(dev_priv, imr_reg, val); - schedule_work(&dev_priv->psr.work); + schedule_work(&intel_dp->psr.work); } } @@ -292,12 +296,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) struct drm_i915_private *dev_priv = to_i915(dp_to_dig_port(intel_dp)->base.base.dev); - if (dev_priv->psr.dp) { - drm_warn(&dev_priv->drm, - "More than one eDP panel found, PSR support should be extended\n"); - return; - } - drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd, sizeof(intel_dp->psr_dpcd)); @@ -318,12 +316,10 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) return; } - dev_priv->psr.sink_support = true; - dev_priv->psr.sink_sync_latency = + intel_dp->psr.sink_support = true; + intel_dp->psr.sink_sync_latency = intel_dp_get_sink_sync_latency(intel_dp); - dev_priv->psr.dp = intel_dp; - if (INTEL_GEN(dev_priv) >= 9 && (intel_dp->psr_dpcd[0] == DP_PSR2_WITH_Y_COORD_IS_SUPPORTED)) { bool y_req = intel_dp->psr_dpcd[1] & @@ -341,14 +337,14 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) * Y-coordinate requirement panels we would need to enable * GTC first. */ - dev_priv->psr.sink_psr2_support = y_req && alpm; + intel_dp->psr.sink_psr2_support = y_req && alpm; drm_dbg_kms(&dev_priv->drm, "PSR2 %ssupported\n", - dev_priv->psr.sink_psr2_support ? "" : "not "); + intel_dp->psr.sink_psr2_support ? "" : "not "); - if (dev_priv->psr.sink_psr2_support) { - dev_priv->psr.colorimetry_support = + if (intel_dp->psr.sink_psr2_support) { + intel_dp->psr.colorimetry_support = intel_dp_get_colorimetry_status(intel_dp); - dev_priv->psr.su_x_granularity = + intel_dp->psr.su_x_granularity = intel_dp_get_su_x_granulartiy(intel_dp); } } @@ -374,7 +370,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) BUILD_BUG_ON(sizeof(aux_msg) > 20); for (i = 0; i < sizeof(aux_msg); i += 4) intel_de_write(dev_priv, - EDP_PSR_AUX_DATA(dev_priv->psr.transcoder, i >> 2), + EDP_PSR_AUX_DATA(intel_dp->psr.transcoder, i >> 2), intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); aux_clock_divider = intel_dp->get_aux_clock_divider(intel_dp, 0); @@ -385,7 +381,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) /* Select only valid bits for SRD_AUX_CTL */ aux_ctl &= psr_aux_mask; - intel_de_write(dev_priv, EDP_PSR_AUX_CTL(dev_priv->psr.transcoder), + intel_de_write(dev_priv, EDP_PSR_AUX_CTL(intel_dp->psr.transcoder), aux_ctl); } @@ -395,14 +391,14 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp) u8 dpcd_val = DP_PSR_ENABLE; /* Enable ALPM at sink for psr2 */ - if (dev_priv->psr.psr2_enabled) { + if (intel_dp->psr.psr2_enabled) { drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE); dpcd_val |= DP_PSR_ENABLE_PSR2 | DP_PSR_IRQ_HPD_WITH_CRC_ERRORS; } else { - if (dev_priv->psr.link_standby) + if (intel_dp->psr.link_standby) dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE; if (INTEL_GEN(dev_priv) >= 8) @@ -465,7 +461,7 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) * off-by-one issue that HW has in some cases. */ idle_frames = max(6, dev_priv->vbt.psr.idle_frames); - idle_frames = max(idle_frames, dev_priv->psr.sink_sync_latency + 1); + idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1); if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf)) idle_frames = 0xf; @@ -485,7 +481,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) if (IS_HASWELL(dev_priv)) val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; - if (dev_priv->psr.link_standby) + if (intel_dp->psr.link_standby) val |= EDP_PSR_LINK_STANDBY; val |= intel_psr1_get_tp_time(intel_dp); @@ -493,9 +489,9 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) if (INTEL_GEN(dev_priv) >= 8) val |= EDP_PSR_CRC_ENABLE; - val |= (intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & + val |= (intel_de_read(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder)) & EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK); - intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), val); + intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), val); } static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) @@ -530,7 +526,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) val |= EDP_Y_COORDINATE_ENABLE; - val |= EDP_PSR2_FRAME_BEFORE_SU(dev_priv->psr.sink_sync_latency + 1); + val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1); val |= intel_psr2_get_tp_time(intel_dp); if (INTEL_GEN(dev_priv) >= 12) { @@ -549,7 +545,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) val |= EDP_PSR2_FAST_WAKE(7); } - if (dev_priv->psr.psr2_sel_fetch_enabled) { + if (intel_dp->psr.psr2_sel_fetch_enabled) { /* WA 1408330847 */ if (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) || IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)) @@ -558,20 +554,20 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) DIS_RAM_BYPASS_PSR2_MAN_TRACK); intel_de_write(dev_priv, - PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), PSR2_MAN_TRK_CTL_ENABLE); } else if (HAS_PSR2_SEL_FETCH(dev_priv)) { intel_de_write(dev_priv, - PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0); + PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0); } /* * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is * recommending keep this bit unset while PSR2 is enabled. */ - intel_de_write(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder), 0); + intel_de_write(dev_priv, EDP_PSR_CTL(intel_dp->psr.transcoder), 0); - intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val); + intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val); } static bool @@ -594,55 +590,58 @@ static u32 intel_get_frame_time_us(const struct intel_crtc_state *cstate) drm_mode_vrefresh(&cstate->hw.adjusted_mode)); } -static void psr2_program_idle_frames(struct drm_i915_private *dev_priv, +static void psr2_program_idle_frames(struct intel_dp *intel_dp, u32 idle_frames) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 val; idle_frames <<= EDP_PSR2_IDLE_FRAME_SHIFT; - val = intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)); + val = intel_de_read(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder)); val &= ~EDP_PSR2_IDLE_FRAME_MASK; val |= idle_frames; - intel_de_write(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder), val); + intel_de_write(dev_priv, EDP_PSR2_CTL(intel_dp->psr.transcoder), val); } -static void tgl_psr2_enable_dc3co(struct drm_i915_private *dev_priv) +static void tgl_psr2_enable_dc3co(struct intel_dp *intel_dp) { - psr2_program_idle_frames(dev_priv, 0); + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + + psr2_program_idle_frames(intel_dp, 0); intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_DC3CO); } -static void tgl_psr2_disable_dc3co(struct drm_i915_private *dev_priv) +static void tgl_psr2_disable_dc3co(struct intel_dp *intel_dp) { - struct intel_dp *intel_dp = dev_priv->psr.dp; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); intel_display_power_set_target_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6); - psr2_program_idle_frames(dev_priv, psr_compute_idle_frames(intel_dp)); + psr2_program_idle_frames(intel_dp, psr_compute_idle_frames(intel_dp)); } static void tgl_dc3co_disable_work(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), psr.dc3co_work.work); + struct intel_dp *intel_dp = + container_of(work, typeof(*intel_dp), psr.dc3co_work.work); - mutex_lock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); /* If delayed work is pending, it is not idle */ - if (delayed_work_pending(&dev_priv->psr.dc3co_work)) + if (delayed_work_pending(&intel_dp->psr.dc3co_work)) goto unlock; - tgl_psr2_disable_dc3co(dev_priv); + tgl_psr2_disable_dc3co(intel_dp); unlock: - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); } -static void tgl_disallow_dc3co_on_psr2_exit(struct drm_i915_private *dev_priv) +static void tgl_disallow_dc3co_on_psr2_exit(struct intel_dp *intel_dp) { - if (!dev_priv->psr.dc3co_enabled) + if (!intel_dp->psr.dc3co_enabled) return; - cancel_delayed_work(&dev_priv->psr.dc3co_work); + cancel_delayed_work(&intel_dp->psr.dc3co_work); /* Before PSR2 exit disallow dc3co*/ - tgl_psr2_disable_dc3co(dev_priv); + tgl_psr2_disable_dc3co(intel_dp); } static void @@ -715,7 +714,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay; int psr_max_h = 0, psr_max_v = 0, max_bpp = 0; - if (!dev_priv->psr.sink_psr2_support) + if (!intel_dp->psr.sink_psr2_support) return false; if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) { @@ -725,7 +724,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; } - if (!psr2_global_enabled(dev_priv)) { + if (!psr2_global_enabled(intel_dp)) { drm_dbg_kms(&dev_priv->drm, "PSR2 disabled by flag\n"); return false; } @@ -774,10 +773,10 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, * only need to validate the SU block width is a multiple of * x granularity. */ - if (crtc_hdisplay % dev_priv->psr.su_x_granularity) { + if (crtc_hdisplay % intel_dp->psr.su_x_granularity) { drm_dbg_kms(&dev_priv->drm, "PSR2 not enabled, hdisplay(%d) not multiple of %d\n", - crtc_hdisplay, dev_priv->psr.su_x_granularity); + crtc_hdisplay, intel_dp->psr.su_x_granularity); return false; } @@ -806,7 +805,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, void intel_psr_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -819,30 +817,15 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, if (crtc_state->vrr.enable) return; - if (!CAN_PSR(dev_priv)) + if (!CAN_PSR(intel_dp)) return; - if (intel_dp != dev_priv->psr.dp) - return; - - if (!psr_global_enabled(dev_priv)) { + if (!psr_global_enabled(intel_dp)) { drm_dbg_kms(&dev_priv->drm, "PSR disabled by flag\n"); return; } - /* - * HSW spec explicitly says PSR is tied to port A. - * BDW+ platforms have a instance of PSR registers per transcoder but - * for now it only supports one instance of PSR, so lets keep it - * hardcoded to PORT_A - */ - if (dig_port->base.port != PORT_A) { - drm_dbg_kms(&dev_priv->drm, - "PSR condition failed: Port not supported\n"); - return; - } - - if (dev_priv->psr.sink_not_reliable) { + if (intel_dp->psr.sink_not_reliable) { drm_dbg_kms(&dev_priv->drm, "PSR sink implementation is not reliable\n"); return; @@ -878,23 +861,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, static void intel_psr_activate(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + enum transcoder transcoder = intel_dp->psr.transcoder; - if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) + if (transcoder_has_psr2(dev_priv, transcoder)) drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, EDP_PSR2_CTL(dev_priv->psr.transcoder)) & EDP_PSR2_ENABLE); + intel_de_read(dev_priv, EDP_PSR2_CTL(transcoder)) & EDP_PSR2_ENABLE); drm_WARN_ON(&dev_priv->drm, - intel_de_read(dev_priv, EDP_PSR_CTL(dev_priv->psr.transcoder)) & EDP_PSR_ENABLE); - drm_WARN_ON(&dev_priv->drm, dev_priv->psr.active); - lockdep_assert_held(&dev_priv->psr.lock); + intel_de_read(dev_priv, EDP_PSR_CTL(transcoder)) & EDP_PSR_ENABLE); + drm_WARN_ON(&dev_priv->drm, intel_dp->psr.active); + lockdep_assert_held(&intel_dp->psr.lock); /* psr1 and psr2 are mutually exclusive.*/ - if (dev_priv->psr.psr2_enabled) + if (intel_dp->psr.psr2_enabled) hsw_activate_psr2(intel_dp); else hsw_activate_psr1(intel_dp); - dev_priv->psr.active = true; + intel_dp->psr.active = true; } static void intel_psr_enable_source(struct intel_dp *intel_dp, @@ -910,7 +894,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) hsw_psr_setup_aux(intel_dp); - if (dev_priv->psr.psr2_enabled && (IS_GEN(dev_priv, 9) && + if (intel_dp->psr.psr2_enabled && (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv))) { i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder); u32 chicken = intel_de_read(dev_priv, reg); @@ -934,10 +918,10 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, if (INTEL_GEN(dev_priv) < 11) mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE; - intel_de_write(dev_priv, EDP_PSR_DEBUG(dev_priv->psr.transcoder), + intel_de_write(dev_priv, EDP_PSR_DEBUG(intel_dp->psr.transcoder), mask); - psr_irq_control(dev_priv); + psr_irq_control(intel_dp); if (crtc_state->dc3co_exitline) { u32 val; @@ -955,30 +939,30 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, if (HAS_PSR_HW_TRACKING(dev_priv) && HAS_PSR2_SEL_FETCH(dev_priv)) intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING, - dev_priv->psr.psr2_sel_fetch_enabled ? + intel_dp->psr.psr2_sel_fetch_enabled ? IGNORE_PSR2_HW_TRACKING : 0); } -static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, +static void intel_psr_enable_locked(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct intel_dp *intel_dp = dev_priv->psr.dp; struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct intel_encoder *encoder = &dig_port->base; u32 val; - drm_WARN_ON(&dev_priv->drm, dev_priv->psr.enabled); + drm_WARN_ON(&dev_priv->drm, intel_dp->psr.enabled); - dev_priv->psr.psr2_enabled = crtc_state->has_psr2; - dev_priv->psr.busy_frontbuffer_bits = 0; - dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - dev_priv->psr.dc3co_enabled = !!crtc_state->dc3co_exitline; - dev_priv->psr.transcoder = crtc_state->cpu_transcoder; + intel_dp->psr.psr2_enabled = crtc_state->has_psr2; + intel_dp->psr.busy_frontbuffer_bits = 0; + intel_dp->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; + intel_dp->psr.dc3co_enabled = !!crtc_state->dc3co_exitline; + intel_dp->psr.transcoder = crtc_state->cpu_transcoder; /* DC5/DC6 requires at least 6 idle frames */ val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6); - dev_priv->psr.dc3co_exit_delay = val; - dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch; + intel_dp->psr.dc3co_exit_delay = val; + intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch; /* * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR @@ -990,27 +974,27 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, */ if (INTEL_GEN(dev_priv) >= 12) { val = intel_de_read(dev_priv, - TRANS_PSR_IIR(dev_priv->psr.transcoder)); + TRANS_PSR_IIR(intel_dp->psr.transcoder)); val &= EDP_PSR_ERROR(0); } else { val = intel_de_read(dev_priv, EDP_PSR_IIR); - val &= EDP_PSR_ERROR(dev_priv->psr.transcoder); + val &= EDP_PSR_ERROR(intel_dp->psr.transcoder); } if (val) { - dev_priv->psr.sink_not_reliable = true; + intel_dp->psr.sink_not_reliable = true; drm_dbg_kms(&dev_priv->drm, "PSR interruption error set, not enabling PSR\n"); return; } drm_dbg_kms(&dev_priv->drm, "Enabling PSR%s\n", - dev_priv->psr.psr2_enabled ? "2" : "1"); + intel_dp->psr.psr2_enabled ? "2" : "1"); intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state, - &dev_priv->psr.vsc); - intel_write_dp_vsc_sdp(encoder, crtc_state, &dev_priv->psr.vsc); + &intel_dp->psr.vsc); + intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc); intel_psr_enable_sink(intel_dp); intel_psr_enable_source(intel_dp, crtc_state); - dev_priv->psr.enabled = true; + intel_dp->psr.enabled = true; intel_psr_activate(intel_dp); } @@ -1029,7 +1013,7 @@ void intel_psr_enable(struct intel_dp *intel_dp, { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp) + if (!CAN_PSR(intel_dp)) return; if (!crtc_state->has_psr) @@ -1037,46 +1021,47 @@ void intel_psr_enable(struct intel_dp *intel_dp, drm_WARN_ON(&dev_priv->drm, dev_priv->drrs.dp); - mutex_lock(&dev_priv->psr.lock); - intel_psr_enable_locked(dev_priv, crtc_state, conn_state); - mutex_unlock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); + intel_psr_enable_locked(intel_dp, crtc_state, conn_state); + mutex_unlock(&intel_dp->psr.lock); } -static void intel_psr_exit(struct drm_i915_private *dev_priv) +static void intel_psr_exit(struct intel_dp *intel_dp) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); u32 val; - if (!dev_priv->psr.active) { - if (transcoder_has_psr2(dev_priv, dev_priv->psr.transcoder)) { + if (!intel_dp->psr.active) { + if (transcoder_has_psr2(dev_priv, intel_dp->psr.transcoder)) { val = intel_de_read(dev_priv, - EDP_PSR2_CTL(dev_priv->psr.transcoder)); + EDP_PSR2_CTL(intel_dp->psr.transcoder)); drm_WARN_ON(&dev_priv->drm, val & EDP_PSR2_ENABLE); } val = intel_de_read(dev_priv, - EDP_PSR_CTL(dev_priv->psr.transcoder)); + EDP_PSR_CTL(intel_dp->psr.transcoder)); drm_WARN_ON(&dev_priv->drm, val & EDP_PSR_ENABLE); return; } - if (dev_priv->psr.psr2_enabled) { - tgl_disallow_dc3co_on_psr2_exit(dev_priv); + if (intel_dp->psr.psr2_enabled) { + tgl_disallow_dc3co_on_psr2_exit(intel_dp); val = intel_de_read(dev_priv, - EDP_PSR2_CTL(dev_priv->psr.transcoder)); + EDP_PSR2_CTL(intel_dp->psr.transcoder)); drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR2_ENABLE)); val &= ~EDP_PSR2_ENABLE; intel_de_write(dev_priv, - EDP_PSR2_CTL(dev_priv->psr.transcoder), val); + EDP_PSR2_CTL(intel_dp->psr.transcoder), val); } else { val = intel_de_read(dev_priv, - EDP_PSR_CTL(dev_priv->psr.transcoder)); + EDP_PSR_CTL(intel_dp->psr.transcoder)); drm_WARN_ON(&dev_priv->drm, !(val & EDP_PSR_ENABLE)); val &= ~EDP_PSR_ENABLE; intel_de_write(dev_priv, - EDP_PSR_CTL(dev_priv->psr.transcoder), val); + EDP_PSR_CTL(intel_dp->psr.transcoder), val); } - dev_priv->psr.active = false; + intel_dp->psr.active = false; } static void intel_psr_disable_locked(struct intel_dp *intel_dp) @@ -1085,21 +1070,21 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) i915_reg_t psr_status; u32 psr_status_mask; - lockdep_assert_held(&dev_priv->psr.lock); + lockdep_assert_held(&intel_dp->psr.lock); - if (!dev_priv->psr.enabled) + if (!intel_dp->psr.enabled) return; drm_dbg_kms(&dev_priv->drm, "Disabling PSR%s\n", - dev_priv->psr.psr2_enabled ? "2" : "1"); + intel_dp->psr.psr2_enabled ? "2" : "1"); - intel_psr_exit(dev_priv); + intel_psr_exit(intel_dp); - if (dev_priv->psr.psr2_enabled) { - psr_status = EDP_PSR2_STATUS(dev_priv->psr.transcoder); + if (intel_dp->psr.psr2_enabled) { + psr_status = EDP_PSR2_STATUS(intel_dp->psr.transcoder); psr_status_mask = EDP_PSR2_STATUS_STATE_MASK; } else { - psr_status = EDP_PSR_STATUS(dev_priv->psr.transcoder); + psr_status = EDP_PSR_STATUS(intel_dp->psr.transcoder); psr_status_mask = EDP_PSR_STATUS_STATE_MASK; } @@ -1109,7 +1094,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n"); /* WA 1408330847 */ - if (dev_priv->psr.psr2_sel_fetch_enabled && + if (intel_dp->psr.psr2_sel_fetch_enabled && (IS_TGL_DISP_STEPPING(dev_priv, STEP_A0, STEP_A0) || IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))) intel_de_rmw(dev_priv, CHICKEN_PAR1_1, @@ -1118,10 +1103,10 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) /* Disable PSR on Sink */ drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); - if (dev_priv->psr.psr2_enabled) + if (intel_dp->psr.psr2_enabled) drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, 0); - dev_priv->psr.enabled = false; + intel_dp->psr.enabled = false; } /** @@ -1139,20 +1124,22 @@ void intel_psr_disable(struct intel_dp *intel_dp, if (!old_crtc_state->has_psr) return; - if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(dev_priv))) + if (drm_WARN_ON(&dev_priv->drm, !CAN_PSR(intel_dp))) return; - mutex_lock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); intel_psr_disable_locked(intel_dp); - mutex_unlock(&dev_priv->psr.lock); - cancel_work_sync(&dev_priv->psr.work); - cancel_delayed_work_sync(&dev_priv->psr.dc3co_work); + mutex_unlock(&intel_dp->psr.lock); + cancel_work_sync(&intel_dp->psr.work); + cancel_delayed_work_sync(&intel_dp->psr.dc3co_work); } -static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) +static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + if (IS_TIGERLAKE(dev_priv)) /* * Writes to CURSURFLIVE in TGL are causing IOMMU errors and @@ -1166,7 +1153,7 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) * So using this workaround until this issue is root caused * and a better fix is found. */ - intel_psr_exit(dev_priv); + intel_psr_exit(intel_dp); else if (INTEL_GEN(dev_priv) >= 9) /* * Display WA #0884: skl+ @@ -1177,13 +1164,13 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv) * but it makes more sense write to the current active * pipe. */ - intel_de_write(dev_priv, CURSURFLIVE(dev_priv->psr.pipe), 0); + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); else /* * A write to CURSURFLIVE do not cause HW tracking to exit PSR * on older gens so doing the manual exit instead. */ - intel_psr_exit(dev_priv); + intel_psr_exit(intel_dp); } void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, @@ -1231,16 +1218,24 @@ void intel_psr2_program_plane_sel_fetch(struct intel_plane *plane, void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct i915_psr *psr = &dev_priv->psr; + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_encoder *encoder; if (!HAS_PSR2_SEL_FETCH(dev_priv) || !crtc_state->enable_psr2_sel_fetch) return; - intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder), - crtc_state->psr2_man_track_ctl); + for_each_intel_encoder_mask_can_psr(&dev_priv->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + if (!intel_dp->psr.enabled) + continue; + + intel_de_write(dev_priv, + PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder), + crtc_state->psr2_man_track_ctl); + } } static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, @@ -1435,13 +1430,13 @@ void intel_psr_update(struct intel_dp *intel_dp, const struct drm_connector_state *conn_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct i915_psr *psr = &dev_priv->psr; + struct intel_psr *psr = &intel_dp->psr; bool enable, psr2_enable; - if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp) + if (!CAN_PSR(intel_dp)) return; - mutex_lock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); enable = crtc_state->has_psr; psr2_enable = crtc_state->has_psr2; @@ -1449,15 +1444,15 @@ void intel_psr_update(struct intel_dp *intel_dp, if (enable == psr->enabled && psr2_enable == psr->psr2_enabled) { /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) - psr_force_hw_tracking_exit(dev_priv); + psr_force_hw_tracking_exit(intel_dp); else if (INTEL_GEN(dev_priv) < 9 && psr->enabled) { /* * Activate PSR again after a force exit when enabling * CRC in older gens */ - if (!dev_priv->psr.active && - !dev_priv->psr.busy_frontbuffer_bits) - schedule_work(&dev_priv->psr.work); + if (!intel_dp->psr.active && + !intel_dp->psr.busy_frontbuffer_bits) + schedule_work(&intel_dp->psr.work); } goto unlock; @@ -1467,34 +1462,23 @@ void intel_psr_update(struct intel_dp *intel_dp, intel_psr_disable_locked(intel_dp); if (enable) - intel_psr_enable_locked(dev_priv, crtc_state, conn_state); + intel_psr_enable_locked(intel_dp, crtc_state, conn_state); unlock: - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); } /** - * intel_psr_wait_for_idle - wait for PSR1 to idle - * @new_crtc_state: new CRTC state + * psr_wait_for_idle - wait for PSR1 to idle + * @intel_dp: Intel DP * @out_value: PSR status in case of failure * - * This function is expected to be called from pipe_update_start() where it is - * not expected to race with PSR enable or disable. - * * Returns: 0 on success or -ETIMEOUT if PSR status does not idle. + * */ -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, - u32 *out_value) +static int psr_wait_for_idle(struct intel_dp *intel_dp, u32 *out_value) { - struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - - if (!dev_priv->psr.enabled || !new_crtc_state->has_psr) - return 0; - - /* FIXME: Update this for PSR2 if we need to wait for idle */ - if (READ_ONCE(dev_priv->psr.psr2_enabled)) - return 0; + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); /* * From bspec: Panel Self Refresh (BDW+) @@ -1502,32 +1486,68 @@ int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, * exit training time + 1.5 ms of aux channel handshake. 50 ms is * defensive enough to cover everything. */ - return __intel_wait_for_register(&dev_priv->uncore, - EDP_PSR_STATUS(dev_priv->psr.transcoder), + EDP_PSR_STATUS(intel_dp->psr.transcoder), EDP_PSR_STATUS_STATE_MASK, EDP_PSR_STATUS_STATE_IDLE, 2, 50, out_value); } -static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) +/** + * intel_psr_wait_for_idle - wait for PSR1 to idle + * @new_crtc_state: new CRTC state + * + * This function is expected to be called from pipe_update_start() where it is + * not expected to race with PSR enable or disable. + */ +void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state) +{ + struct drm_i915_private *dev_priv = to_i915(new_crtc_state->uapi.crtc->dev); + struct intel_encoder *encoder; + + if (!new_crtc_state->has_psr) + return; + + for_each_intel_encoder_mask_can_psr(&dev_priv->drm, encoder, + new_crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + u32 psr_status; + + mutex_lock(&intel_dp->psr.lock); + if (!intel_dp->psr.enabled || + (intel_dp->psr.enabled && intel_dp->psr.psr2_enabled)) { + mutex_unlock(&intel_dp->psr.lock); + continue; + } + + /* when the PSR1 is enabled */ + if (psr_wait_for_idle(intel_dp, &psr_status)) + drm_err(&dev_priv->drm, + "PSR idle timed out 0x%x, atomic update may fail\n", + psr_status); + mutex_unlock(&intel_dp->psr.lock); + } +} + +static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); i915_reg_t reg; u32 mask; int err; - if (!dev_priv->psr.enabled) + if (!intel_dp->psr.enabled) return false; - if (dev_priv->psr.psr2_enabled) { - reg = EDP_PSR2_STATUS(dev_priv->psr.transcoder); + if (intel_dp->psr.psr2_enabled) { + reg = EDP_PSR2_STATUS(intel_dp->psr.transcoder); mask = EDP_PSR2_STATUS_STATE_MASK; } else { - reg = EDP_PSR_STATUS(dev_priv->psr.transcoder); + reg = EDP_PSR_STATUS(intel_dp->psr.transcoder); mask = EDP_PSR_STATUS_STATE_MASK; } - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); err = intel_de_wait_for_clear(dev_priv, reg, mask, 50); if (err) @@ -1535,8 +1555,8 @@ static bool __psr_wait_for_idle_locked(struct drm_i915_private *dev_priv) "Timed out waiting for PSR Idle for re-enable\n"); /* After the unlocked wait, verify that PSR is still wanted! */ - mutex_lock(&dev_priv->psr.lock); - return err == 0 && dev_priv->psr.enabled; + mutex_lock(&intel_dp->psr.lock); + return err == 0 && intel_dp->psr.enabled; } static int intel_psr_fastset_force(struct drm_i915_private *dev_priv) @@ -1602,8 +1622,9 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv) return err; } -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 val) { + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); const u32 mode = val & I915_PSR_DEBUG_MODE_MASK; u32 old_mode; int ret; @@ -1614,21 +1635,21 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) return -EINVAL; } - ret = mutex_lock_interruptible(&dev_priv->psr.lock); + ret = mutex_lock_interruptible(&intel_dp->psr.lock); if (ret) return ret; - old_mode = dev_priv->psr.debug & I915_PSR_DEBUG_MODE_MASK; - dev_priv->psr.debug = val; + old_mode = intel_dp->psr.debug & I915_PSR_DEBUG_MODE_MASK; + intel_dp->psr.debug = val; /* * Do it right away if it's already enabled, otherwise it will be done * when enabling the source. */ - if (dev_priv->psr.enabled) - psr_irq_control(dev_priv); + if (intel_dp->psr.enabled) + psr_irq_control(intel_dp); - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); if (old_mode != mode) ret = intel_psr_fastset_force(dev_priv); @@ -1636,28 +1657,28 @@ int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 val) return ret; } -static void intel_psr_handle_irq(struct drm_i915_private *dev_priv) +static void intel_psr_handle_irq(struct intel_dp *intel_dp) { - struct i915_psr *psr = &dev_priv->psr; + struct intel_psr *psr = &intel_dp->psr; - intel_psr_disable_locked(psr->dp); + intel_psr_disable_locked(intel_dp); psr->sink_not_reliable = true; /* let's make sure that sink is awaken */ - drm_dp_dpcd_writeb(&psr->dp->aux, DP_SET_POWER, DP_SET_POWER_D0); + drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0); } static void intel_psr_work(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), psr.work); + struct intel_dp *intel_dp = + container_of(work, typeof(*intel_dp), psr.work); - mutex_lock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); - if (!dev_priv->psr.enabled) + if (!intel_dp->psr.enabled) goto unlock; - if (READ_ONCE(dev_priv->psr.irq_aux_error)) - intel_psr_handle_irq(dev_priv); + if (READ_ONCE(intel_dp->psr.irq_aux_error)) + intel_psr_handle_irq(intel_dp); /* * We have to make sure PSR is ready for re-enable @@ -1665,7 +1686,7 @@ static void intel_psr_work(struct work_struct *work) * PSR might take some time to get fully disabled * and be ready for re-enable. */ - if (!__psr_wait_for_idle_locked(dev_priv)) + if (!__psr_wait_for_idle_locked(intel_dp)) goto unlock; /* @@ -1673,12 +1694,12 @@ static void intel_psr_work(struct work_struct *work) * recheck. Since psr_flush first clears this and then reschedules we * won't ever miss a flush when bailing out here. */ - if (dev_priv->psr.busy_frontbuffer_bits || dev_priv->psr.active) + if (intel_dp->psr.busy_frontbuffer_bits || intel_dp->psr.active) goto unlock; - intel_psr_activate(dev_priv->psr.dp); + intel_psr_activate(intel_dp); unlock: - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); } /** @@ -1697,27 +1718,31 @@ static void intel_psr_work(struct work_struct *work) void intel_psr_invalidate(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits, enum fb_op_origin origin) { - if (!CAN_PSR(dev_priv)) - return; + struct intel_encoder *encoder; if (origin == ORIGIN_FLIP) return; - mutex_lock(&dev_priv->psr.lock); - if (!dev_priv->psr.enabled) { - mutex_unlock(&dev_priv->psr.lock); - return; - } + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + unsigned int pipe_frontbuffer_bits = frontbuffer_bits; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); - dev_priv->psr.busy_frontbuffer_bits |= frontbuffer_bits; + mutex_lock(&intel_dp->psr.lock); + if (!intel_dp->psr.enabled) { + mutex_unlock(&intel_dp->psr.lock); + continue; + } - if (frontbuffer_bits) - intel_psr_exit(dev_priv); + pipe_frontbuffer_bits &= + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe); + intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits; - mutex_unlock(&dev_priv->psr.lock); -} + if (pipe_frontbuffer_bits) + intel_psr_exit(intel_dp); + mutex_unlock(&intel_dp->psr.lock); + } +} /* * When we will be completely rely on PSR2 S/W tracking in future, * intel_psr_flush() will invalidate and flush the PSR for ORIGIN_FLIP @@ -1725,15 +1750,15 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv, * accordingly in future. */ static void -tgl_dc3co_flush(struct drm_i915_private *dev_priv, - unsigned int frontbuffer_bits, enum fb_op_origin origin) +tgl_dc3co_flush(struct intel_dp *intel_dp, unsigned int frontbuffer_bits, + enum fb_op_origin origin) { - mutex_lock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); - if (!dev_priv->psr.dc3co_enabled) + if (!intel_dp->psr.dc3co_enabled) goto unlock; - if (!dev_priv->psr.psr2_enabled || !dev_priv->psr.active) + if (!intel_dp->psr.psr2_enabled || !intel_dp->psr.active) goto unlock; /* @@ -1741,15 +1766,15 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv, * when delayed work schedules that means display has been idle. */ if (!(frontbuffer_bits & - INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe))) + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe))) goto unlock; - tgl_psr2_enable_dc3co(dev_priv); - mod_delayed_work(system_wq, &dev_priv->psr.dc3co_work, - dev_priv->psr.dc3co_exit_delay); + tgl_psr2_enable_dc3co(intel_dp); + mod_delayed_work(system_wq, &intel_dp->psr.dc3co_work, + intel_dp->psr.dc3co_exit_delay); unlock: - mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&intel_dp->psr.lock); } /** @@ -1768,47 +1793,73 @@ tgl_dc3co_flush(struct drm_i915_private *dev_priv, void intel_psr_flush(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits, enum fb_op_origin origin) { - if (!CAN_PSR(dev_priv)) - return; + struct intel_encoder *encoder; - if (origin == ORIGIN_FLIP) { - tgl_dc3co_flush(dev_priv, frontbuffer_bits, origin); - return; - } + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + unsigned int pipe_frontbuffer_bits = frontbuffer_bits; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - mutex_lock(&dev_priv->psr.lock); - if (!dev_priv->psr.enabled) { - mutex_unlock(&dev_priv->psr.lock); - return; - } + if (origin == ORIGIN_FLIP) { + tgl_dc3co_flush(intel_dp, frontbuffer_bits, origin); + continue; + } + + mutex_lock(&intel_dp->psr.lock); + if (!intel_dp->psr.enabled) { + mutex_unlock(&intel_dp->psr.lock); + continue; + } - frontbuffer_bits &= INTEL_FRONTBUFFER_ALL_MASK(dev_priv->psr.pipe); - dev_priv->psr.busy_frontbuffer_bits &= ~frontbuffer_bits; + pipe_frontbuffer_bits &= + INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe); + intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits; - /* By definition flush = invalidate + flush */ - if (frontbuffer_bits) - psr_force_hw_tracking_exit(dev_priv); + /* By definition flush = invalidate + flush */ + if (pipe_frontbuffer_bits) + psr_force_hw_tracking_exit(intel_dp); - if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) - schedule_work(&dev_priv->psr.work); - mutex_unlock(&dev_priv->psr.lock); + if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits) + schedule_work(&intel_dp->psr.work); + mutex_unlock(&intel_dp->psr.lock); + } } /** * intel_psr_init - Init basic PSR work and mutex. - * @dev_priv: i915 device private + * @intel_dp: Intel DP * - * This function is called only once at driver load to initialize basic - * PSR stuff. + * This function is called after the initializing connector. + * (the initializing of connector treats the handling of connector capabilities) + * And it initializes basic PSR stuff for each DP Encoder. */ -void intel_psr_init(struct drm_i915_private *dev_priv) +void intel_psr_init(struct intel_dp *intel_dp) { + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + if (!HAS_PSR(dev_priv)) return; - if (!dev_priv->psr.sink_support) + if (!intel_dp->psr.sink_support) return; + /* + * HSW spec explicitly says PSR is tied to port A. + * BDW+ platforms have a instance of PSR registers per transcoder but + * BDW, GEN9 and GEN11 are not validated by HW team in other transcoder + * than eDP one. + * For now it only supports one instance of PSR for BDW, GEN9 and GEN11. + * So lets keep it hardcoded to PORT_A for BDW, GEN9 and GEN11. + * But GEN12 supports a instance of PSR registers per transcoder. + */ + if (INTEL_GEN(dev_priv) < 12 && dig_port->base.port != PORT_A) { + drm_dbg_kms(&dev_priv->drm, + "PSR condition failed: Port not supported\n"); + return; + } + + intel_dp->psr.source_support = true; + if (IS_HASWELL(dev_priv)) /* * HSW don't have PSR registers on the same space as transcoder @@ -1824,14 +1875,14 @@ void intel_psr_init(struct drm_i915_private *dev_priv) /* Set link_standby x link_off defaults */ if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) /* HSW and BDW require workarounds that we don't implement. */ - dev_priv->psr.link_standby = false; + intel_dp->psr.link_standby = false; else if (INTEL_GEN(dev_priv) < 12) /* For new platforms up to TGL let's respect VBT back again */ - dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; + intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link; - INIT_WORK(&dev_priv->psr.work, intel_psr_work); - INIT_DELAYED_WORK(&dev_priv->psr.dc3co_work, tgl_dc3co_disable_work); - mutex_init(&dev_priv->psr.lock); + INIT_WORK(&intel_dp->psr.work, intel_psr_work); + INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work); + mutex_init(&intel_dp->psr.lock); } static int psr_get_status_and_error_status(struct intel_dp *intel_dp, @@ -1857,7 +1908,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); struct drm_dp_aux *aux = &intel_dp->aux; - struct i915_psr *psr = &dev_priv->psr; + struct intel_psr *psr = &intel_dp->psr; u8 val; int r; @@ -1884,7 +1935,7 @@ static void psr_alpm_check(struct intel_dp *intel_dp) static void psr_capability_changed_check(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct i915_psr *psr = &dev_priv->psr; + struct intel_psr *psr = &intel_dp->psr; u8 val; int r; @@ -1908,18 +1959,18 @@ static void psr_capability_changed_check(struct intel_dp *intel_dp) void intel_psr_short_pulse(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - struct i915_psr *psr = &dev_priv->psr; + struct intel_psr *psr = &intel_dp->psr; u8 status, error_status; const u8 errors = DP_PSR_RFB_STORAGE_ERROR | DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR | DP_PSR_LINK_CRC_ERROR; - if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp)) + if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp)) return; mutex_lock(&psr->lock); - if (!psr->enabled || psr->dp != intel_dp) + if (!psr->enabled) goto exit; if (psr_get_status_and_error_status(intel_dp, &status, &error_status)) { @@ -1962,15 +2013,14 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp) bool intel_psr_enabled(struct intel_dp *intel_dp) { - struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); bool ret; - if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp)) + if (!CAN_PSR(intel_dp) || !intel_dp_is_edp(intel_dp)) return false; - mutex_lock(&dev_priv->psr.lock); - ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled); - mutex_unlock(&dev_priv->psr.lock); + mutex_lock(&intel_dp->psr.lock); + ret = intel_dp->psr.enabled; + mutex_unlock(&intel_dp->psr.lock); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 0a517978e8af..0491a49ffd50 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -18,7 +18,6 @@ struct intel_atomic_state; struct intel_plane_state; struct intel_plane; -#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support) void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_enable(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, @@ -28,20 +27,19 @@ void intel_psr_disable(struct intel_dp *intel_dp, void intel_psr_update(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); -int intel_psr_debug_set(struct drm_i915_private *dev_priv, u64 value); +int intel_psr_debug_set(struct intel_dp *intel_dp, u64 value); void intel_psr_invalidate(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits, enum fb_op_origin origin); void intel_psr_flush(struct drm_i915_private *dev_priv, unsigned frontbuffer_bits, enum fb_op_origin origin); -void intel_psr_init(struct drm_i915_private *dev_priv); +void intel_psr_init(struct intel_dp *intel_dp); void intel_psr_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state); -void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir); +void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir); void intel_psr_short_pulse(struct intel_dp *intel_dp); -int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state, - u32 *out_value); +void intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state); bool intel_psr_enabled(struct intel_dp *intel_dp); int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 402030251c64..26025251b038 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -96,7 +96,6 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI); DEFINE_WAIT(wait); - u32 psr_status; if (new_crtc_state->uapi.async_flip) return; @@ -122,10 +121,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) * VBL interrupts will start the PSR exit and prevent a PSR * re-entry as well. */ - if (intel_psr_wait_for_idle(new_crtc_state, &psr_status)) - drm_err(&dev_priv->drm, - "PSR idle timed out 0x%x, atomic update may fail\n", - psr_status); + intel_psr_wait_for_idle(new_crtc_state); local_irq_disable(); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a2fd7e5039b3..b289832f00b1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -478,42 +478,6 @@ struct i915_drrs { enum drrs_support_type type; }; -struct i915_psr { - struct mutex lock; - -#define I915_PSR_DEBUG_MODE_MASK 0x0f -#define I915_PSR_DEBUG_DEFAULT 0x00 -#define I915_PSR_DEBUG_DISABLE 0x01 -#define I915_PSR_DEBUG_ENABLE 0x02 -#define I915_PSR_DEBUG_FORCE_PSR1 0x03 -#define I915_PSR_DEBUG_IRQ 0x10 - - u32 debug; - bool sink_support; - bool enabled; - struct intel_dp *dp; - enum pipe pipe; - enum transcoder transcoder; - bool active; - struct work_struct work; - unsigned busy_frontbuffer_bits; - bool sink_psr2_support; - bool link_standby; - bool colorimetry_support; - bool psr2_enabled; - bool psr2_sel_fetch_enabled; - u8 sink_sync_latency; - ktime_t last_entry_attempt; - ktime_t last_exit; - bool sink_not_reliable; - bool irq_aux_error; - u16 su_x_granularity; - bool dc3co_enabled; - u32 dc3co_exit_delay; - struct delayed_work dc3co_work; - struct drm_dp_vsc_sdp vsc; -}; - #define QUIRK_LVDS_SSC_DISABLE (1<<1) #define QUIRK_INVERT_BRIGHTNESS (1<<2) #define QUIRK_BACKLIGHT_PRESENT (1<<3) @@ -1041,8 +1005,6 @@ struct drm_i915_private { struct i915_power_domains power_domains; - struct i915_psr psr; - struct i915_gpu_error gpu_error; struct drm_i915_gem_object *vlv_pctx; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0ff3f64c4bb5..98145a7f28a4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2094,10 +2094,19 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv, ivb_err_int_handler(dev_priv); if (de_iir & DE_EDP_PSR_INT_HSW) { - u32 psr_iir = intel_uncore_read(&dev_priv->uncore, EDP_PSR_IIR); + struct intel_encoder *encoder; - intel_psr_irq_handler(dev_priv, psr_iir); - intel_uncore_write(&dev_priv->uncore, EDP_PSR_IIR, psr_iir); + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + u32 psr_iir = intel_uncore_read(&dev_priv->uncore, + EDP_PSR_IIR); + + intel_psr_irq_handler(intel_dp, psr_iir); + intel_uncore_write(&dev_priv->uncore, + EDP_PSR_IIR, psr_iir); + break; + } } if (de_iir & DE_AUX_CHANNEL_A_IVB) @@ -2310,21 +2319,30 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) } if (iir & GEN8_DE_EDP_PSR) { + struct intel_encoder *encoder; u32 psr_iir; i915_reg_t iir_reg; - if (INTEL_GEN(dev_priv) >= 12) - iir_reg = TRANS_PSR_IIR(dev_priv->psr.transcoder); - else - iir_reg = EDP_PSR_IIR; + for_each_intel_encoder_can_psr(&dev_priv->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg); - intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir); + if (INTEL_GEN(dev_priv) >= 12) + iir_reg = TRANS_PSR_IIR(intel_dp->psr.transcoder); + else + iir_reg = EDP_PSR_IIR; - if (psr_iir) - found = true; + psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg); + intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir); - intel_psr_irq_handler(dev_priv, psr_iir); + if (psr_iir) + found = true; + + intel_psr_irq_handler(intel_dp, psr_iir); + + /* prior GEN12 only have one EDP PSR */ + if (INTEL_GEN(dev_priv) < 12) + break; + } } if (!found)