From: Dyllan Kobal <[email protected]>

If I am understanding the logic here correctly amdgpu_dm_commit_streams()
is suppose to be deciding whether to start the 200ms FRL link-status
polling worker by scanning the streams being committed and setting
frl_stream_found.  The intent is "if any FRL stream in use, arm 
the worker so it can call dc_link_frl_poll_status_flag() and
trigger DETECT_REASON_RETRAIN on link errors".

The conditional seems to be inverted: it sets frl_stream_found 
when the stream is *not* HDMI FRL.  Consequently:

  - On a commit with only an FRL stream (the normal case once an
    HDMI 2.1 sink is up), the worker is cancel_delayed_work_sync()'d
    and never re-armed.
  - On commits that include only TMDS/DP streams, the worker fires
    pointlessly and walks every dc_link looking for FRL links that
    aren't there.

The net effect on HDMI 2.1 FRL sinks is that FRL link retraining is
completely disabled.

Verified on a Sony Bravia 8 II connected to an RX 9070 XT (DCN 4.0.1).  
ftrace function tracer filtered to hdmi_frl_status_polling_work:

  before fix:  0 invocations in 10 s
  after fix:  48 invocations in 10 s (expected 5 Hz cadence)

After the fix, dc_link_detect(DETECT_REASON_RETRAIN) recovers the
link automatically on the next transient instead of requiring a full
hotplug.

Fixes: f7d5a0012653 ("drm/amd/display: Tie FRL support into amdgpu_dm")
Signed-off-by: Dyllan Kobal <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index cc8e8717a460..4bd760871f85 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10986,7 +10986,7 @@ static void amdgpu_dm_commit_streams(struct 
drm_atomic_state *state,
        for (i = 0; i < params.stream_count; i++) {
                struct dc_stream_state *stream = params.streams[i];
 
-               if (stream->signal != SIGNAL_TYPE_HDMI_FRL) {
+               if (stream->signal == SIGNAL_TYPE_HDMI_FRL) {
                        frl_stream_found = true;
                        break;
                }
-- 
2.54.0


Reply via email to