Commit 4e9e50b6 authored by Michael Strauss's avatar Michael Strauss Committed by Alex Deucher

drm/amd/display: Allow UHBR Interop With eDP Supported Link Rates Table

[WHY]
eDP 2.0 is introducing support for UHBR link rates, however current eDP ILR
link optimization does not account for UHBR capabilities.
Either UHBR capabilities will be provided via the same 128b/132b rate DPCD caps
that are currently used on DP2.1, or Table 4-13 may be updated to include UHBR
rates.

[HOW]
Add extra Supported Link Rates table translations for UHBR10/13.5/20.
Update eDP link setting optimization search to be aware of 128b/132b DPCD
rate caps in order to unblock UHBR on panels with Supported Link Rates table.
Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarMichael Strauss <michael.strauss@amd.com>
Signed-off-by: default avatarRoman Li <roman.li@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7c9cb6d1
...@@ -1189,8 +1189,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, ...@@ -1189,8 +1189,7 @@ static bool detect_link_and_local_sink(struct dc_link *link,
//sink only can use supported link rate table, we are foreced to enable it //sink only can use supported link rate table, we are foreced to enable it
if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN) if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
link->panel_config.ilr.optimize_edp_link_rate = true; link->panel_config.ilr.optimize_edp_link_rate = true;
if (edp_is_ilr_optimization_enabled(link)) link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
link->reported_link_cap.link_rate = get_max_link_rate_from_ilr_table(link);
} }
} else { } else {
......
...@@ -212,6 +212,13 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in ...@@ -212,6 +212,13 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in
case 10000000: case 10000000:
link_rate = LINK_RATE_UHBR10; // UHBR10 - 10.0 Gbps/Lane link_rate = LINK_RATE_UHBR10; // UHBR10 - 10.0 Gbps/Lane
break; break;
case 13500000:
link_rate = LINK_RATE_UHBR13_5; // UHBR13.5 - 13.5 Gbps/Lane
break;
case 20000000:
link_rate = LINK_RATE_UHBR20; // UHBR20 - 20.0 Gbps/Lane
break;
default: default:
link_rate = LINK_RATE_UNKNOWN; link_rate = LINK_RATE_UNKNOWN;
break; break;
...@@ -541,6 +548,23 @@ static enum dc_link_rate increase_link_rate(struct dc_link *link, ...@@ -541,6 +548,23 @@ static enum dc_link_rate increase_link_rate(struct dc_link *link,
} }
} }
static void increase_edp_link_rate(struct dc_link *link,
struct dc_link_settings *current_link_setting)
{
if (current_link_setting->use_link_rate_set) {
if (current_link_setting->link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
current_link_setting->link_rate_set++;
current_link_setting->link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting->link_rate_set];
} else {
current_link_setting->use_link_rate_set = false;
current_link_setting->link_rate = LINK_RATE_UHBR10;
}
} else {
current_link_setting->link_rate = increase_link_rate(link, current_link_setting->link_rate);
}
}
static bool decide_fallback_link_setting_max_bw_policy( static bool decide_fallback_link_setting_max_bw_policy(
struct dc_link *link, struct dc_link *link,
const struct dc_link_settings *max, const struct dc_link_settings *max,
...@@ -759,14 +783,7 @@ bool edp_decide_link_settings(struct dc_link *link, ...@@ -759,14 +783,7 @@ bool edp_decide_link_settings(struct dc_link *link,
increase_lane_count( increase_lane_count(
current_link_setting.lane_count); current_link_setting.lane_count);
} else { } else {
if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { increase_edp_link_rate(link, &current_link_setting);
current_link_setting.link_rate_set++;
current_link_setting.link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
current_link_setting.lane_count =
initial_link_setting.lane_count;
} else
break;
} }
} }
return false; return false;
...@@ -818,9 +835,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, ...@@ -818,9 +835,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
if (policy) { if (policy) {
/* minimize lane */ /* minimize lane */
if (current_link_setting.link_rate < max_link_rate) { if (current_link_setting.link_rate < max_link_rate) {
current_link_setting.link_rate = increase_edp_link_rate(link, &current_link_setting);
increase_link_rate(link,
current_link_setting.link_rate);
} else { } else {
if (current_link_setting.lane_count < if (current_link_setting.lane_count <
link->verified_link_cap.lane_count) { link->verified_link_cap.lane_count) {
...@@ -839,9 +854,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, ...@@ -839,9 +854,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count( increase_lane_count(
current_link_setting.lane_count); current_link_setting.lane_count);
} else { } else {
current_link_setting.link_rate = increase_edp_link_rate(link, &current_link_setting);
increase_link_rate(link,
current_link_setting.link_rate);
current_link_setting.lane_count = current_link_setting.lane_count =
initial_link_setting.lane_count; initial_link_setting.lane_count;
} }
...@@ -874,18 +887,15 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, ...@@ -874,18 +887,15 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
} }
if (policy) { if (policy) {
/* minimize lane */ /* minimize lane */
if (current_link_setting.link_rate_set < if (current_link_setting.link_rate < max_link_rate) {
link->dpcd_caps.edp_supported_link_rates_count increase_edp_link_rate(link, &current_link_setting);
&& current_link_setting.link_rate < max_link_rate) {
current_link_setting.link_rate_set++;
current_link_setting.link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
} else { } else {
if (current_link_setting.lane_count < link->verified_link_cap.lane_count) { if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
current_link_setting.lane_count = current_link_setting.lane_count =
increase_lane_count( increase_lane_count(
current_link_setting.lane_count); current_link_setting.lane_count);
current_link_setting.link_rate_set = initial_link_setting.link_rate_set; current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
current_link_setting.use_link_rate_set = initial_link_setting.use_link_rate_set;
current_link_setting.link_rate = current_link_setting.link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set]; link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
} else } else
...@@ -899,13 +909,8 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link, ...@@ -899,13 +909,8 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count( increase_lane_count(
current_link_setting.lane_count); current_link_setting.lane_count);
} else { } else {
if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) { increase_edp_link_rate(link, &current_link_setting);
current_link_setting.link_rate_set++; if (current_link_setting.link_rate == LINK_RATE_UNKNOWN)
current_link_setting.link_rate =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
current_link_setting.lane_count =
initial_link_setting.lane_count;
} else
break; break;
} }
} }
......
...@@ -305,16 +305,17 @@ bool edp_is_ilr_optimization_enabled(struct dc_link *link) ...@@ -305,16 +305,17 @@ bool edp_is_ilr_optimization_enabled(struct dc_link *link)
return true; return true;
} }
enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link) enum dc_link_rate get_max_edp_link_rate(struct dc_link *link)
{ {
enum dc_link_rate link_rate = link->reported_link_cap.link_rate; enum dc_link_rate max_ilr_rate = LINK_RATE_UNKNOWN;
enum dc_link_rate max_non_ilr_rate = dp_get_max_link_cap(link).link_rate;
for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) { for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) {
if (link_rate < link->dpcd_caps.edp_supported_link_rates[i]) if (max_ilr_rate < link->dpcd_caps.edp_supported_link_rates[i])
link_rate = link->dpcd_caps.edp_supported_link_rates[i]; max_ilr_rate = link->dpcd_caps.edp_supported_link_rates[i];
} }
return link_rate; return (max_ilr_rate > max_non_ilr_rate ? max_ilr_rate : max_non_ilr_rate);
} }
bool edp_is_ilr_optimization_required(struct dc_link *link, bool edp_is_ilr_optimization_required(struct dc_link *link,
......
...@@ -69,7 +69,7 @@ bool edp_wait_for_t12(struct dc_link *link); ...@@ -69,7 +69,7 @@ bool edp_wait_for_t12(struct dc_link *link);
bool edp_is_ilr_optimization_required(struct dc_link *link, bool edp_is_ilr_optimization_required(struct dc_link *link,
struct dc_crtc_timing *crtc_timing); struct dc_crtc_timing *crtc_timing);
bool edp_is_ilr_optimization_enabled(struct dc_link *link); bool edp_is_ilr_optimization_enabled(struct dc_link *link);
enum dc_link_rate get_max_link_rate_from_ilr_table(struct dc_link *link); enum dc_link_rate get_max_edp_link_rate(struct dc_link *link);
bool edp_backlight_enable_aux(struct dc_link *link, bool enable); bool edp_backlight_enable_aux(struct dc_link *link, bool enable);
void edp_add_delay_for_T9(struct dc_link *link); void edp_add_delay_for_T9(struct dc_link *link);
bool edp_receiver_ready_T9(struct dc_link *link); bool edp_receiver_ready_T9(struct dc_link *link);
......
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