From 2db23196eb0ffa4c53c27811a5fadf64a6509b04 Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Thu, 10 Oct 2019 16:41:52 -0400 Subject: [PATCH] drm/amd/display: disable lttpr for invalid lttpr caps. 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 Reviewed-by: Wenjing Liu Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_link_dp.c | 90 ++++++++++--------- drivers/gpu/drm/amd/display/dc/dc_types.h | 15 +--- .../gpu/drm/amd/display/dc/inc/dc_link_dp.h | 2 +- 3 files changed, 49 insertions(+), 58 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 6e1f00ab66467..7d18fc1e68c6f 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 @@ -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); } } diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 837859e65e45e..45dfed8bcaf7a 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -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; diff --git a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h index a6500b98fe0d9..1e6ff6eb5bfc5 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h +++ b/drivers/gpu/drm/amd/display/dc/inc/dc_link_dp.h @@ -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; -- 2.39.5