From 952ab0b302396bd6cba0859c585208882389807d Mon Sep 17 00:00:00 2001 From: "Leo (Hanghong) Ma" Date: Mon, 16 Aug 2021 14:35:59 -0400 Subject: [PATCH] drm/amd/display: Fix system hang at boot [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 Signed-off-by: Leo (Hanghong) Ma Reviewed-by: Aric Cyr Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 2 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c | 27 ++++++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c index 58abfa5..b9570b7 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -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)); } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index cf8fee7..2ce668a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -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; -- 2.7.4