From 83e2b80d589c0262d047f21e16b80f3ffe32617a Mon Sep 17 00:00:00 2001 From: Ding Wang Date: Tue, 18 Jul 2017 17:18:11 -0400 Subject: [PATCH 0649/4131] drm/amd/display: fix decide_link_settings Signed-off-by: Ding Wang Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 140 ++++++++++------------- drivers/gpu/drm/amd/display/dc/dc.h | 1 + 3 files changed, 63 insertions(+), 84 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index ad1b905..de05ad0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -308,10 +308,8 @@ static void set_preferred_link_settings(struct dc *dc, { struct core_link *core_link = DC_LINK_TO_CORE(link); - core_link->public.verified_link_cap.lane_count = - link_setting->lane_count; - core_link->public.verified_link_cap.link_rate = - link_setting->link_rate; + core_link->public.preferred_link_setting = + *link_setting; dp_retrain_link_dp_test(core_link, link_setting, false); } 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 445cd22..e90b3eb 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 @@ -33,32 +33,6 @@ enum { LINK_TRAINING_MAX_CR_RETRY = 100 }; -static const struct dc_link_settings link_training_fallback_table[] = { -/* 4320 Mbytes/sec*/ -{ LANE_COUNT_FOUR, LINK_RATE_HIGH3, LINK_SPREAD_DISABLED }, -/* 2160 Mbytes/sec*/ -{ LANE_COUNT_FOUR, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED }, -/* 1080 Mbytes/sec*/ -{ LANE_COUNT_FOUR, LINK_RATE_HIGH, LINK_SPREAD_DISABLED }, -/* 648 Mbytes/sec*/ -{ LANE_COUNT_FOUR, LINK_RATE_LOW, LINK_SPREAD_DISABLED }, -/* 2160 Mbytes/sec*/ -{ LANE_COUNT_TWO, LINK_RATE_HIGH3, LINK_SPREAD_DISABLED }, -/* 1080 Mbytes/sec*/ -{ LANE_COUNT_TWO, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED }, -/* 540 Mbytes/sec*/ -{ LANE_COUNT_TWO, LINK_RATE_HIGH, LINK_SPREAD_DISABLED }, -/* 324 Mbytes/sec*/ -{ LANE_COUNT_TWO, LINK_RATE_LOW, LINK_SPREAD_DISABLED }, -/* 1080 Mbytes/sec*/ -{ LANE_COUNT_ONE, LINK_RATE_HIGH3, LINK_SPREAD_DISABLED }, -/* 540 Mbytes/sec*/ -{ LANE_COUNT_ONE, LINK_RATE_HIGH2, LINK_SPREAD_DISABLED }, -/* 270 Mbytes/sec*/ -{ LANE_COUNT_ONE, LINK_RATE_HIGH, LINK_SPREAD_DISABLED }, -/* 162 Mbytes/sec*/ -{ LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED } }; - static void wait_for_training_aux_rd_interval( struct core_link* link, uint32_t default_wait_in_micro_secs) @@ -1053,29 +1027,6 @@ bool perform_link_training_with_retries( return false; } -/*TODO add more check to see if link support request link configuration */ -static bool is_link_setting_supported( - const struct dc_link_settings *link_setting, - const struct dc_link_settings *max_link_setting) -{ - if (link_setting->lane_count > max_link_setting->lane_count || - link_setting->link_rate > max_link_setting->link_rate) - return false; - return true; -} - -static const uint32_t get_link_training_fallback_table_len( - struct core_link *link) -{ - return ARRAY_SIZE(link_training_fallback_table); -} - -static const struct dc_link_settings *get_link_training_fallback_table( - struct core_link *link, uint32_t i) -{ - return &link_training_fallback_table[i]; -} - static struct dc_link_settings get_max_link_cap(struct core_link *link) { /* Set Default link settings */ @@ -1284,6 +1235,32 @@ enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate) } } +enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count) +{ + switch (lane_count) { + case LANE_COUNT_ONE: + return LANE_COUNT_TWO; + case LANE_COUNT_TWO: + return LANE_COUNT_FOUR; + default: + return LANE_COUNT_UNKNOWN; + } +} + +enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate) +{ + switch (link_rate) { + case LINK_RATE_LOW: + return LINK_RATE_HIGH; + case LINK_RATE_HIGH: + return LINK_RATE_HIGH2; + case LINK_RATE_HIGH2: + return LINK_RATE_HIGH3; + default: + return LINK_RATE_UNKNOWN; + } +} + /* * function: set link rate and lane count fallback based * on current link setting and last link training result @@ -1463,57 +1440,60 @@ void decide_link_settings(struct core_stream *stream, struct dc_link_settings *link_setting) { - const struct dc_link_settings *cur_ls; + struct dc_link_settings initial_link_setting = { + LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED}; + struct dc_link_settings current_link_setting = + initial_link_setting; struct core_link* link; uint32_t req_bw; uint32_t link_bw; - uint32_t i; req_bw = bandwidth_in_kbps_from_timing( &stream->public.timing); + link = stream->sink->link; + /* if preferred is specified through AMDDP, use it, if it's enough * to drive the mode */ - link = stream->sink->link; - - if ((link->public.reported_link_cap.lane_count != LANE_COUNT_UNKNOWN) && - (link->public.reported_link_cap.link_rate <= - link->public.verified_link_cap.link_rate)) { + if (link->public.preferred_link_setting.lane_count != + LANE_COUNT_UNKNOWN && + link->public.preferred_link_setting.link_rate != + LINK_RATE_UNKNOWN) { + *link_setting = link->public.preferred_link_setting; + return; + } + /* search for the minimum link setting that: + * 1. is supported according to the link training result + * 2. could support the b/w requested by the timing + */ + while (current_link_setting.link_rate <= + link->public.max_link_setting.link_rate) { link_bw = bandwidth_in_kbps_from_link_settings( - &link->public.reported_link_cap); - - if (req_bw < link_bw) { - *link_setting = link->public.reported_link_cap; + ¤t_link_setting); + if (req_bw <= link_bw) { + *link_setting = current_link_setting; return; } - } - /* search for first suitable setting for the requested - * bandwidth - */ - for (i = 0; i < get_link_training_fallback_table_len(link); i++) { - - cur_ls = get_link_training_fallback_table(link, i); - - link_bw = - bandwidth_in_kbps_from_link_settings( - cur_ls); - - if (req_bw < link_bw) { - if (is_link_setting_supported( - cur_ls, - &link->public.max_link_setting)) { - *link_setting = *cur_ls; - return; - } + if (current_link_setting.lane_count < + link->public.max_link_setting.lane_count) { + current_link_setting.lane_count = + increase_lane_count( + current_link_setting.lane_count); + } else { + current_link_setting.link_rate = + increase_link_rate( + current_link_setting.link_rate); + current_link_setting.lane_count = + initial_link_setting.lane_count; } } BREAK_TO_DEBUGGER(); ASSERT(link->public.verified_link_cap.lane_count != - LANE_COUNT_UNKNOWN); + LANE_COUNT_UNKNOWN); *link_setting = link->public.verified_link_cap; } diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 6172708..ee04c35 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -674,6 +674,7 @@ struct dc_link { struct dc_link_settings max_link_setting; struct dc_link_settings cur_link_settings; struct dc_lane_settings cur_lane_setting; + struct dc_link_settings preferred_link_setting; uint8_t ddc_hw_inst; -- 2.7.4