Commit fb8cf277 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: DP link layer test 4.2.1.1 fix due to specs update

[why]
DP link layer CTS specs updated to change the test parameters in test
4.2.1.1.
Before it requires source to delay 400us on aux no reply.
With the specs updates Errata5, it requires source to delay 3.2ms
(based on LTTPR aux timeout)
This causes our test to fail after updating with the latest test
equipment firmware.

[how]
the change is to allow LTTPR 3.2ms aux timeout delay by default.
And only set to 400us if LTTPR is not present.
Before this piece of logic is interwined with LTTPR support.
Now we will default to 3.2ms aux timeout even if LTTPR support is not
enabled by driver.
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 1c994f2d
...@@ -691,10 +691,9 @@ static bool detect_dp(struct dc_link *link, ...@@ -691,10 +691,9 @@ static bool detect_dp(struct dc_link *link,
if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) { if (sink_caps->transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT;
dpcd_set_source_specific_data(link);
if (!detect_dp_sink_caps(link)) if (!detect_dp_sink_caps(link))
return false; return false;
dpcd_set_source_specific_data(link);
if (is_mst_supported(link)) { if (is_mst_supported(link)) {
sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST; sink_caps->signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
......
...@@ -648,16 +648,17 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, ...@@ -648,16 +648,17 @@ bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
} }
uint32_t dc_link_aux_configure_timeout(struct ddc_service *ddc, bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
uint32_t timeout) uint32_t timeout)
{ {
uint32_t prev_timeout = 0; bool result = false;
struct ddc *ddc_pin = ddc->ddc_pin; struct ddc *ddc_pin = ddc->ddc_pin;
if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) if (ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout) {
prev_timeout = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout);
ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en]->funcs->configure_timeout(ddc, timeout); result = true;
return prev_timeout; }
return result;
} }
/*test only function*/ /*test only function*/
......
...@@ -245,7 +245,7 @@ static uint8_t dc_dp_initialize_scrambling_data_symbols( ...@@ -245,7 +245,7 @@ static uint8_t dc_dp_initialize_scrambling_data_symbols(
static inline bool is_repeater(struct dc_link *link, uint32_t offset) static inline bool is_repeater(struct dc_link *link, uint32_t offset)
{ {
return (!link->is_lttpr_mode_transparent && offset != 0); return (link->lttpr_non_transparent_mode && offset != 0);
} }
static void dpcd_set_lt_pattern_and_lane_settings( static void dpcd_set_lt_pattern_and_lane_settings(
...@@ -1038,7 +1038,7 @@ static enum link_training_result perform_clock_recovery_sequence( ...@@ -1038,7 +1038,7 @@ static enum link_training_result perform_clock_recovery_sequence(
/* 3. wait receiver to lock-on*/ /* 3. wait receiver to lock-on*/
wait_time_microsec = lt_settings->cr_pattern_time; wait_time_microsec = lt_settings->cr_pattern_time;
if (!link->is_lttpr_mode_transparent) if (link->lttpr_non_transparent_mode)
wait_time_microsec = TRAINING_AUX_RD_INTERVAL; wait_time_microsec = TRAINING_AUX_RD_INTERVAL;
wait_for_training_aux_rd_interval( wait_for_training_aux_rd_interval(
...@@ -1268,7 +1268,7 @@ static void configure_lttpr_mode(struct dc_link *link) ...@@ -1268,7 +1268,7 @@ static void configure_lttpr_mode(struct dc_link *link)
link->dpcd_caps.lttpr_caps.mode = repeater_mode; link->dpcd_caps.lttpr_caps.mode = repeater_mode;
} }
if (!link->is_lttpr_mode_transparent) { if (link->lttpr_non_transparent_mode) {
DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__); DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__);
...@@ -1473,7 +1473,7 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -1473,7 +1473,7 @@ enum link_training_result dc_link_dp_perform_link_training(
&lt_settings); &lt_settings);
/* Configure lttpr mode */ /* Configure lttpr mode */
if (!link->is_lttpr_mode_transparent) if (link->lttpr_non_transparent_mode)
configure_lttpr_mode(link); configure_lttpr_mode(link);
if (link->ctx->dc->work_arounds.lt_early_cr_pattern) if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
...@@ -1489,7 +1489,7 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -1489,7 +1489,7 @@ enum link_training_result dc_link_dp_perform_link_training(
dp_set_fec_ready(link, fec_enable); dp_set_fec_ready(link, fec_enable);
if (!link->is_lttpr_mode_transparent) { if (link->lttpr_non_transparent_mode) {
/* 2. perform link training (set link training done /* 2. perform link training (set link training done
* to false is done as well) * to false is done as well)
...@@ -1756,7 +1756,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link) ...@@ -1756,7 +1756,7 @@ static struct dc_link_settings get_max_link_cap(struct dc_link *link)
* account for lttpr repeaters cap * account for lttpr repeaters cap
* notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3). * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
*/ */
if (!link->is_lttpr_mode_transparent) { if (link->lttpr_non_transparent_mode) {
if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count) if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count; max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
...@@ -1914,7 +1914,7 @@ bool dp_verify_link_cap( ...@@ -1914,7 +1914,7 @@ bool dp_verify_link_cap(
max_link_cap = get_max_link_cap(link); max_link_cap = get_max_link_cap(link);
/* Grant extended timeout request */ /* Grant extended timeout request */
if (!link->is_lttpr_mode_transparent && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) { if (link->lttpr_non_transparent_mode && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) {
uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80; uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80;
core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant)); core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
...@@ -3255,17 +3255,7 @@ static bool retrieve_link_cap(struct dc_link *link) ...@@ -3255,17 +3255,7 @@ static bool retrieve_link_cap(struct dc_link *link)
uint32_t read_dpcd_retry_cnt = 3; uint32_t read_dpcd_retry_cnt = 3;
int i; int i;
struct dp_sink_hw_fw_revision dp_hw_fw_revision; struct dp_sink_hw_fw_revision dp_hw_fw_revision;
bool is_lttpr_present = false;
/* 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;
link->is_lttpr_mode_transparent = true;
if (ext_timeout_support) {
dc_link_aux_configure_timeout(link->ddc,
LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD);
}
memset(dpcd_data, '\0', sizeof(dpcd_data)); memset(dpcd_data, '\0', sizeof(dpcd_data));
memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data)); memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
...@@ -3274,6 +3264,13 @@ static bool retrieve_link_cap(struct dc_link *link) ...@@ -3274,6 +3264,13 @@ static bool retrieve_link_cap(struct dc_link *link)
memset(&edp_config_cap, '\0', memset(&edp_config_cap, '\0',
sizeof(union edp_configuration_cap)); sizeof(union edp_configuration_cap));
/* if extended timeout is supported in hardware,
* default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
* CTS 4.2.1.1 regression introduced by CTS specs requirement update.
*/
dc_link_aux_try_to_configure_timeout(link->ddc,
LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
status = core_link_read_dpcd(link, DP_SET_POWER, status = core_link_read_dpcd(link, DP_SET_POWER,
&dpcd_power_state, sizeof(dpcd_power_state)); &dpcd_power_state, sizeof(dpcd_power_state));
...@@ -3300,8 +3297,9 @@ static bool retrieve_link_cap(struct dc_link *link) ...@@ -3300,8 +3297,9 @@ static bool retrieve_link_cap(struct dc_link *link)
return false; return false;
} }
if (ext_timeout_support) { if (link->dc->caps.extended_aux_timeout_support) {
/* By reading LTTPR capability, RX assumes that we will enable LTTPR extended aux timeout if LTTPR is present.
* Therefore, only query LTTPR capability when LTTPR extended aux timeout is supported by hardware */
status = core_link_read_dpcd( status = core_link_read_dpcd(
link, link,
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV, DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
...@@ -3332,20 +3330,21 @@ static bool retrieve_link_cap(struct dc_link *link) ...@@ -3332,20 +3330,21 @@ static bool retrieve_link_cap(struct dc_link *link)
lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT - lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV]; DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
if (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 && is_lttpr_present = (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 > 0 &&
link->dpcd_caps.lttpr_caps.max_lane_count <= 4 && link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
link->dpcd_caps.lttpr_caps.revision.raw >= 0x14) { link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
link->is_lttpr_mode_transparent = false; if (is_lttpr_present)
} else { CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
/*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);
}
CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
} }
/* decide lttpr non transparent mode */
link->lttpr_non_transparent_mode = is_lttpr_present && link->dc->config.allow_lttpr_non_transparent_mode;
if (!is_lttpr_present)
dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
{ {
union training_aux_rd_interval aux_rd_interval; union training_aux_rd_interval aux_rd_interval;
......
...@@ -281,7 +281,7 @@ void dp_set_hw_lane_settings( ...@@ -281,7 +281,7 @@ void dp_set_hw_lane_settings(
{ {
struct link_encoder *encoder = link->link_enc; struct link_encoder *encoder = link->link_enc;
if (!link->is_lttpr_mode_transparent && !is_immediate_downstream(link, offset)) if (link->lttpr_non_transparent_mode && !is_immediate_downstream(link, offset))
return; return;
/* call Encoder to set lane settings */ /* call Encoder to set lane settings */
......
...@@ -274,7 +274,7 @@ struct dc_config { ...@@ -274,7 +274,7 @@ struct dc_config {
bool edp_not_connected; bool edp_not_connected;
bool force_enum_edp; bool force_enum_edp;
bool forced_clocks; bool forced_clocks;
bool disable_extended_timeout_support; // Used to disable extended timeout and lttpr feature as well bool allow_lttpr_non_transparent_mode;
bool multi_mon_pp_mclk_switch; bool multi_mon_pp_mclk_switch;
bool disable_dmcu; bool disable_dmcu;
bool enable_4to1MPC; bool enable_4to1MPC;
......
...@@ -101,6 +101,7 @@ struct dc_link { ...@@ -101,6 +101,7 @@ struct dc_link {
bool aux_access_disabled; bool aux_access_disabled;
bool sync_lt_in_progress; bool sync_lt_in_progress;
bool is_lttpr_mode_transparent; bool is_lttpr_mode_transparent;
bool lttpr_non_transparent_mode;
/* caps is the same as reported_link_cap. link_traing use /* caps is the same as reported_link_cap. link_traing use
* reported_link_cap. Will clean up. TODO * reported_link_cap. Will clean up. TODO
......
...@@ -105,7 +105,7 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc, ...@@ -105,7 +105,7 @@ int dc_link_aux_transfer_raw(struct ddc_service *ddc,
bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc, bool dc_link_aux_transfer_with_retries(struct ddc_service *ddc,
struct aux_payload *payload); struct aux_payload *payload);
uint32_t dc_link_aux_configure_timeout(struct ddc_service *ddc, bool dc_link_aux_try_to_configure_timeout(struct ddc_service *ddc,
uint32_t timeout); uint32_t timeout);
void dal_ddc_service_write_scdc_data( void dal_ddc_service_write_scdc_data(
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define LINK_TRAINING_ATTEMPTS 4 #define LINK_TRAINING_ATTEMPTS 4
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */ #define LINK_TRAINING_RETRY_DELAY 50 /* ms */
#define LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD 3200 /*us*/ #define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/
#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/ #define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/
struct dc_link; struct dc_link;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment