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