drm/amd/display: disable lttpr for invalid lttpr caps.
authorabdoulaye berthe <abdoulaye.berthe@amd.com>
Thu, 10 Oct 2019 20:41:52 +0000 (16:41 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 13 Nov 2019 20:29:43 +0000 (15:29 -0500)
1-Read lttpr caps in 5-bytes
2-Parse caps
3-Validate caps and set lttpr_mode
4-Use hw default timeout when lttpr is disabled.

Signed-off-by: abdoulaye berthe <abdoulaye.berthe@amd.com>
Reviewed-by: Wenjing Liu <Wenjing.Liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h

index 6e1f00a..7d18fc1 100644 (file)
@@ -1172,7 +1172,7 @@ static void configure_lttpr_mode(struct dc_link *link)
        uint8_t repeater_cnt;
        uint32_t aux_interval_address;
        uint8_t repeater_id;
-       enum lttpr_mode repeater_mode = phy_repeater_mode_transparent;
+       uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
 
        core_link_write_dpcd(link,
                        DP_PHY_REPEATER_MODE,
@@ -1180,7 +1180,7 @@ static void configure_lttpr_mode(struct dc_link *link)
                        sizeof(repeater_mode));
 
        if (!link->is_lttpr_mode_transparent) {
-               repeater_mode = phy_repeater_mode_non_transparent;
+               repeater_mode = DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
                core_link_write_dpcd(link,
                                DP_PHY_REPEATER_MODE,
                                (uint8_t *)&repeater_mode,
@@ -2964,7 +2964,11 @@ static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
 
 static bool retrieve_link_cap(struct dc_link *link)
 {
-       uint8_t dpcd_data[DP_ADAPTER_CAP - DP_DPCD_REV + 1];
+       /* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
+        * which means size 16 will be good for both of those DPCD register block reads
+        */
+       uint8_t dpcd_data[16];
+       uint8_t lttpr_dpcd_data[6];
 
        /*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
         */
@@ -2977,7 +2981,6 @@ static bool retrieve_link_cap(struct dc_link *link)
        union dp_downstream_port_present ds_port = { 0 };
        enum dc_status status = DC_ERROR_UNEXPECTED;
        uint32_t read_dpcd_retry_cnt = 3;
-       uint32_t prev_timeout_val;
        int i;
        struct dp_sink_hw_fw_revision dp_hw_fw_revision;
 
@@ -2988,12 +2991,12 @@ static bool retrieve_link_cap(struct dc_link *link)
        link->is_lttpr_mode_transparent = true;
 
        if (ext_timeout_support) {
-               prev_timeout_val =
-                               dc_link_aux_configure_timeout(link->ddc,
-                                               LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD);
+               dc_link_aux_configure_timeout(link->ddc,
+                                       LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD);
        }
 
        memset(dpcd_data, '\0', sizeof(dpcd_data));
+       memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
        memset(&down_strm_port_count,
                '\0', sizeof(union down_stream_port_count));
        memset(&edp_config_cap, '\0',
@@ -3026,47 +3029,46 @@ static bool retrieve_link_cap(struct dc_link *link)
        }
 
        if (ext_timeout_support) {
+
                status = core_link_read_dpcd(
                                link,
-                               DP_PHY_REPEATER_CNT,
-                               &link->dpcd_caps.lttpr_caps.phy_repeater_cnt,
-                               sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt));
-
-               if (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0) {
-
+                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
+                               lttpr_dpcd_data,
+                               sizeof(lttpr_dpcd_data));
+
+               link->dpcd_caps.lttpr_caps.revision.raw =
+                               lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               link->dpcd_caps.lttpr_caps.max_link_rate =
+                               lttpr_dpcd_data[DP_MAX_LINK_RATE_PHY_REPEATER -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               link->dpcd_caps.lttpr_caps.phy_repeater_cnt =
+                               lttpr_dpcd_data[DP_PHY_REPEATER_CNT -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               link->dpcd_caps.lttpr_caps.max_lane_count =
+                               lttpr_dpcd_data[DP_MAX_LANE_COUNT_PHY_REPEATER -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               link->dpcd_caps.lttpr_caps.mode =
+                               lttpr_dpcd_data[DP_PHY_REPEATER_MODE -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               link->dpcd_caps.lttpr_caps.max_ext_timeout =
+                               lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
+                                                               DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+
+               if (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 &&
+                               link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
+                               link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
+                               link->dpcd_caps.lttpr_caps.revision.raw >= 0x14) {
                        link->is_lttpr_mode_transparent = false;
-
-                       status = core_link_read_dpcd(
-                                       link,
-                                       DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
-                                       (uint8_t *)&link->dpcd_caps.lttpr_caps.revision,
-                                       sizeof(link->dpcd_caps.lttpr_caps.revision));
-
-                       status = core_link_read_dpcd(
-                                       link,
-                                       DP_MAX_LINK_RATE_PHY_REPEATER,
-                                       &link->dpcd_caps.lttpr_caps.max_link_rate,
-                                       sizeof(link->dpcd_caps.lttpr_caps.max_link_rate));
-
-                       status = core_link_read_dpcd(
-                                       link,
-                                       DP_PHY_REPEATER_MODE,
-                                       (uint8_t *)&link->dpcd_caps.lttpr_caps.mode,
-                                       sizeof(link->dpcd_caps.lttpr_caps.mode));
-
-                       status = core_link_read_dpcd(
-                                       link,
-                                       DP_MAX_LANE_COUNT_PHY_REPEATER,
-                                       &link->dpcd_caps.lttpr_caps.max_lane_count,
-                                       sizeof(link->dpcd_caps.lttpr_caps.max_lane_count));
-
-                       status = core_link_read_dpcd(
-                                       link,
-                                       DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT,
-                                       &link->dpcd_caps.lttpr_caps.max_ext_timeout,
-                                       sizeof(link->dpcd_caps.lttpr_caps.max_ext_timeout));
                } else {
-                       dc_link_aux_configure_timeout(link->ddc, prev_timeout_val);
+                       /*No lttpr reset timeout to its default value*/
+                       link->is_lttpr_mode_transparent = true;
+                       dc_link_aux_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
                }
        }
 
index 837859e..45dfed8 100644 (file)
@@ -420,20 +420,9 @@ enum link_training_offset {
        LTTPR_PHY_REPEATER8 = 8
 };
 
-enum lttpr_mode {
-       phy_repeater_mode_transparent           = 0x55,
-       phy_repeater_mode_non_transparent       = 0xAA
-};
-
-enum lttpr_rev {
-       lttpr_rev_unknown       = 0x0,
-       lttpr_rev_14            = 0x14,
-       lttpr_rev_max           = 0x20
-};
-
 struct dc_lttpr_caps {
-       enum lttpr_rev revision;
-       enum lttpr_mode mode;
+       union dpcd_rev revision;
+       uint8_t mode;
        uint8_t max_lane_count;
        uint8_t max_link_rate;
        uint8_t phy_repeater_cnt;
index a6500b9..1e6ff6e 100644 (file)
@@ -29,7 +29,7 @@
 #define LINK_TRAINING_ATTEMPTS 4
 #define LINK_TRAINING_RETRY_DELAY 50 /* ms */
 #define LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD 3200 /*us*/
-#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 400 /*us*/
+#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/
 
 struct dc_link;
 struct dc_stream_state;