drm/amd/display: Update FIXED_VS Link Rate Toggle Workaround Usage
authorMichael Strauss <michael.strauss@amd.com>
Fri, 24 Jan 2025 20:02:27 +0000 (15:02 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Feb 2025 16:45:11 +0000 (11:45 -0500)
[WHY]
Previously the 128b/132b LTTPR support DPCD field was used to decide if
FIXED_VS training sequence required a rate toggle before initiating LT.

When running DP2.1 4.9.x.x compliance tests, emulated LTTPRs can report
no-128b/132b support which is then forwarded by the FIXED_VS retimer.
As a result this test exposes the rate toggle again, erroneously causing
failures as certain compliance sinks don't expect this behaviour.

[HOW]
Add new DPCD register defines/reads to read LTTPR IEEE OUI and device ID.

Decide whether to perform the rate toggle based on the LTTPR's IEEE OUI
which guarantees that we only perform the toggle on affected retimers.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Michael Strauss <michael.strauss@amd.com>
Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c

index ae6e2d8552acfd22292b2c58b8047d949889ed60..8bb628ab78554e55013e16c438ce65a8991d20f0 100644 (file)
@@ -1128,6 +1128,8 @@ struct dc_lttpr_caps {
        union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
        union dp_alpm_lttpr_cap alpm;
        uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
+       uint8_t lttpr_ieee_oui[3];
+       uint8_t lttpr_device_id[6];
 };
 
 struct dc_dongle_dfp_cap_ext {
@@ -1391,6 +1393,12 @@ struct dp_trace {
 #ifndef DP_BRANCH_VENDOR_SPECIFIC_START
 #define DP_BRANCH_VENDOR_SPECIFIC_START     0x50C
 #endif
+#ifndef DP_LTTPR_IEEE_OUI
+#define DP_LTTPR_IEEE_OUI 0xF003D
+#endif
+#ifndef DP_LTTPR_DEVICE_ID
+#define DP_LTTPR_DEVICE_ID 0xF0040
+#endif
 /** USB4 DPCD BW Allocation Registers Chapter 10.7 **/
 #ifndef DP_TUNNELING_CAPABILITIES
 #define DP_TUNNELING_CAPABILITIES                      0xE000D /* 1.4a */
index f6e0868507f7d443492f0b527def4c11f1fbadbe..0785c030f6a6d99e8bf64f519f125181d49559f1 100644 (file)
@@ -1575,10 +1575,18 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link)
        /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
        is_lttpr_present = dp_is_lttpr_present(link);
 
-       if (is_lttpr_present)
+       DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present);
+
+       if (is_lttpr_present) {
                CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
 
-       DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present);
+               core_link_read_dpcd(link, DP_LTTPR_IEEE_OUI, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui));
+               CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui), "LTTPR IEEE OUI: ");
+
+               core_link_read_dpcd(link, DP_LTTPR_DEVICE_ID, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id));
+               CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id), "LTTPR Device ID: ");
+       }
+
        return status;
 }
 
index ccf8096dde2909957eef6100633e4b3e3ec66d09..ce174ce5579c0771ec945451dbe2d17770e78551 100644 (file)
@@ -270,7 +270,8 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence(
 
        rate = get_dpcd_link_rate(&lt_settings->link_settings);
 
-       if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) {
+       // Only perform toggle if FIXED_VS LTTPR reports no IEEE OUI
+       if (memcmp("\x0,\x0,\x0", &link->dpcd_caps.lttpr_caps.lttpr_ieee_oui[0], 3) == 0) {
                /* Vendor specific: Toggle link rate */
                toggle_rate = (rate == 0x6) ? 0xA : 0x6;