From 88e3375dda894e7a409aecbab774cf1018a7a696 Mon Sep 17 00:00:00 2001
From: Jimmy Kizito <Jimmy.Kizito@amd.com>
Date: Thu, 24 Mar 2022 13:42:45 -0400
Subject: drm/amd/display: Avoid reading LTTPR caps in non-LTTPR mode.
Git-commit: 77361ed89a8b03c7e121f4b8c517d7be93ccd8df
Patch-mainline: v6.0-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225 jsc#PED-2849
[Why]
LTTPR capable devices on the DisplayPort path may assume that
extended LTTPR AUX timeouts will be used after LTTPR capabilities
are read.
When DPTX operates in non-LTTPR mode, AUX timeouts are not
extended and this can result in AUX transactions timing out.
[How]
Use shared helper function to determine LTTPR mode and do not
read LTTPR capabilities in non-LTTPR mode.
Reviewed-by: Mustapha Ghaddar <Mustapha.Ghaddar@amd.com>
Reviewed-by: Meenakshikumar Somasundaram <Meenakshikumar.Somasundaram@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz@amd.com>
Signed-off-by: Jimmy Kizito <Jimmy.Kizito@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
.../gpu/drm/amd/display/dc/core/dc_link_dp.c | 44 +++++++++++++------
1 file changed, 31 insertions(+), 13 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 6457b919a044..927826a1c358 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
@@ -5129,16 +5129,13 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link)
return true;
}
-bool dp_retrieve_lttpr_cap(struct dc_link *link)
+/* Logic to determine LTTPR mode */
+static void determine_lttpr_mode(struct dc_link *link)
{
- uint8_t lttpr_dpcd_data[8];
bool allow_lttpr_non_transparent_mode = 0;
bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
- enum dc_status status = DC_ERROR_UNEXPECTED;
- bool is_lttpr_present = false;
- memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
@@ -5148,9 +5145,6 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
allow_lttpr_non_transparent_mode = 1;
}
- /*
- * Logic to determine LTTPR mode
- */
link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
if (vbios_lttpr_enable && vbios_lttpr_interop)
link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
@@ -5172,6 +5166,18 @@ bool dp_retrieve_lttpr_cap(struct dc_link *link)
link->dc->debug.dpia_debug.bits.force_non_lttpr)
link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
#endif
+}
+
+bool dp_retrieve_lttpr_cap(struct dc_link *link)
+{
+ uint8_t lttpr_dpcd_data[8];
+ enum dc_status status = DC_ERROR_UNEXPECTED;
+ bool is_lttpr_present = false;
+
+ memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
+
+ /* Logic to determine LTTPR mode*/
+ determine_lttpr_mode(link);
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
/* By reading LTTPR capability, RX assumes that we will enable
@@ -5287,11 +5293,23 @@ static enum dc_status wa_try_to_wake_dprx(struct dc_link *link, uint64_t timeout
uint64_t time_taken_ms = 0;
enum dc_connection_type type = dc_connection_none;
- status = core_link_read_dpcd(
- link,
- DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
- &dpcd_data,
- sizeof(dpcd_data));
+ determine_lttpr_mode(link);
+
+ /* Issue an AUX read to test DPRX responsiveness. If LTTPR is supported the first read is expected to
+ * be to determine LTTPR capabilities. Otherwise trying to read power state should be an innocuous AUX read.
+ */
+ if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
+ status = core_link_read_dpcd(
+ link,
+ DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
+ &dpcd_data,
+ sizeof(dpcd_data));
+ else
+ status = core_link_read_dpcd(
+ link,
+ DP_SET_POWER,
+ &dpcd_data,
+ sizeof(dpcd_data));
if (status != DC_OK) {
DC_LOG_WARNING("%s: Read DPCD LTTPR_CAP failed - try to toggle DPCD SET_POWER for %lld ms.",
--
2.38.1