mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-14 23:16:25 +07:00
drm/amd/display: fix decide_link_settings
Signed-off-by: Ding Wang <Ding.Wang@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
03618e9107
commit
8c4abe0b07
@ -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 {
|
|||||||
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(
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
|||||||
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;
|
||||||
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;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for first suitable setting for the requested
|
/* search for the minimum link setting that:
|
||||||
* bandwidth
|
* 1. is supported according to the link training result
|
||||||
*/
|
* 2. could support the b/w requested by the timing
|
||||||
for (i = 0; i < get_link_training_fallback_table_len(link); i++) {
|
*/
|
||||||
|
while (current_link_setting.link_rate <=
|
||||||
|
link->public.max_link_setting.link_rate) {
|
||||||
|
link_bw = bandwidth_in_kbps_from_link_settings(
|
||||||
|
¤t_link_setting);
|
||||||
|
if (req_bw <= link_bw) {
|
||||||
|
*link_setting = current_link_setting;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cur_ls = get_link_training_fallback_table(link, i);
|
if (current_link_setting.lane_count <
|
||||||
|
link->public.max_link_setting.lane_count) {
|
||||||
link_bw =
|
current_link_setting.lane_count =
|
||||||
bandwidth_in_kbps_from_link_settings(
|
increase_lane_count(
|
||||||
cur_ls);
|
current_link_setting.lane_count);
|
||||||
|
} else {
|
||||||
if (req_bw < link_bw) {
|
current_link_setting.link_rate =
|
||||||
if (is_link_setting_supported(
|
increase_link_rate(
|
||||||
cur_ls,
|
current_link_setting.link_rate);
|
||||||
&link->public.max_link_setting)) {
|
current_link_setting.lane_count =
|
||||||
*link_setting = *cur_ls;
|
initial_link_setting.lane_count;
|
||||||
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 {
|
|||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user