To implement workaround for underrun on idle PSR HW issue (Wa_16025596647) we need to know enabled. Figure out which non-PSR pipes we will have active and store it into intel_crtc_state->active_non_psr_pipes. This is currently assuming only one eDP on a time. I.e. possible secondary eDP with PSR capable panel is not considered. Bspec: 74151 Signed-off-by: Jouni Högander <jouni.hogander@xxxxxxxxx> --- .../drm/i915/display/intel_display_types.h | 3 +++ drivers/gpu/drm/i915/display/intel_psr.c | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 99a6fd2900b9..3d203a2003f1 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1114,6 +1114,7 @@ struct intel_crtc_state { bool wm_level_disabled; u32 dc3co_exitline; u16 su_y_granularity; + u8 active_non_psr_pipes; /* * Frequency the dpll for the port should run at. Differs from the @@ -1650,6 +1651,8 @@ struct intel_psr { u8 entry_setup_frames; bool link_ok; + + u8 active_non_psr_pipes; }; struct intel_dp { diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 4e938bad808c..1415e1e7aaf2 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1658,6 +1658,9 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); + struct intel_crtc *crtc; + u8 active_pipes = 0; if (!psr_global_enabled(intel_dp)) { drm_dbg_kms(display->drm, "PSR disabled by flag\n"); @@ -1711,6 +1714,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, drm_dbg_kms(display->drm, "PSR disabled to workaround PSR FSM hang issue\n"); } + + /* Rest is for Wa_16025596647 */ + if (DISPLAY_VER(display) != 20 && + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + return; + + /* Not needed by Panel Replay */ + if (crtc_state->has_panel_replay) + return; + + /* We ignore possible secondary PSR/Panel Replay capable eDP */ + for_each_intel_crtc(display->drm, crtc) + active_pipes |= crtc->active ? BIT(crtc->pipe) : 0; + + active_pipes = intel_calc_active_pipes(state, active_pipes); + + crtc_state->active_non_psr_pipes = active_pipes & + ~BIT(to_intel_crtc(crtc_state->uapi.crtc)->pipe); } void intel_psr_get_config(struct intel_encoder *encoder, @@ -1995,6 +2016,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_dp->psr.psr2_sel_fetch_cff_enabled = false; intel_dp->psr.req_psr2_sdp_prior_scanline = crtc_state->req_psr2_sdp_prior_scanline; + intel_dp->psr.active_non_psr_pipes = crtc_state->active_non_psr_pipes; if (!psr_interrupt_error_check(intel_dp)) return; @@ -2170,6 +2192,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) intel_dp->psr.psr2_sel_fetch_enabled = false; intel_dp->psr.su_region_et_enabled = false; intel_dp->psr.psr2_sel_fetch_cff_enabled = false; + intel_dp->psr.active_non_psr_pipes = 0; } /** -- 2.43.0