From adccecb927349ea98ee429f75a3e50955432acf2 Mon Sep 17 00:00:00 2001 From: Zeyu Fan Date: Fri, 23 Dec 2016 16:53:12 -0500 Subject: [PATCH 0113/4131] drm/amd/display: Fix link retraining hw sequence Signed-off-by: Zeyu Fan Reviewed-by: Hersen Wu Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 15 +++---- drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c | 49 +++++++++++++++++++++- drivers/gpu/drm/amd/display/dc/dc.h | 3 +- drivers/gpu/drm/amd/display/dc/inc/link_hwss.h | 4 ++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 69819d8..ad1ce60 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -357,17 +357,18 @@ static void perform_link_training(struct dc *dc, } static void set_preferred_link_settings(struct dc *dc, - struct dc_link_settings *link_setting) + struct dc_link_settings *link_setting, + const struct dc_link *link) { - struct core_dc *core_dc = DC_TO_CORE(dc); - int i; + struct core_link *core_link = DC_LINK_TO_CORE(link); - for (i = 0; i < core_dc->link_count; i++) { - core_dc->links[i]->public.verified_link_cap.lane_count = + core_link->public.verified_link_cap.lane_count = link_setting->lane_count; - core_dc->links[i]->public.verified_link_cap.link_rate = + core_link->public.verified_link_cap.link_rate = link_setting->link_rate; - } + dp_retrain_link_physi(core_link, + link_setting, + false); } static void enable_hpd(const struct dc_link *link) 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 4febc8d..f870a0e 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 @@ -200,7 +200,6 @@ void dp_set_hw_test_pattern( encoder->funcs->dp_set_phy_pattern(encoder, &pattern_param); } - void dp_retrain_link(struct core_link *link) { struct pipe_ctx *pipes = link->dc->current_context->res_ctx.pipe_ctx; @@ -221,3 +220,51 @@ void dp_retrain_link(struct core_link *link) } } } + +void dp_retrain_link_physi(struct core_link *link, + struct dc_link_settings *link_setting, + bool skip_video_pattern) +{ + struct pipe_ctx *pipes = + &link->dc->current_context->res_ctx.pipe_ctx[0]; + unsigned int i; + + for (i = 0; i < MAX_PIPES; i++) { + if (pipes[i].stream != NULL && + pipes[i].stream->sink != NULL && + pipes[i].stream->sink->link != NULL && + pipes[i].stream_enc != NULL && + pipes[i].stream->sink->link == link) { + dm_delay_in_microseconds(link->ctx, 100); + + pipes[i].stream_enc->funcs->dp_blank( + pipes[i].stream_enc); + + dp_receiver_power_ctrl(link, false); + + link->link_enc->funcs->disable_output( + link->link_enc, + SIGNAL_TYPE_DISPLAY_PORT); + + /* Clear current link setting. + * memset(&link->public.cur_link_settings, 0, + * sizeof(link->public.cur_link_settings)); + */ + + link->link_enc->funcs->enable_dp_output( + link->link_enc, + link_setting, + pipes[i].clock_source->id); + + dp_receiver_power_ctrl(link, true); + + dc_link_dp_perform_link_training( + &link->public, + link_setting, + skip_video_pattern); + + link->dc->hwss.unblank_stream(&pipes[i], + link_setting); + } + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 599f8b0..83d78c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -117,7 +117,8 @@ struct dc_link_funcs { struct dc_link_settings *link_setting, bool skip_video_pattern); void (*set_preferred_link_settings)(struct dc *dc, - struct dc_link_settings *link_setting); + struct dc_link_settings *link_setting, + const struct dc_link *link); void (*enable_hpd)(const struct dc_link *link); void (*disable_hpd)(const struct dc_link *link); void (*set_test_pattern)( diff --git a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h index 662fa30..30831c5 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/inc/link_hwss.h @@ -70,4 +70,8 @@ enum dp_panel_mode dp_get_panel_mode(struct core_link *link); void dp_retrain_link(struct core_link *link); +void dp_retrain_link_physi(struct core_link *link, + struct dc_link_settings *link_setting, + bool skip_video_pattern); + #endif /* __DC_LINK_HWSS_H__ */ -- 2.7.4