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