From b01f22ec88103d781f27aadb29277a35302db083 Mon Sep 17 00:00:00 2001 From: David Galiffi Date: Wed, 29 Jan 2020 17:02:32 -0500 Subject: [PATCH] drm/amd/display: Workaround required for link training reliability [Why] A software workaround is required for all vendor-built cards on platform. [How] When performing DP link training, we must send TPS1 before DPCD:100h is written with the proper bit rate value. This change must be applies in ALL cases when LT happens. Signed-off-by: David Galiffi Reviewed-by: Tony Cheng Acked-by: Rodrigo Siqueira Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 19 ++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index c0fcee4b5b69..8de9d6f9a477 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -945,6 +945,17 @@ static enum link_training_result perform_channel_equalization_sequence( } #define TRAINING_AUX_RD_INTERVAL 100 //us +static void start_clock_recovery_pattern_early(struct dc_link *link, + struct link_training_settings *lt_settings, + uint32_t offset) +{ + DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS1. Wait 400us.\n", + __func__); + dp_set_hw_training_pattern(link, DP_TRAINING_PATTERN_SEQUENCE_1, offset); + dp_set_hw_lane_settings(link, lt_settings, offset); + udelay(400); +} + static enum link_training_result perform_clock_recovery_sequence( struct dc_link *link, struct link_training_settings *lt_settings, @@ -962,7 +973,8 @@ static enum link_training_result perform_clock_recovery_sequence( retries_cr = 0; retry_count = 0; - dp_set_hw_training_pattern(link, tr_pattern, offset); + if (!link->wa_flags.dp_early_cr_pattern) + dp_set_hw_training_pattern(link, tr_pattern, offset); /* najeeb - The synaptics MST hub can put the LT in * infinite loop by switching the VS @@ -1434,6 +1446,9 @@ enum link_training_result dc_link_dp_perform_link_training( &link->preferred_training_settings, <_settings); + if (link->wa_flags.dp_early_cr_pattern) + start_clock_recovery_pattern_early(link, <_settings, DPRX); + /* 1. set link rate, lane count and spread. */ dpcd_set_link_settings(link, <_settings); @@ -1654,6 +1669,8 @@ enum link_training_result dc_link_dp_sync_lt_attempt( dp_set_panel_mode(link, panel_mode); /* Attempt to train with given link training settings */ + if (link->wa_flags.dp_early_cr_pattern) + start_clock_recovery_pattern_early(link, <_settings, DPRX); /* Set link rate, lane count and spread. */ dpcd_set_link_settings(link, <_settings); diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index 5f341e960506..6344de3ca979 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -135,6 +135,7 @@ struct dc_link { bool dp_keep_receiver_powered; bool dp_skip_DID2; bool dp_skip_reset_segment; + bool dp_early_cr_pattern; } wa_flags; struct link_mst_stream_allocation_table mst_stream_alloc_table; -- 2.11.0