Intel-GFX Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters
@ 2026-04-30  3:08 bitey
  2026-04-30  7:45 ` Jani Nikula
  2026-04-30 17:55 ` ✗ LGCI.VerificationFailed: failure for " Patchwork
  0 siblings, 2 replies; 4+ messages in thread
From: bitey @ 2026-04-30  3:08 UTC (permalink / raw)
  To: intel-gfx, dri-devel; +Cc: jani.nikula, rodrigo.vivi

On Ivy Bridge (and other pre-gen8 platforms), active DP-to-HDMI protocol
converters such as the Chrontel CH73111 trigger an infinite link retrain
loop on kernels 6.x+. The monitor connected through the adapter goes
black and recovers approximately once per second, eventually causing
system instability.

Three changes introduced in the i915 DP stack combine to cause this:

1. intel_dp_stop_link_train() now automatically schedules a post-training
   link check via intel_encoder_link_check_queue_work(). The Chrontel
   adapter reports non-standard DPCD link status, which causes the check
   to fail and trigger a retrain, looping indefinitely.

2. intel_dp_needs_link_retrain() unconditionally returns true when
   seq_train_failures > 0, bypassing the actual DPCD link status read.
   A single marginal training attempt permanently marks the link as
   needing retrain.

3. intel_dp_short_pulse() forces LINK_STATUS_CHANGED on every short HPD
   for all platforms, causing unnecessary link checks that initiate the
   retrain cycle on adapters that generate frequent short HPDs.

Fix all three by gating the new behavior behind DISPLAY_VER(display) >= 8,
restoring the 5.15-era behavior for Ivy Bridge/Sandy Bridge and earlier.
These platforms use the older g4x DP path and do not benefit from the
aggressive post-training link monitoring.

Tested on Intel HD 2500 (Ivy Bridge, device ID 0152) with a Chrontel
CH73111 DP-to-HDMI adapter driving a 1920x1080 display over 2 lanes
at HBR (270 MHz).

Signed-off-by: bitey <s.mavlenkov@mail.ru>
---
 drivers/gpu/drm/i915/display/intel_dp.c              | 8 +++++++-
 drivers/gpu/drm/i915/display/intel_dp_link_training.c | 3 ++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ORIGINAL..FIXED 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5676,6 +5676,7 @@ static int
 intel_dp_read_link_status(struct intel_dp *intel_dp,
 			  u8 link_status[DP_LINK_STATUS_SIZE])
 {
+	struct intel_display *display = to_intel_display(intel_dp);
 	int err;
 
 	memset(link_status, 0, DP_LINK_STATUS_SIZE);
@@ -5712,7 +5713,8 @@ static bool intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
 	if (intel_dp->link.retrain_disabled)
 		return false;
 
-	if (intel_dp->link.seq_train_failures)
+	if (DISPLAY_VER(display) >= 8 &&
+	    intel_dp->link.seq_train_failures)
 		return true;
 
 	/* Retrain if link not ok */
@@ -5965,6 +5967,7 @@ static bool
 intel_dp_short_pulse(struct intel_dp *intel_dp)
 {
+	struct intel_display *display = to_intel_display(intel_dp);
 	bool reprobe_needed = false;
 	u8 esi[4] = {};
 
@@ -5988,7 +5991,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
 	 * TODO: let the link status check depend on LINK_STATUS_CHANGED
 	 * or intel_dp->link.force_retrain for DPCD_REV >= 1.2
 	 */
-	esi[3] |= LINK_STATUS_CHANGED;
+	if (DISPLAY_VER(display) >= 8)
+		esi[3] |= LINK_STATUS_CHANGED;
 	if (intel_dp_handle_link_service_irq(intel_dp, esi[3]))
 		reprobe_needed = true;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index ORIGINAL..FIXED 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1154,7 +1154,8 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp,
 
 	intel_hpd_unblock(encoder);
 
-	if (!display->hotplug.ignore_long_hpd &&
+	if (DISPLAY_VER(display) >= 8 &&
+	    !display->hotplug.ignore_long_hpd &&
 	    intel_dp->link.seq_train_failures < MAX_SEQ_TRAIN_FAILURES) {
 		int delay_ms = intel_dp->link.seq_train_failures ? 0 : 2000;
 
-- 
2.49.0

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

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

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-30  3:08 [PATCH] drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters bitey
2026-04-30  7:45 ` Jani Nikula
2026-05-01 18:02   ` Сергей Мавленков
2026-04-30 17:55 ` ✗ LGCI.VerificationFailed: failure for " Patchwork

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