diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1071-drm-amd-display-Set-link-rate-set-if-eDP-ver-1.4.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1071-drm-amd-display-Set-link-rate-set-if-eDP-ver-1.4.patch | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1071-drm-amd-display-Set-link-rate-set-if-eDP-ver-1.4.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1071-drm-amd-display-Set-link-rate-set-if-eDP-ver-1.4.patch new file mode 100644 index 00000000..79f7c949 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1071-drm-amd-display-Set-link-rate-set-if-eDP-ver-1.4.patch @@ -0,0 +1,190 @@ +From efcd2202fda12894d5f618b860eeb2415506f9c9 Mon Sep 17 00:00:00 2001 +From: Derek Lai <Derek.Lai@amd.com> +Date: Tue, 11 Dec 2018 16:27:09 +0800 +Subject: [PATCH 1071/2940] 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> +--- + .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 105 +++++++++++++++++- + drivers/gpu/drm/amd/display/dc/dc.h | 1 + + drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 13 ++- + 3 files changed, 111 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +index cf9362704d12..431805c566cf 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -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) + { +- retrieve_link_cap(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; + +- if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN) +- link->reported_link_cap.link_rate = LINK_RATE_HIGH2; ++ retrieve_link_cap(link); + ++ 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; + } + +diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h +index b7c72e02c652..ba6cd2cb6f74 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc.h ++++ b/drivers/gpu/drm/amd/display/dc/dc.h +@@ -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; +diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +index da93ab43f2d8..d4eab33c453b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h ++++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +@@ -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 { +-- +2.17.1 + |