drm/amd/display: initialize lttpr
authorabdoulaye berthe <abdoulaye.berthe@amd.com>
Fri, 19 Jul 2019 14:25:39 +0000 (10:25 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 13 Nov 2019 20:29:43 +0000 (15:29 -0500)
[Description]
When reading link, update the procedure as follows:
1-Set aux timeout to extended: 3.2ms
2-Start with reading lttpr caps
3-Determine if lttpr support should be enabled. Reset aux timeout to
400us if no repeater is found.

Signed-off-by: abdoulaye berthe <abdoulaye.berthe@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@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.h
drivers/gpu/drm/amd/display/dc/dc_link.h
drivers/gpu/drm/amd/display/dc/dc_types.h

index 0f59b68..2a89f90 100644 (file)
@@ -21,6 +21,9 @@
 #define DC_LOGGER \
        link->ctx->logger
 
+
+#define DP_REPEATER_CONFIGURATION_AND_STATUS_OFFSET   0x50
+
 /* maximum pre emphasis level allowed for each voltage swing level*/
 static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = {
                PRE_EMPHASIS_LEVEL3,
@@ -2753,6 +2756,14 @@ static bool retrieve_link_cap(struct dc_link *link)
        int i;
        struct dp_sink_hw_fw_revision dp_hw_fw_revision;
 
+       /* Set default timeout to 3.2ms and read LTTPR capabilities */
+       bool ext_timeout_support = link->dc->caps.extended_aux_timeout_support &&
+                       !link->dc->config.disable_extended_timeout_support;
+       if (ext_timeout_support) {
+               status = dc_link_aux_configure_timeout(link->ddc, LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD);
+               link->is_lttpr_mode_transparent = true;
+       }
+
        memset(dpcd_data, '\0', sizeof(dpcd_data));
        memset(&down_strm_port_count,
                '\0', sizeof(union down_stream_port_count));
@@ -2785,6 +2796,51 @@ static bool retrieve_link_cap(struct dc_link *link)
                return false;
        }
 
+       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) {
+
+                       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, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
+               }
+       }
+
        {
                union training_aux_rd_interval aux_rd_interval;
 
index f12ad4b..8ff7556 100644 (file)
@@ -994,6 +994,8 @@ struct dpcd_caps {
        union dpcd_fec_capability fec_cap;
        struct dpcd_dsc_capabilities dsc_caps;
 #endif
+       struct dc_lttpr_caps lttpr_caps;
+
 };
 
 #include "dc_link.h"
index 9270e43..67ba666 100644 (file)
@@ -85,6 +85,7 @@ struct dc_link {
        bool link_state_valid;
        bool aux_access_disabled;
        bool sync_lt_in_progress;
+       bool is_lttpr_mode_transparent;
 
        /* caps is the same as reported_link_cap. link_traing use
         * reported_link_cap. Will clean up.  TODO
index 7ab7644..837859e 100644 (file)
@@ -122,6 +122,7 @@ struct dc_context {
 #define DC_EDID_BLOCK_SIZE 128
 #define MAX_SURFACE_NUM 4
 #define NUM_PIXEL_FORMATS 10
+#define MAX_REPEATER_CNT 8
 
 #include "dc_ddc_types.h"
 
@@ -405,6 +406,41 @@ enum dpcd_downstream_port_max_bpc {
        DOWN_STREAM_MAX_12BPC,
        DOWN_STREAM_MAX_16BPC
 };
+
+
+enum link_training_offset {
+       DPRX                = 0,
+       LTTPR_PHY_REPEATER1 = 1,
+       LTTPR_PHY_REPEATER2 = 2,
+       LTTPR_PHY_REPEATER3 = 3,
+       LTTPR_PHY_REPEATER4 = 4,
+       LTTPR_PHY_REPEATER5 = 5,
+       LTTPR_PHY_REPEATER6 = 6,
+       LTTPR_PHY_REPEATER7 = 7,
+       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;
+       uint8_t max_lane_count;
+       uint8_t max_link_rate;
+       uint8_t phy_repeater_cnt;
+       uint8_t max_ext_timeout;
+       uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
+};
+
 struct dc_dongle_caps {
        /* dongle type (DP converter, CV smart dongle) */
        enum display_dongle_type dongle_type;