Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915/alpm: Keep the extended fast wake ahead of the IO buffer wake
@ 2026-09-02 16:25 Jake Steinman
  2026-09-03  4:11 ` Hogander, Jouni
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Jake Steinman @ 2026-09-02 16:25 UTC (permalink / raw)
  To: intel-gfx, intel-xe
  Cc: Jouni Högander, Animesh Manna, Ville Syrjälä,
	Jani Nikula

On display version 20+ the extended fast wake time is programmed in
ALPM_CTL and the IO buffer wake in PSR2_CTL. intel_alpm_compute_params()
derives both from precharge + preamble + PHY wake + tFW exit latency
(42 us here); the IO buffer wake only differs when io_buffer_wake_time
is larger than the precharge, which is not the case on this panel. So
both end up on the same number of scanlines, 11 on this mode.

On the Dell XPS 16 DA16260 (Panther Lake, LG panel with sink OUI
00:22:b9, 3200x2000@120, 4 x 2.7 Gbps, DSC) equal values make every ALPM
link wake fail: the sink sets the Link CRC error bit in
DP_PSR_ERROR_STATUS within ~25 ms of it being cleared, on every wake, for
as long as PSR2 is active. Changing the two fields at runtime shows that
the relation between them matters, not the absolute time:

  fast wake 11 / IO wake 11  -> CRC error on every wake
  fast wake 12 / IO wake 11  -> clean
  fast wake 40 / IO wake 40  -> CRC error on every wake
  fast wake 40 / IO wake 20  -> clean
  fast wake 11 / IO wake 20  -> CRC error on every wake

The fast wake sequence has to start strictly before the IO buffer wake.
With the current values PSR2 on this panel only looked usable because
the constant wake failures kept forcing the sink to resync.

Make fast_wake_lines strictly greater than io_wake_lines on display 20+,
or, when already at the maximum, put the IO buffer wake one line below
it. Use the larger of the two in the vblank and guardband checks, which
so far only looked at the IO buffer wake on display 20+.

This is one of the two machines behind the eDP Panel Replay quirk in
intel_quirks.c (Dell XPS 14 DA14260 / XPS 16 DA16260). The change does
not make Panel Replay or PSR2 selective updates work there on its own:
with the wake fixed the panel still never receives a selective update
(sink 0x200a stays at PSR_STATE only) while the PSR2 engine sits in
SU_STANDBY and consumes the TRANS_PUSH frame change events. That is
reported separately on intel-gfx.

Link: https://lore.kernel.org/intel-gfx/20260902162150.58778-1-j@metarealtyinc.ca/
Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/7521
Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/7682
Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org
Signed-off-by: Jake Steinman <j@metarealtyinc.ca>
---
diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c
index f138376..c244273 100644
--- a/drivers/gpu/drm/i915/display/intel_alpm.c
+++ b/drivers/gpu/drm/i915/display/intel_alpm.c
@@ -238,8 +238,29 @@ bool intel_alpm_compute_params(struct intel_dp *intel_dp,
 		io_wake_lines = fast_wake_lines = max_wake_lines;
 
 	/* According to Bspec lower limit should be set as 7 lines. */
-	crtc_state->alpm_state.io_wake_lines = max(io_wake_lines, 7);
-	crtc_state->alpm_state.fast_wake_lines = max(fast_wake_lines, 7);
+	io_wake_lines = max(io_wake_lines, 7);
+	fast_wake_lines = max(fast_wake_lines, 7);
+
+	/*
+	 * On display 20+ the extended fast wake sequence programmed in
+	 * ALPM_CTL has to start strictly before the IO buffer wake programmed
+	 * in PSR2_CTL. Both are derived from the same precharge, preamble,
+	 * PHY wake and tFW exit latency above, so they normally end up on the
+	 * same number of lines. With equal values the
+	 * LG panel (sink OUI 00:22:b9) in the Dell XPS 14/16 DA14260/DA16260
+	 * reports a Link CRC error on every link wake. One extra fast wake
+	 * line is enough to fix it; when we are already at the maximum keep
+	 * the IO buffer wake one line below the fast wake instead.
+	 */
+	if (DISPLAY_VER(display) >= 20 && fast_wake_lines <= io_wake_lines) {
+		if (io_wake_lines < max_wake_lines)
+			fast_wake_lines = io_wake_lines + 1;
+		else
+			io_wake_lines = fast_wake_lines - 1;
+	}
+
+	crtc_state->alpm_state.io_wake_lines = io_wake_lines;
+	crtc_state->alpm_state.fast_wake_lines = fast_wake_lines;
 
 	return true;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index c0933dd..ec80a2e 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1443,7 +1443,8 @@ static bool wake_lines_fit_into_vblank(struct intel_dp *intel_dp,
 		wake_lines = DISPLAY_VER(display) < 20 ?
 			psr2_block_count_lines(crtc_state->alpm_state.io_wake_lines,
 					       crtc_state->alpm_state.fast_wake_lines) :
-			crtc_state->alpm_state.io_wake_lines;
+			max(crtc_state->alpm_state.io_wake_lines,
+			    crtc_state->alpm_state.fast_wake_lines);
 
 	/*
 	 * Guardband has not been computed yet, so we conservatively check if the
@@ -4556,7 +4557,8 @@ void intel_psr_compute_config_late(struct intel_dp *intel_dp,
 		wake_lines = DISPLAY_VER(display) < 20 ?
 			     psr2_block_count_lines(crtc_state->alpm_state.io_wake_lines,
 						    crtc_state->alpm_state.fast_wake_lines) :
-			     crtc_state->alpm_state.io_wake_lines;
+			     max(crtc_state->alpm_state.io_wake_lines,
+				 crtc_state->alpm_state.fast_wake_lines);
 	else
 		wake_lines = 0;
 
@@ -4612,7 +4614,8 @@ int intel_psr_min_guardband(struct intel_crtc_state *crtc_state)
 		wake_lines = DISPLAY_VER(display) < 20 ?
 			     psr2_block_count_lines(crtc_state->alpm_state.io_wake_lines,
 						    crtc_state->alpm_state.fast_wake_lines) :
-			     crtc_state->alpm_state.io_wake_lines;
+			     max(crtc_state->alpm_state.io_wake_lines,
+				 crtc_state->alpm_state.fast_wake_lines);
 	else
 		return 0;
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-04 12:51 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 16:25 [PATCH] drm/i915/alpm: Keep the extended fast wake ahead of the IO buffer wake Jake Steinman
2026-09-03  4:11 ` Hogander, Jouni
2026-09-03 13:14 ` Jake Steinman
2026-09-03 13:17 ` [PATCH v2] drm/i915/alpm: Add a quirk to keep the " Jake Steinman
2026-09-03 16:14   ` sashiko-bot
     [not found]   ` <20260904004308.185788-1-j@metarealtyinc.ca>
2026-09-04  4:47     ` [PATCH v3] " Hogander, Jouni
     [not found]     ` <20260904114835.483057-1-j@metarealtyinc.ca>
2026-09-04 12:51       ` Hogander, Jouni
2026-09-03 16:09 ` ✗ LGCI.VerificationFailed: failure for drm/i915/alpm: Keep the extended fast wake ahead of the IO buffer wake (rev2) Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox