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