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

drm/amd/display: isolate 8b 10b link training sequence into its own function

[how]
1. move 8b 10 link trianing into its own function
2. make link status check after a link success link as part of
dp transition to video idle sequence.
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarQingqing Zhuo <qingqing.zhuo@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3df21257
...@@ -1170,8 +1170,16 @@ static inline enum link_training_result dp_transition_to_video_idle( ...@@ -1170,8 +1170,16 @@ static inline enum link_training_result dp_transition_to_video_idle(
* TPS4 must be used instead of POST_LT_ADJ_REQ. * TPS4 must be used instead of POST_LT_ADJ_REQ.
*/ */
if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 || if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4) lt_settings->pattern_for_eq == DP_TRAINING_PATTERN_SEQUENCE_4) {
/* delay 5ms after Main Link output idle pattern and then check
* DPCD 0202h.
*/
if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
msleep(5);
status = dp_check_link_loss_status(link, lt_settings);
}
return status; return status;
}
if (status == LINK_TRAINING_SUCCESS && if (status == LINK_TRAINING_SUCCESS &&
perform_post_lt_adj_req_sequence(link, lt_settings) == false) perform_post_lt_adj_req_sequence(link, lt_settings) == false)
...@@ -1621,18 +1629,9 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train ...@@ -1621,18 +1629,9 @@ enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_train
static void dpcd_exit_training_mode(struct dc_link *link) static void dpcd_exit_training_mode(struct dc_link *link)
{ {
const uint8_t clear_pattern = 0;
/* clear training pattern set */ /* clear training pattern set */
core_link_write_dpcd( dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
link,
DP_TRAINING_PATTERN_SET,
&clear_pattern,
sizeof(clear_pattern));
DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
__func__,
DP_TRAINING_PATTERN_SET,
clear_pattern);
} }
enum dc_status dpcd_configure_channel_coding(struct dc_link *link, enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
...@@ -1656,41 +1655,22 @@ enum dc_status dpcd_configure_channel_coding(struct dc_link *link, ...@@ -1656,41 +1655,22 @@ enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
return status; return status;
} }
enum link_training_result dc_link_dp_perform_link_training( static enum link_training_result dp_perform_8b_10b_link_training(
struct dc_link *link, struct dc_link *link,
const struct dc_link_settings *link_settings, struct link_training_settings *lt_settings)
bool skip_video_pattern)
{ {
enum link_training_result status = LINK_TRAINING_SUCCESS; enum link_training_result status = LINK_TRAINING_SUCCESS;
struct link_training_settings lt_settings;
/* reset previous training states */ uint8_t repeater_cnt;
dpcd_exit_training_mode(link); uint8_t repeater_id;
/* decide training settings */
dp_decide_training_settings(
link,
link_settings,
&link->preferred_training_settings,
&lt_settings);
dpcd_configure_lttpr_mode(link, &lt_settings);
dp_set_fec_ready(link, lt_settings.should_set_fec_ready);
dpcd_configure_channel_coding(link, &lt_settings);
/* enter training mode:
* Per DP specs starting from here, DPTX device shall not issue
* Non-LT AUX transactions inside training mode.
*/
if (link->ctx->dc->work_arounds.lt_early_cr_pattern) if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
start_clock_recovery_pattern_early(link, &lt_settings, DPRX); start_clock_recovery_pattern_early(link, lt_settings, DPRX);
/* 1. set link rate, lane count and spread. */ /* 1. set link rate, lane count and spread. */
dpcd_set_link_settings(link, &lt_settings); dpcd_set_link_settings(link, lt_settings);
if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) { if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
uint8_t repeater_cnt;
uint8_t repeater_id;
/* 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)
...@@ -1699,13 +1679,13 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -1699,13 +1679,13 @@ enum link_training_result dc_link_dp_perform_link_training(
for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS); for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
repeater_id--) { repeater_id--) {
status = perform_clock_recovery_sequence(link, &lt_settings, repeater_id); status = perform_clock_recovery_sequence(link, lt_settings, repeater_id);
if (status != LINK_TRAINING_SUCCESS) if (status != LINK_TRAINING_SUCCESS)
break; break;
status = perform_channel_equalization_sequence(link, status = perform_channel_equalization_sequence(link,
&lt_settings, lt_settings,
repeater_id); repeater_id);
if (status != LINK_TRAINING_SUCCESS) if (status != LINK_TRAINING_SUCCESS)
...@@ -1716,36 +1696,62 @@ enum link_training_result dc_link_dp_perform_link_training( ...@@ -1716,36 +1696,62 @@ enum link_training_result dc_link_dp_perform_link_training(
} }
if (status == LINK_TRAINING_SUCCESS) { if (status == LINK_TRAINING_SUCCESS) {
status = perform_clock_recovery_sequence(link, &lt_settings, DPRX); status = perform_clock_recovery_sequence(link, lt_settings, DPRX);
if (status == LINK_TRAINING_SUCCESS) { if (status == LINK_TRAINING_SUCCESS) {
status = perform_channel_equalization_sequence(link, status = perform_channel_equalization_sequence(link,
&lt_settings, lt_settings,
DPRX); DPRX);
} }
} }
/* 3. set training not in progress*/ return status;
dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE); }
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
enum link_training_result dc_link_dp_perform_link_training(
struct dc_link *link,
const struct dc_link_settings *link_settings,
bool skip_video_pattern)
{
enum link_training_result status = LINK_TRAINING_SUCCESS;
struct link_training_settings lt_settings;
enum dp_link_encoding encoding =
dp_get_link_encoding_format(link_settings);
/* decide training settings */
dp_decide_training_settings(
link,
link_settings,
&link->preferred_training_settings,
&lt_settings);
/* reset previous training states */
dpcd_exit_training_mode(link);
/* configure link prior to entering training mode */
dpcd_configure_lttpr_mode(link, &lt_settings);
dp_set_fec_ready(link, lt_settings.should_set_fec_ready);
dpcd_configure_channel_coding(link, &lt_settings);
/* enter training mode:
* Per DP specs starting from here, DPTX device shall not issue
* Non-LT AUX transactions inside training mode.
*/
if (encoding == DP_8b_10b_ENCODING)
status = dp_perform_8b_10b_link_training(link, &lt_settings);
else
ASSERT(0);
/* exit training mode and switch to video idle */
dpcd_exit_training_mode(link);
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern)
status = dp_transition_to_video_idle(link, status = dp_transition_to_video_idle(link,
&lt_settings, &lt_settings,
status); status);
}
/* delay 5ms after Main Link output idle pattern and then check /* dump debug data */
* DPCD 0202h.
*/
if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
msleep(5);
status = dp_check_link_loss_status(link, &lt_settings);
}
/* 6. print status message*/
print_status_message(link, &lt_settings, status); print_status_message(link, &lt_settings, status);
if (status != LINK_TRAINING_SUCCESS) if (status != LINK_TRAINING_SUCCESS)
link->ctx->dc->debug_data.ltFailCount++; link->ctx->dc->debug_data.ltFailCount++;
return status; return status;
} }
......
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