]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amd/display: prevent hang on link training fail
authorBrendan Tam <Brendan.Tam@amd.com>
Fri, 14 Mar 2025 17:09:13 +0000 (13:09 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 26 Mar 2025 21:43:25 +0000 (17:43 -0400)
[Why]
When link training fails, the phy clock will be disabled. However, in
enable_streams, it is assumed that link training succeeded and the
mux selects the phy clock, causing a hang when a register write is made.

[How]
When enable_stream is hit, check if link training failed. If it did, fall
back to the ref clock to avoid a hang and keep the system in a recoverable
state.

Reviewed-by: Dillon Varone <dillon.varone@amd.com>
Signed-off-by: Brendan Tam <Brendan.Tam@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c

index 926c08e790c104eac189fdc18564e756f77e5d0c..846c9c51f2d981efb1db6b3a9a0642c6b81b7731 100644 (file)
@@ -3033,7 +3033,11 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
                dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, dp_hpo_inst);
 
                phyd32clk = get_phyd32clk_src(link);
-               dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+               if (link->cur_link_settings.link_rate == LINK_RATE_UNKNOWN) {
+                       dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+               } else {
+                       dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+               }
        } else {
                if (dccg->funcs->enable_symclk_se)
                        dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
index 8f5da0ded85072735a663ef29ba7191acbc03806..5489f3d431f64d97523ba194739980e3fdf1251d 100644 (file)
@@ -936,8 +936,11 @@ void dcn401_enable_stream(struct pipe_ctx *pipe_ctx)
        if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
                if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
                        dccg->funcs->set_dpstreamclk(dccg, DPREFCLK, tg->inst, dp_hpo_inst);
-
-                       dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+                       if (link->cur_link_settings.link_rate == LINK_RATE_UNKNOWN) {
+                               dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
+                       } else {
+                               dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
+                       }
                } else {
                        dccg->funcs->enable_symclk_se(dccg, stream_enc->stream_enc_inst,
                                        link_enc->transmitter - TRANSMITTER_UNIPHY_A);