1 /* Copyright 2015 Advanced Micro Devices, Inc. */
2 #include "dm_services.h"
4 #include "dc_link_dp.h"
5 #include "dm_helpers.h"
7 #include "inc/core_types.h"
9 #include "dc_link_ddc.h"
10 #include "core_status.h"
11 #include "dpcd_defs.h"
17 /* maximum pre emphasis level allowed for each voltage swing level*/
18 static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = {
22 PRE_EMPHASIS_DISABLED };
25 POST_LT_ADJ_REQ_LIMIT = 6,
26 POST_LT_ADJ_REQ_TIMEOUT = 200
30 LINK_TRAINING_MAX_RETRY_COUNT = 5,
31 /* to avoid infinite loop where-in the receiver
32 * switches between different VS
34 LINK_TRAINING_MAX_CR_RETRY = 100
37 static bool decide_fallback_link_setting(
38 struct dc_link_settings initial_link_settings,
39 struct dc_link_settings *current_link_setting,
40 enum link_training_result training_result);
41 static struct dc_link_settings get_common_supported_link_settings (
42 struct dc_link_settings link_setting_a,
43 struct dc_link_settings link_setting_b);
45 static void wait_for_training_aux_rd_interval(
47 uint32_t default_wait_in_micro_secs)
49 union training_aux_rd_interval training_rd_interval;
51 /* overwrite the delay if rev > 1.1*/
52 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
53 /* DP 1.2 or later - retrieve delay through
54 * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
57 DP_TRAINING_AUX_RD_INTERVAL,
58 (uint8_t *)&training_rd_interval,
59 sizeof(training_rd_interval));
61 if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
62 default_wait_in_micro_secs =
63 training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
66 udelay(default_wait_in_micro_secs);
68 DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
70 default_wait_in_micro_secs);
73 static void dpcd_set_training_pattern(
75 union dpcd_training_pattern dpcd_pattern)
79 DP_TRAINING_PATTERN_SET,
83 DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
85 DP_TRAINING_PATTERN_SET,
86 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
89 static void dpcd_set_link_settings(
91 const struct link_training_settings *lt_settings)
93 uint8_t rate = (uint8_t)
94 (lt_settings->link_settings.link_rate);
96 union down_spread_ctrl downspread = {{0}};
97 union lane_count_set lane_count_set = {{0}};
98 uint8_t link_set_buffer[2];
100 downspread.raw = (uint8_t)
101 (lt_settings->link_settings.link_spread);
103 lane_count_set.bits.LANE_COUNT_SET =
104 lt_settings->link_settings.lane_count;
106 lane_count_set.bits.ENHANCED_FRAMING = 1;
108 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
109 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
111 link_set_buffer[0] = rate;
112 link_set_buffer[1] = lane_count_set.raw;
114 core_link_write_dpcd(link, DP_LINK_BW_SET,
116 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
117 &downspread.raw, sizeof(downspread));
119 DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n",
122 lt_settings->link_settings.link_rate,
124 lt_settings->link_settings.lane_count,
126 lt_settings->link_settings.link_spread);
130 static enum dpcd_training_patterns
131 hw_training_pattern_to_dpcd_training_pattern(
132 struct dc_link *link,
133 enum hw_dp_training_pattern pattern)
135 enum dpcd_training_patterns dpcd_tr_pattern =
136 DPCD_TRAINING_PATTERN_VIDEOIDLE;
139 case HW_DP_TRAINING_PATTERN_1:
140 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
142 case HW_DP_TRAINING_PATTERN_2:
143 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
145 case HW_DP_TRAINING_PATTERN_3:
146 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
148 case HW_DP_TRAINING_PATTERN_4:
149 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
153 DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
158 return dpcd_tr_pattern;
162 static void dpcd_set_lt_pattern_and_lane_settings(
163 struct dc_link *link,
164 const struct link_training_settings *lt_settings,
165 enum hw_dp_training_pattern pattern)
167 union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
168 const uint32_t dpcd_base_lt_offset =
169 DP_TRAINING_PATTERN_SET;
170 uint8_t dpcd_lt_buffer[5] = {0};
171 union dpcd_training_pattern dpcd_pattern = {{0}};
173 uint32_t size_in_bytes;
174 bool edp_workaround = false; /* TODO link_prop.INTERNAL */
176 /*****************************************************************
177 * DpcdAddress_TrainingPatternSet
178 *****************************************************************/
179 dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
180 hw_training_pattern_to_dpcd_training_pattern(link, pattern);
182 dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - dpcd_base_lt_offset]
185 DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
187 DP_TRAINING_PATTERN_SET,
188 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
190 /*****************************************************************
191 * DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set
192 *****************************************************************/
193 for (lane = 0; lane <
194 (uint32_t)(lt_settings->link_settings.lane_count); lane++) {
196 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
197 (uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING);
198 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
199 (uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS);
201 dpcd_lane[lane].bits.MAX_SWING_REACHED =
202 (lt_settings->lane_settings[lane].VOLTAGE_SWING ==
203 VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
204 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
205 (lt_settings->lane_settings[lane].PRE_EMPHASIS ==
206 PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
209 /* concatinate everything into one buffer*/
211 size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
215 &dpcd_lt_buffer[DP_TRAINING_LANE0_SET - dpcd_base_lt_offset],
219 DC_LOG_HW_LINK_TRAINING("%s:\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
221 DP_TRAINING_LANE0_SET,
222 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
223 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
224 dpcd_lane[0].bits.MAX_SWING_REACHED,
225 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
227 if (edp_workaround) {
228 /* for eDP write in 2 parts because the 5-byte burst is
229 * causing issues on some eDP panels (EPR#366724)
231 core_link_write_dpcd(
233 DP_TRAINING_PATTERN_SET,
235 sizeof(dpcd_pattern.raw) );
237 core_link_write_dpcd(
239 DP_TRAINING_LANE0_SET,
240 (uint8_t *)(dpcd_lane),
244 /* write it all in (1 + number-of-lanes)-byte burst*/
245 core_link_write_dpcd(
249 size_in_bytes + sizeof(dpcd_pattern.raw) );
251 link->cur_lane_setting = lt_settings->lane_settings[0];
254 static bool is_cr_done(enum dc_lane_count ln_count,
255 union lane_status *dpcd_lane_status)
259 /*LANEx_CR_DONE bits All 1's?*/
260 for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
261 if (!dpcd_lane_status[lane].bits.CR_DONE_0)
268 static bool is_ch_eq_done(enum dc_lane_count ln_count,
269 union lane_status *dpcd_lane_status,
270 union lane_align_status_updated *lane_status_updated)
274 if (!lane_status_updated->bits.INTERLANE_ALIGN_DONE)
277 for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
278 if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0 ||
279 !dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
287 static void update_drive_settings(
288 struct link_training_settings *dest,
289 struct link_training_settings src)
292 for (lane = 0; lane < src.link_settings.lane_count; lane++) {
293 dest->lane_settings[lane].VOLTAGE_SWING =
294 src.lane_settings[lane].VOLTAGE_SWING;
295 dest->lane_settings[lane].PRE_EMPHASIS =
296 src.lane_settings[lane].PRE_EMPHASIS;
297 dest->lane_settings[lane].POST_CURSOR2 =
298 src.lane_settings[lane].POST_CURSOR2;
302 static uint8_t get_nibble_at_index(const uint8_t *buf,
306 nibble = buf[index / 2];
316 static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
317 enum dc_voltage_swing voltage)
319 enum dc_pre_emphasis pre_emphasis;
320 pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
322 if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
323 pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
329 static void find_max_drive_settings(
330 const struct link_training_settings *link_training_setting,
331 struct link_training_settings *max_lt_setting)
334 struct dc_lane_settings max_requested;
336 max_requested.VOLTAGE_SWING =
337 link_training_setting->
338 lane_settings[0].VOLTAGE_SWING;
339 max_requested.PRE_EMPHASIS =
340 link_training_setting->
341 lane_settings[0].PRE_EMPHASIS;
342 /*max_requested.postCursor2 =
343 * link_training_setting->laneSettings[0].postCursor2;*/
345 /* Determine what the maximum of the requested settings are*/
346 for (lane = 1; lane < link_training_setting->link_settings.lane_count;
348 if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
349 max_requested.VOLTAGE_SWING)
351 max_requested.VOLTAGE_SWING =
352 link_training_setting->
353 lane_settings[lane].VOLTAGE_SWING;
355 if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
356 max_requested.PRE_EMPHASIS)
357 max_requested.PRE_EMPHASIS =
358 link_training_setting->
359 lane_settings[lane].PRE_EMPHASIS;
362 if (link_training_setting->laneSettings[lane].postCursor2 >
363 max_requested.postCursor2)
365 max_requested.postCursor2 =
366 link_training_setting->laneSettings[lane].postCursor2;
371 /* make sure the requested settings are
372 * not higher than maximum settings*/
373 if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
374 max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
376 if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
377 max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
379 if (max_requested.postCursor2 > PostCursor2_MaxLevel)
380 max_requested.postCursor2 = PostCursor2_MaxLevel;
383 /* make sure the pre-emphasis matches the voltage swing*/
384 if (max_requested.PRE_EMPHASIS >
385 get_max_pre_emphasis_for_voltage_swing(
386 max_requested.VOLTAGE_SWING))
387 max_requested.PRE_EMPHASIS =
388 get_max_pre_emphasis_for_voltage_swing(
389 max_requested.VOLTAGE_SWING);
392 * Post Cursor2 levels are completely independent from
393 * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
394 * can only be applied to each allowable combination of voltage
395 * swing and pre-emphasis levels */
396 /* if ( max_requested.postCursor2 >
397 * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
398 * max_requested.postCursor2 =
399 * getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
402 max_lt_setting->link_settings.link_rate =
403 link_training_setting->link_settings.link_rate;
404 max_lt_setting->link_settings.lane_count =
405 link_training_setting->link_settings.lane_count;
406 max_lt_setting->link_settings.link_spread =
407 link_training_setting->link_settings.link_spread;
409 for (lane = 0; lane <
410 link_training_setting->link_settings.lane_count;
412 max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
413 max_requested.VOLTAGE_SWING;
414 max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
415 max_requested.PRE_EMPHASIS;
416 /*max_lt_setting->laneSettings[lane].postCursor2 =
417 * max_requested.postCursor2;
423 static void get_lane_status_and_drive_settings(
424 struct dc_link *link,
425 const struct link_training_settings *link_training_setting,
426 union lane_status *ln_status,
427 union lane_align_status_updated *ln_status_updated,
428 struct link_training_settings *req_settings)
430 uint8_t dpcd_buf[6] = {0};
431 union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {{{0}}};
432 struct link_training_settings request_settings = {{0}};
435 memset(req_settings, '\0', sizeof(struct link_training_settings));
440 (uint8_t *)(dpcd_buf),
443 for (lane = 0; lane <
444 (uint32_t)(link_training_setting->link_settings.lane_count);
447 ln_status[lane].raw =
448 get_nibble_at_index(&dpcd_buf[0], lane);
449 dpcd_lane_adjust[lane].raw =
450 get_nibble_at_index(&dpcd_buf[4], lane);
453 ln_status_updated->raw = dpcd_buf[2];
455 DC_LOG_HW_LINK_TRAINING("%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ",
457 DP_LANE0_1_STATUS, dpcd_buf[0],
458 DP_LANE2_3_STATUS, dpcd_buf[1]);
460 DC_LOG_HW_LINK_TRAINING("%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n",
462 DP_ADJUST_REQUEST_LANE0_1,
464 DP_ADJUST_REQUEST_LANE2_3,
467 /*copy to req_settings*/
468 request_settings.link_settings.lane_count =
469 link_training_setting->link_settings.lane_count;
470 request_settings.link_settings.link_rate =
471 link_training_setting->link_settings.link_rate;
472 request_settings.link_settings.link_spread =
473 link_training_setting->link_settings.link_spread;
475 for (lane = 0; lane <
476 (uint32_t)(link_training_setting->link_settings.lane_count);
479 request_settings.lane_settings[lane].VOLTAGE_SWING =
480 (enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
482 request_settings.lane_settings[lane].PRE_EMPHASIS =
483 (enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
487 /*Note: for postcursor2, read adjusted
488 * postcursor2 settings from*/
489 /*DpcdAddress_AdjustRequestPostCursor2 =
490 *0x020C (not implemented yet)*/
492 /* we find the maximum of the requested settings across all lanes*/
493 /* and set this maximum for all lanes*/
494 find_max_drive_settings(&request_settings, req_settings);
496 /* if post cursor 2 is needed in the future,
497 * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
502 static void dpcd_set_lane_settings(
503 struct dc_link *link,
504 const struct link_training_settings *link_training_setting)
506 union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
509 for (lane = 0; lane <
510 (uint32_t)(link_training_setting->
511 link_settings.lane_count);
513 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
514 (uint8_t)(link_training_setting->
515 lane_settings[lane].VOLTAGE_SWING);
516 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
517 (uint8_t)(link_training_setting->
518 lane_settings[lane].PRE_EMPHASIS);
519 dpcd_lane[lane].bits.MAX_SWING_REACHED =
520 (link_training_setting->
521 lane_settings[lane].VOLTAGE_SWING ==
522 VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
523 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
524 (link_training_setting->
525 lane_settings[lane].PRE_EMPHASIS ==
526 PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
529 core_link_write_dpcd(link,
530 DP_TRAINING_LANE0_SET,
531 (uint8_t *)(dpcd_lane),
532 link_training_setting->link_settings.lane_count);
535 if (LTSettings.link.rate == LinkRate_High2)
537 DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
538 for ( uint32_t lane = 0;
539 lane < lane_count_DPMax; lane++)
541 dpcd_lane2[lane].bits.post_cursor2_set =
542 static_cast<unsigned char>(
543 LTSettings.laneSettings[lane].postCursor2);
544 dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
546 m_pDpcdAccessSrv->WriteDpcdData(
547 DpcdAddress_Lane0Set2,
548 reinterpret_cast<unsigned char*>(dpcd_lane2),
549 LTSettings.link.lanes);
553 DC_LOG_HW_LINK_TRAINING("%s\n %x VS set = %x PE set = %x max VS Reached = %x max PE Reached = %x\n",
555 DP_TRAINING_LANE0_SET,
556 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
557 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
558 dpcd_lane[0].bits.MAX_SWING_REACHED,
559 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
561 link->cur_lane_setting = link_training_setting->lane_settings[0];
565 static bool is_max_vs_reached(
566 const struct link_training_settings *lt_settings)
569 for (lane = 0; lane <
570 (uint32_t)(lt_settings->link_settings.lane_count);
572 if (lt_settings->lane_settings[lane].VOLTAGE_SWING
573 == VOLTAGE_SWING_MAX_LEVEL)
580 void dc_link_dp_set_drive_settings(
581 struct dc_link *link,
582 struct link_training_settings *lt_settings)
584 /* program ASIC PHY settings*/
585 dp_set_hw_lane_settings(link, lt_settings);
587 /* Notify DP sink the PHY settings from source */
588 dpcd_set_lane_settings(link, lt_settings);
591 static bool perform_post_lt_adj_req_sequence(
592 struct dc_link *link,
593 struct link_training_settings *lt_settings)
595 enum dc_lane_count lane_count =
596 lt_settings->link_settings.lane_count;
598 uint32_t adj_req_count;
599 uint32_t adj_req_timer;
600 bool req_drv_setting_changed;
603 req_drv_setting_changed = false;
604 for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
607 req_drv_setting_changed = false;
609 for (adj_req_timer = 0;
610 adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
613 struct link_training_settings req_settings;
614 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
615 union lane_align_status_updated
616 dpcd_lane_status_updated;
618 get_lane_status_and_drive_settings(
622 &dpcd_lane_status_updated,
625 if (dpcd_lane_status_updated.bits.
626 POST_LT_ADJ_REQ_IN_PROGRESS == 0)
629 if (!is_cr_done(lane_count, dpcd_lane_status))
635 &dpcd_lane_status_updated))
638 for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
641 lane_settings[lane].VOLTAGE_SWING !=
642 req_settings.lane_settings[lane].
644 lt_settings->lane_settings[lane].PRE_EMPHASIS !=
645 req_settings.lane_settings[lane].PRE_EMPHASIS) {
647 req_drv_setting_changed = true;
652 if (req_drv_setting_changed) {
653 update_drive_settings(
654 lt_settings,req_settings);
656 dc_link_dp_set_drive_settings(link,
664 if (!req_drv_setting_changed) {
665 DC_LOG_WARNING("%s: Post Link Training Adjust Request Timed out\n",
672 DC_LOG_WARNING("%s: Post Link Training Adjust Request limit reached\n",
680 static enum hw_dp_training_pattern get_supported_tp(struct dc_link *link)
682 enum hw_dp_training_pattern highest_tp = HW_DP_TRAINING_PATTERN_2;
683 struct encoder_feature_support *features = &link->link_enc->features;
684 struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
686 if (features->flags.bits.IS_TPS3_CAPABLE)
687 highest_tp = HW_DP_TRAINING_PATTERN_3;
689 if (features->flags.bits.IS_TPS4_CAPABLE)
690 highest_tp = HW_DP_TRAINING_PATTERN_4;
692 if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
693 highest_tp >= HW_DP_TRAINING_PATTERN_4)
694 return HW_DP_TRAINING_PATTERN_4;
696 if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
697 highest_tp >= HW_DP_TRAINING_PATTERN_3)
698 return HW_DP_TRAINING_PATTERN_3;
700 return HW_DP_TRAINING_PATTERN_2;
703 static enum link_training_result get_cr_failure(enum dc_lane_count ln_count,
704 union lane_status *dpcd_lane_status)
706 enum link_training_result result = LINK_TRAINING_SUCCESS;
708 if (ln_count >= LANE_COUNT_ONE && !dpcd_lane_status[0].bits.CR_DONE_0)
709 result = LINK_TRAINING_CR_FAIL_LANE0;
710 else if (ln_count >= LANE_COUNT_TWO && !dpcd_lane_status[1].bits.CR_DONE_0)
711 result = LINK_TRAINING_CR_FAIL_LANE1;
712 else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[2].bits.CR_DONE_0)
713 result = LINK_TRAINING_CR_FAIL_LANE23;
714 else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[3].bits.CR_DONE_0)
715 result = LINK_TRAINING_CR_FAIL_LANE23;
719 static enum link_training_result perform_channel_equalization_sequence(
720 struct dc_link *link,
721 struct link_training_settings *lt_settings)
723 struct link_training_settings req_settings;
724 enum hw_dp_training_pattern hw_tr_pattern;
725 uint32_t retries_ch_eq;
726 enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
727 union lane_align_status_updated dpcd_lane_status_updated = {{0}};
728 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};
730 hw_tr_pattern = get_supported_tp(link);
732 dp_set_hw_training_pattern(link, hw_tr_pattern);
734 for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
737 dp_set_hw_lane_settings(link, lt_settings);
741 /* EPR #361076 - write as a 5-byte burst,
742 * but only for the 1-st iteration*/
743 dpcd_set_lt_pattern_and_lane_settings(
748 dpcd_set_lane_settings(link, lt_settings);
750 /* 3. wait for receiver to lock-on*/
751 wait_for_training_aux_rd_interval(link, 400);
753 /* 4. Read lane status and requested
754 * drive settings as set by the sink*/
756 get_lane_status_and_drive_settings(
760 &dpcd_lane_status_updated,
763 /* 5. check CR done*/
764 if (!is_cr_done(lane_count, dpcd_lane_status))
765 return LINK_TRAINING_EQ_FAIL_CR;
767 /* 6. check CHEQ done*/
768 if (is_ch_eq_done(lane_count,
770 &dpcd_lane_status_updated))
771 return LINK_TRAINING_SUCCESS;
773 /* 7. update VS/PE/PC2 in lt_settings*/
774 update_drive_settings(lt_settings, req_settings);
777 return LINK_TRAINING_EQ_FAIL_EQ;
781 static enum link_training_result perform_clock_recovery_sequence(
782 struct dc_link *link,
783 struct link_training_settings *lt_settings)
786 uint32_t retry_count;
788 struct link_training_settings req_settings;
789 enum dc_lane_count lane_count =
790 lt_settings->link_settings.lane_count;
791 enum hw_dp_training_pattern hw_tr_pattern = HW_DP_TRAINING_PATTERN_1;
792 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
793 union lane_align_status_updated dpcd_lane_status_updated;
797 /* initial drive setting (VS/PE/PC2)*/
798 for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
799 lt_settings->lane_settings[lane].VOLTAGE_SWING =
800 VOLTAGE_SWING_LEVEL0;
801 lt_settings->lane_settings[lane].PRE_EMPHASIS =
802 PRE_EMPHASIS_DISABLED;
803 lt_settings->lane_settings[lane].POST_CURSOR2 =
804 POST_CURSOR2_DISABLED;
807 dp_set_hw_training_pattern(link, hw_tr_pattern);
809 /* najeeb - The synaptics MST hub can put the LT in
810 * infinite loop by switching the VS
812 /* between level 0 and level 1 continuously, here
813 * we try for CR lock for LinkTrainingMaxCRRetry count*/
814 while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
815 (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
817 memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
818 memset(&dpcd_lane_status_updated, '\0',
819 sizeof(dpcd_lane_status_updated));
821 /* 1. call HWSS to set lane settings*/
822 dp_set_hw_lane_settings(
826 /* 2. update DPCD of the receiver*/
828 /* EPR #361076 - write as a 5-byte burst,
829 * but only for the 1-st iteration.*/
830 dpcd_set_lt_pattern_and_lane_settings(
835 dpcd_set_lane_settings(
839 /* 3. wait receiver to lock-on*/
840 wait_for_training_aux_rd_interval(
844 /* 4. Read lane status and requested drive
845 * settings as set by the sink
847 get_lane_status_and_drive_settings(
851 &dpcd_lane_status_updated,
854 /* 5. check CR done*/
855 if (is_cr_done(lane_count, dpcd_lane_status))
856 return LINK_TRAINING_SUCCESS;
858 /* 6. max VS reached*/
859 if (is_max_vs_reached(lt_settings))
863 /* Note: VS same for all lanes,
864 * so comparing first lane is sufficient*/
865 if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
866 req_settings.lane_settings[0].VOLTAGE_SWING)
871 /* 8. update VS/PE/PC2 in lt_settings*/
872 update_drive_settings(lt_settings, req_settings);
877 if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
879 DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
881 LINK_TRAINING_MAX_CR_RETRY);
885 return get_cr_failure(lane_count, dpcd_lane_status);
888 static inline enum link_training_result perform_link_training_int(
889 struct dc_link *link,
890 struct link_training_settings *lt_settings,
891 enum link_training_result status)
893 union lane_count_set lane_count_set = { {0} };
894 union dpcd_training_pattern dpcd_pattern = { {0} };
896 /* 3. set training not in progress*/
897 dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
898 dpcd_set_training_pattern(link, dpcd_pattern);
900 /* 4. mainlink output idle pattern*/
901 dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
904 * 5. post training adjust if required
905 * If the upstream DPTX and downstream DPRX both support TPS4,
906 * TPS4 must be used instead of POST_LT_ADJ_REQ.
908 if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
909 get_supported_tp(link) == HW_DP_TRAINING_PATTERN_4)
912 if (status == LINK_TRAINING_SUCCESS &&
913 perform_post_lt_adj_req_sequence(link, lt_settings) == false)
914 status = LINK_TRAINING_LQA_FAIL;
916 lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
917 lane_count_set.bits.ENHANCED_FRAMING = 1;
918 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
920 core_link_write_dpcd(
924 sizeof(lane_count_set));
929 enum link_training_result dc_link_dp_perform_link_training(
930 struct dc_link *link,
931 const struct dc_link_settings *link_setting,
932 bool skip_video_pattern)
934 enum link_training_result status = LINK_TRAINING_SUCCESS;
936 char *link_rate = "Unknown";
937 char *lt_result = "Unknown";
939 struct link_training_settings lt_settings;
941 memset(<_settings, '\0', sizeof(lt_settings));
943 lt_settings.link_settings.link_rate = link_setting->link_rate;
944 lt_settings.link_settings.lane_count = link_setting->lane_count;
946 /*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
948 /* TODO hard coded to SS for now
949 * lt_settings.link_settings.link_spread =
950 * dal_display_path_is_ss_supported(
951 * path_mode->display_path) ?
952 * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
953 * LINK_SPREAD_DISABLED;
955 lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
957 /* 1. set link rate, lane count and spread*/
958 dpcd_set_link_settings(link, <_settings);
960 /* 2. perform link training (set link training done
961 * to false is done as well)*/
962 status = perform_clock_recovery_sequence(link, <_settings);
963 if (status == LINK_TRAINING_SUCCESS) {
964 status = perform_channel_equalization_sequence(link,
968 if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
969 status = perform_link_training_int(link,
974 /* 6. print status message*/
975 switch (lt_settings.link_settings.link_rate) {
983 case LINK_RATE_HIGH2:
989 case LINK_RATE_HIGH3:
997 case LINK_TRAINING_SUCCESS:
1000 case LINK_TRAINING_CR_FAIL_LANE0:
1001 lt_result = "CR failed lane0";
1003 case LINK_TRAINING_CR_FAIL_LANE1:
1004 lt_result = "CR failed lane1";
1006 case LINK_TRAINING_CR_FAIL_LANE23:
1007 lt_result = "CR failed lane23";
1009 case LINK_TRAINING_EQ_FAIL_CR:
1010 lt_result = "CR failed in EQ";
1012 case LINK_TRAINING_EQ_FAIL_EQ:
1013 lt_result = "EQ failed";
1015 case LINK_TRAINING_LQA_FAIL:
1016 lt_result = "LQA failed";
1022 /* Connectivity log: link training */
1023 CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d",
1025 lt_settings.link_settings.lane_count,
1027 lt_settings.lane_settings[0].VOLTAGE_SWING,
1028 lt_settings.lane_settings[0].PRE_EMPHASIS);
1034 bool perform_link_training_with_retries(
1035 struct dc_link *link,
1036 const struct dc_link_settings *link_setting,
1037 bool skip_video_pattern,
1041 uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY;
1043 for (j = 0; j < attempts; ++j) {
1045 if (dc_link_dp_perform_link_training(
1048 skip_video_pattern) == LINK_TRAINING_SUCCESS)
1051 msleep(delay_between_attempts);
1052 delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
1058 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
1060 /* Set Default link settings */
1061 struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
1062 LINK_SPREAD_05_DOWNSPREAD_30KHZ};
1064 /* Higher link settings based on feature supported */
1065 if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
1066 max_link_cap.link_rate = LINK_RATE_HIGH2;
1068 if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1069 max_link_cap.link_rate = LINK_RATE_HIGH3;
1071 /* Lower link settings based on sink's link cap */
1072 if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
1073 max_link_cap.lane_count =
1074 link->reported_link_cap.lane_count;
1075 if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
1076 max_link_cap.link_rate =
1077 link->reported_link_cap.link_rate;
1078 if (link->reported_link_cap.link_spread <
1079 max_link_cap.link_spread)
1080 max_link_cap.link_spread =
1081 link->reported_link_cap.link_spread;
1082 return max_link_cap;
1085 bool dp_hbr_verify_link_cap(
1086 struct dc_link *link,
1087 struct dc_link_settings *known_limit_link_setting)
1089 struct dc_link_settings max_link_cap = {0};
1090 struct dc_link_settings cur_link_setting = {0};
1091 struct dc_link_settings *cur = &cur_link_setting;
1092 struct dc_link_settings initial_link_settings = {0};
1094 bool skip_link_training;
1095 bool skip_video_pattern;
1096 struct clock_source *dp_cs;
1097 enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1098 enum link_training_result status;
1101 skip_link_training = false;
1103 max_link_cap = get_max_link_cap(link);
1105 /* TODO implement override and monitor patch later */
1107 /* try to train the link from high to low to
1108 * find the physical link capability
1110 /* disable PHY done possible by BIOS, will be done by driver itself */
1111 dp_disable_link_phy(link, link->connector_signal);
1113 dp_cs = link->dc->res_pool->dp_clock_source;
1116 dp_cs_id = dp_cs->id;
1119 * dp clock source is not initialized for some reason.
1120 * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
1125 /* link training starts with the maximum common settings
1126 * supported by both sink and ASIC.
1128 initial_link_settings = get_common_supported_link_settings(
1129 *known_limit_link_setting,
1131 cur_link_setting = initial_link_settings;
1133 skip_video_pattern = true;
1135 if (cur->link_rate == LINK_RATE_LOW)
1136 skip_video_pattern = false;
1140 link->connector_signal,
1145 if (skip_link_training)
1148 status = dc_link_dp_perform_link_training(
1151 skip_video_pattern);
1152 if (status == LINK_TRAINING_SUCCESS)
1157 link->verified_link_cap = *cur;
1159 /* always disable the link before trying another
1160 * setting or before returning we'll enable it later
1161 * based on the actual mode we're driving
1163 dp_disable_link_phy(link, link->connector_signal);
1164 } while (!success && decide_fallback_link_setting(
1165 initial_link_settings, cur, status));
1167 /* Link Training failed for all Link Settings
1168 * (Lane Count is still unknown)
1171 /* If all LT fails for all settings,
1172 * set verified = failed safe (1 lane low)
1174 link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1175 link->verified_link_cap.link_rate = LINK_RATE_LOW;
1177 link->verified_link_cap.link_spread =
1178 LINK_SPREAD_DISABLED;
1185 static struct dc_link_settings get_common_supported_link_settings (
1186 struct dc_link_settings link_setting_a,
1187 struct dc_link_settings link_setting_b)
1189 struct dc_link_settings link_settings = {0};
1191 link_settings.lane_count =
1192 (link_setting_a.lane_count <=
1193 link_setting_b.lane_count) ?
1194 link_setting_a.lane_count :
1195 link_setting_b.lane_count;
1196 link_settings.link_rate =
1197 (link_setting_a.link_rate <=
1198 link_setting_b.link_rate) ?
1199 link_setting_a.link_rate :
1200 link_setting_b.link_rate;
1201 link_settings.link_spread = LINK_SPREAD_DISABLED;
1203 /* in DP compliance test, DPR-120 may have
1204 * a random value in its MAX_LINK_BW dpcd field.
1205 * We map it to the maximum supported link rate that
1206 * is smaller than MAX_LINK_BW in this case.
1208 if (link_settings.link_rate > LINK_RATE_HIGH3) {
1209 link_settings.link_rate = LINK_RATE_HIGH3;
1210 } else if (link_settings.link_rate < LINK_RATE_HIGH3
1211 && link_settings.link_rate > LINK_RATE_HIGH2) {
1212 link_settings.link_rate = LINK_RATE_HIGH2;
1213 } else if (link_settings.link_rate < LINK_RATE_HIGH2
1214 && link_settings.link_rate > LINK_RATE_HIGH) {
1215 link_settings.link_rate = LINK_RATE_HIGH;
1216 } else if (link_settings.link_rate < LINK_RATE_HIGH
1217 && link_settings.link_rate > LINK_RATE_LOW) {
1218 link_settings.link_rate = LINK_RATE_LOW;
1219 } else if (link_settings.link_rate < LINK_RATE_LOW) {
1220 link_settings.link_rate = LINK_RATE_UNKNOWN;
1223 return link_settings;
1226 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
1228 return lane_count <= LANE_COUNT_ONE;
1231 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
1233 return link_rate <= LINK_RATE_LOW;
1236 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
1238 switch (lane_count) {
1239 case LANE_COUNT_FOUR:
1240 return LANE_COUNT_TWO;
1241 case LANE_COUNT_TWO:
1242 return LANE_COUNT_ONE;
1243 case LANE_COUNT_ONE:
1244 return LANE_COUNT_UNKNOWN;
1246 return LANE_COUNT_UNKNOWN;
1250 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
1252 switch (link_rate) {
1253 case LINK_RATE_HIGH3:
1254 return LINK_RATE_HIGH2;
1255 case LINK_RATE_HIGH2:
1256 return LINK_RATE_HIGH;
1257 case LINK_RATE_HIGH:
1258 return LINK_RATE_LOW;
1260 return LINK_RATE_UNKNOWN;
1262 return LINK_RATE_UNKNOWN;
1266 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
1268 switch (lane_count) {
1269 case LANE_COUNT_ONE:
1270 return LANE_COUNT_TWO;
1271 case LANE_COUNT_TWO:
1272 return LANE_COUNT_FOUR;
1274 return LANE_COUNT_UNKNOWN;
1278 static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
1280 switch (link_rate) {
1282 return LINK_RATE_HIGH;
1283 case LINK_RATE_HIGH:
1284 return LINK_RATE_HIGH2;
1285 case LINK_RATE_HIGH2:
1286 return LINK_RATE_HIGH3;
1288 return LINK_RATE_UNKNOWN;
1293 * function: set link rate and lane count fallback based
1294 * on current link setting and last link training result
1296 * true - link setting could be set
1297 * false - has reached minimum setting
1298 * and no further fallback could be done
1300 static bool decide_fallback_link_setting(
1301 struct dc_link_settings initial_link_settings,
1302 struct dc_link_settings *current_link_setting,
1303 enum link_training_result training_result)
1305 if (!current_link_setting)
1308 switch (training_result) {
1309 case LINK_TRAINING_CR_FAIL_LANE0:
1310 case LINK_TRAINING_CR_FAIL_LANE1:
1311 case LINK_TRAINING_CR_FAIL_LANE23:
1312 case LINK_TRAINING_LQA_FAIL:
1314 if (!reached_minimum_link_rate
1315 (current_link_setting->link_rate)) {
1316 current_link_setting->link_rate =
1318 current_link_setting->link_rate);
1319 } else if (!reached_minimum_lane_count
1320 (current_link_setting->lane_count)) {
1321 current_link_setting->link_rate =
1322 initial_link_settings.link_rate;
1323 if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
1325 else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
1326 current_link_setting->lane_count =
1328 else if (training_result ==
1329 LINK_TRAINING_CR_FAIL_LANE23)
1330 current_link_setting->lane_count =
1333 current_link_setting->lane_count =
1335 current_link_setting->lane_count);
1341 case LINK_TRAINING_EQ_FAIL_EQ:
1343 if (!reached_minimum_lane_count
1344 (current_link_setting->lane_count)) {
1345 current_link_setting->lane_count =
1347 current_link_setting->lane_count);
1348 } else if (!reached_minimum_link_rate
1349 (current_link_setting->link_rate)) {
1350 current_link_setting->link_rate =
1352 current_link_setting->link_rate);
1358 case LINK_TRAINING_EQ_FAIL_CR:
1360 if (!reached_minimum_link_rate
1361 (current_link_setting->link_rate)) {
1362 current_link_setting->link_rate =
1364 current_link_setting->link_rate);
1376 static uint32_t bandwidth_in_kbps_from_timing(
1377 const struct dc_crtc_timing *timing)
1379 uint32_t bits_per_channel = 0;
1382 switch (timing->display_color_depth) {
1383 case COLOR_DEPTH_666:
1384 bits_per_channel = 6;
1386 case COLOR_DEPTH_888:
1387 bits_per_channel = 8;
1389 case COLOR_DEPTH_101010:
1390 bits_per_channel = 10;
1392 case COLOR_DEPTH_121212:
1393 bits_per_channel = 12;
1395 case COLOR_DEPTH_141414:
1396 bits_per_channel = 14;
1398 case COLOR_DEPTH_161616:
1399 bits_per_channel = 16;
1405 ASSERT(bits_per_channel != 0);
1407 kbps = timing->pix_clk_khz;
1408 kbps *= bits_per_channel;
1410 if (timing->flags.Y_ONLY != 1) {
1411 /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
1413 if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
1415 else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
1416 kbps = kbps * 2 / 3;
1423 static uint32_t bandwidth_in_kbps_from_link_settings(
1424 const struct dc_link_settings *link_setting)
1426 uint32_t link_rate_in_kbps = link_setting->link_rate *
1427 LINK_RATE_REF_FREQ_IN_KHZ;
1429 uint32_t lane_count = link_setting->lane_count;
1430 uint32_t kbps = link_rate_in_kbps;
1432 kbps *= 8; /* 8 bits per byte*/
1438 bool dp_validate_mode_timing(
1439 struct dc_link *link,
1440 const struct dc_crtc_timing *timing)
1445 const struct dc_link_settings *link_setting;
1447 /*always DP fail safe mode*/
1448 if (timing->pix_clk_khz == (uint32_t)25175 &&
1449 timing->h_addressable == (uint32_t)640 &&
1450 timing->v_addressable == (uint32_t)480)
1453 /* We always use verified link settings */
1454 link_setting = &link->verified_link_cap;
1456 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1457 /*if (flags.DYNAMIC_VALIDATION == 1 &&
1458 link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
1459 link_setting = &link->verified_link_cap;
1462 req_bw = bandwidth_in_kbps_from_timing(timing);
1463 max_bw = bandwidth_in_kbps_from_link_settings(link_setting);
1465 if (req_bw <= max_bw) {
1466 /* remember the biggest mode here, during
1467 * initial link training (to get
1468 * verified_link_cap), LS sends event about
1469 * cannot train at reported cap to upper
1470 * layer and upper layer will re-enumerate modes.
1471 * this is not necessary if the lower
1472 * verified_link_cap is enough to drive
1475 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1476 /* if (flags.DYNAMIC_VALIDATION == 1)
1477 dpsst->max_req_bw_for_verified_linkcap = dal_max(
1478 dpsst->max_req_bw_for_verified_linkcap, req_bw); */
1484 void decide_link_settings(struct dc_stream_state *stream,
1485 struct dc_link_settings *link_setting)
1488 struct dc_link_settings initial_link_setting = {
1489 LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED};
1490 struct dc_link_settings current_link_setting =
1491 initial_link_setting;
1492 struct dc_link *link;
1496 req_bw = bandwidth_in_kbps_from_timing(&stream->timing);
1498 link = stream->sink->link;
1500 /* if preferred is specified through AMDDP, use it, if it's enough
1503 if (link->preferred_link_setting.lane_count !=
1504 LANE_COUNT_UNKNOWN &&
1505 link->preferred_link_setting.link_rate !=
1506 LINK_RATE_UNKNOWN) {
1507 *link_setting = link->preferred_link_setting;
1511 /* MST doesn't perform link training for now
1512 * TODO: add MST specific link training routine
1514 if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
1515 *link_setting = link->verified_link_cap;
1519 /* EDP use the link cap setting */
1520 if (stream->sink->sink_signal == SIGNAL_TYPE_EDP) {
1521 *link_setting = link->verified_link_cap;
1525 /* search for the minimum link setting that:
1526 * 1. is supported according to the link training result
1527 * 2. could support the b/w requested by the timing
1529 while (current_link_setting.link_rate <=
1530 link->verified_link_cap.link_rate) {
1531 link_bw = bandwidth_in_kbps_from_link_settings(
1532 ¤t_link_setting);
1533 if (req_bw <= link_bw) {
1534 *link_setting = current_link_setting;
1538 if (current_link_setting.lane_count <
1539 link->verified_link_cap.lane_count) {
1540 current_link_setting.lane_count =
1541 increase_lane_count(
1542 current_link_setting.lane_count);
1544 current_link_setting.link_rate =
1546 current_link_setting.link_rate);
1547 current_link_setting.lane_count =
1548 initial_link_setting.lane_count;
1552 BREAK_TO_DEBUGGER();
1553 ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
1555 *link_setting = link->verified_link_cap;
1558 /*************************Short Pulse IRQ***************************/
1560 static bool hpd_rx_irq_check_link_loss_status(
1561 struct dc_link *link,
1562 union hpd_irq_data *hpd_irq_dpcd_data)
1564 uint8_t irq_reg_rx_power_state = 0;
1565 enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
1566 union lane_status lane_status;
1568 bool sink_status_changed;
1571 sink_status_changed = false;
1572 return_code = false;
1574 if (link->cur_link_settings.lane_count == 0)
1577 /*1. Check that Link Status changed, before re-training.*/
1579 /*parse lane status*/
1580 for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
1581 /* check status of lanes 0,1
1582 * changed DpcdAddress_Lane01Status (0x202)
1584 lane_status.raw = get_nibble_at_index(
1585 &hpd_irq_dpcd_data->bytes.lane01_status.raw,
1588 if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1589 !lane_status.bits.CR_DONE_0 ||
1590 !lane_status.bits.SYMBOL_LOCKED_0) {
1591 /* if one of the channel equalization, clock
1592 * recovery or symbol lock is dropped
1593 * consider it as (link has been
1594 * dropped) dp sink status has changed
1596 sink_status_changed = true;
1601 /* Check interlane align.*/
1602 if (sink_status_changed ||
1603 !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
1605 DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
1609 /*2. Check that we can handle interrupt: Not in FS DOS,
1610 * Not in "Display Timeout" state, Link is trained.
1612 dpcd_result = core_link_read_dpcd(link,
1614 &irq_reg_rx_power_state,
1615 sizeof(irq_reg_rx_power_state));
1617 if (dpcd_result != DC_OK) {
1618 DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
1621 if (irq_reg_rx_power_state != DP_SET_POWER_D0)
1622 return_code = false;
1629 static enum dc_status read_hpd_rx_irq_data(
1630 struct dc_link *link,
1631 union hpd_irq_data *irq_data)
1633 static enum dc_status retval;
1635 /* The HW reads 16 bytes from 200h on HPD,
1636 * but if we get an AUX_DEFER, the HW cannot retry
1637 * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
1638 * fail, so we now explicitly read 6 bytes which is
1639 * the req from the above mentioned test cases.
1641 * For DP 1.4 we need to read those from 2002h range.
1643 if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
1644 retval = core_link_read_dpcd(
1648 sizeof(union hpd_irq_data));
1650 /* Read 2 bytes at this location,... */
1651 retval = core_link_read_dpcd(
1657 if (retval != DC_OK)
1660 /* ... then read remaining 4 at the other location */
1661 retval = core_link_read_dpcd(
1663 DP_LANE0_1_STATUS_ESI,
1671 static bool allow_hpd_rx_irq(const struct dc_link *link)
1674 * Don't handle RX IRQ unless one of following is met:
1675 * 1) The link is established (cur_link_settings != unknown)
1676 * 2) We kicked off MST detection
1677 * 3) We know we're dealing with an active dongle
1680 if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
1681 (link->type == dc_connection_mst_branch) ||
1682 is_dp_active_dongle(link))
1688 static bool handle_hpd_irq_psr_sink(const struct dc_link *link)
1690 union dpcd_psr_configuration psr_configuration;
1692 if (!link->psr_enabled)
1695 dm_helpers_dp_read_dpcd(
1698 368,/*DpcdAddress_PSR_Enable_Cfg*/
1699 &psr_configuration.raw,
1700 sizeof(psr_configuration.raw));
1703 if (psr_configuration.bits.ENABLE) {
1704 unsigned char dpcdbuf[3] = {0};
1705 union psr_error_status psr_error_status;
1706 union psr_sink_psr_status psr_sink_psr_status;
1708 dm_helpers_dp_read_dpcd(
1711 0x2006, /*DpcdAddress_PSR_Error_Status*/
1712 (unsigned char *) dpcdbuf,
1715 /*DPCD 2006h ERROR STATUS*/
1716 psr_error_status.raw = dpcdbuf[0];
1717 /*DPCD 2008h SINK PANEL SELF REFRESH STATUS*/
1718 psr_sink_psr_status.raw = dpcdbuf[2];
1720 if (psr_error_status.bits.LINK_CRC_ERROR ||
1721 psr_error_status.bits.RFB_STORAGE_ERROR) {
1722 /* Acknowledge and clear error bits */
1723 dm_helpers_dp_write_dpcd(
1726 8198,/*DpcdAddress_PSR_Error_Status*/
1727 &psr_error_status.raw,
1728 sizeof(psr_error_status.raw));
1730 /* PSR error, disable and re-enable PSR */
1731 dc_link_set_psr_enable(link, false, true);
1732 dc_link_set_psr_enable(link, true, true);
1735 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
1736 PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
1737 /* No error is detect, PSR is active.
1738 * We should return with IRQ_HPD handled without
1739 * checking for loss of sync since PSR would have
1740 * powered down main link.
1748 static void dp_test_send_link_training(struct dc_link *link)
1750 struct dc_link_settings link_settings = {0};
1752 core_link_read_dpcd(
1755 (unsigned char *)(&link_settings.lane_count),
1757 core_link_read_dpcd(
1760 (unsigned char *)(&link_settings.link_rate),
1763 /* Set preferred link settings */
1764 link->verified_link_cap.lane_count = link_settings.lane_count;
1765 link->verified_link_cap.link_rate = link_settings.link_rate;
1767 dp_retrain_link_dp_test(link, &link_settings, false);
1770 /* TODO hbr2 compliance eye output is unstable
1771 * (toggling on and off) with debugger break
1772 * This caueses intermittent PHY automation failure
1773 * Need to look into the root cause */
1774 static uint8_t force_tps4_for_cp2520 = 1;
1776 static void dp_test_send_phy_test_pattern(struct dc_link *link)
1778 union phy_test_pattern dpcd_test_pattern;
1779 union lane_adjust dpcd_lane_adjustment[2];
1780 unsigned char dpcd_post_cursor_2_adjustment = 0;
1781 unsigned char test_80_bit_pattern[
1782 (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
1783 DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
1784 enum dp_test_pattern test_pattern;
1785 struct dc_link_training_settings link_settings;
1786 union lane_adjust dpcd_lane_adjust;
1788 struct link_training_settings link_training_settings;
1791 dpcd_test_pattern.raw = 0;
1792 memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
1793 memset(&link_settings, 0, sizeof(link_settings));
1795 /* get phy test pattern and pattern parameters from DP receiver */
1796 core_link_read_dpcd(
1798 DP_TEST_PHY_PATTERN,
1799 &dpcd_test_pattern.raw,
1800 sizeof(dpcd_test_pattern));
1801 core_link_read_dpcd(
1803 DP_ADJUST_REQUEST_LANE0_1,
1804 &dpcd_lane_adjustment[0].raw,
1805 sizeof(dpcd_lane_adjustment));
1807 /*get post cursor 2 parameters
1808 * For DP 1.1a or eariler, this DPCD register's value is 0
1809 * For DP 1.2 or later:
1810 * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
1811 * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
1813 core_link_read_dpcd(
1815 DP_ADJUST_REQUEST_POST_CURSOR2,
1816 &dpcd_post_cursor_2_adjustment,
1817 sizeof(dpcd_post_cursor_2_adjustment));
1819 /* translate request */
1820 switch (dpcd_test_pattern.bits.PATTERN) {
1821 case PHY_TEST_PATTERN_D10_2:
1822 test_pattern = DP_TEST_PATTERN_D102;
1824 case PHY_TEST_PATTERN_SYMBOL_ERROR:
1825 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
1827 case PHY_TEST_PATTERN_PRBS7:
1828 test_pattern = DP_TEST_PATTERN_PRBS7;
1830 case PHY_TEST_PATTERN_80BIT_CUSTOM:
1831 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
1833 case PHY_TEST_PATTERN_CP2520_1:
1834 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1835 test_pattern = (force_tps4_for_cp2520 == 1) ?
1836 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1837 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1839 case PHY_TEST_PATTERN_CP2520_2:
1840 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1841 test_pattern = (force_tps4_for_cp2520 == 1) ?
1842 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1843 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1845 case PHY_TEST_PATTERN_CP2520_3:
1846 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
1849 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
1853 if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM)
1854 core_link_read_dpcd(
1856 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
1857 test_80_bit_pattern,
1858 sizeof(test_80_bit_pattern));
1860 /* prepare link training settings */
1861 link_settings.link = link->cur_link_settings;
1863 for (lane = 0; lane <
1864 (unsigned int)(link->cur_link_settings.lane_count);
1866 dpcd_lane_adjust.raw =
1867 get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
1868 link_settings.lane_settings[lane].VOLTAGE_SWING =
1869 (enum dc_voltage_swing)
1870 (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
1871 link_settings.lane_settings[lane].PRE_EMPHASIS =
1872 (enum dc_pre_emphasis)
1873 (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
1874 link_settings.lane_settings[lane].POST_CURSOR2 =
1875 (enum dc_post_cursor2)
1876 ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
1879 for (i = 0; i < 4; i++)
1880 link_training_settings.lane_settings[i] =
1881 link_settings.lane_settings[i];
1882 link_training_settings.link_settings = link_settings.link;
1883 link_training_settings.allow_invalid_msa_timing_param = false;
1884 /*Usage: Measure DP physical lane signal
1885 * by DP SI test equipment automatically.
1886 * PHY test pattern request is generated by equipment via HPD interrupt.
1887 * HPD needs to be active all the time. HPD should be active
1888 * all the time. Do not touch it.
1889 * forward request to DS
1891 dc_link_dp_set_test_pattern(
1894 &link_training_settings,
1895 test_80_bit_pattern,
1896 (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
1897 DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1);
1900 static void dp_test_send_link_test_pattern(struct dc_link *link)
1902 union link_test_pattern dpcd_test_pattern;
1903 union test_misc dpcd_test_params;
1904 enum dp_test_pattern test_pattern;
1906 memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
1907 memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
1909 /* get link test pattern and pattern parameters */
1910 core_link_read_dpcd(
1913 &dpcd_test_pattern.raw,
1914 sizeof(dpcd_test_pattern));
1915 core_link_read_dpcd(
1918 &dpcd_test_params.raw,
1919 sizeof(dpcd_test_params));
1921 switch (dpcd_test_pattern.bits.PATTERN) {
1922 case LINK_TEST_PATTERN_COLOR_RAMP:
1923 test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
1925 case LINK_TEST_PATTERN_VERTICAL_BARS:
1926 test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
1927 break; /* black and white */
1928 case LINK_TEST_PATTERN_COLOR_SQUARES:
1929 test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
1930 TEST_DYN_RANGE_VESA ?
1931 DP_TEST_PATTERN_COLOR_SQUARES :
1932 DP_TEST_PATTERN_COLOR_SQUARES_CEA);
1935 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
1939 dc_link_dp_set_test_pattern(
1947 static void handle_automated_test(struct dc_link *link)
1949 union test_request test_request;
1950 union test_response test_response;
1952 memset(&test_request, 0, sizeof(test_request));
1953 memset(&test_response, 0, sizeof(test_response));
1955 core_link_read_dpcd(
1959 sizeof(union test_request));
1960 if (test_request.bits.LINK_TRAINING) {
1961 /* ACK first to let DP RX test box monitor LT sequence */
1962 test_response.bits.ACK = 1;
1963 core_link_write_dpcd(
1967 sizeof(test_response));
1968 dp_test_send_link_training(link);
1969 /* no acknowledge request is needed again */
1970 test_response.bits.ACK = 0;
1972 if (test_request.bits.LINK_TEST_PATTRN) {
1973 dp_test_send_link_test_pattern(link);
1974 test_response.bits.ACK = 1;
1976 if (test_request.bits.PHY_TEST_PATTERN) {
1977 dp_test_send_phy_test_pattern(link);
1978 test_response.bits.ACK = 1;
1980 if (!test_request.raw)
1981 /* no requests, revert all test signals
1982 * TODO: revert all test signals
1984 test_response.bits.ACK = 1;
1985 /* send request acknowledgment */
1986 if (test_response.bits.ACK)
1987 core_link_write_dpcd(
1991 sizeof(test_response));
1994 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data)
1996 union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}};
1997 union device_service_irq device_service_clear = { { 0 } };
1998 enum dc_status result = DDC_RESULT_UNKNOWN;
1999 bool status = false;
2000 /* For use cases related to down stream connection status change,
2001 * PSR and device auto test, refer to function handle_sst_hpd_irq
2004 DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
2005 __func__, link->link_index);
2008 /* All the "handle_hpd_irq_xxx()" methods
2009 * should be called only after
2010 * dal_dpsst_ls_read_hpd_irq_data
2011 * Order of calls is important too
2013 result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
2014 if (out_hpd_irq_dpcd_data)
2015 *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
2017 if (result != DC_OK) {
2018 DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
2023 if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
2024 device_service_clear.bits.AUTOMATED_TEST = 1;
2025 core_link_write_dpcd(
2027 DP_DEVICE_SERVICE_IRQ_VECTOR,
2028 &device_service_clear.raw,
2029 sizeof(device_service_clear.raw));
2030 device_service_clear.raw = 0;
2031 handle_automated_test(link);
2035 if (!allow_hpd_rx_irq(link)) {
2036 DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
2037 __func__, link->link_index);
2041 if (handle_hpd_irq_psr_sink(link))
2042 /* PSR-related error was detected and handled */
2045 /* If PSR-related error handled, Main link may be off,
2046 * so do not handle as a normal sink status change interrupt.
2049 if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
2052 /* check if we have MST msg and return since we poll for it */
2053 if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
2056 /* For now we only handle 'Downstream port status' case.
2057 * If we got sink count changed it means
2058 * Downstream port status changed,
2059 * then DM should call DC to do the detection. */
2060 if (hpd_rx_irq_check_link_loss_status(
2062 &hpd_irq_dpcd_data)) {
2063 /* Connectivity log: link loss */
2064 CONN_DATA_LINK_LOSS(link,
2065 hpd_irq_dpcd_data.raw,
2066 sizeof(hpd_irq_dpcd_data),
2069 perform_link_training_with_retries(link,
2070 &link->cur_link_settings,
2071 true, LINK_TRAINING_ATTEMPTS);
2076 if (link->type == dc_connection_active_dongle &&
2077 hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
2078 != link->dpcd_sink_count)
2081 /* reasons for HPD RX:
2082 * 1. Link Loss - ie Re-train the Link
2083 * 2. MST sideband message
2084 * 3. Automated Test - ie. Internal Commit
2085 * 4. CP (copy protection) - (not interesting for DM???)
2087 * 6. Downstream Port status changed
2088 * -ie. Detect - this the only one
2089 * which is interesting for DM because
2090 * it must call dc_link_detect.
2095 /*query dpcd for version and mst cap addresses*/
2096 bool is_mst_supported(struct dc_link *link)
2099 enum dc_status st = DC_OK;
2106 st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
2109 if (st == DC_OK && rev.raw >= DPCD_REV_12) {
2111 st = core_link_read_dpcd(link, DP_MSTM_CAP,
2112 &cap.raw, sizeof(cap));
2113 if (st == DC_OK && cap.bits.MST_CAP == 1)
2120 bool is_dp_active_dongle(const struct dc_link *link)
2122 enum display_dongle_type dongle_type = link->dpcd_caps.dongle_type;
2124 return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) ||
2125 (dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER) ||
2126 (dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER);
2129 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
2132 case DOWN_STREAM_MAX_8BPC:
2134 case DOWN_STREAM_MAX_10BPC:
2136 case DOWN_STREAM_MAX_12BPC:
2138 case DOWN_STREAM_MAX_16BPC:
2147 static void get_active_converter_info(
2148 uint8_t data, struct dc_link *link)
2150 union dp_downstream_port_present ds_port = { .byte = data };
2152 /* decode converter info*/
2153 if (!ds_port.fields.PORT_PRESENT) {
2154 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2155 ddc_service_set_dongle_type(link->ddc,
2156 link->dpcd_caps.dongle_type);
2160 switch (ds_port.fields.PORT_TYPE) {
2161 case DOWNSTREAM_VGA:
2162 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
2164 case DOWNSTREAM_DVI_HDMI:
2165 /* At this point we don't know is it DVI or HDMI,
2167 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
2170 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2174 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
2175 uint8_t det_caps[4];
2176 union dwnstream_port_caps_byte0 *port_caps =
2177 (union dwnstream_port_caps_byte0 *)det_caps;
2178 core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
2179 det_caps, sizeof(det_caps));
2181 switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
2182 case DOWN_STREAM_DETAILED_VGA:
2183 link->dpcd_caps.dongle_type =
2184 DISPLAY_DONGLE_DP_VGA_CONVERTER;
2186 case DOWN_STREAM_DETAILED_DVI:
2187 link->dpcd_caps.dongle_type =
2188 DISPLAY_DONGLE_DP_DVI_CONVERTER;
2190 case DOWN_STREAM_DETAILED_HDMI:
2191 link->dpcd_caps.dongle_type =
2192 DISPLAY_DONGLE_DP_HDMI_CONVERTER;
2194 link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
2195 if (ds_port.fields.DETAILED_CAPS) {
2197 union dwnstream_port_caps_byte3_hdmi
2198 hdmi_caps = {.raw = det_caps[3] };
2199 union dwnstream_port_caps_byte2
2200 hdmi_color_caps = {.raw = det_caps[2] };
2201 link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk =
2202 det_caps[1] * 25000;
2204 link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
2205 hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
2206 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
2207 hdmi_caps.bits.YCrCr422_PASS_THROUGH;
2208 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
2209 hdmi_caps.bits.YCrCr420_PASS_THROUGH;
2210 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
2211 hdmi_caps.bits.YCrCr422_CONVERSION;
2212 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
2213 hdmi_caps.bits.YCrCr420_CONVERSION;
2215 link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
2216 translate_dpcd_max_bpc(
2217 hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
2219 link->dpcd_caps.dongle_caps.extendedCapValid = true;
2226 ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
2229 struct dp_device_vendor_id dp_id;
2231 /* read IEEE branch device id */
2232 core_link_read_dpcd(
2238 link->dpcd_caps.branch_dev_id =
2239 (dp_id.ieee_oui[0] << 16) +
2240 (dp_id.ieee_oui[1] << 8) +
2244 link->dpcd_caps.branch_dev_name,
2245 dp_id.ieee_device_id,
2246 sizeof(dp_id.ieee_device_id));
2250 struct dp_sink_hw_fw_revision dp_hw_fw_revision;
2252 core_link_read_dpcd(
2254 DP_BRANCH_REVISION_START,
2255 (uint8_t *)&dp_hw_fw_revision,
2256 sizeof(dp_hw_fw_revision));
2258 link->dpcd_caps.branch_hw_revision =
2259 dp_hw_fw_revision.ieee_hw_rev;
2263 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
2267 union dp_downstream_port_present ds_port = { 0 };
2269 if (!link->dpcd_caps.dpcd_rev.raw) {
2271 dp_receiver_power_ctrl(link, true);
2272 core_link_read_dpcd(link, DP_DPCD_REV,
2274 link->dpcd_caps.dpcd_rev.raw = dpcd_data[
2277 } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
2280 ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2283 if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
2284 switch (link->dpcd_caps.branch_dev_id) {
2285 /* Some active dongles (DP-VGA, DP-DLDVI converters) power down
2286 * all internal circuits including AUX communication preventing
2287 * reading DPCD table and EDID (spec violation).
2288 * Encoder will skip DP RX power down on disable_output to
2289 * keep receiver powered all the time.*/
2290 case DP_BRANCH_DEVICE_ID_1:
2291 case DP_BRANCH_DEVICE_ID_4:
2292 link->wa_flags.dp_keep_receiver_powered = true;
2295 /* TODO: May need work around for other dongles. */
2297 link->wa_flags.dp_keep_receiver_powered = false;
2301 link->wa_flags.dp_keep_receiver_powered = false;
2304 static bool retrieve_link_cap(struct dc_link *link)
2306 uint8_t dpcd_data[DP_ADAPTER_CAP - DP_DPCD_REV + 1];
2308 union down_stream_port_count down_strm_port_count;
2309 union edp_configuration_cap edp_config_cap;
2310 union dp_downstream_port_present ds_port = { 0 };
2311 enum dc_status status = DC_ERROR_UNEXPECTED;
2312 uint32_t read_dpcd_retry_cnt = 3;
2315 memset(dpcd_data, '\0', sizeof(dpcd_data));
2316 memset(&down_strm_port_count,
2317 '\0', sizeof(union down_stream_port_count));
2318 memset(&edp_config_cap, '\0',
2319 sizeof(union edp_configuration_cap));
2321 for (i = 0; i < read_dpcd_retry_cnt; i++) {
2322 status = core_link_read_dpcd(
2327 if (status == DC_OK)
2331 if (status != DC_OK) {
2332 dm_error("%s: Read dpcd data failed.\n", __func__);
2337 union training_aux_rd_interval aux_rd_interval;
2339 aux_rd_interval.raw =
2340 dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
2342 if (aux_rd_interval.bits.EXT_RECIEVER_CAP_FIELD_PRESENT == 1) {
2343 core_link_read_dpcd(
2351 link->dpcd_caps.dpcd_rev.raw =
2352 dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
2354 ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2357 get_active_converter_info(ds_port.byte, link);
2359 dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
2361 link->dpcd_caps.allow_invalid_MSA_timing_param =
2362 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
2364 link->dpcd_caps.max_ln_count.raw = dpcd_data[
2365 DP_MAX_LANE_COUNT - DP_DPCD_REV];
2367 link->dpcd_caps.max_down_spread.raw = dpcd_data[
2368 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
2370 link->reported_link_cap.lane_count =
2371 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
2372 link->reported_link_cap.link_rate = dpcd_data[
2373 DP_MAX_LINK_RATE - DP_DPCD_REV];
2374 link->reported_link_cap.link_spread =
2375 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
2376 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
2378 edp_config_cap.raw = dpcd_data[
2379 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
2380 link->dpcd_caps.panel_mode_edp =
2381 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
2382 link->dpcd_caps.dpcd_display_control_capable =
2383 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
2385 link->test_pattern_enabled = false;
2386 link->compliance_test_state.raw = 0;
2388 /* read sink count */
2389 core_link_read_dpcd(link,
2391 &link->dpcd_caps.sink_count.raw,
2392 sizeof(link->dpcd_caps.sink_count.raw));
2394 /* Connectivity log: detection */
2395 CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
2400 bool detect_dp_sink_caps(struct dc_link *link)
2402 return retrieve_link_cap(link);
2404 /* dc init_hw has power encoder using default
2405 * signal for connector. For native DP, no
2406 * need to power up encoder again. If not native
2407 * DP, hw_init may need check signal or power up
2410 /* TODO save sink caps in link->sink */
2413 void detect_edp_sink_caps(struct dc_link *link)
2415 retrieve_link_cap(link);
2417 if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)
2418 link->reported_link_cap.link_rate = LINK_RATE_HIGH2;
2420 link->verified_link_cap = link->reported_link_cap;
2423 void dc_link_dp_enable_hpd(const struct dc_link *link)
2425 struct link_encoder *encoder = link->link_enc;
2427 if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
2428 encoder->funcs->enable_hpd(encoder);
2431 void dc_link_dp_disable_hpd(const struct dc_link *link)
2433 struct link_encoder *encoder = link->link_enc;
2435 if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
2436 encoder->funcs->disable_hpd(encoder);
2439 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
2441 if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
2442 test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
2443 test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
2449 static void set_crtc_test_pattern(struct dc_link *link,
2450 struct pipe_ctx *pipe_ctx,
2451 enum dp_test_pattern test_pattern)
2453 enum controller_dp_test_pattern controller_test_pattern;
2454 enum dc_color_depth color_depth = pipe_ctx->
2455 stream->timing.display_color_depth;
2456 struct bit_depth_reduction_params params;
2458 memset(¶ms, 0, sizeof(params));
2460 switch (test_pattern) {
2461 case DP_TEST_PATTERN_COLOR_SQUARES:
2462 controller_test_pattern =
2463 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
2465 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
2466 controller_test_pattern =
2467 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
2469 case DP_TEST_PATTERN_VERTICAL_BARS:
2470 controller_test_pattern =
2471 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
2473 case DP_TEST_PATTERN_HORIZONTAL_BARS:
2474 controller_test_pattern =
2475 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
2477 case DP_TEST_PATTERN_COLOR_RAMP:
2478 controller_test_pattern =
2479 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
2482 controller_test_pattern =
2483 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
2487 switch (test_pattern) {
2488 case DP_TEST_PATTERN_COLOR_SQUARES:
2489 case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
2490 case DP_TEST_PATTERN_VERTICAL_BARS:
2491 case DP_TEST_PATTERN_HORIZONTAL_BARS:
2492 case DP_TEST_PATTERN_COLOR_RAMP:
2494 /* disable bit depth reduction */
2495 pipe_ctx->stream->bit_depth_params = params;
2496 pipe_ctx->stream_res.opp->funcs->
2497 opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms);
2499 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2500 controller_test_pattern, color_depth);
2503 case DP_TEST_PATTERN_VIDEO_MODE:
2505 /* restore bitdepth reduction */
2506 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
2508 pipe_ctx->stream->bit_depth_params = params;
2509 pipe_ctx->stream_res.opp->funcs->
2510 opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, ¶ms);
2512 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2513 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
2523 bool dc_link_dp_set_test_pattern(
2524 struct dc_link *link,
2525 enum dp_test_pattern test_pattern,
2526 const struct link_training_settings *p_link_settings,
2527 const unsigned char *p_custom_pattern,
2528 unsigned int cust_pattern_size)
2530 struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
2531 struct pipe_ctx *pipe_ctx = &pipes[0];
2534 unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
2535 union dpcd_training_pattern training_pattern;
2536 enum dpcd_phy_test_patterns pattern;
2538 memset(&training_pattern, 0, sizeof(training_pattern));
2540 for (i = 0; i < MAX_PIPES; i++) {
2541 if (pipes[i].stream->sink->link == link) {
2542 pipe_ctx = &pipes[i];
2547 /* Reset CRTC Test Pattern if it is currently running and request
2548 * is VideoMode Reset DP Phy Test Pattern if it is currently running
2549 * and request is VideoMode
2551 if (link->test_pattern_enabled && test_pattern ==
2552 DP_TEST_PATTERN_VIDEO_MODE) {
2553 /* Set CRTC Test Pattern */
2554 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
2555 dp_set_hw_test_pattern(link, test_pattern,
2556 (uint8_t *)p_custom_pattern,
2557 (uint32_t)cust_pattern_size);
2559 /* Unblank Stream */
2560 link->dc->hwss.unblank_stream(
2562 &link->verified_link_cap);
2563 /* TODO:m_pHwss->MuteAudioEndpoint
2564 * (pPathMode->pDisplayPath, false);
2567 /* Reset Test Pattern state */
2568 link->test_pattern_enabled = false;
2573 /* Check for PHY Test Patterns */
2574 if (is_dp_phy_pattern(test_pattern)) {
2575 /* Set DPCD Lane Settings before running test pattern */
2576 if (p_link_settings != NULL) {
2577 dp_set_hw_lane_settings(link, p_link_settings);
2578 dpcd_set_lane_settings(link, p_link_settings);
2581 /* Blank stream if running test pattern */
2582 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
2585 * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
2588 pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
2591 dp_set_hw_test_pattern(link, test_pattern,
2592 (uint8_t *)p_custom_pattern,
2593 (uint32_t)cust_pattern_size);
2595 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
2596 /* Set Test Pattern state */
2597 link->test_pattern_enabled = true;
2598 if (p_link_settings != NULL)
2599 dpcd_set_link_settings(link,
2603 switch (test_pattern) {
2604 case DP_TEST_PATTERN_VIDEO_MODE:
2605 pattern = PHY_TEST_PATTERN_NONE;
2607 case DP_TEST_PATTERN_D102:
2608 pattern = PHY_TEST_PATTERN_D10_2;
2610 case DP_TEST_PATTERN_SYMBOL_ERROR:
2611 pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
2613 case DP_TEST_PATTERN_PRBS7:
2614 pattern = PHY_TEST_PATTERN_PRBS7;
2616 case DP_TEST_PATTERN_80BIT_CUSTOM:
2617 pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
2619 case DP_TEST_PATTERN_CP2520_1:
2620 pattern = PHY_TEST_PATTERN_CP2520_1;
2622 case DP_TEST_PATTERN_CP2520_2:
2623 pattern = PHY_TEST_PATTERN_CP2520_2;
2625 case DP_TEST_PATTERN_CP2520_3:
2626 pattern = PHY_TEST_PATTERN_CP2520_3;
2632 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
2633 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
2636 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
2637 /* tell receiver that we are sending qualification
2638 * pattern DP 1.2 or later - DP receiver's link quality
2639 * pattern is set using DPCD LINK_QUAL_LANEx_SET
2640 * register (0x10B~0x10E)\
2642 for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
2643 link_qual_pattern[lane] =
2644 (unsigned char)(pattern);
2646 core_link_write_dpcd(link,
2647 DP_LINK_QUAL_LANE0_SET,
2649 sizeof(link_qual_pattern));
2650 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
2651 link->dpcd_caps.dpcd_rev.raw == 0) {
2652 /* tell receiver that we are sending qualification
2653 * pattern DP 1.1a or earlier - DP receiver's link
2654 * quality pattern is set using
2655 * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
2656 * register (0x102). We will use v_1.3 when we are
2657 * setting test pattern for DP 1.1.
2659 core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
2660 &training_pattern.raw,
2661 sizeof(training_pattern));
2662 training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
2663 core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
2664 &training_pattern.raw,
2665 sizeof(training_pattern));
2669 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
2670 /* Set Test Pattern state */
2671 link->test_pattern_enabled = true;
2677 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
2679 unsigned char mstmCntl;
2681 core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
2683 mstmCntl |= DP_MST_EN;
2685 mstmCntl &= (~DP_MST_EN);
2687 core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);