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: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Michael Strauss 2024-08-15 18:45:17 -04:00 committed by Alex Deucher
parent 7c9cb6d1bf
commit 4e9e50b6ae
4 changed files with 40 additions and 35 deletions

View File

@ -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
if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
link->panel_config.ilr.optimize_edp_link_rate = true;
if (edp_is_ilr_optimization_enabled(link))
link->reported_link_cap.link_rate = get_max_link_rate_from_ilr_table(link);
link->reported_link_cap.link_rate = get_max_edp_link_rate(link);
}
} else {

View File

@ -212,6 +212,13 @@ static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in
case 10000000:
link_rate = LINK_RATE_UHBR10; // UHBR10 - 10.0 Gbps/Lane
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:
link_rate = LINK_RATE_UNKNOWN;
break;
@ -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(
struct dc_link *link,
const struct dc_link_settings *max,
@ -759,14 +783,7 @@ bool edp_decide_link_settings(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
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];
current_link_setting.lane_count =
initial_link_setting.lane_count;
} else
break;
increase_edp_link_rate(link, &current_link_setting);
}
}
return false;
@ -818,9 +835,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
if (policy) {
/* minimize lane */
if (current_link_setting.link_rate < max_link_rate) {
current_link_setting.link_rate =
increase_link_rate(link,
current_link_setting.link_rate);
increase_edp_link_rate(link, &current_link_setting);
} else {
if (current_link_setting.lane_count <
link->verified_link_cap.lane_count) {
@ -839,9 +854,7 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
current_link_setting.link_rate =
increase_link_rate(link,
current_link_setting.link_rate);
increase_edp_link_rate(link, &current_link_setting);
current_link_setting.lane_count =
initial_link_setting.lane_count;
}
@ -874,18 +887,15 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
}
if (policy) {
/* minimize lane */
if (current_link_setting.link_rate_set <
link->dpcd_caps.edp_supported_link_rates_count
&& 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];
if (current_link_setting.link_rate < max_link_rate) {
increase_edp_link_rate(link, &current_link_setting);
} else {
if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
current_link_setting.lane_count =
increase_lane_count(
current_link_setting.lane_count);
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 =
link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
} else
@ -899,13 +909,8 @@ bool decide_edp_link_settings_with_dsc(struct dc_link *link,
increase_lane_count(
current_link_setting.lane_count);
} else {
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];
current_link_setting.lane_count =
initial_link_setting.lane_count;
} else
increase_edp_link_rate(link, &current_link_setting);
if (current_link_setting.link_rate == LINK_RATE_UNKNOWN)
break;
}
}

View File

@ -305,16 +305,17 @@ bool edp_is_ilr_optimization_enabled(struct dc_link *link)
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++) {
if (link_rate < link->dpcd_caps.edp_supported_link_rates[i])
link_rate = link->dpcd_caps.edp_supported_link_rates[i];
if (max_ilr_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,

View File

@ -69,7 +69,7 @@ bool edp_wait_for_t12(struct dc_link *link);
bool edp_is_ilr_optimization_required(struct dc_link *link,
struct dc_crtc_timing *crtc_timing);
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);
void edp_add_delay_for_T9(struct dc_link *link);
bool edp_receiver_ready_T9(struct dc_link *link);