mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-24 01:36:48 +07:00
drm/amd/display: Set link rate set if eDP ver >= 1.4.
[Why] If eDP ver >= 1.4, the Source device must use LINK_RATE_SET. [How] Get LINK_RATE_SET by reading DPCD 10h-1fh, then write DPCD 00115h before link training. Signed-off-by: Derek Lai <Derek.Lai@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
7eb9097541
commit
b03a599b3e
@ -117,6 +117,13 @@ static void dpcd_set_link_settings(
|
||||
core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
|
||||
&downspread.raw, sizeof(downspread));
|
||||
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
|
||||
(link->dpcd_caps.link_rate_set >= 1 &&
|
||||
link->dpcd_caps.link_rate_set <= 8)) {
|
||||
core_link_write_dpcd(link, DP_LINK_RATE_SET,
|
||||
&link->dpcd_caps.link_rate_set, 1);
|
||||
}
|
||||
|
||||
DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n",
|
||||
__func__,
|
||||
DP_LINK_BW_SET,
|
||||
@ -2489,13 +2496,105 @@ bool detect_dp_sink_caps(struct dc_link *link)
|
||||
/* TODO save sink caps in link->sink */
|
||||
}
|
||||
|
||||
enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
|
||||
{
|
||||
enum dc_link_rate link_rate;
|
||||
// LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
|
||||
switch (link_rate_in_khz) {
|
||||
case 1620000:
|
||||
link_rate = LINK_RATE_LOW; // Rate_1 (RBR) - 1.62 Gbps/Lane
|
||||
break;
|
||||
case 2160000:
|
||||
link_rate = LINK_RATE_RATE_2; // Rate_2 - 2.16 Gbps/Lane
|
||||
break;
|
||||
case 2430000:
|
||||
link_rate = LINK_RATE_RATE_3; // Rate_3 - 2.43 Gbps/Lane
|
||||
break;
|
||||
case 2700000:
|
||||
link_rate = LINK_RATE_HIGH; // Rate_4 (HBR) - 2.70 Gbps/Lane
|
||||
break;
|
||||
case 3240000:
|
||||
link_rate = LINK_RATE_RBR2; // Rate_5 (RBR2) - 3.24 Gbps/Lane
|
||||
break;
|
||||
case 4320000:
|
||||
link_rate = LINK_RATE_RATE_6; // Rate_6 - 4.32 Gbps/Lane
|
||||
break;
|
||||
case 5400000:
|
||||
link_rate = LINK_RATE_HIGH2; // Rate_7 (HBR2) - 5.40 Gbps/Lane
|
||||
break;
|
||||
case 8100000:
|
||||
link_rate = LINK_RATE_HIGH3; // Rate_8 (HBR3) - 8.10 Gbps/Lane
|
||||
break;
|
||||
default:
|
||||
link_rate = LINK_RATE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
return link_rate;
|
||||
}
|
||||
|
||||
void detect_edp_sink_caps(struct dc_link *link)
|
||||
{
|
||||
uint8_t supported_link_rates[16] = {0};
|
||||
uint32_t entry;
|
||||
uint32_t link_rate_in_khz;
|
||||
enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
|
||||
uint8_t link_rate_set = 0;
|
||||
|
||||
retrieve_link_cap(link);
|
||||
|
||||
if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
|
||||
link->reported_link_cap.link_rate = LINK_RATE_HIGH2;
|
||||
if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
|
||||
// Read DPCD 00010h - 0001Fh 16 bytes at one shot
|
||||
core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
|
||||
supported_link_rates, sizeof(supported_link_rates));
|
||||
|
||||
link->dpcd_caps.link_rate_set = 0;
|
||||
for (entry = 0; entry < 16; entry += 2) {
|
||||
// DPCD register reports per-lane link rate = 16-bit link rate capability
|
||||
// value X 200 kHz. Need multipler to find link rate in kHz.
|
||||
link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
|
||||
supported_link_rates[entry]) * 200;
|
||||
|
||||
if (link_rate_in_khz != 0) {
|
||||
link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
|
||||
if (link->reported_link_cap.link_rate < link_rate) {
|
||||
link->reported_link_cap.link_rate = link_rate;
|
||||
|
||||
switch (link_rate) {
|
||||
case LINK_RATE_LOW:
|
||||
link_rate_set = 1;
|
||||
break;
|
||||
case LINK_RATE_RATE_2:
|
||||
link_rate_set = 2;
|
||||
break;
|
||||
case LINK_RATE_RATE_3:
|
||||
link_rate_set = 3;
|
||||
break;
|
||||
case LINK_RATE_HIGH:
|
||||
link_rate_set = 4;
|
||||
break;
|
||||
case LINK_RATE_RBR2:
|
||||
link_rate_set = 5;
|
||||
break;
|
||||
case LINK_RATE_RATE_6:
|
||||
link_rate_set = 6;
|
||||
break;
|
||||
case LINK_RATE_HIGH2:
|
||||
link_rate_set = 7;
|
||||
break;
|
||||
case LINK_RATE_HIGH3:
|
||||
link_rate_set = 8;
|
||||
break;
|
||||
default:
|
||||
link_rate_set = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (link->dpcd_caps.link_rate_set < link_rate_set)
|
||||
link->dpcd_caps.link_rate_set = link_rate_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
link->verified_link_cap = link->reported_link_cap;
|
||||
}
|
||||
|
||||
|
@ -659,6 +659,7 @@ struct dpcd_caps {
|
||||
int8_t branch_dev_name[6];
|
||||
int8_t branch_hw_revision;
|
||||
int8_t branch_fw_revision[2];
|
||||
uint8_t link_rate_set;
|
||||
|
||||
bool allow_invalid_MSA_timing_param;
|
||||
bool panel_mode_edp;
|
||||
|
@ -46,11 +46,14 @@ enum dc_lane_count {
|
||||
*/
|
||||
enum dc_link_rate {
|
||||
LINK_RATE_UNKNOWN = 0,
|
||||
LINK_RATE_LOW = 0x06,
|
||||
LINK_RATE_HIGH = 0x0A,
|
||||
LINK_RATE_RBR2 = 0x0C,
|
||||
LINK_RATE_HIGH2 = 0x14,
|
||||
LINK_RATE_HIGH3 = 0x1E
|
||||
LINK_RATE_LOW = 0x06, // Rate_1 (RBR) - 1.62 Gbps/Lane
|
||||
LINK_RATE_RATE_2 = 0x08, // Rate_2 - 2.16 Gbps/Lane
|
||||
LINK_RATE_RATE_3 = 0x09, // Rate_3 - 2.43 Gbps/Lane
|
||||
LINK_RATE_HIGH = 0x0A, // Rate_4 (HBR) - 2.70 Gbps/Lane
|
||||
LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane
|
||||
LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane
|
||||
LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane
|
||||
LINK_RATE_HIGH3 = 0x1E // Rate_8 (HBR3)- 8.10 Gbps/Lane
|
||||
};
|
||||
|
||||
enum dc_link_spread {
|
||||
|
Loading…
Reference in New Issue
Block a user