From: Jimmy Kizito <[email protected]>

[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 <[email protected]>
Reviewed-by: Meenakshikumar Somasundaram <[email protected]>
Reviewed-by: Jun Lei <[email protected]>
Acked-by: Hamza Mahfooz <[email protected]>
Signed-off-by: Jimmy Kizito <[email protected]>
---
 .../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 9b20f340c21f..b5b16340fd39 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
@@ -5134,16 +5134,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)) {
@@ -5153,9 +5150,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;
@@ -5177,6 +5171,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
@@ -5292,11 +5298,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.36.1

Reply via email to