ced42484dcfc7a45e51aec5ff1c69e823fe78ae9
[platform/kernel/linux-starfive.git] / drivers / gpu / drm / amd / display / dc / core / dc_link_dp.c
1 /* Copyright 2015 Advanced Micro Devices, Inc. */
2 #include "dm_services.h"
3 #include "dc.h"
4 #include "dc_link_dp.h"
5 #include "dm_helpers.h"
6
7 #include "inc/core_types.h"
8 #include "link_hwss.h"
9 #include "dc_link_ddc.h"
10 #include "core_status.h"
11 #include "dpcd_defs.h"
12
13 #include "resource.h"
14
15 /* maximum pre emphasis level allowed for each voltage swing level*/
16 static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = {
17                 PRE_EMPHASIS_LEVEL3,
18                 PRE_EMPHASIS_LEVEL2,
19                 PRE_EMPHASIS_LEVEL1,
20                 PRE_EMPHASIS_DISABLED };
21
22 enum {
23         POST_LT_ADJ_REQ_LIMIT = 6,
24         POST_LT_ADJ_REQ_TIMEOUT = 200
25 };
26
27 enum {
28         LINK_TRAINING_MAX_RETRY_COUNT = 5,
29         /* to avoid infinite loop where-in the receiver
30          * switches between different VS
31          */
32         LINK_TRAINING_MAX_CR_RETRY = 100
33 };
34
35 static bool decide_fallback_link_setting(
36                 struct dc_link_settings initial_link_settings,
37                 struct dc_link_settings *current_link_setting,
38                 enum link_training_result training_result);
39 static struct dc_link_settings get_common_supported_link_settings (
40                 struct dc_link_settings link_setting_a,
41                 struct dc_link_settings link_setting_b);
42
43 static void wait_for_training_aux_rd_interval(
44         struct dc_link *link,
45         uint32_t default_wait_in_micro_secs)
46 {
47         union training_aux_rd_interval training_rd_interval;
48
49         /* overwrite the delay if rev > 1.1*/
50         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
51                 /* DP 1.2 or later - retrieve delay through
52                  * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
53                 core_link_read_dpcd(
54                         link,
55                         DP_TRAINING_AUX_RD_INTERVAL,
56                         (uint8_t *)&training_rd_interval,
57                         sizeof(training_rd_interval));
58
59                 if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
60                         default_wait_in_micro_secs =
61                                 training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
62         }
63
64         udelay(default_wait_in_micro_secs);
65
66         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
67                 "%s:\n wait = %d\n",
68                 __func__,
69                 default_wait_in_micro_secs);
70 }
71
72 static void dpcd_set_training_pattern(
73         struct dc_link *link,
74         union dpcd_training_pattern dpcd_pattern)
75 {
76         core_link_write_dpcd(
77                 link,
78                 DP_TRAINING_PATTERN_SET,
79                 &dpcd_pattern.raw,
80                 1);
81
82         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
83                 "%s\n %x pattern = %x\n",
84                 __func__,
85                 DP_TRAINING_PATTERN_SET,
86                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
87 }
88
89 static void dpcd_set_link_settings(
90         struct dc_link *link,
91         const struct link_training_settings *lt_settings)
92 {
93         uint8_t rate = (uint8_t)
94         (lt_settings->link_settings.link_rate);
95
96         union down_spread_ctrl downspread = {{0}};
97         union lane_count_set lane_count_set = {{0}};
98         uint8_t link_set_buffer[2];
99
100         downspread.raw = (uint8_t)
101         (lt_settings->link_settings.link_spread);
102
103         lane_count_set.bits.LANE_COUNT_SET =
104         lt_settings->link_settings.lane_count;
105
106         lane_count_set.bits.ENHANCED_FRAMING = 1;
107
108         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
109                 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
110
111         link_set_buffer[0] = rate;
112         link_set_buffer[1] = lane_count_set.raw;
113
114         core_link_write_dpcd(link, DP_LINK_BW_SET,
115         link_set_buffer, 2);
116         core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
117         &downspread.raw, sizeof(downspread));
118
119         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
120                 "%s\n %x rate = %x\n %x lane = %x\n %x spread = %x\n",
121                 __func__,
122                 DP_LINK_BW_SET,
123                 lt_settings->link_settings.link_rate,
124                 DP_LANE_COUNT_SET,
125                 lt_settings->link_settings.lane_count,
126                 DP_DOWNSPREAD_CTRL,
127                 lt_settings->link_settings.link_spread);
128
129 }
130
131 static enum dpcd_training_patterns
132         hw_training_pattern_to_dpcd_training_pattern(
133         struct dc_link *link,
134         enum hw_dp_training_pattern pattern)
135 {
136         enum dpcd_training_patterns dpcd_tr_pattern =
137         DPCD_TRAINING_PATTERN_VIDEOIDLE;
138
139         switch (pattern) {
140         case HW_DP_TRAINING_PATTERN_1:
141                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
142                 break;
143         case HW_DP_TRAINING_PATTERN_2:
144                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
145                 break;
146         case HW_DP_TRAINING_PATTERN_3:
147                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
148                 break;
149         case HW_DP_TRAINING_PATTERN_4:
150                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
151                 break;
152         default:
153                 ASSERT(0);
154                 dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
155                         "%s: Invalid HW Training pattern: %d\n",
156                         __func__, pattern);
157                 break;
158         }
159
160         return dpcd_tr_pattern;
161
162 }
163
164 static void dpcd_set_lt_pattern_and_lane_settings(
165         struct dc_link *link,
166         const struct link_training_settings *lt_settings,
167         enum hw_dp_training_pattern pattern)
168 {
169         union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
170         const uint32_t dpcd_base_lt_offset =
171         DP_TRAINING_PATTERN_SET;
172         uint8_t dpcd_lt_buffer[5] = {0};
173         union dpcd_training_pattern dpcd_pattern = {{0}};
174         uint32_t lane;
175         uint32_t size_in_bytes;
176         bool edp_workaround = false; /* TODO link_prop.INTERNAL */
177
178         /*****************************************************************
179         * DpcdAddress_TrainingPatternSet
180         *****************************************************************/
181         dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
182                 hw_training_pattern_to_dpcd_training_pattern(link, pattern);
183
184         dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - dpcd_base_lt_offset]
185                 = dpcd_pattern.raw;
186
187         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
188                 "%s\n %x pattern = %x\n",
189                 __func__,
190                 DP_TRAINING_PATTERN_SET,
191                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
192
193         /*****************************************************************
194         * DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set
195         *****************************************************************/
196         for (lane = 0; lane <
197                 (uint32_t)(lt_settings->link_settings.lane_count); lane++) {
198
199                 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
200                 (uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING);
201                 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
202                 (uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS);
203
204                 dpcd_lane[lane].bits.MAX_SWING_REACHED =
205                 (lt_settings->lane_settings[lane].VOLTAGE_SWING ==
206                 VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
207                 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
208                 (lt_settings->lane_settings[lane].PRE_EMPHASIS ==
209                 PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
210         }
211
212         /* concatinate everything into one buffer*/
213
214         size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
215
216          // 0x00103 - 0x00102
217         memmove(
218                 &dpcd_lt_buffer[DP_TRAINING_LANE0_SET - dpcd_base_lt_offset],
219                 dpcd_lane,
220                 size_in_bytes);
221
222         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
223                 "%s:\n %x VS set = %x  PE set = %x \
224                 max VS Reached = %x  max PE Reached = %x\n",
225                 __func__,
226                 DP_TRAINING_LANE0_SET,
227                 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
228                 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
229                 dpcd_lane[0].bits.MAX_SWING_REACHED,
230                 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
231
232         if (edp_workaround) {
233                 /* for eDP write in 2 parts because the 5-byte burst is
234                 * causing issues on some eDP panels (EPR#366724)
235                 */
236                 core_link_write_dpcd(
237                         link,
238                         DP_TRAINING_PATTERN_SET,
239                         &dpcd_pattern.raw,
240                         sizeof(dpcd_pattern.raw) );
241
242                 core_link_write_dpcd(
243                         link,
244                         DP_TRAINING_LANE0_SET,
245                         (uint8_t *)(dpcd_lane),
246                         size_in_bytes);
247
248                 } else
249                 /* write it all in (1 + number-of-lanes)-byte burst*/
250                         core_link_write_dpcd(
251                                 link,
252                                 dpcd_base_lt_offset,
253                                 dpcd_lt_buffer,
254                                 size_in_bytes + sizeof(dpcd_pattern.raw) );
255
256         link->cur_lane_setting = lt_settings->lane_settings[0];
257 }
258
259 static bool is_cr_done(enum dc_lane_count ln_count,
260         union lane_status *dpcd_lane_status)
261 {
262         bool done = true;
263         uint32_t lane;
264         /*LANEx_CR_DONE bits All 1's?*/
265         for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
266                 if (!dpcd_lane_status[lane].bits.CR_DONE_0)
267                         done = false;
268         }
269         return done;
270
271 }
272
273 static bool is_ch_eq_done(enum dc_lane_count ln_count,
274         union lane_status *dpcd_lane_status,
275         union lane_align_status_updated *lane_status_updated)
276 {
277         bool done = true;
278         uint32_t lane;
279         if (!lane_status_updated->bits.INTERLANE_ALIGN_DONE)
280                 done = false;
281         else {
282                 for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
283                         if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0 ||
284                                 !dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
285                                 done = false;
286                 }
287         }
288         return done;
289
290 }
291
292 static void update_drive_settings(
293                 struct link_training_settings *dest,
294                 struct link_training_settings src)
295 {
296         uint32_t lane;
297         for (lane = 0; lane < src.link_settings.lane_count; lane++) {
298                 dest->lane_settings[lane].VOLTAGE_SWING =
299                         src.lane_settings[lane].VOLTAGE_SWING;
300                 dest->lane_settings[lane].PRE_EMPHASIS =
301                         src.lane_settings[lane].PRE_EMPHASIS;
302                 dest->lane_settings[lane].POST_CURSOR2 =
303                         src.lane_settings[lane].POST_CURSOR2;
304         }
305 }
306
307 static uint8_t get_nibble_at_index(const uint8_t *buf,
308         uint32_t index)
309 {
310         uint8_t nibble;
311         nibble = buf[index / 2];
312
313         if (index % 2)
314                 nibble >>= 4;
315         else
316                 nibble &= 0x0F;
317
318         return nibble;
319 }
320
321 static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
322         enum dc_voltage_swing voltage)
323 {
324         enum dc_pre_emphasis pre_emphasis;
325         pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
326
327         if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
328                 pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
329
330         return pre_emphasis;
331
332 }
333
334 static void find_max_drive_settings(
335         const struct link_training_settings *link_training_setting,
336         struct link_training_settings *max_lt_setting)
337 {
338         uint32_t lane;
339         struct dc_lane_settings max_requested;
340
341         max_requested.VOLTAGE_SWING =
342                 link_training_setting->
343                 lane_settings[0].VOLTAGE_SWING;
344         max_requested.PRE_EMPHASIS =
345                 link_training_setting->
346                 lane_settings[0].PRE_EMPHASIS;
347         /*max_requested.postCursor2 =
348          * link_training_setting->laneSettings[0].postCursor2;*/
349
350         /* Determine what the maximum of the requested settings are*/
351         for (lane = 1; lane < link_training_setting->link_settings.lane_count;
352                         lane++) {
353                 if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
354                         max_requested.VOLTAGE_SWING)
355
356                         max_requested.VOLTAGE_SWING =
357                         link_training_setting->
358                         lane_settings[lane].VOLTAGE_SWING;
359
360                 if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
361                                 max_requested.PRE_EMPHASIS)
362                         max_requested.PRE_EMPHASIS =
363                         link_training_setting->
364                         lane_settings[lane].PRE_EMPHASIS;
365
366                 /*
367                 if (link_training_setting->laneSettings[lane].postCursor2 >
368                  max_requested.postCursor2)
369                 {
370                 max_requested.postCursor2 =
371                 link_training_setting->laneSettings[lane].postCursor2;
372                 }
373                 */
374         }
375
376         /* make sure the requested settings are
377          * not higher than maximum settings*/
378         if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
379                 max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
380
381         if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
382                 max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
383         /*
384         if (max_requested.postCursor2 > PostCursor2_MaxLevel)
385         max_requested.postCursor2 = PostCursor2_MaxLevel;
386         */
387
388         /* make sure the pre-emphasis matches the voltage swing*/
389         if (max_requested.PRE_EMPHASIS >
390                 get_max_pre_emphasis_for_voltage_swing(
391                         max_requested.VOLTAGE_SWING))
392                 max_requested.PRE_EMPHASIS =
393                 get_max_pre_emphasis_for_voltage_swing(
394                         max_requested.VOLTAGE_SWING);
395
396         /*
397          * Post Cursor2 levels are completely independent from
398          * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
399          * can only be applied to each allowable combination of voltage
400          * swing and pre-emphasis levels */
401          /* if ( max_requested.postCursor2 >
402           *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
403           *  max_requested.postCursor2 =
404           *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
405           */
406
407         max_lt_setting->link_settings.link_rate =
408                 link_training_setting->link_settings.link_rate;
409         max_lt_setting->link_settings.lane_count =
410         link_training_setting->link_settings.lane_count;
411         max_lt_setting->link_settings.link_spread =
412                 link_training_setting->link_settings.link_spread;
413
414         for (lane = 0; lane <
415                 link_training_setting->link_settings.lane_count;
416                 lane++) {
417                 max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
418                         max_requested.VOLTAGE_SWING;
419                 max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
420                         max_requested.PRE_EMPHASIS;
421                 /*max_lt_setting->laneSettings[lane].postCursor2 =
422                  * max_requested.postCursor2;
423                  */
424         }
425
426 }
427
428 static void get_lane_status_and_drive_settings(
429         struct dc_link *link,
430         const struct link_training_settings *link_training_setting,
431         union lane_status *ln_status,
432         union lane_align_status_updated *ln_status_updated,
433         struct link_training_settings *req_settings)
434 {
435         uint8_t dpcd_buf[6] = {0};
436         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {{{0}}};
437         struct link_training_settings request_settings = {{0}};
438         uint32_t lane;
439
440         memset(req_settings, '\0', sizeof(struct link_training_settings));
441
442         core_link_read_dpcd(
443                 link,
444                 DP_LANE0_1_STATUS,
445                 (uint8_t *)(dpcd_buf),
446                 sizeof(dpcd_buf));
447
448         for (lane = 0; lane <
449                 (uint32_t)(link_training_setting->link_settings.lane_count);
450                 lane++) {
451
452                 ln_status[lane].raw =
453                         get_nibble_at_index(&dpcd_buf[0], lane);
454                 dpcd_lane_adjust[lane].raw =
455                         get_nibble_at_index(&dpcd_buf[4], lane);
456         }
457
458         ln_status_updated->raw = dpcd_buf[2];
459
460         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
461                 "%s:\n%x Lane01Status = %x\n %x Lane23Status = %x\n ",
462                 __func__,
463                 DP_LANE0_1_STATUS, dpcd_buf[0],
464                 DP_LANE2_3_STATUS, dpcd_buf[1]);
465
466         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
467                 "%s:\n %x Lane01AdjustRequest = %x\n %x Lane23AdjustRequest = %x\n",
468                 __func__,
469                 DP_ADJUST_REQUEST_LANE0_1,
470                 dpcd_buf[4],
471                 DP_ADJUST_REQUEST_LANE2_3,
472                 dpcd_buf[5]);
473
474         /*copy to req_settings*/
475         request_settings.link_settings.lane_count =
476                 link_training_setting->link_settings.lane_count;
477         request_settings.link_settings.link_rate =
478                 link_training_setting->link_settings.link_rate;
479         request_settings.link_settings.link_spread =
480                 link_training_setting->link_settings.link_spread;
481
482         for (lane = 0; lane <
483                 (uint32_t)(link_training_setting->link_settings.lane_count);
484                 lane++) {
485
486                 request_settings.lane_settings[lane].VOLTAGE_SWING =
487                         (enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
488                                 VOLTAGE_SWING_LANE);
489                 request_settings.lane_settings[lane].PRE_EMPHASIS =
490                         (enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
491                                 PRE_EMPHASIS_LANE);
492         }
493
494         /*Note: for postcursor2, read adjusted
495          * postcursor2 settings from*/
496         /*DpcdAddress_AdjustRequestPostCursor2 =
497          *0x020C (not implemented yet)*/
498
499         /* we find the maximum of the requested settings across all lanes*/
500         /* and set this maximum for all lanes*/
501         find_max_drive_settings(&request_settings, req_settings);
502
503         /* if post cursor 2 is needed in the future,
504          * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
505          */
506
507 }
508
509 static void dpcd_set_lane_settings(
510         struct dc_link *link,
511         const struct link_training_settings *link_training_setting)
512 {
513         union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
514         uint32_t lane;
515
516         for (lane = 0; lane <
517                 (uint32_t)(link_training_setting->
518                 link_settings.lane_count);
519                 lane++) {
520                 dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
521                         (uint8_t)(link_training_setting->
522                         lane_settings[lane].VOLTAGE_SWING);
523                 dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
524                         (uint8_t)(link_training_setting->
525                         lane_settings[lane].PRE_EMPHASIS);
526                 dpcd_lane[lane].bits.MAX_SWING_REACHED =
527                         (link_training_setting->
528                         lane_settings[lane].VOLTAGE_SWING ==
529                         VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
530                 dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
531                         (link_training_setting->
532                         lane_settings[lane].PRE_EMPHASIS ==
533                         PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
534         }
535
536         core_link_write_dpcd(link,
537                 DP_TRAINING_LANE0_SET,
538                 (uint8_t *)(dpcd_lane),
539                 link_training_setting->link_settings.lane_count);
540
541         /*
542         if (LTSettings.link.rate == LinkRate_High2)
543         {
544                 DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
545                 for ( uint32_t lane = 0;
546                 lane < lane_count_DPMax; lane++)
547                 {
548                         dpcd_lane2[lane].bits.post_cursor2_set =
549                         static_cast<unsigned char>(
550                         LTSettings.laneSettings[lane].postCursor2);
551                         dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
552                 }
553                 m_pDpcdAccessSrv->WriteDpcdData(
554                 DpcdAddress_Lane0Set2,
555                 reinterpret_cast<unsigned char*>(dpcd_lane2),
556                 LTSettings.link.lanes);
557         }
558         */
559
560         dm_logger_write(link->ctx->logger, LOG_HW_LINK_TRAINING,
561                 "%s\n %x VS set = %x  PE set = %x \
562                 max VS Reached = %x  max PE Reached = %x\n",
563                 __func__,
564                 DP_TRAINING_LANE0_SET,
565                 dpcd_lane[0].bits.VOLTAGE_SWING_SET,
566                 dpcd_lane[0].bits.PRE_EMPHASIS_SET,
567                 dpcd_lane[0].bits.MAX_SWING_REACHED,
568                 dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
569
570         link->cur_lane_setting = link_training_setting->lane_settings[0];
571
572 }
573
574 static bool is_max_vs_reached(
575         const struct link_training_settings *lt_settings)
576 {
577         uint32_t lane;
578         for (lane = 0; lane <
579                 (uint32_t)(lt_settings->link_settings.lane_count);
580                 lane++) {
581                 if (lt_settings->lane_settings[lane].VOLTAGE_SWING
582                         == VOLTAGE_SWING_MAX_LEVEL)
583                         return true;
584         }
585         return false;
586
587 }
588
589 void dc_link_dp_set_drive_settings(
590         struct dc_link *link,
591         struct link_training_settings *lt_settings)
592 {
593         /* program ASIC PHY settings*/
594         dp_set_hw_lane_settings(link, lt_settings);
595
596         /* Notify DP sink the PHY settings from source */
597         dpcd_set_lane_settings(link, lt_settings);
598 }
599
600 static bool perform_post_lt_adj_req_sequence(
601         struct dc_link *link,
602         struct link_training_settings *lt_settings)
603 {
604         enum dc_lane_count lane_count =
605         lt_settings->link_settings.lane_count;
606
607         uint32_t adj_req_count;
608         uint32_t adj_req_timer;
609         bool req_drv_setting_changed;
610         uint32_t lane;
611
612         req_drv_setting_changed = false;
613         for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
614         adj_req_count++) {
615
616                 req_drv_setting_changed = false;
617
618                 for (adj_req_timer = 0;
619                         adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
620                         adj_req_timer++) {
621
622                         struct link_training_settings req_settings;
623                         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
624                         union lane_align_status_updated
625                                 dpcd_lane_status_updated;
626
627                         get_lane_status_and_drive_settings(
628                         link,
629                         lt_settings,
630                         dpcd_lane_status,
631                         &dpcd_lane_status_updated,
632                         &req_settings);
633
634                         if (dpcd_lane_status_updated.bits.
635                                         POST_LT_ADJ_REQ_IN_PROGRESS == 0)
636                                 return true;
637
638                         if (!is_cr_done(lane_count, dpcd_lane_status))
639                                 return false;
640
641                         if (!is_ch_eq_done(
642                                 lane_count,
643                                 dpcd_lane_status,
644                                 &dpcd_lane_status_updated))
645                                 return false;
646
647                         for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
648
649                                 if (lt_settings->
650                                 lane_settings[lane].VOLTAGE_SWING !=
651                                 req_settings.lane_settings[lane].
652                                 VOLTAGE_SWING ||
653                                 lt_settings->lane_settings[lane].PRE_EMPHASIS !=
654                                 req_settings.lane_settings[lane].PRE_EMPHASIS) {
655
656                                         req_drv_setting_changed = true;
657                                         break;
658                                 }
659                         }
660
661                         if (req_drv_setting_changed) {
662                                 update_drive_settings(
663                                         lt_settings,req_settings);
664
665                                 dc_link_dp_set_drive_settings(link,
666                                                 lt_settings);
667                                 break;
668                         }
669
670                         msleep(1);
671                 }
672
673                 if (!req_drv_setting_changed) {
674                         dm_logger_write(link->ctx->logger, LOG_WARNING,
675                                 "%s: Post Link Training Adjust Request Timed out\n",
676                                 __func__);
677
678                         ASSERT(0);
679                         return true;
680                 }
681         }
682         dm_logger_write(link->ctx->logger, LOG_WARNING,
683                 "%s: Post Link Training Adjust Request limit reached\n",
684                 __func__);
685
686         ASSERT(0);
687         return true;
688
689 }
690
691 static enum hw_dp_training_pattern get_supported_tp(struct dc_link *link)
692 {
693         enum hw_dp_training_pattern highest_tp = HW_DP_TRAINING_PATTERN_2;
694         struct encoder_feature_support *features = &link->link_enc->features;
695         struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
696
697         if (features->flags.bits.IS_TPS3_CAPABLE)
698                 highest_tp = HW_DP_TRAINING_PATTERN_3;
699
700         if (features->flags.bits.IS_TPS4_CAPABLE)
701                 highest_tp = HW_DP_TRAINING_PATTERN_4;
702
703         if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
704                 highest_tp >= HW_DP_TRAINING_PATTERN_4)
705                 return HW_DP_TRAINING_PATTERN_4;
706
707         if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
708                 highest_tp >= HW_DP_TRAINING_PATTERN_3)
709                 return HW_DP_TRAINING_PATTERN_3;
710
711         return HW_DP_TRAINING_PATTERN_2;
712 }
713
714 static enum link_training_result perform_channel_equalization_sequence(
715         struct dc_link *link,
716         struct link_training_settings *lt_settings)
717 {
718         struct link_training_settings req_settings;
719         enum hw_dp_training_pattern hw_tr_pattern;
720         uint32_t retries_ch_eq;
721         enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
722         union lane_align_status_updated dpcd_lane_status_updated = {{0}};
723         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {{{0}}};;
724
725         hw_tr_pattern = get_supported_tp(link);
726
727         dp_set_hw_training_pattern(link, hw_tr_pattern);
728
729         for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
730                 retries_ch_eq++) {
731
732                 dp_set_hw_lane_settings(link, lt_settings);
733
734                 /* 2. update DPCD*/
735                 if (!retries_ch_eq)
736                         /* EPR #361076 - write as a 5-byte burst,
737                          * but only for the 1-st iteration*/
738                         dpcd_set_lt_pattern_and_lane_settings(
739                                 link,
740                                 lt_settings,
741                                 hw_tr_pattern);
742                 else
743                         dpcd_set_lane_settings(link, lt_settings);
744
745                 /* 3. wait for receiver to lock-on*/
746                 wait_for_training_aux_rd_interval(link, 400);
747
748                 /* 4. Read lane status and requested
749                  * drive settings as set by the sink*/
750
751                 get_lane_status_and_drive_settings(
752                         link,
753                         lt_settings,
754                         dpcd_lane_status,
755                         &dpcd_lane_status_updated,
756                         &req_settings);
757
758                 /* 5. check CR done*/
759                 if (!is_cr_done(lane_count, dpcd_lane_status))
760                         return LINK_TRAINING_EQ_FAIL_CR;
761
762                 /* 6. check CHEQ done*/
763                 if (is_ch_eq_done(lane_count,
764                         dpcd_lane_status,
765                         &dpcd_lane_status_updated))
766                         return LINK_TRAINING_SUCCESS;
767
768                 /* 7. update VS/PE/PC2 in lt_settings*/
769                 update_drive_settings(lt_settings, req_settings);
770         }
771
772         return LINK_TRAINING_EQ_FAIL_EQ;
773
774 }
775
776 static bool perform_clock_recovery_sequence(
777         struct dc_link *link,
778         struct link_training_settings *lt_settings)
779 {
780         uint32_t retries_cr;
781         uint32_t retry_count;
782         uint32_t lane;
783         struct link_training_settings req_settings;
784         enum dc_lane_count lane_count =
785         lt_settings->link_settings.lane_count;
786         enum hw_dp_training_pattern hw_tr_pattern = HW_DP_TRAINING_PATTERN_1;
787         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
788         union lane_align_status_updated dpcd_lane_status_updated;
789
790         retries_cr = 0;
791         retry_count = 0;
792         /* initial drive setting (VS/PE/PC2)*/
793         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
794                 lt_settings->lane_settings[lane].VOLTAGE_SWING =
795                 VOLTAGE_SWING_LEVEL0;
796                 lt_settings->lane_settings[lane].PRE_EMPHASIS =
797                 PRE_EMPHASIS_DISABLED;
798                 lt_settings->lane_settings[lane].POST_CURSOR2 =
799                 POST_CURSOR2_DISABLED;
800         }
801
802         dp_set_hw_training_pattern(link, hw_tr_pattern);
803
804         /* najeeb - The synaptics MST hub can put the LT in
805         * infinite loop by switching the VS
806         */
807         /* between level 0 and level 1 continuously, here
808         * we try for CR lock for LinkTrainingMaxCRRetry count*/
809         while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
810         (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
811
812                 memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
813                 memset(&dpcd_lane_status_updated, '\0',
814                 sizeof(dpcd_lane_status_updated));
815
816                 /* 1. call HWSS to set lane settings*/
817                 dp_set_hw_lane_settings(
818                                 link,
819                                 lt_settings);
820
821                 /* 2. update DPCD of the receiver*/
822                 if (!retries_cr)
823                         /* EPR #361076 - write as a 5-byte burst,
824                          * but only for the 1-st iteration.*/
825                         dpcd_set_lt_pattern_and_lane_settings(
826                                         link,
827                                         lt_settings,
828                                         hw_tr_pattern);
829                 else
830                         dpcd_set_lane_settings(
831                                         link,
832                                         lt_settings);
833
834                 /* 3. wait receiver to lock-on*/
835                 wait_for_training_aux_rd_interval(
836                                 link,
837                                 100);
838
839                 /* 4. Read lane status and requested drive
840                 * settings as set by the sink
841                 */
842                 get_lane_status_and_drive_settings(
843                                 link,
844                                 lt_settings,
845                                 dpcd_lane_status,
846                                 &dpcd_lane_status_updated,
847                                 &req_settings);
848
849                 /* 5. check CR done*/
850                 if (is_cr_done(lane_count, dpcd_lane_status))
851                         return true;
852
853                 /* 6. max VS reached*/
854                 if (is_max_vs_reached(lt_settings))
855                         return false;
856
857                 /* 7. same voltage*/
858                 /* Note: VS same for all lanes,
859                 * so comparing first lane is sufficient*/
860                 if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
861                         req_settings.lane_settings[0].VOLTAGE_SWING)
862                         retries_cr++;
863                 else
864                         retries_cr = 0;
865
866                 /* 8. update VS/PE/PC2 in lt_settings*/
867                 update_drive_settings(lt_settings, req_settings);
868
869                 retry_count++;
870         }
871
872         if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
873                 ASSERT(0);
874                 dm_logger_write(link->ctx->logger, LOG_ERROR,
875                         "%s: Link Training Error, could not \
876                          get CR after %d tries. \
877                         Possibly voltage swing issue", __func__,
878                         LINK_TRAINING_MAX_CR_RETRY);
879
880         }
881
882         return false;
883 }
884
885 static inline bool perform_link_training_int(
886         struct dc_link *link,
887         struct link_training_settings *lt_settings,
888         bool status)
889 {
890         union lane_count_set lane_count_set = { {0} };
891         union dpcd_training_pattern dpcd_pattern = { {0} };
892
893         /* 3. set training not in progress*/
894         dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
895         dpcd_set_training_pattern(link, dpcd_pattern);
896
897         /* 4. mainlink output idle pattern*/
898         dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
899
900         /*
901          * 5. post training adjust if required
902          * If the upstream DPTX and downstream DPRX both support TPS4,
903          * TPS4 must be used instead of POST_LT_ADJ_REQ.
904          */
905         if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
906                         get_supported_tp(link) == HW_DP_TRAINING_PATTERN_4)
907                 return status;
908
909         if (status &&
910                 perform_post_lt_adj_req_sequence(link, lt_settings) == false)
911                 status = false;
912
913         lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
914         lane_count_set.bits.ENHANCED_FRAMING = 1;
915         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
916
917         core_link_write_dpcd(
918                 link,
919                 DP_LANE_COUNT_SET,
920                 &lane_count_set.raw,
921                 sizeof(lane_count_set));
922
923         return status;
924 }
925
926 enum link_training_result dc_link_dp_perform_link_training(
927         struct dc_link *link,
928         const struct dc_link_settings *link_setting,
929         bool skip_video_pattern)
930 {
931         enum link_training_result status = LINK_TRAINING_SUCCESS;
932
933         char *link_rate = "Unknown";
934         struct link_training_settings lt_settings;
935
936         memset(&lt_settings, '\0', sizeof(lt_settings));
937
938         lt_settings.link_settings.link_rate = link_setting->link_rate;
939         lt_settings.link_settings.lane_count = link_setting->lane_count;
940
941         /*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
942
943         /* TODO hard coded to SS for now
944          * lt_settings.link_settings.link_spread =
945          * dal_display_path_is_ss_supported(
946          * path_mode->display_path) ?
947          * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
948          * LINK_SPREAD_DISABLED;
949          */
950         lt_settings.link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
951
952         /* 1. set link rate, lane count and spread*/
953         dpcd_set_link_settings(link, &lt_settings);
954
955         /* 2. perform link training (set link training done
956          *  to false is done as well)*/
957         if (!perform_clock_recovery_sequence(link, &lt_settings)) {
958                 status = LINK_TRAINING_CR_FAIL;
959         } else {
960                 status = perform_channel_equalization_sequence(link,
961                                 &lt_settings);
962         }
963
964         if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
965                 if (!perform_link_training_int(link,
966                                 &lt_settings,
967                                 status == LINK_TRAINING_SUCCESS)) {
968                         /* the next link training setting in this case
969                          * would be the same as CR failure case.
970                          */
971                         status = LINK_TRAINING_CR_FAIL;
972                 }
973         }
974
975         /* 6. print status message*/
976         switch (lt_settings.link_settings.link_rate) {
977
978         case LINK_RATE_LOW:
979                 link_rate = "RBR";
980                 break;
981         case LINK_RATE_HIGH:
982                 link_rate = "HBR";
983                 break;
984         case LINK_RATE_HIGH2:
985                 link_rate = "HBR2";
986                 break;
987         case LINK_RATE_RBR2:
988                 link_rate = "RBR2";
989                 break;
990         case LINK_RATE_HIGH3:
991                 link_rate = "HBR3";
992                 break;
993         default:
994                 break;
995         }
996
997         /* Connectivity log: link training */
998         CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d",
999                         link_rate,
1000                         lt_settings.link_settings.lane_count,
1001                         (status ==  LINK_TRAINING_SUCCESS) ? "pass" :
1002                         ((status == LINK_TRAINING_CR_FAIL) ? "CR failed" :
1003                         "EQ failed"),
1004                         lt_settings.lane_settings[0].VOLTAGE_SWING,
1005                         lt_settings.lane_settings[0].PRE_EMPHASIS);
1006
1007         return status;
1008 }
1009
1010
1011 bool perform_link_training_with_retries(
1012         struct dc_link *link,
1013         const struct dc_link_settings *link_setting,
1014         bool skip_video_pattern,
1015         int attempts)
1016 {
1017         uint8_t j;
1018         uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY;
1019
1020         for (j = 0; j < attempts; ++j) {
1021
1022                 if (dc_link_dp_perform_link_training(
1023                                 link,
1024                                 link_setting,
1025                                 skip_video_pattern) == LINK_TRAINING_SUCCESS)
1026                         return true;
1027
1028                 msleep(delay_between_attempts);
1029                 delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
1030         }
1031
1032         return false;
1033 }
1034
1035 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
1036 {
1037         /* Set Default link settings */
1038         struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
1039                         LINK_SPREAD_05_DOWNSPREAD_30KHZ};
1040
1041         /* Higher link settings based on feature supported */
1042         if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
1043                 max_link_cap.link_rate = LINK_RATE_HIGH2;
1044
1045         if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1046                 max_link_cap.link_rate = LINK_RATE_HIGH3;
1047
1048         /* Lower link settings based on sink's link cap */
1049         if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
1050                 max_link_cap.lane_count =
1051                                 link->reported_link_cap.lane_count;
1052         if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
1053                 max_link_cap.link_rate =
1054                                 link->reported_link_cap.link_rate;
1055         if (link->reported_link_cap.link_spread <
1056                         max_link_cap.link_spread)
1057                 max_link_cap.link_spread =
1058                                 link->reported_link_cap.link_spread;
1059         return max_link_cap;
1060 }
1061
1062 bool dp_hbr_verify_link_cap(
1063         struct dc_link *link,
1064         struct dc_link_settings *known_limit_link_setting)
1065 {
1066         struct dc_link_settings max_link_cap = {0};
1067         struct dc_link_settings cur_link_setting = {0};
1068         struct dc_link_settings *cur = &cur_link_setting;
1069         struct dc_link_settings initial_link_settings = {0};
1070         bool success;
1071         bool skip_link_training;
1072         bool skip_video_pattern;
1073         struct clock_source *dp_cs;
1074         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1075         enum link_training_result status;
1076
1077         success = false;
1078         skip_link_training = false;
1079
1080         max_link_cap = get_max_link_cap(link);
1081
1082         /* TODO implement override and monitor patch later */
1083
1084         /* try to train the link from high to low to
1085          * find the physical link capability
1086          */
1087         /* disable PHY done possible by BIOS, will be done by driver itself */
1088         dp_disable_link_phy(link, link->connector_signal);
1089
1090         dp_cs = link->dc->res_pool->dp_clock_source;
1091
1092         if (dp_cs)
1093                 dp_cs_id = dp_cs->id;
1094         else {
1095                 /*
1096                  * dp clock source is not initialized for some reason.
1097                  * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
1098                  */
1099                 ASSERT(dp_cs);
1100         }
1101
1102         /* link training starts with the maximum common settings
1103          * supported by both sink and ASIC.
1104          */
1105         initial_link_settings = get_common_supported_link_settings(
1106                         *known_limit_link_setting,
1107                         max_link_cap);
1108         cur_link_setting = initial_link_settings;
1109         do {
1110                 skip_video_pattern = true;
1111
1112                 if (cur->link_rate == LINK_RATE_LOW)
1113                         skip_video_pattern = false;
1114
1115                 dp_enable_link_phy(
1116                                 link,
1117                                 link->connector_signal,
1118                                 dp_cs_id,
1119                                 cur);
1120
1121                 if (skip_link_training)
1122                         success = true;
1123                 else {
1124                         status = dc_link_dp_perform_link_training(
1125                                                         link,
1126                                                         cur,
1127                                                         skip_video_pattern);
1128                         if (status == LINK_TRAINING_SUCCESS)
1129                                 success = true;
1130                 }
1131
1132                 if (success)
1133                         link->verified_link_cap = *cur;
1134
1135                 /* always disable the link before trying another
1136                  * setting or before returning we'll enable it later
1137                  * based on the actual mode we're driving
1138                  */
1139                 dp_disable_link_phy(link, link->connector_signal);
1140         } while (!success && decide_fallback_link_setting(
1141                         initial_link_settings, cur, status));
1142
1143         /* Link Training failed for all Link Settings
1144          *  (Lane Count is still unknown)
1145          */
1146         if (!success) {
1147                 /* If all LT fails for all settings,
1148                  * set verified = failed safe (1 lane low)
1149                  */
1150                 link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1151                 link->verified_link_cap.link_rate = LINK_RATE_LOW;
1152
1153                 link->verified_link_cap.link_spread =
1154                 LINK_SPREAD_DISABLED;
1155         }
1156
1157
1158         return success;
1159 }
1160
1161 static struct dc_link_settings get_common_supported_link_settings (
1162                 struct dc_link_settings link_setting_a,
1163                 struct dc_link_settings link_setting_b)
1164 {
1165         struct dc_link_settings link_settings = {0};
1166
1167         link_settings.lane_count =
1168                 (link_setting_a.lane_count <=
1169                         link_setting_b.lane_count) ?
1170                         link_setting_a.lane_count :
1171                         link_setting_b.lane_count;
1172         link_settings.link_rate =
1173                 (link_setting_a.link_rate <=
1174                         link_setting_b.link_rate) ?
1175                         link_setting_a.link_rate :
1176                         link_setting_b.link_rate;
1177         link_settings.link_spread = LINK_SPREAD_DISABLED;
1178
1179         /* in DP compliance test, DPR-120 may have
1180          * a random value in its MAX_LINK_BW dpcd field.
1181          * We map it to the maximum supported link rate that
1182          * is smaller than MAX_LINK_BW in this case.
1183          */
1184         if (link_settings.link_rate > LINK_RATE_HIGH3) {
1185                 link_settings.link_rate = LINK_RATE_HIGH3;
1186         } else if (link_settings.link_rate < LINK_RATE_HIGH3
1187                         && link_settings.link_rate > LINK_RATE_HIGH2) {
1188                 link_settings.link_rate = LINK_RATE_HIGH2;
1189         } else if (link_settings.link_rate < LINK_RATE_HIGH2
1190                         && link_settings.link_rate > LINK_RATE_HIGH) {
1191                 link_settings.link_rate = LINK_RATE_HIGH;
1192         } else if (link_settings.link_rate < LINK_RATE_HIGH
1193                         && link_settings.link_rate > LINK_RATE_LOW) {
1194                 link_settings.link_rate = LINK_RATE_LOW;
1195         } else if (link_settings.link_rate < LINK_RATE_LOW) {
1196                 link_settings.link_rate = LINK_RATE_UNKNOWN;
1197         }
1198
1199         return link_settings;
1200 }
1201
1202 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
1203 {
1204         return lane_count <= LANE_COUNT_ONE;
1205 }
1206
1207 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
1208 {
1209         return link_rate <= LINK_RATE_LOW;
1210 }
1211
1212 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
1213 {
1214         switch (lane_count) {
1215         case LANE_COUNT_FOUR:
1216                 return LANE_COUNT_TWO;
1217         case LANE_COUNT_TWO:
1218                 return LANE_COUNT_ONE;
1219         case LANE_COUNT_ONE:
1220                 return LANE_COUNT_UNKNOWN;
1221         default:
1222                 return LANE_COUNT_UNKNOWN;
1223         }
1224 }
1225
1226 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
1227 {
1228         switch (link_rate) {
1229         case LINK_RATE_HIGH3:
1230                 return LINK_RATE_HIGH2;
1231         case LINK_RATE_HIGH2:
1232                 return LINK_RATE_HIGH;
1233         case LINK_RATE_HIGH:
1234                 return LINK_RATE_LOW;
1235         case LINK_RATE_LOW:
1236                 return LINK_RATE_UNKNOWN;
1237         default:
1238                 return LINK_RATE_UNKNOWN;
1239         }
1240 }
1241
1242 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
1243 {
1244         switch (lane_count) {
1245         case LANE_COUNT_ONE:
1246                 return LANE_COUNT_TWO;
1247         case LANE_COUNT_TWO:
1248                 return LANE_COUNT_FOUR;
1249         default:
1250                 return LANE_COUNT_UNKNOWN;
1251         }
1252 }
1253
1254 static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
1255 {
1256         switch (link_rate) {
1257         case LINK_RATE_LOW:
1258                 return LINK_RATE_HIGH;
1259         case LINK_RATE_HIGH:
1260                 return LINK_RATE_HIGH2;
1261         case LINK_RATE_HIGH2:
1262                 return LINK_RATE_HIGH3;
1263         default:
1264                 return LINK_RATE_UNKNOWN;
1265         }
1266 }
1267
1268 /*
1269  * function: set link rate and lane count fallback based
1270  * on current link setting and last link training result
1271  * return value:
1272  *                      true - link setting could be set
1273  *                      false - has reached minimum setting
1274  *                                      and no further fallback could be done
1275  */
1276 static bool decide_fallback_link_setting(
1277                 struct dc_link_settings initial_link_settings,
1278                 struct dc_link_settings *current_link_setting,
1279                 enum link_training_result training_result)
1280 {
1281         if (!current_link_setting)
1282                 return false;
1283
1284         switch (training_result) {
1285         case LINK_TRAINING_CR_FAIL:
1286         {
1287                 if (!reached_minimum_link_rate
1288                                 (current_link_setting->link_rate)) {
1289                         current_link_setting->link_rate =
1290                                 reduce_link_rate(
1291                                         current_link_setting->link_rate);
1292                 } else if (!reached_minimum_lane_count
1293                                 (current_link_setting->lane_count)) {
1294                         current_link_setting->link_rate =
1295                                 initial_link_settings.link_rate;
1296                         current_link_setting->lane_count =
1297                                 reduce_lane_count(
1298                                         current_link_setting->lane_count);
1299                 } else {
1300                         return false;
1301                 }
1302                 break;
1303         }
1304         case LINK_TRAINING_EQ_FAIL_EQ:
1305         {
1306                 if (!reached_minimum_lane_count
1307                                 (current_link_setting->lane_count)) {
1308                         current_link_setting->lane_count =
1309                                 reduce_lane_count(
1310                                         current_link_setting->lane_count);
1311                 } else if (!reached_minimum_link_rate
1312                                 (current_link_setting->link_rate)) {
1313                         current_link_setting->link_rate =
1314                                 reduce_link_rate(
1315                                         current_link_setting->link_rate);
1316                 } else {
1317                         return false;
1318                 }
1319                 break;
1320         }
1321         case LINK_TRAINING_EQ_FAIL_CR:
1322         {
1323                 if (!reached_minimum_link_rate
1324                                 (current_link_setting->link_rate)) {
1325                         current_link_setting->link_rate =
1326                                 reduce_link_rate(
1327                                         current_link_setting->link_rate);
1328                 } else {
1329                         return false;
1330                 }
1331                 break;
1332         }
1333         default:
1334                 return false;
1335         }
1336         return true;
1337 }
1338
1339 static uint32_t bandwidth_in_kbps_from_timing(
1340         const struct dc_crtc_timing *timing)
1341 {
1342         uint32_t bits_per_channel = 0;
1343         uint32_t kbps;
1344         switch (timing->display_color_depth) {
1345
1346         case COLOR_DEPTH_666:
1347                 bits_per_channel = 6;
1348                 break;
1349         case COLOR_DEPTH_888:
1350                 bits_per_channel = 8;
1351                 break;
1352         case COLOR_DEPTH_101010:
1353                 bits_per_channel = 10;
1354                 break;
1355         case COLOR_DEPTH_121212:
1356                 bits_per_channel = 12;
1357                 break;
1358         case COLOR_DEPTH_141414:
1359                 bits_per_channel = 14;
1360                 break;
1361         case COLOR_DEPTH_161616:
1362                 bits_per_channel = 16;
1363                 break;
1364         default:
1365                 break;
1366         }
1367         ASSERT(bits_per_channel != 0);
1368
1369         kbps = timing->pix_clk_khz;
1370         kbps *= bits_per_channel;
1371
1372         if (timing->flags.Y_ONLY != 1)
1373                 /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
1374                 kbps *= 3;
1375
1376         return kbps;
1377
1378 }
1379
1380 static uint32_t bandwidth_in_kbps_from_link_settings(
1381         const struct dc_link_settings *link_setting)
1382 {
1383         uint32_t link_rate_in_kbps = link_setting->link_rate *
1384                 LINK_RATE_REF_FREQ_IN_KHZ;
1385
1386         uint32_t lane_count  = link_setting->lane_count;
1387         uint32_t kbps = link_rate_in_kbps;
1388         kbps *= lane_count;
1389         kbps *= 8;   /* 8 bits per byte*/
1390
1391         return kbps;
1392
1393 }
1394
1395 bool dp_validate_mode_timing(
1396         struct dc_link *link,
1397         const struct dc_crtc_timing *timing)
1398 {
1399         uint32_t req_bw;
1400         uint32_t max_bw;
1401
1402         const struct dc_link_settings *link_setting;
1403
1404         /*always DP fail safe mode*/
1405         if (timing->pix_clk_khz == (uint32_t)25175 &&
1406                 timing->h_addressable == (uint32_t)640 &&
1407                 timing->v_addressable == (uint32_t)480)
1408                 return true;
1409
1410         /* We always use verified link settings */
1411         link_setting = &link->verified_link_cap;
1412
1413         /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1414         /*if (flags.DYNAMIC_VALIDATION == 1 &&
1415                 link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
1416                 link_setting = &link->verified_link_cap;
1417         */
1418
1419         req_bw = bandwidth_in_kbps_from_timing(timing);
1420         max_bw = bandwidth_in_kbps_from_link_settings(link_setting);
1421
1422         if (req_bw <= max_bw) {
1423                 /* remember the biggest mode here, during
1424                  * initial link training (to get
1425                  * verified_link_cap), LS sends event about
1426                  * cannot train at reported cap to upper
1427                  * layer and upper layer will re-enumerate modes.
1428                  * this is not necessary if the lower
1429                  * verified_link_cap is enough to drive
1430                  * all the modes */
1431
1432                 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
1433                 /* if (flags.DYNAMIC_VALIDATION == 1)
1434                         dpsst->max_req_bw_for_verified_linkcap = dal_max(
1435                                 dpsst->max_req_bw_for_verified_linkcap, req_bw); */
1436                 return true;
1437         } else
1438                 return false;
1439 }
1440
1441 void decide_link_settings(struct dc_stream_state *stream,
1442         struct dc_link_settings *link_setting)
1443 {
1444
1445         struct dc_link_settings initial_link_setting = {
1446                 LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED};
1447         struct dc_link_settings current_link_setting =
1448                         initial_link_setting;
1449         struct dc_link *link;
1450         uint32_t req_bw;
1451         uint32_t link_bw;
1452
1453         req_bw = bandwidth_in_kbps_from_timing(&stream->timing);
1454
1455         link = stream->sink->link;
1456
1457         /* if preferred is specified through AMDDP, use it, if it's enough
1458          * to drive the mode
1459          */
1460         if (link->preferred_link_setting.lane_count !=
1461                         LANE_COUNT_UNKNOWN &&
1462                         link->preferred_link_setting.link_rate !=
1463                                         LINK_RATE_UNKNOWN) {
1464                 *link_setting =  link->preferred_link_setting;
1465                 return;
1466         }
1467
1468         /* MST doesn't perform link training for now
1469          * TODO: add MST specific link training routine
1470          */
1471         if (is_mst_supported(link)) {
1472                 *link_setting = link->verified_link_cap;
1473                 return;
1474         }
1475
1476         /* search for the minimum link setting that:
1477          * 1. is supported according to the link training result
1478          * 2. could support the b/w requested by the timing
1479          */
1480         while (current_link_setting.link_rate <=
1481                         link->verified_link_cap.link_rate) {
1482                 link_bw = bandwidth_in_kbps_from_link_settings(
1483                                 &current_link_setting);
1484                 if (req_bw <= link_bw) {
1485                         *link_setting = current_link_setting;
1486                         return;
1487                 }
1488
1489                 if (current_link_setting.lane_count <
1490                                 link->verified_link_cap.lane_count) {
1491                         current_link_setting.lane_count =
1492                                         increase_lane_count(
1493                                                         current_link_setting.lane_count);
1494                 } else {
1495                         current_link_setting.link_rate =
1496                                         increase_link_rate(
1497                                                         current_link_setting.link_rate);
1498                         current_link_setting.lane_count =
1499                                         initial_link_setting.lane_count;
1500                 }
1501         }
1502
1503         BREAK_TO_DEBUGGER();
1504         ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
1505
1506         *link_setting = link->verified_link_cap;
1507 }
1508
1509 /*************************Short Pulse IRQ***************************/
1510
1511 static bool hpd_rx_irq_check_link_loss_status(
1512         struct dc_link *link,
1513         union hpd_irq_data *hpd_irq_dpcd_data)
1514 {
1515         uint8_t irq_reg_rx_power_state;
1516         enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
1517         union lane_status lane_status;
1518         uint32_t lane;
1519         bool sink_status_changed;
1520         bool return_code;
1521
1522         sink_status_changed = false;
1523         return_code = false;
1524
1525         if (link->cur_link_settings.lane_count == 0)
1526                 return return_code;
1527         /*1. Check that we can handle interrupt: Not in FS DOS,
1528          *  Not in "Display Timeout" state, Link is trained.
1529          */
1530
1531         dpcd_result = core_link_read_dpcd(link,
1532                 DP_SET_POWER,
1533                 &irq_reg_rx_power_state,
1534                 sizeof(irq_reg_rx_power_state));
1535
1536         if (dpcd_result != DC_OK) {
1537                 irq_reg_rx_power_state = DP_SET_POWER_D0;
1538                 dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
1539                         "%s: DPCD read failed to obtain power state.\n",
1540                         __func__);
1541         }
1542
1543         if (irq_reg_rx_power_state == DP_SET_POWER_D0) {
1544
1545                 /*2. Check that Link Status changed, before re-training.*/
1546
1547                 /*parse lane status*/
1548                 for (lane = 0;
1549                         lane < link->cur_link_settings.lane_count;
1550                         lane++) {
1551
1552                         /* check status of lanes 0,1
1553                          * changed DpcdAddress_Lane01Status (0x202)*/
1554                         lane_status.raw = get_nibble_at_index(
1555                                 &hpd_irq_dpcd_data->bytes.lane01_status.raw,
1556                                 lane);
1557
1558                         if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1559                                 !lane_status.bits.CR_DONE_0 ||
1560                                 !lane_status.bits.SYMBOL_LOCKED_0) {
1561                                 /* if one of the channel equalization, clock
1562                                  * recovery or symbol lock is dropped
1563                                  * consider it as (link has been
1564                                  * dropped) dp sink status has changed*/
1565                                 sink_status_changed = true;
1566                                 break;
1567                         }
1568
1569                 }
1570
1571                 /* Check interlane align.*/
1572                 if (sink_status_changed ||
1573                         !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.
1574                         INTERLANE_ALIGN_DONE) {
1575
1576                         dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
1577                                 "%s: Link Status changed.\n",
1578                                 __func__);
1579
1580                         return_code = true;
1581                 }
1582         }
1583
1584         return return_code;
1585 }
1586
1587 static enum dc_status read_hpd_rx_irq_data(
1588         struct dc_link *link,
1589         union hpd_irq_data *irq_data)
1590 {
1591         /* The HW reads 16 bytes from 200h on HPD,
1592          * but if we get an AUX_DEFER, the HW cannot retry
1593          * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
1594          * fail, so we now explicitly read 6 bytes which is
1595          * the req from the above mentioned test cases.
1596          */
1597         return core_link_read_dpcd(
1598         link,
1599         DP_SINK_COUNT,
1600         irq_data->raw,
1601         sizeof(union hpd_irq_data));
1602 }
1603
1604 static bool allow_hpd_rx_irq(const struct dc_link *link)
1605 {
1606         /*
1607          * Don't handle RX IRQ unless one of following is met:
1608          * 1) The link is established (cur_link_settings != unknown)
1609          * 2) We kicked off MST detection
1610          * 3) We know we're dealing with an active dongle
1611          */
1612
1613         if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
1614                 (link->type == dc_connection_mst_branch) ||
1615                 is_dp_active_dongle(link))
1616                 return true;
1617
1618         return false;
1619 }
1620
1621 static bool handle_hpd_irq_psr_sink(const struct dc_link *link)
1622 {
1623         union dpcd_psr_configuration psr_configuration;
1624
1625         if (!link->psr_enabled)
1626                 return false;
1627
1628         dm_helpers_dp_read_dpcd(
1629                 link->ctx,
1630                 link,
1631                 368,/*DpcdAddress_PSR_Enable_Cfg*/
1632                 &psr_configuration.raw,
1633                 sizeof(psr_configuration.raw));
1634
1635
1636         if (psr_configuration.bits.ENABLE) {
1637                 unsigned char dpcdbuf[3] = {0};
1638                 union psr_error_status psr_error_status;
1639                 union psr_sink_psr_status psr_sink_psr_status;
1640
1641                 dm_helpers_dp_read_dpcd(
1642                         link->ctx,
1643                         link,
1644                         0x2006, /*DpcdAddress_PSR_Error_Status*/
1645                         (unsigned char *) dpcdbuf,
1646                         sizeof(dpcdbuf));
1647
1648                 /*DPCD 2006h   ERROR STATUS*/
1649                 psr_error_status.raw = dpcdbuf[0];
1650                 /*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
1651                 psr_sink_psr_status.raw = dpcdbuf[2];
1652
1653                 if (psr_error_status.bits.LINK_CRC_ERROR ||
1654                                 psr_error_status.bits.RFB_STORAGE_ERROR) {
1655                         /* Acknowledge and clear error bits */
1656                         dm_helpers_dp_write_dpcd(
1657                                 link->ctx,
1658                                 link,
1659                                 8198,/*DpcdAddress_PSR_Error_Status*/
1660                                 &psr_error_status.raw,
1661                                 sizeof(psr_error_status.raw));
1662
1663                         /* PSR error, disable and re-enable PSR */
1664                         dc_link_set_psr_enable(link, false, true);
1665                         dc_link_set_psr_enable(link, true, true);
1666
1667                         return true;
1668                 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
1669                                 PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
1670                         /* No error is detect, PSR is active.
1671                          * We should return with IRQ_HPD handled without
1672                          * checking for loss of sync since PSR would have
1673                          * powered down main link.
1674                          */
1675                         return true;
1676                 }
1677         }
1678         return false;
1679 }
1680
1681 static void dp_test_send_link_training(struct dc_link *link)
1682 {
1683         struct dc_link_settings link_settings = {0};
1684
1685         core_link_read_dpcd(
1686                         link,
1687                         DP_TEST_LANE_COUNT,
1688                         (unsigned char *)(&link_settings.lane_count),
1689                         1);
1690         core_link_read_dpcd(
1691                         link,
1692                         DP_TEST_LINK_RATE,
1693                         (unsigned char *)(&link_settings.link_rate),
1694                         1);
1695
1696         /* Set preferred link settings */
1697         link->verified_link_cap.lane_count = link_settings.lane_count;
1698         link->verified_link_cap.link_rate = link_settings.link_rate;
1699
1700         dp_retrain_link_dp_test(link, &link_settings, false);
1701 }
1702
1703 /* TODO hbr2 compliance eye output is unstable
1704  * (toggling on and off) with debugger break
1705  * This caueses intermittent PHY automation failure
1706  * Need to look into the root cause */
1707 static uint8_t force_tps4_for_cp2520 = 1;
1708
1709 static void dp_test_send_phy_test_pattern(struct dc_link *link)
1710 {
1711         union phy_test_pattern dpcd_test_pattern;
1712         union lane_adjust dpcd_lane_adjustment[2];
1713         unsigned char dpcd_post_cursor_2_adjustment = 0;
1714         unsigned char test_80_bit_pattern[
1715                         (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
1716                         DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
1717         enum dp_test_pattern test_pattern;
1718         struct dc_link_training_settings link_settings;
1719         union lane_adjust dpcd_lane_adjust;
1720         unsigned int lane;
1721         struct link_training_settings link_training_settings;
1722         int i = 0;
1723
1724         dpcd_test_pattern.raw = 0;
1725         memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
1726         memset(&link_settings, 0, sizeof(link_settings));
1727
1728         /* get phy test pattern and pattern parameters from DP receiver */
1729         core_link_read_dpcd(
1730                         link,
1731                         DP_TEST_PHY_PATTERN,
1732                         &dpcd_test_pattern.raw,
1733                         sizeof(dpcd_test_pattern));
1734         core_link_read_dpcd(
1735                         link,
1736                         DP_ADJUST_REQUEST_LANE0_1,
1737                         &dpcd_lane_adjustment[0].raw,
1738                         sizeof(dpcd_lane_adjustment));
1739
1740         /*get post cursor 2 parameters
1741          * For DP 1.1a or eariler, this DPCD register's value is 0
1742          * For DP 1.2 or later:
1743          * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
1744          * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
1745          */
1746         core_link_read_dpcd(
1747                         link,
1748                         DP_ADJUST_REQUEST_POST_CURSOR2,
1749                         &dpcd_post_cursor_2_adjustment,
1750                         sizeof(dpcd_post_cursor_2_adjustment));
1751
1752         /* translate request */
1753         switch (dpcd_test_pattern.bits.PATTERN) {
1754         case PHY_TEST_PATTERN_D10_2:
1755                 test_pattern = DP_TEST_PATTERN_D102;
1756                 break;
1757         case PHY_TEST_PATTERN_SYMBOL_ERROR:
1758                 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
1759                 break;
1760         case PHY_TEST_PATTERN_PRBS7:
1761                 test_pattern = DP_TEST_PATTERN_PRBS7;
1762                 break;
1763         case PHY_TEST_PATTERN_80BIT_CUSTOM:
1764                 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
1765                 break;
1766         case PHY_TEST_PATTERN_CP2520_1:
1767                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1768                 test_pattern = (force_tps4_for_cp2520 == 1) ?
1769                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1770                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1771                 break;
1772         case PHY_TEST_PATTERN_CP2520_2:
1773                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
1774                 test_pattern = (force_tps4_for_cp2520 == 1) ?
1775                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
1776                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
1777                 break;
1778         case PHY_TEST_PATTERN_CP2520_3:
1779                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
1780                 break;
1781         default:
1782                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
1783         break;
1784         }
1785
1786         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM)
1787                 core_link_read_dpcd(
1788                                 link,
1789                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
1790                                 test_80_bit_pattern,
1791                                 sizeof(test_80_bit_pattern));
1792
1793         /* prepare link training settings */
1794         link_settings.link = link->cur_link_settings;
1795
1796         for (lane = 0; lane <
1797                 (unsigned int)(link->cur_link_settings.lane_count);
1798                 lane++) {
1799                 dpcd_lane_adjust.raw =
1800                         get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
1801                 link_settings.lane_settings[lane].VOLTAGE_SWING =
1802                         (enum dc_voltage_swing)
1803                         (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
1804                 link_settings.lane_settings[lane].PRE_EMPHASIS =
1805                         (enum dc_pre_emphasis)
1806                         (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
1807                 link_settings.lane_settings[lane].POST_CURSOR2 =
1808                         (enum dc_post_cursor2)
1809                         ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
1810         }
1811
1812         for (i = 0; i < 4; i++)
1813                 link_training_settings.lane_settings[i] =
1814                                 link_settings.lane_settings[i];
1815         link_training_settings.link_settings = link_settings.link;
1816         link_training_settings.allow_invalid_msa_timing_param = false;
1817         /*Usage: Measure DP physical lane signal
1818          * by DP SI test equipment automatically.
1819          * PHY test pattern request is generated by equipment via HPD interrupt.
1820          * HPD needs to be active all the time. HPD should be active
1821          * all the time. Do not touch it.
1822          * forward request to DS
1823          */
1824         dc_link_dp_set_test_pattern(
1825                 link,
1826                 test_pattern,
1827                 &link_training_settings,
1828                 test_80_bit_pattern,
1829                 (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
1830                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1);
1831 }
1832
1833 static void dp_test_send_link_test_pattern(struct dc_link *link)
1834 {
1835         union link_test_pattern dpcd_test_pattern;
1836         union test_misc dpcd_test_params;
1837         enum dp_test_pattern test_pattern;
1838
1839         memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
1840         memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
1841
1842         /* get link test pattern and pattern parameters */
1843         core_link_read_dpcd(
1844                         link,
1845                         DP_TEST_PATTERN,
1846                         &dpcd_test_pattern.raw,
1847                         sizeof(dpcd_test_pattern));
1848         core_link_read_dpcd(
1849                         link,
1850                         DP_TEST_MISC0,
1851                         &dpcd_test_params.raw,
1852                         sizeof(dpcd_test_params));
1853
1854         switch (dpcd_test_pattern.bits.PATTERN) {
1855         case LINK_TEST_PATTERN_COLOR_RAMP:
1856                 test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
1857         break;
1858         case LINK_TEST_PATTERN_VERTICAL_BARS:
1859                 test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
1860         break; /* black and white */
1861         case LINK_TEST_PATTERN_COLOR_SQUARES:
1862                 test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
1863                                 TEST_DYN_RANGE_VESA ?
1864                                 DP_TEST_PATTERN_COLOR_SQUARES :
1865                                 DP_TEST_PATTERN_COLOR_SQUARES_CEA);
1866         break;
1867         default:
1868                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
1869         break;
1870         }
1871
1872         dc_link_dp_set_test_pattern(
1873                         link,
1874                         test_pattern,
1875                         NULL,
1876                         NULL,
1877                         0);
1878 }
1879
1880 static void handle_automated_test(struct dc_link *link)
1881 {
1882         union test_request test_request;
1883         union test_response test_response;
1884
1885         memset(&test_request, 0, sizeof(test_request));
1886         memset(&test_response, 0, sizeof(test_response));
1887
1888         core_link_read_dpcd(
1889                 link,
1890                 DP_TEST_REQUEST,
1891                 &test_request.raw,
1892                 sizeof(union test_request));
1893         if (test_request.bits.LINK_TRAINING) {
1894                 /* ACK first to let DP RX test box monitor LT sequence */
1895                 test_response.bits.ACK = 1;
1896                 core_link_write_dpcd(
1897                         link,
1898                         DP_TEST_RESPONSE,
1899                         &test_response.raw,
1900                         sizeof(test_response));
1901                 dp_test_send_link_training(link);
1902                 /* no acknowledge request is needed again */
1903                 test_response.bits.ACK = 0;
1904         }
1905         if (test_request.bits.LINK_TEST_PATTRN) {
1906                 dp_test_send_link_test_pattern(link);
1907                 test_response.bits.ACK = 1;
1908         }
1909         if (test_request.bits.PHY_TEST_PATTERN) {
1910                 dp_test_send_phy_test_pattern(link);
1911                 test_response.bits.ACK = 1;
1912         }
1913         if (!test_request.raw)
1914                 /* no requests, revert all test signals
1915                  * TODO: revert all test signals
1916                  */
1917                 test_response.bits.ACK = 1;
1918         /* send request acknowledgment */
1919         if (test_response.bits.ACK)
1920                 core_link_write_dpcd(
1921                         link,
1922                         DP_TEST_RESPONSE,
1923                         &test_response.raw,
1924                         sizeof(test_response));
1925 }
1926
1927 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data)
1928 {
1929         union hpd_irq_data hpd_irq_dpcd_data = {{{{0}}}};
1930         union device_service_irq device_service_clear = { { 0 } };
1931         enum dc_status result = DDC_RESULT_UNKNOWN;
1932         bool status = false;
1933         /* For use cases related to down stream connection status change,
1934          * PSR and device auto test, refer to function handle_sst_hpd_irq
1935          * in DAL2.1*/
1936
1937         dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
1938                 "%s: Got short pulse HPD on link %d\n",
1939                 __func__, link->link_index);
1940
1941
1942          /* All the "handle_hpd_irq_xxx()" methods
1943                  * should be called only after
1944                  * dal_dpsst_ls_read_hpd_irq_data
1945                  * Order of calls is important too
1946                  */
1947         result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
1948         if (out_hpd_irq_dpcd_data)
1949                 *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
1950
1951         if (result != DC_OK) {
1952                 dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
1953                         "%s: DPCD read failed to obtain irq data\n",
1954                         __func__);
1955                 return false;
1956         }
1957
1958         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
1959                 device_service_clear.bits.AUTOMATED_TEST = 1;
1960                 core_link_write_dpcd(
1961                         link,
1962                         DP_DEVICE_SERVICE_IRQ_VECTOR,
1963                         &device_service_clear.raw,
1964                         sizeof(device_service_clear.raw));
1965                 device_service_clear.raw = 0;
1966                 handle_automated_test(link);
1967                 return false;
1968         }
1969
1970         if (!allow_hpd_rx_irq(link)) {
1971                 dm_logger_write(link->ctx->logger, LOG_HW_HPD_IRQ,
1972                         "%s: skipping HPD handling on %d\n",
1973                         __func__, link->link_index);
1974                 return false;
1975         }
1976
1977         if (handle_hpd_irq_psr_sink(link))
1978                 /* PSR-related error was detected and handled */
1979                 return true;
1980
1981         /* If PSR-related error handled, Main link may be off,
1982          * so do not handle as a normal sink status change interrupt.
1983          */
1984
1985         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
1986                 return true;
1987
1988         /* check if we have MST msg and return since we poll for it */
1989         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
1990                 return false;
1991
1992         /* For now we only handle 'Downstream port status' case.
1993          * If we got sink count changed it means
1994          * Downstream port status changed,
1995          * then DM should call DC to do the detection. */
1996         if (hpd_rx_irq_check_link_loss_status(
1997                 link,
1998                 &hpd_irq_dpcd_data)) {
1999                 /* Connectivity log: link loss */
2000                 CONN_DATA_LINK_LOSS(link,
2001                                         hpd_irq_dpcd_data.raw,
2002                                         sizeof(hpd_irq_dpcd_data),
2003                                         "Status: ");
2004
2005                 perform_link_training_with_retries(link,
2006                         &link->cur_link_settings,
2007                         true, LINK_TRAINING_ATTEMPTS);
2008
2009                 status = false;
2010         }
2011
2012         if (link->type == dc_connection_active_dongle &&
2013                 hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
2014                         != link->dpcd_sink_count)
2015                 status = true;
2016
2017         /* reasons for HPD RX:
2018          * 1. Link Loss - ie Re-train the Link
2019          * 2. MST sideband message
2020          * 3. Automated Test - ie. Internal Commit
2021          * 4. CP (copy protection) - (not interesting for DM???)
2022          * 5. DRR
2023          * 6. Downstream Port status changed
2024          * -ie. Detect - this the only one
2025          * which is interesting for DM because
2026          * it must call dc_link_detect.
2027          */
2028         return status;
2029 }
2030
2031 /*query dpcd for version and mst cap addresses*/
2032 bool is_mst_supported(struct dc_link *link)
2033 {
2034         bool mst          = false;
2035         enum dc_status st = DC_OK;
2036         union dpcd_rev rev;
2037         union mstm_cap cap;
2038
2039         rev.raw  = 0;
2040         cap.raw  = 0;
2041
2042         st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
2043                         sizeof(rev));
2044
2045         if (st == DC_OK && rev.raw >= DPCD_REV_12) {
2046
2047                 st = core_link_read_dpcd(link, DP_MSTM_CAP,
2048                                 &cap.raw, sizeof(cap));
2049                 if (st == DC_OK && cap.bits.MST_CAP == 1)
2050                         mst = true;
2051         }
2052         return mst;
2053
2054 }
2055
2056 bool is_dp_active_dongle(const struct dc_link *link)
2057 {
2058         enum display_dongle_type dongle_type = link->dpcd_caps.dongle_type;
2059
2060         return (dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) ||
2061                         (dongle_type == DISPLAY_DONGLE_DP_DVI_CONVERTER) ||
2062                         (dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER);
2063 }
2064
2065 static void get_active_converter_info(
2066         uint8_t data, struct dc_link *link)
2067 {
2068         union dp_downstream_port_present ds_port = { .byte = data };
2069
2070         /* decode converter info*/
2071         if (!ds_port.fields.PORT_PRESENT) {
2072                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2073                 ddc_service_set_dongle_type(link->ddc,
2074                                 link->dpcd_caps.dongle_type);
2075                 return;
2076         }
2077
2078         switch (ds_port.fields.PORT_TYPE) {
2079         case DOWNSTREAM_VGA:
2080                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
2081                 break;
2082         case DOWNSTREAM_DVI_HDMI:
2083                 /* At this point we don't know is it DVI or HDMI,
2084                  * assume DVI.*/
2085                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
2086                 break;
2087         default:
2088                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
2089                 break;
2090         }
2091
2092         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
2093                 uint8_t det_caps[4];
2094                 union dwnstream_port_caps_byte0 *port_caps =
2095                         (union dwnstream_port_caps_byte0 *)det_caps;
2096                 core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
2097                                 det_caps, sizeof(det_caps));
2098
2099                 switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
2100                 case DOWN_STREAM_DETAILED_VGA:
2101                         link->dpcd_caps.dongle_type =
2102                                 DISPLAY_DONGLE_DP_VGA_CONVERTER;
2103                         break;
2104                 case DOWN_STREAM_DETAILED_DVI:
2105                         link->dpcd_caps.dongle_type =
2106                                 DISPLAY_DONGLE_DP_DVI_CONVERTER;
2107                         break;
2108                 case DOWN_STREAM_DETAILED_HDMI:
2109                         link->dpcd_caps.dongle_type =
2110                                 DISPLAY_DONGLE_DP_HDMI_CONVERTER;
2111
2112                         link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
2113                         if (ds_port.fields.DETAILED_CAPS) {
2114
2115                                 union dwnstream_port_caps_byte3_hdmi
2116                                         hdmi_caps = {.raw = det_caps[3] };
2117                                 union dwnstream_port_caps_byte1
2118                                         hdmi_color_caps = {.raw = det_caps[2] };
2119                                 link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk =
2120                                         det_caps[1] * 25000;
2121
2122                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
2123                                         hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
2124                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
2125                                         hdmi_caps.bits.YCrCr422_PASS_THROUGH;
2126                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
2127                                         hdmi_caps.bits.YCrCr420_PASS_THROUGH;
2128                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
2129                                         hdmi_caps.bits.YCrCr422_CONVERSION;
2130                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
2131                                         hdmi_caps.bits.YCrCr420_CONVERSION;
2132
2133                                 link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
2134                                         hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT;
2135
2136                                 link->dpcd_caps.dongle_caps.extendedCapValid = true;
2137                         }
2138
2139                         break;
2140                 }
2141         }
2142
2143         ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
2144
2145         {
2146                 struct dp_device_vendor_id dp_id;
2147
2148                 /* read IEEE branch device id */
2149                 core_link_read_dpcd(
2150                         link,
2151                         DP_BRANCH_OUI,
2152                         (uint8_t *)&dp_id,
2153                         sizeof(dp_id));
2154
2155                 link->dpcd_caps.branch_dev_id =
2156                         (dp_id.ieee_oui[0] << 16) +
2157                         (dp_id.ieee_oui[1] << 8) +
2158                         dp_id.ieee_oui[2];
2159
2160                 memmove(
2161                         link->dpcd_caps.branch_dev_name,
2162                         dp_id.ieee_device_id,
2163                         sizeof(dp_id.ieee_device_id));
2164         }
2165
2166         {
2167                 struct dp_sink_hw_fw_revision dp_hw_fw_revision;
2168
2169                 core_link_read_dpcd(
2170                         link,
2171                         DP_BRANCH_REVISION_START,
2172                         (uint8_t *)&dp_hw_fw_revision,
2173                         sizeof(dp_hw_fw_revision));
2174
2175                 link->dpcd_caps.branch_hw_revision =
2176                         dp_hw_fw_revision.ieee_hw_rev;
2177         }
2178 }
2179
2180 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
2181                 int length)
2182 {
2183         int retry = 0;
2184         union dp_downstream_port_present ds_port = { 0 };
2185
2186         if (!link->dpcd_caps.dpcd_rev.raw) {
2187                 do {
2188                         dp_receiver_power_ctrl(link, true);
2189                         core_link_read_dpcd(link, DP_DPCD_REV,
2190                                                         dpcd_data, length);
2191                         link->dpcd_caps.dpcd_rev.raw = dpcd_data[
2192                                 DP_DPCD_REV -
2193                                 DP_DPCD_REV];
2194                 } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
2195         }
2196
2197         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2198                                  DP_DPCD_REV];
2199
2200         if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
2201                 switch (link->dpcd_caps.branch_dev_id) {
2202                 /* Some active dongles (DP-VGA, DP-DLDVI converters) power down
2203                  * all internal circuits including AUX communication preventing
2204                  * reading DPCD table and EDID (spec violation).
2205                  * Encoder will skip DP RX power down on disable_output to
2206                  * keep receiver powered all the time.*/
2207                 case DP_BRANCH_DEVICE_ID_1:
2208                 case DP_BRANCH_DEVICE_ID_4:
2209                         link->wa_flags.dp_keep_receiver_powered = true;
2210                         break;
2211
2212                 /* TODO: May need work around for other dongles. */
2213                 default:
2214                         link->wa_flags.dp_keep_receiver_powered = false;
2215                         break;
2216                 }
2217         } else
2218                 link->wa_flags.dp_keep_receiver_powered = false;
2219 }
2220
2221 static void retrieve_link_cap(struct dc_link *link)
2222 {
2223         uint8_t dpcd_data[DP_TRAINING_AUX_RD_INTERVAL - DP_DPCD_REV + 1];
2224
2225         union down_stream_port_count down_strm_port_count;
2226         union edp_configuration_cap edp_config_cap;
2227         union dp_downstream_port_present ds_port = { 0 };
2228
2229         memset(dpcd_data, '\0', sizeof(dpcd_data));
2230         memset(&down_strm_port_count,
2231                 '\0', sizeof(union down_stream_port_count));
2232         memset(&edp_config_cap, '\0',
2233                 sizeof(union edp_configuration_cap));
2234
2235         core_link_read_dpcd(
2236                 link,
2237                 DP_DPCD_REV,
2238                 dpcd_data,
2239                 sizeof(dpcd_data));
2240
2241         {
2242                 union training_aux_rd_interval aux_rd_interval;
2243
2244                 aux_rd_interval.raw =
2245                         dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
2246
2247                 if (aux_rd_interval.bits.EXT_RECIEVER_CAP_FIELD_PRESENT == 1) {
2248                         core_link_read_dpcd(
2249                                 link,
2250                                 DP_DP13_DPCD_REV,
2251                                 dpcd_data,
2252                                 sizeof(dpcd_data));
2253                 }
2254         }
2255
2256         link->dpcd_caps.dpcd_rev.raw =
2257                 dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
2258
2259         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
2260                                  DP_DPCD_REV];
2261
2262         get_active_converter_info(ds_port.byte, link);
2263
2264         dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
2265
2266         link->dpcd_caps.allow_invalid_MSA_timing_param =
2267                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
2268
2269         link->dpcd_caps.max_ln_count.raw = dpcd_data[
2270                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
2271
2272         link->dpcd_caps.max_down_spread.raw = dpcd_data[
2273                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
2274
2275         link->reported_link_cap.lane_count =
2276                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
2277         link->reported_link_cap.link_rate = dpcd_data[
2278                 DP_MAX_LINK_RATE - DP_DPCD_REV];
2279         link->reported_link_cap.link_spread =
2280                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
2281                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
2282
2283         edp_config_cap.raw = dpcd_data[
2284                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
2285         link->dpcd_caps.panel_mode_edp =
2286                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
2287         link->dpcd_caps.dpcd_display_control_capable =
2288                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
2289
2290         link->test_pattern_enabled = false;
2291         link->compliance_test_state.raw = 0;
2292
2293         /* read sink count */
2294         core_link_read_dpcd(link,
2295                         DP_SINK_COUNT,
2296                         &link->dpcd_caps.sink_count.raw,
2297                         sizeof(link->dpcd_caps.sink_count.raw));
2298
2299         /* Connectivity log: detection */
2300         CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
2301 }
2302
2303 void detect_dp_sink_caps(struct dc_link *link)
2304 {
2305         retrieve_link_cap(link);
2306
2307         /* dc init_hw has power encoder using default
2308          * signal for connector. For native DP, no
2309          * need to power up encoder again. If not native
2310          * DP, hw_init may need check signal or power up
2311          * encoder here.
2312          */
2313         /* TODO save sink caps in link->sink */
2314 }
2315
2316 void detect_edp_sink_caps(struct dc_link *link)
2317 {
2318         retrieve_link_cap(link);
2319         link->verified_link_cap = link->reported_link_cap;
2320 }
2321
2322 void dc_link_dp_enable_hpd(const struct dc_link *link)
2323 {
2324         struct link_encoder *encoder = link->link_enc;
2325
2326         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
2327                 encoder->funcs->enable_hpd(encoder);
2328 }
2329
2330 void dc_link_dp_disable_hpd(const struct dc_link *link)
2331 {
2332         struct link_encoder *encoder = link->link_enc;
2333
2334         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
2335                 encoder->funcs->disable_hpd(encoder);
2336 }
2337
2338 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
2339 {
2340         if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
2341                         test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
2342                         test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
2343                 return true;
2344         else
2345                 return false;
2346 }
2347
2348 static void set_crtc_test_pattern(struct dc_link *link,
2349                                 struct pipe_ctx *pipe_ctx,
2350                                 enum dp_test_pattern test_pattern)
2351 {
2352         enum controller_dp_test_pattern controller_test_pattern;
2353         enum dc_color_depth color_depth = pipe_ctx->
2354                 stream->timing.display_color_depth;
2355         struct bit_depth_reduction_params params;
2356
2357         memset(&params, 0, sizeof(params));
2358
2359         switch (test_pattern) {
2360         case DP_TEST_PATTERN_COLOR_SQUARES:
2361                 controller_test_pattern =
2362                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
2363         break;
2364         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
2365                 controller_test_pattern =
2366                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
2367         break;
2368         case DP_TEST_PATTERN_VERTICAL_BARS:
2369                 controller_test_pattern =
2370                                 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
2371         break;
2372         case DP_TEST_PATTERN_HORIZONTAL_BARS:
2373                 controller_test_pattern =
2374                                 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
2375         break;
2376         case DP_TEST_PATTERN_COLOR_RAMP:
2377                 controller_test_pattern =
2378                                 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
2379         break;
2380         default:
2381                 controller_test_pattern =
2382                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
2383         break;
2384         }
2385
2386         switch (test_pattern) {
2387         case DP_TEST_PATTERN_COLOR_SQUARES:
2388         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
2389         case DP_TEST_PATTERN_VERTICAL_BARS:
2390         case DP_TEST_PATTERN_HORIZONTAL_BARS:
2391         case DP_TEST_PATTERN_COLOR_RAMP:
2392         {
2393                 /* disable bit depth reduction */
2394                 pipe_ctx->stream->bit_depth_params = params;
2395                 pipe_ctx->stream_res.opp->funcs->
2396                         opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, &params);
2397
2398                 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2399                                 controller_test_pattern, color_depth);
2400         }
2401         break;
2402         case DP_TEST_PATTERN_VIDEO_MODE:
2403         {
2404                 /* restore bitdepth reduction */
2405                 resource_build_bit_depth_reduction_params(pipe_ctx->stream,
2406                                         &params);
2407                 pipe_ctx->stream->bit_depth_params = params;
2408                 pipe_ctx->stream_res.opp->funcs->
2409                         opp_program_bit_depth_reduction(pipe_ctx->stream_res.opp, &params);
2410
2411                 pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
2412                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
2413                                 color_depth);
2414         }
2415         break;
2416
2417         default:
2418         break;
2419         }
2420 }
2421
2422 bool dc_link_dp_set_test_pattern(
2423         struct dc_link *link,
2424         enum dp_test_pattern test_pattern,
2425         const struct link_training_settings *p_link_settings,
2426         const unsigned char *p_custom_pattern,
2427         unsigned int cust_pattern_size)
2428 {
2429         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
2430         struct pipe_ctx *pipe_ctx = &pipes[0];
2431         unsigned int lane;
2432         unsigned int i;
2433         unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
2434         union dpcd_training_pattern training_pattern;
2435         enum dpcd_phy_test_patterns pattern;
2436
2437         memset(&training_pattern, 0, sizeof(training_pattern));
2438
2439         for (i = 0; i < MAX_PIPES; i++) {
2440                 if (pipes[i].stream->sink->link == link) {
2441                         pipe_ctx = &pipes[i];
2442                         break;
2443                 }
2444         }
2445
2446         /* Reset CRTC Test Pattern if it is currently running and request
2447          * is VideoMode Reset DP Phy Test Pattern if it is currently running
2448          * and request is VideoMode
2449          */
2450         if (link->test_pattern_enabled && test_pattern ==
2451                         DP_TEST_PATTERN_VIDEO_MODE) {
2452                 /* Set CRTC Test Pattern */
2453                 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
2454                 dp_set_hw_test_pattern(link, test_pattern,
2455                                 (uint8_t *)p_custom_pattern,
2456                                 (uint32_t)cust_pattern_size);
2457
2458                 /* Unblank Stream */
2459                 link->dc->hwss.unblank_stream(
2460                         pipe_ctx,
2461                         &link->verified_link_cap);
2462                 /* TODO:m_pHwss->MuteAudioEndpoint
2463                  * (pPathMode->pDisplayPath, false);
2464                  */
2465
2466                 /* Reset Test Pattern state */
2467                 link->test_pattern_enabled = false;
2468
2469                 return true;
2470         }
2471
2472         /* Check for PHY Test Patterns */
2473         if (is_dp_phy_pattern(test_pattern)) {
2474                 /* Set DPCD Lane Settings before running test pattern */
2475                 if (p_link_settings != NULL) {
2476                         dp_set_hw_lane_settings(link, p_link_settings);
2477                         dpcd_set_lane_settings(link, p_link_settings);
2478                 }
2479
2480                 /* Blank stream if running test pattern */
2481                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
2482                         /*TODO:
2483                          * m_pHwss->
2484                          * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
2485                          */
2486                         /* Blank stream */
2487                         pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
2488                 }
2489
2490                 dp_set_hw_test_pattern(link, test_pattern,
2491                                 (uint8_t *)p_custom_pattern,
2492                                 (uint32_t)cust_pattern_size);
2493
2494                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
2495                         /* Set Test Pattern state */
2496                         link->test_pattern_enabled = true;
2497                         if (p_link_settings != NULL)
2498                                 dpcd_set_link_settings(link,
2499                                                 p_link_settings);
2500                 }
2501
2502                 switch (test_pattern) {
2503                 case DP_TEST_PATTERN_VIDEO_MODE:
2504                         pattern = PHY_TEST_PATTERN_NONE;
2505                         break;
2506                 case DP_TEST_PATTERN_D102:
2507                         pattern = PHY_TEST_PATTERN_D10_2;
2508                         break;
2509                 case DP_TEST_PATTERN_SYMBOL_ERROR:
2510                         pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
2511                         break;
2512                 case DP_TEST_PATTERN_PRBS7:
2513                         pattern = PHY_TEST_PATTERN_PRBS7;
2514                         break;
2515                 case DP_TEST_PATTERN_80BIT_CUSTOM:
2516                         pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
2517                         break;
2518                 case DP_TEST_PATTERN_CP2520_1:
2519                         pattern = PHY_TEST_PATTERN_CP2520_1;
2520                         break;
2521                 case DP_TEST_PATTERN_CP2520_2:
2522                         pattern = PHY_TEST_PATTERN_CP2520_2;
2523                         break;
2524                 case DP_TEST_PATTERN_CP2520_3:
2525                         pattern = PHY_TEST_PATTERN_CP2520_3;
2526                         break;
2527                 default:
2528                         return false;
2529                 }
2530
2531                 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
2532                 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
2533                         return false;
2534
2535                 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
2536                         /* tell receiver that we are sending qualification
2537                          * pattern DP 1.2 or later - DP receiver's link quality
2538                          * pattern is set using DPCD LINK_QUAL_LANEx_SET
2539                          * register (0x10B~0x10E)\
2540                          */
2541                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
2542                                 link_qual_pattern[lane] =
2543                                                 (unsigned char)(pattern);
2544
2545                         core_link_write_dpcd(link,
2546                                         DP_LINK_QUAL_LANE0_SET,
2547                                         link_qual_pattern,
2548                                         sizeof(link_qual_pattern));
2549                 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
2550                            link->dpcd_caps.dpcd_rev.raw == 0) {
2551                         /* tell receiver that we are sending qualification
2552                          * pattern DP 1.1a or earlier - DP receiver's link
2553                          * quality pattern is set using
2554                          * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
2555                          * register (0x102). We will use v_1.3 when we are
2556                          * setting test pattern for DP 1.1.
2557                          */
2558                         core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
2559                                             &training_pattern.raw,
2560                                             sizeof(training_pattern));
2561                         training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
2562                         core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
2563                                              &training_pattern.raw,
2564                                              sizeof(training_pattern));
2565                 }
2566         } else {
2567         /* CRTC Patterns */
2568                 set_crtc_test_pattern(link, pipe_ctx, test_pattern);
2569                 /* Set Test Pattern state */
2570                 link->test_pattern_enabled = true;
2571         }
2572
2573         return true;
2574 }
2575
2576 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
2577 {
2578         unsigned char mstmCntl;
2579
2580         core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
2581         if (enable)
2582                 mstmCntl |= DP_MST_EN;
2583         else
2584                 mstmCntl &= (~DP_MST_EN);
2585
2586         core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
2587 }