drm/amd/display: Fix system hang at boot
authorLeo (Hanghong) Ma <hanghong.ma@amd.com>
Mon, 16 Aug 2021 18:35:59 +0000 (14:35 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 14 Sep 2021 19:57:09 +0000 (15:57 -0400)
[Why]
During DQE's promotion test, system hang issue is found on linux
system;

[How]
1. Add NULL pointor check for the link in the sequence trace
   function;
2. Get the right link for the stream encoder before blank DP
   stream;

Acked-by: Mikita Lipski <mikita.lipski@amd.com>
Signed-off-by: Leo (Hanghong) Ma <hanghong.ma@amd.com>
Reviewed-by: Aric Cyr <aric.cyr@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c
drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c

index 58abfa5..b9570b7 100644 (file)
@@ -64,7 +64,7 @@ void dp_receiver_power_ctrl(struct dc_link *link, bool on)
 
 void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
 {
-       if (link->dc->debug.enable_driver_sequence_debug)
+       if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
                core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
                                        &dp_test_mode, sizeof(dp_test_mode));
 }
index cf8fee7..2ce668a 100644 (file)
@@ -1638,23 +1638,30 @@ static enum dc_status apply_single_controller_ctx_to_hw(
 
 static void power_down_encoders(struct dc *dc)
 {
-       int i;
-
-       /* do not know BIOS back-front mapping, simply blank all. It will not
-        * hurt for non-DP
-        */
-       for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
-               dc->res_pool->stream_enc[i]->funcs->dp_blank(dc->links[i],
-                                       dc->res_pool->stream_enc[i]);
-       }
+       int i, j;
 
        for (i = 0; i < dc->link_count; i++) {
                enum signal_type signal = dc->links[i]->connector_signal;
 
                if ((signal == SIGNAL_TYPE_EDP) ||
-                       (signal == SIGNAL_TYPE_DISPLAY_PORT))
+                       (signal == SIGNAL_TYPE_DISPLAY_PORT)) {
+                       if (dc->links[i]->link_enc->funcs->get_dig_frontend &&
+                               dc->links[i]->link_enc->funcs->is_dig_enabled(dc->links[i]->link_enc)) {
+                               unsigned int fe = dc->links[i]->link_enc->funcs->get_dig_frontend(
+                                                                       dc->links[i]->link_enc);
+
+                               for (j = 0; j < dc->res_pool->stream_enc_count; j++) {
+                                       if (fe == dc->res_pool->stream_enc[j]->id) {
+                                               dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i],
+                                                                       dc->res_pool->stream_enc[j]);
+                                               break;
+                                       }
+                               }
+                       }
+
                        if (!dc->links[i]->wa_flags.dp_keep_receiver_powered)
                                dp_receiver_power_ctrl(dc->links[i], false);
+               }
 
                if (signal != SIGNAL_TYPE_EDP)
                        signal = SIGNAL_TYPE_NONE;