Skip to content

Commit cf4cebc

Browse files
Peichen Huangalexdeucher
authored andcommitted
drm/amd/display: Restructure dpia link training
[WHY] We intend to consolidate dp tunneling and conventional dp link training. [HOW] 1. Use the same link training entry for both dp and dpia 2. Move SET_CONFIG of non-transparent mode to dmub side 3. Add set_tps_notification dmub_cmd to notify tps request for non-transparent dpia link training 4. Check dpcd request result and abort link training early if dpia aux tunneling fails 5. Add option to avoid affect old product 6. Separately handle wait_time_microsec for dpia Reviewed-by: Cruise Hung <cruise.hung@amd.com> Reviewed-by: George Shen <george.shen@amd.com> Reviewed-by: Meenakshikumar Somasundaram <meenakshikumar.somasundaram@amd.com> Signed-off-by: Peichen Huang <PeiChen.Huang@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent ae51008 commit cf4cebc

11 files changed

Lines changed: 233 additions & 52 deletions

File tree

drivers/gpu/drm/amd/display/dc/core/dc.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5755,6 +5755,27 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
57555755
return DC_OK;
57565756
}
57575757

5758+
/**
5759+
* dc_process_dmub_dpia_set_tps_notification - Submits tps notification
5760+
*
5761+
* @dc: [in] dc structure
5762+
* @link_index: [in] link index
5763+
* @ts: [in] request tps
5764+
*
5765+
* Submits set_tps_notification command to dmub via inbox message
5766+
*/
5767+
void dc_process_dmub_dpia_set_tps_notification(const struct dc *dc, uint32_t link_index, uint8_t tps)
5768+
{
5769+
union dmub_rb_cmd cmd = {0};
5770+
5771+
cmd.set_tps_notification.header.type = DMUB_CMD__DPIA;
5772+
cmd.set_tps_notification.header.sub_type = DMUB_CMD__DPIA_SET_TPS_NOTIFICATION;
5773+
cmd.set_tps_notification.tps_notification.instance = dc->links[link_index]->ddc_hw_inst;
5774+
cmd.set_tps_notification.tps_notification.tps = tps;
5775+
5776+
dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
5777+
}
5778+
57585779
/**
57595780
* dc_process_dmub_dpia_hpd_int_enable - Submits DPIA DPD interruption
57605781
*

drivers/gpu/drm/amd/display/dc/dc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ struct dc_config {
462462
bool support_edp0_on_dp1;
463463
unsigned int enable_fpo_flicker_detection;
464464
bool disable_hbr_audio_dp2;
465+
bool consolidated_dpia_dp_lt;
465466
};
466467

467468
enum visual_confirm {
@@ -762,7 +763,8 @@ union dpia_debug_options {
762763
uint32_t disable_mst_dsc_work_around:1; /* bit 3 */
763764
uint32_t enable_force_tbt3_work_around:1; /* bit 4 */
764765
uint32_t disable_usb4_pm_support:1; /* bit 5 */
765-
uint32_t reserved:26;
766+
uint32_t enable_consolidated_dpia_dp_lt:1; /* bit 6 */
767+
uint32_t reserved:25;
766768
} bits;
767769
uint32_t raw;
768770
};
@@ -2525,6 +2527,8 @@ enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc,
25252527
uint8_t mst_alloc_slots,
25262528
uint8_t *mst_slots_in_use);
25272529

2530+
void dc_process_dmub_dpia_set_tps_notification(const struct dc *dc, uint32_t link_index, uint8_t tps);
2531+
25282532
void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc,
25292533
uint32_t hpd_int_enable);
25302534

drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dpia.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,31 @@ static void update_dpia_stream_allocation_table(struct dc_link *link,
5050
DC_LOG_MST("dpia : status[%d]: alloc_slots[%d]: used_slots[%d]\n",
5151
status, mst_alloc_slots, prev_mst_slots_in_use);
5252

53-
ASSERT(link_enc);
54-
link_enc->funcs->update_mst_stream_allocation_table(link_enc, table);
53+
if (link_enc)
54+
link_enc->funcs->update_mst_stream_allocation_table(link_enc, table);
55+
}
56+
57+
static void set_dio_dpia_link_test_pattern(struct dc_link *link,
58+
const struct link_resource *link_res,
59+
struct encoder_set_dp_phy_pattern_param *tp_params)
60+
{
61+
if (tp_params->dp_phy_pattern != DP_TEST_PATTERN_VIDEO_MODE)
62+
return;
63+
64+
struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
65+
66+
if (!link_enc)
67+
return;
68+
69+
link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
70+
link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
71+
}
72+
73+
static void set_dio_dpia_lane_settings(struct dc_link *link,
74+
const struct link_resource *link_res,
75+
const struct dc_link_settings *link_settings,
76+
const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
77+
{
5578
}
5679

5780
static const struct link_hwss dpia_link_hwss = {
@@ -65,8 +88,8 @@ static const struct link_hwss dpia_link_hwss = {
6588
.ext = {
6689
.set_throttled_vcp_size = set_dio_throttled_vcp_size,
6790
.enable_dp_link_output = enable_dio_dp_link_output,
68-
.set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
69-
.set_dp_lane_settings = set_dio_dp_lane_settings,
91+
.set_dp_link_test_pattern = set_dio_dpia_link_test_pattern,
92+
.set_dp_lane_settings = set_dio_dpia_lane_settings,
7093
.update_stream_allocation_table = update_dpia_stream_allocation_table,
7194
},
7295
};

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,41 @@ bool dp_is_interlane_aligned(union lane_align_status_updated align_status)
515515
return align_status.bits.INTERLANE_ALIGN_DONE == 1;
516516
}
517517

518+
bool dp_check_interlane_aligned(union lane_align_status_updated align_status,
519+
struct dc_link *link,
520+
uint8_t retries)
521+
{
522+
/* Take into consideration corner case for DP 1.4a LL Compliance CTS as USB4
523+
* has to share encoders unlike DP and USBC
524+
*/
525+
return (dp_is_interlane_aligned(align_status) ||
526+
(link->skip_fallback_on_link_loss && retries));
527+
}
528+
529+
uint32_t dp_get_eq_aux_rd_interval(
530+
const struct dc_link *link,
531+
const struct link_training_settings *lt_settings,
532+
uint32_t offset,
533+
uint8_t retries)
534+
{
535+
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
536+
if (offset == 0 && retries == 1 && lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
537+
return max(lt_settings->eq_pattern_time, (uint32_t) DPIA_CLK_SYNC_DELAY);
538+
else
539+
return dpia_get_eq_aux_rd_interval(link, lt_settings, offset);
540+
} else if (is_repeater(lt_settings, offset))
541+
return dp_translate_training_aux_read_interval(
542+
link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]);
543+
else
544+
return lt_settings->eq_pattern_time;
545+
}
546+
547+
bool dp_check_dpcd_reqeust_status(const struct dc_link *link,
548+
enum dc_status status)
549+
{
550+
return (status != DC_OK && link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA);
551+
}
552+
518553
enum link_training_result dp_check_link_loss_status(
519554
struct dc_link *link,
520555
const struct link_training_settings *link_training_setting)
@@ -973,13 +1008,17 @@ void repeater_training_done(struct dc_link *link, uint32_t offset)
9731008
dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
9741009
}
9751010

976-
static void dpcd_exit_training_mode(struct dc_link *link, enum dp_link_encoding encoding)
1011+
static enum link_training_result dpcd_exit_training_mode(struct dc_link *link, enum dp_link_encoding encoding)
9771012
{
1013+
enum dc_status status;
9781014
uint8_t sink_status = 0;
9791015
uint8_t i;
9801016

9811017
/* clear training pattern set */
982-
dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
1018+
status = dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
1019+
1020+
if (dp_check_dpcd_reqeust_status(link, status))
1021+
return LINK_TRAINING_ABORT;
9831022

9841023
if (encoding == DP_128b_132b_ENCODING) {
9851024
/* poll for intra-hop disable */
@@ -990,6 +1029,8 @@ static void dpcd_exit_training_mode(struct dc_link *link, enum dp_link_encoding
9901029
fsleep(1000);
9911030
}
9921031
}
1032+
1033+
return LINK_TRAINING_SUCCESS;
9931034
}
9941035

9951036
enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
@@ -1013,17 +1054,18 @@ enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
10131054
return status;
10141055
}
10151056

