Commit 8c4abe0b authored by Ding Wang's avatar Ding Wang Committed by Alex Deucher

drm/amd/display: fix decide_link_settings

Signed-off-by: default avatarDing Wang <Ding.Wang@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 03618e91
...@@ -308,10 +308,8 @@ static void set_preferred_link_settings(struct dc *dc, ...@@ -308,10 +308,8 @@ static void set_preferred_link_settings(struct dc *dc,
{ {
struct core_link *core_link = DC_LINK_TO_CORE(link); struct core_link *core_link = DC_LINK_TO_CORE(link);
core_link->public.verified_link_cap.lane_count = core_link->public.preferred_link_setting =
link_setting->lane_count; *link_setting;
core_link->public.verified_link_cap.link_rate =
link_setting->link_rate;
dp_retrain_link_dp_test(core_link, link_setting, false); dp_retrain_link_dp_test(core_link, link_setting, false);
} }
......
...@@ -33,32 +33,6 @@ enum { ...@@ -33,32 +33,6 @@ enum {
LINK_TRAINING_MAX_CR_RETRY = 100 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( static void wait_for_training_aux_rd_interval(
struct core_link* link, struct core_link* link,
uint32_t default_wait_in_micro_secs) uint32_t default_wait_in_micro_secs)
...@@ -1053,29 +1027,6 @@ bool perform_link_training_with_retries( ...@@ -1053,29 +1027,6 @@ bool perform_link_training_with_retries(
return false; 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) static struct dc_link_settings get_max_link_cap(struct core_link *link)
{ {
/* Set Default link settings */ /* Set Default link settings */
...@@ -1284,6 +1235,32 @@ enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate) ...@@ -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 * function: set link rate and lane count fallback based
* on current link setting and last link training result * on current link setting and last link training result
...@@ -1463,57 +1440,60 @@ void decide_link_settings(struct core_stream *stream, ...@@ -1463,57 +1440,60 @@ void decide_link_settings(struct core_stream *stream,
struct dc_link_settings *link_setting) 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; struct core_link* link;
uint32_t req_bw; uint32_t req_bw;
uint32_t link_bw; uint32_t link_bw;
uint32_t i;
req_bw = bandwidth_in_kbps_from_timing( req_bw = bandwidth_in_kbps_from_timing(
&stream->public.timing); &stream->public.timing);
link = stream->sink->link;
/* if preferred is specified through AMDDP, use it, if it's enough /* if preferred is specified through AMDDP, use it, if it's enough
* to drive the mode * to drive the mode
*/ */
link = stream->sink->link; if (link->public.preferred_link_setting.lane_count !=
LANE_COUNT_UNKNOWN &&
if ((link->public.reported_link_cap.lane_count != LANE_COUNT_UNKNOWN) && link->public.preferred_link_setting.link_rate !=
(link->public.reported_link_cap.link_rate <= LINK_RATE_UNKNOWN) {
link->public.verified_link_cap.link_rate)) { *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_bw = bandwidth_in_kbps_from_link_settings(
&link->public.reported_link_cap); &current_link_setting);
if (req_bw <= link_bw) {
if (req_bw < link_bw) { *link_setting = current_link_setting;
*link_setting = link->public.reported_link_cap;
return; return;
} }
}
/* search for first suitable setting for the requested if (current_link_setting.lane_count <
* bandwidth link->public.max_link_setting.lane_count) {
*/ current_link_setting.lane_count =
for (i = 0; i < get_link_training_fallback_table_len(link); i++) { increase_lane_count(
current_link_setting.lane_count);
cur_ls = get_link_training_fallback_table(link, i); } else {
current_link_setting.link_rate =
link_bw = increase_link_rate(
bandwidth_in_kbps_from_link_settings( current_link_setting.link_rate);
cur_ls); current_link_setting.lane_count =
initial_link_setting.lane_count;
if (req_bw < link_bw) {
if (is_link_setting_supported(
cur_ls,
&link->public.max_link_setting)) {
*link_setting = *cur_ls;
return;
}
} }
} }
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
ASSERT(link->public.verified_link_cap.lane_count != ASSERT(link->public.verified_link_cap.lane_count !=
LANE_COUNT_UNKNOWN); LANE_COUNT_UNKNOWN);
*link_setting = link->public.verified_link_cap; *link_setting = link->public.verified_link_cap;
} }
......
...@@ -674,6 +674,7 @@ struct dc_link { ...@@ -674,6 +674,7 @@ struct dc_link {
struct dc_link_settings max_link_setting; struct dc_link_settings max_link_setting;
struct dc_link_settings cur_link_settings; struct dc_link_settings cur_link_settings;
struct dc_lane_settings cur_lane_setting; struct dc_lane_settings cur_lane_setting;
struct dc_link_settings preferred_link_setting;
uint8_t ddc_hw_inst; uint8_t ddc_hw_inst;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment