public inbox for intel-gfx@lists.freedesktop.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

* Re: [PATCH] drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters
  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
  1 sibling, 1 reply; 4+ messages in thread
From: Jani Nikula @ 2026-04-30  7:45 UTC (permalink / raw)
  To: bitey, intel-gfx, dri-devel; +Cc: rodrigo.vivi

On Thu, 30 Apr 2026, bitey <s.mavlenkov@mail.ru> wrote:
> 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).

Please file a bug over at [1] with the full dmesg reproducing the
issues, and reply with the link to the bug.

Thanks,
Jani.


[1] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html


>
> 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;

-- 
Jani Nikula, Intel

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

* ✗ LGCI.VerificationFailed: failure for drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters
  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-04-30 17:55 ` Patchwork
  1 sibling, 0 replies; 4+ messages in thread
From: Patchwork @ 2026-04-30 17:55 UTC (permalink / raw)
  To: bitey; +Cc: intel-gfx

== Series Details ==

Series: drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters
URL   : https://patchwork.freedesktop.org/series/165800/
State : failure

== Summary ==

Address 's.mavlenkov@mail.ru' is not on the allowlist, which prevents CI from being triggered for this patch.
If you want Intel GFX CI to accept this address, please contact the script maintainers at i915-ci-infra@lists.freedesktop.org.
Exception occurred during validation, bailing out!



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

* Re: [PATCH] drm/i915/dp: Fix link retrain loop on pre-gen8 platforms with DP adapters
  2026-04-30  7:45 ` Jani Nikula
@ 2026-05-01 18:02   ` Сергей Мавленков
  0 siblings, 0 replies; 4+ messages in thread
From: Сергей Мавленков @ 2026-05-01 18:02 UTC (permalink / raw)
  To: Jani Nikula; +Cc: rodrigo.vivi, intel-gfx, dri-devel

[-- Attachment #1: Type: text/plain, Size: 4663 bytes --]

Hi Jani,

Thank you for the pointer. I've filed the bug here:
https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/15994
The full dmesg, hardware details, root cause analysis, and proposed fix
are all in the issue.

Best regards,
Кусь

> 
> Четверг, 30 апреля 2026, 10:45 +03:00 от Jani Nikula <jani.nikula@linux.intel.com
> >:
> On Thu, 30 Apr 2026, bitey <s.mavlenkov@mail.ru> wrote:
> > 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).
> 
> Please file a bug over at [1] with the full dmesg reproducing the
> issues, and reply with the link to the bug.
> 
> Thanks,
> Jani.
> 
> 
> [1] https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html
> 
> 
> 
> >
> > 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;
> 
> --
> Jani Nikula, Intel
>

[-- Attachment #2: Type: text/html, Size: 6087 bytes --]

^ 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