1016-
void dpcd_set_training_pattern(
1057+
enum dc_status dpcd_set_training_pattern(
10171058
struct dc_link *link,
10181059
enum dc_dp_training_pattern training_pattern)
10191060
{
1061+
enum dc_status status;
10201062
union dpcd_training_pattern dpcd_pattern = {0};
10211063

10221064
dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
10231065
dp_training_pattern_to_dpcd_training_pattern(
10241066
link, training_pattern);
10251067

1026-
core_link_write_dpcd(
1068+
status = core_link_write_dpcd(
10271069
link,
10281070
DP_TRAINING_PATTERN_SET,
10291071
&dpcd_pattern.raw,
@@ -1033,6 +1075,8 @@ void dpcd_set_training_pattern(
10331075
__func__,
10341076
DP_TRAINING_PATTERN_SET,
10351077
dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
1078+
1079+
return status;
10361080
}
10371081

10381082
enum dc_status dpcd_set_link_settings(
@@ -1185,6 +1229,13 @@ void dpcd_set_lt_pattern_and_lane_settings(
11851229
dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
11861230
= dpcd_pattern.raw;
11871231

1232+
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
1233+
dpia_set_tps_notification(
1234+
link,
1235+
lt_settings,
1236+
dpcd_pattern.v1_4.TRAINING_PATTERN_SET,
1237+
offset);
1238+
11881239
if (is_repeater(lt_settings, offset)) {
11891240
DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n 0x%X pattern = %x\n",
11901241
__func__,
@@ -1455,7 +1506,8 @@ static enum link_training_result dp_transition_to_video_idle(
14551506
*/
14561507
if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
14571508
msleep(5);
1458-
status = dp_check_link_loss_status(link, lt_settings);
1509+
if (!link->skip_fallback_on_link_loss)
1510+
status = dp_check_link_loss_status(link, lt_settings);
14591511
}
14601512
return status;
14611513
}
@@ -1521,7 +1573,9 @@ enum link_training_result dp_perform_link_training(
15211573
ASSERT(0);
15221574

15231575
/* exit training mode */
1524-
dpcd_exit_training_mode(link, encoding);
1576+
if ((dpcd_exit_training_mode(link, encoding) != LINK_TRAINING_SUCCESS || status == LINK_TRAINING_ABORT) &&
1577+
link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
1578+
dpia_training_abort(link, &lt_settings, 0);
15251579

15261580
/* switch to video idle */
15271581
if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern)
@@ -1599,8 +1653,7 @@ bool perform_link_training_with_retries(
15991653
dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &cur_link_settings);
16001654
return true;
16011655
} else {
1602-
/** @todo Consolidate USB4 DP and DPx.x training. */
1603-
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
1656+
if (!link->dc->config.consolidated_dpia_dp_lt && link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
16041657
status = dpia_perform_link_training(
16051658
link,
16061659
&pipe_ctx->link_res,
@@ -1629,8 +1682,17 @@ bool perform_link_training_with_retries(
16291682
dp_trace_lt_total_count_increment(link, false);
16301683
dp_trace_lt_result_update(link, status, false);
16311684
dp_trace_set_lt_end_timestamp(link, false);
1632-
if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low)
1685+
if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low) {
1686+
// Update verified link settings to current one
1687+
// Because DPIA LT might fallback to lower link setting.
1688+
if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
1689+
stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
1690+
link->verified_link_cap.link_rate = link->cur_link_settings.link_rate;
1691+
link->verified_link_cap.lane_count = link->cur_link_settings.lane_count;
1692+
dm_helpers_dp_mst_update_branch_bandwidth(link->ctx, link);
1693+
}
16331694
return true;
1695+
}
16341696
}
16351697

16361698
fail_count++;

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void dp_set_hw_test_pattern(
5555
uint8_t *custom_pattern,
5656
uint32_t custom_pattern_size);
5757

58-
void dpcd_set_training_pattern(
58+
enum dc_status dpcd_set_training_pattern(
5959
struct dc_link *link,
6060
enum dc_dp_training_pattern training_pattern);
6161

@@ -182,4 +182,18 @@ uint32_t dp_translate_training_aux_read_interval(
182182

183183
uint8_t dp_get_nibble_at_index(const uint8_t *buf,
184184
uint32_t index);
185+
186+
bool dp_check_interlane_aligned(union lane_align_status_updated align_status,
187+
struct dc_link *link,
188+
uint8_t retries);
189+
190+
uint32_t dp_get_eq_aux_rd_interval(
191+
const struct dc_link *link,
192+
const struct link_training_settings *lt_settings,
193+
uint32_t offset,
194+
uint8_t retries);
195+
196+
bool dp_check_dpcd_reqeust_status(const struct dc_link *link,
197+
enum dc_status status);
198+
185199
#endif /* __DC_LINK_DP_TRAINING_H__ */

drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ enum link_training_result perform_8b_10b_clock_recovery_sequence(
157157
struct link_training_settings *lt_settings,
158158
uint32_t offset)
159159
{
160+
enum dc_status status;
160161
uint32_t retries_cr;
161162
uint32_t retry_count;
162163
uint32_t wait_time_microsec;
@@ -216,14 +217,17 @@ enum link_training_result perform_8b_10b_clock_recovery_sequence(
216217
/* 4. Read lane status and requested drive
217218
* settings as set by the sink
218219
*/
219-
dp_get_lane_status_and_lane_adjust(
220+
status = dp_get_lane_status_and_lane_adjust(
220221
link,
221222
lt_settings,
222223
dpcd_lane_status,
223224
&dpcd_lane_status_updated,
224225
dpcd_lane_adjust,
225226
offset);
226227

228+
if (dp_check_dpcd_reqeust_status(link, status))
229+
return LINK_TRAINING_ABORT;
230+
227231
/* 5. check CR done*/
228232
if (dp_is_cr_done(lane_count, dpcd_lane_status)) {
229233
DC_LOG_HW_LINK_TRAINING("%s: Clock recovery OK\n", __func__);
@@ -273,6 +277,7 @@ enum link_training_result perform_8b_10b_channel_equalization_sequence(
273277
struct link_training_settings *lt_settings,
274278
uint32_t offset)
275279
{
280+
enum dc_status status;
276281
enum dc_dp_training_pattern tr_pattern;
277282
uint32_t retries_ch_eq;
278283
uint32_t wait_time_microsec;
@@ -308,12 +313,7 @@ enum link_training_result perform_8b_10b_channel_equalization_sequence(
308313
dpcd_set_lane_settings(link, lt_settings, offset);
309314

310315
/* 3. wait for receiver to lock-on*/
311-
wait_time_microsec = lt_settings->eq_pattern_time;
312-
313-
if (is_repeater(lt_settings, offset))
314-
wait_time_microsec =
315-
dp_translate_training_aux_read_interval(
316-
link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]);
316+
wait_time_microsec = dp_get_eq_aux_rd_interval(link, lt_settings, offset, retries_ch_eq);
317317

318318
dp_wait_for_training_aux_rd_interval(
319319
link,
@@ -322,14 +322,17 @@ enum link_training_result perform_8b_10b_channel_equalization_sequence(
322322
/* 4. Read lane status and requested
323323
* drive settings as set by the sink*/
324324

325-
dp_get_lane_status_and_lane_adjust(
325+
status = dp_get_lane_status_and_lane_adjust(
326326
link,
327327
lt_settings,
328328
dpcd_lane_status,
329329
&dpcd_lane_status_updated,
330330
dpcd_lane_adjust,
331331
offset);
332332

333+
if (dp_check_dpcd_reqeust_status(link, status))
334+
return LINK_TRAINING_ABORT;
335+
333336
/* 5. check CR done*/
334337
if (!dp_is_cr_done(lane_count, dpcd_lane_status))
335338
return dpcd_lane_status[0].bits.CR_DONE_0 ?
@@ -339,7 +342,7 @@ enum link_training_result perform_8b_10b_channel_equalization_sequence(
339342
/* 6. check CHEQ done*/
340343
if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
341344
dp_is_symbol_locked(lane_count, dpcd_lane_status) &&
342-
dp_is_interlane_aligned(dpcd_lane_status_updated))
345+
dp_check_interlane_aligned(dpcd_lane_status_updated, link, retries_ch_eq))
343346
return LINK_TRAINING_SUCCESS;
344347

345348
/* 7. update VS/PE/PC2 in lt_settings*/

0 commit comments

Comments
 (0)