Commit b7effa32 authored by Jouni Högander's avatar Jouni Högander
Browse files

drm/i915/psr: Add mechanism to notify PSR of DC5/6 enable disable



We need to apply/remove workaround for underrun on idle PSR HW issue
(Wa_16025596647) when DC5/6 is enabled/disabled. This patch implements
mechanism to notify PSR about DC5/6 enable/disable and applies/removes the
workaround using this notification.

Bspec: 74115

Signed-off-by: default avatarJouni Högander <jouni.hogander@intel.com>
Reviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
Link: https://lore.kernel.org/r/20250414100508.1208774-9-jouni.hogander@intel.com
parent f02658c4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -579,6 +579,8 @@ struct intel_display {
	struct intel_vbt_data vbt;
	struct intel_dmc_wl wl;
	struct intel_wm wm;

	struct work_struct psr_dc5_dc6_wa_work;
};

#endif /* __INTEL_DISPLAY_CORE_H__ */
+50 −0
Original line number Diff line number Diff line
@@ -3695,6 +3695,56 @@ static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp
		psr1_apply_underrun_on_idle_wa_locked(intel_dp, dc5_dc6_blocked);
}

static void psr_dc5_dc6_wa_work(struct work_struct *work)
{
	struct intel_display *display = container_of(work, typeof(*display),
						     psr_dc5_dc6_wa_work);
	struct intel_encoder *encoder;

	for_each_intel_encoder_with_psr(display->drm, encoder) {
		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);

		mutex_lock(&intel_dp->psr.lock);

		if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled)
			intel_psr_apply_underrun_on_idle_wa_locked(intel_dp);

		mutex_unlock(&intel_dp->psr.lock);
	}
}

/**
 * intel_psr_notify_dc5_dc6 - Notify PSR about enable/disable dc5/dc6
 * @display: intel atomic state
 *
 * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to schedule
 * psr_dc5_dc6_wa_work used for applying/removing the workaround.
 */
void intel_psr_notify_dc5_dc6(struct intel_display *display)
{
	if (DISPLAY_VER(display) != 20 &&
	    !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
		return;

	schedule_work(&display->psr_dc5_dc6_wa_work);
}

/**
 * intel_psr_dc5_dc6_wa_init - Init work for underrun on idle PSR HW bug wa
 * @display: intel atomic state
 *
 * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to init
 * psr_dc5_dc6_wa_work used for applying the workaround.
 */
void intel_psr_dc5_dc6_wa_init(struct intel_display *display)
{
	if (DISPLAY_VER(display) != 20 &&
	    !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0))
		return;

	INIT_WORK(&display->psr_dc5_dc6_wa_work, psr_dc5_dc6_wa_work);
}

/**
 * intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe
 * @state: intel atomic state
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ void intel_psr_resume(struct intel_dp *intel_dp);
bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state);
void intel_psr_notify_pipe_change(struct intel_atomic_state *state,
				  struct intel_crtc *crtc, bool enable);
void intel_psr_notify_dc5_dc6(struct intel_display *display);
void intel_psr_dc5_dc6_wa_init(struct intel_display *display);
bool intel_psr_link_ok(struct intel_dp *intel_dp);

void intel_psr_lock(const struct intel_crtc_state *crtc_state);