From e72aa36ef88f18d541acacaa4051de615ba78efa Mon Sep 17 00:00:00 2001 From: Wenjing Liu Date: Mon, 27 Sep 2021 13:10:07 -0400 Subject: [PATCH] drm/amd/display: fix link training regression for 1 or 2 lane [why] We have a regression that cause maximize lane settings to use uninitialized data from unused lanes. This will cause link training to fail for 1 or 2 lanes because the lane adjust is populated incorrectly sometimes. v2: fix build without CONFIG_DRM_AMD_DC_DCN (Alex) Reviewed-by: Eric Yang Acked-by: Rodrigo Siqueira Tested-by: Daniel Wheeler Signed-off-by: Wenjing Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 35 ++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) 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 4b89a27..cc25ba0 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 @@ -108,6 +108,9 @@ static struct dc_link_settings get_common_supported_link_settings( struct dc_link_settings link_setting_b); static void maximize_lane_settings(const struct link_training_settings *lt_settings, struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); +static void override_lane_settings(const struct link_training_settings *lt_settings, + struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]); + static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link, const struct dc_link_settings *link_settings) { @@ -734,15 +737,13 @@ void dp_decide_lane_settings( } #endif } - - /* we find the maximum of the requested settings across all lanes*/ - /* and set this maximum for all lanes*/ dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings); if (lt_settings->disallow_per_lane_settings) { /* we find the maximum of the requested settings across all lanes*/ /* and set this maximum for all lanes*/ maximize_lane_settings(lt_settings, hw_lane_settings); + override_lane_settings(lt_settings, hw_lane_settings); if (lt_settings->always_match_dpcd_with_hw_lane_settings) dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings); @@ -833,6 +834,34 @@ static void maximize_lane_settings(const struct link_training_settings *lt_setti } } +static void override_lane_settings(const struct link_training_settings *lt_settings, + struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) +{ + uint32_t lane; + + if (lt_settings->voltage_swing == NULL && + lt_settings->pre_emphasis == NULL && +#if defined(CONFIG_DRM_AMD_DC_DCN) + lt_settings->ffe_preset == NULL && +#endif + lt_settings->post_cursor2 == NULL) + + return; + + for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) { + if (lt_settings->voltage_swing) + lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing; + if (lt_settings->pre_emphasis) + lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis; + if (lt_settings->post_cursor2) + lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2; +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (lt_settings->ffe_preset) + lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset; +#endif + } +} + enum dc_status dp_get_lane_status_and_lane_adjust( struct dc_link *link, const struct link_training_settings *link_training_setting, -- 2.7.4