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