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

drm/i915/psr: Do not write registers/bits not applicable for panel replay



Bspec is saying this
mask register: Only PSR_MASK[Mask FBC modify] and PSR_MASK[Mask Hotplug]
are used in panel replay mode.

Status register: Only SRD_STATUS[SRD state] field is used in panel replay
mode.

Due to this stop writing and reading registers and bits not used by panel
replay if panel replay is used.

Bspec: 53370, 68920

v2:
  - use intel_dp_is_edp with PSR_MASK register
  - handle LunarLake as well
  - hanle ALPM configuration as well

Signed-off-by: default avatarJouni Högander <jouni.hogander@intel.com>
Reviewed-by: default avatarAnimesh Manna <animesh.manna@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240405113602.992714-7-jouni.hogander@intel.com
parent b7fc3d12
Loading
Loading
Loading
Loading
+45 −25
Original line number Diff line number Diff line
@@ -346,6 +346,9 @@ static void psr_irq_control(struct intel_dp *intel_dp)
	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
	u32 mask;

	if (intel_dp->psr.panel_replay_enabled)
		return;

	mask = psr_irq_psr_error_bit_get(intel_dp);
	if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
		mask |= psr_irq_post_exit_bit_get(intel_dp) |
@@ -1783,7 +1786,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
	u32 mask;
	u32 mask = 0;

	/*
	 * Only HSW and BDW have PSR AUX registers that need to be setup.
@@ -1797,9 +1800,20 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
	 * mask LPSP to avoid dependency on other drivers that might block
	 * runtime_pm besides preventing  other hw tracking issues now we
	 * can rely on frontbuffer tracking.
	 *
	 * From bspec prior LunarLake:
	 * Only PSR_MASK[Mask FBC modify] and PSR_MASK[Mask Hotplug] are used in
	 * panel replay mode.
	 *
	 * From bspec beyod LunarLake:
	 * Panel Replay on DP: No bits are applicable
	 * Panel Replay on eDP: All bits are applicable
	 */
	mask = EDP_PSR_DEBUG_MASK_MEMUP |
	       EDP_PSR_DEBUG_MASK_HPD;
	if (DISPLAY_VER(dev_priv) < 20 || intel_dp_is_edp(intel_dp))
		mask = EDP_PSR_DEBUG_MASK_HPD;

	if (intel_dp_is_edp(intel_dp)) {
		mask |= EDP_PSR_DEBUG_MASK_MEMUP;

		/*
		 * For some unknown reason on HSW non-ULT (or at least on
@@ -1825,6 +1839,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
		/* allow PSR with sprite enabled */
		if (IS_HASWELL(dev_priv))
			mask |= EDP_PSR_DEBUG_MASK_SPRITE_ENABLE;
	}

	intel_de_write(dev_priv, psr_debug_reg(dev_priv, cpu_transcoder), mask);

@@ -1843,6 +1858,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
			     intel_dp->psr.psr2_sel_fetch_enabled ?
			     IGNORE_PSR2_HW_TRACKING : 0);

	if (intel_dp_is_edp(intel_dp))
		lnl_alpm_configure(intel_dp);

	/*
@@ -1884,6 +1900,9 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
	u32 val;

	if (intel_dp->psr.panel_replay_enabled)
		goto no_err;

	/*
	 * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
	 * will still keep the error set even after the reset done in the
@@ -1901,6 +1920,7 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
		return false;
	}

no_err:
	return true;
}