drm/amd/display: Update link training fallback behaviour.
[linux-block.git] / drivers / gpu / drm / amd / display / dc / core / dc_link_dp.c
1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  */
24 #include "dm_services.h"
25 #include "dc.h"
26 #include "dc_link_dp.h"
27 #include "dm_helpers.h"
28 #include "opp.h"
29 #include "dsc.h"
30 #include "clk_mgr.h"
31 #include "resource.h"
32
33 #include "inc/core_types.h"
34 #include "link_hwss.h"
35 #include "dc_link_ddc.h"
36 #include "core_status.h"
37 #include "dpcd_defs.h"
38 #include "dc_dmub_srv.h"
39 #include "dce/dmub_hw_lock_mgr.h"
40 #include "inc/dc_link_dpia.h"
41 #include "inc/link_enc_cfg.h"
42 #include "link/link_dp_trace.h"
43
44 /*Travis*/
45 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
46 /*Nutmeg*/
47 static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
48
49 #define DC_LOGGER \
50         link->ctx->logger
51 #define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */
52
53 #include "link_dpcd.h"
54
55 #ifndef MAX
56 #define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
57 #endif
58 #ifndef MIN
59 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
60 #endif
61
62         /* maximum pre emphasis level allowed for each voltage swing level*/
63         static const enum dc_pre_emphasis
64         voltage_swing_to_pre_emphasis[] = { PRE_EMPHASIS_LEVEL3,
65                                             PRE_EMPHASIS_LEVEL2,
66                                             PRE_EMPHASIS_LEVEL1,
67                                             PRE_EMPHASIS_DISABLED };
68
69 enum {
70         POST_LT_ADJ_REQ_LIMIT = 6,
71         POST_LT_ADJ_REQ_TIMEOUT = 200
72 };
73
74 struct dp_lt_fallback_entry {
75         enum dc_lane_count lane_count;
76         enum dc_link_rate link_rate;
77 };
78
79 static const struct dp_lt_fallback_entry dp_lt_fallbacks[] = {
80                 /* This link training fallback array is ordered by
81                  * link bandwidth from highest to lowest.
82                  * DP specs makes it a normative policy to always
83                  * choose the next highest link bandwidth during
84                  * link training fallback.
85                  */
86                 {LANE_COUNT_FOUR, LINK_RATE_UHBR20},
87                 {LANE_COUNT_FOUR, LINK_RATE_UHBR13_5},
88                 {LANE_COUNT_TWO, LINK_RATE_UHBR20},
89                 {LANE_COUNT_FOUR, LINK_RATE_UHBR10},
90                 {LANE_COUNT_TWO, LINK_RATE_UHBR13_5},
91                 {LANE_COUNT_FOUR, LINK_RATE_HIGH3},
92                 {LANE_COUNT_ONE, LINK_RATE_UHBR20},
93                 {LANE_COUNT_TWO, LINK_RATE_UHBR10},
94                 {LANE_COUNT_FOUR, LINK_RATE_HIGH2},
95                 {LANE_COUNT_ONE, LINK_RATE_UHBR13_5},
96                 {LANE_COUNT_TWO, LINK_RATE_HIGH3},
97                 {LANE_COUNT_ONE, LINK_RATE_UHBR10},
98                 {LANE_COUNT_TWO, LINK_RATE_HIGH2},
99                 {LANE_COUNT_FOUR, LINK_RATE_HIGH},
100                 {LANE_COUNT_ONE, LINK_RATE_HIGH3},
101                 {LANE_COUNT_FOUR, LINK_RATE_LOW},
102                 {LANE_COUNT_ONE, LINK_RATE_HIGH2},
103                 {LANE_COUNT_TWO, LINK_RATE_HIGH},
104                 {LANE_COUNT_TWO, LINK_RATE_LOW},
105                 {LANE_COUNT_ONE, LINK_RATE_HIGH},
106                 {LANE_COUNT_ONE, LINK_RATE_LOW},
107 };
108
109 static const struct dc_link_settings fail_safe_link_settings = {
110                 .lane_count = LANE_COUNT_ONE,
111                 .link_rate = LINK_RATE_LOW,
112                 .link_spread = LINK_SPREAD_DISABLED,
113 };
114
115 static bool decide_fallback_link_setting(
116                 struct dc_link *link,
117                 struct dc_link_settings initial_link_settings,
118                 struct dc_link_settings *current_link_setting,
119                 enum link_training_result training_result);
120 static void maximize_lane_settings(const struct link_training_settings *lt_settings,
121                 struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
122 static void override_lane_settings(const struct link_training_settings *lt_settings,
123                 struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]);
124
125 static uint32_t get_cr_training_aux_rd_interval(struct dc_link *link,
126                 const struct dc_link_settings *link_settings)
127 {
128         union training_aux_rd_interval training_rd_interval;
129         uint32_t wait_in_micro_secs = 100;
130
131         memset(&training_rd_interval, 0, sizeof(training_rd_interval));
132         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
133                         link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
134                 core_link_read_dpcd(
135                                 link,
136                                 DP_TRAINING_AUX_RD_INTERVAL,
137                                 (uint8_t *)&training_rd_interval,
138                                 sizeof(training_rd_interval));
139                 if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
140                         wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
141         }
142
143         return wait_in_micro_secs;
144 }
145
146 static uint32_t get_eq_training_aux_rd_interval(
147         struct dc_link *link,
148         const struct dc_link_settings *link_settings)
149 {
150         union training_aux_rd_interval training_rd_interval;
151
152         memset(&training_rd_interval, 0, sizeof(training_rd_interval));
153         if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING) {
154                 core_link_read_dpcd(
155                                 link,
156                                 DP_128b_132b_TRAINING_AUX_RD_INTERVAL,
157                                 (uint8_t *)&training_rd_interval,
158                                 sizeof(training_rd_interval));
159         } else if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING &&
160                         link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
161                 core_link_read_dpcd(
162                                 link,
163                                 DP_TRAINING_AUX_RD_INTERVAL,
164                                 (uint8_t *)&training_rd_interval,
165                                 sizeof(training_rd_interval));
166         }
167
168         switch (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL) {
169         case 0: return 400;
170         case 1: return 4000;
171         case 2: return 8000;
172         case 3: return 12000;
173         case 4: return 16000;
174         case 5: return 32000;
175         case 6: return 64000;
176         default: return 400;
177         }
178 }
179
180 void dp_wait_for_training_aux_rd_interval(
181         struct dc_link *link,
182         uint32_t wait_in_micro_secs)
183 {
184         if (wait_in_micro_secs > 1000)
185                 msleep(wait_in_micro_secs/1000);
186         else
187                 udelay(wait_in_micro_secs);
188
189         DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
190                 __func__,
191                 wait_in_micro_secs);
192 }
193
194 enum dpcd_training_patterns
195         dc_dp_training_pattern_to_dpcd_training_pattern(
196         struct dc_link *link,
197         enum dc_dp_training_pattern pattern)
198 {
199         enum dpcd_training_patterns dpcd_tr_pattern =
200         DPCD_TRAINING_PATTERN_VIDEOIDLE;
201
202         switch (pattern) {
203         case DP_TRAINING_PATTERN_SEQUENCE_1:
204                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
205                 break;
206         case DP_TRAINING_PATTERN_SEQUENCE_2:
207                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
208                 break;
209         case DP_TRAINING_PATTERN_SEQUENCE_3:
210                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
211                 break;
212         case DP_TRAINING_PATTERN_SEQUENCE_4:
213                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
214                 break;
215         case DP_128b_132b_TPS1:
216                 dpcd_tr_pattern = DPCD_128b_132b_TPS1;
217                 break;
218         case DP_128b_132b_TPS2:
219                 dpcd_tr_pattern = DPCD_128b_132b_TPS2;
220                 break;
221         case DP_128b_132b_TPS2_CDS:
222                 dpcd_tr_pattern = DPCD_128b_132b_TPS2_CDS;
223                 break;
224         case DP_TRAINING_PATTERN_VIDEOIDLE:
225                 dpcd_tr_pattern = DPCD_TRAINING_PATTERN_VIDEOIDLE;
226                 break;
227         default:
228                 ASSERT(0);
229                 DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
230                         __func__, pattern);
231                 break;
232         }
233
234         return dpcd_tr_pattern;
235 }
236
237 static void dpcd_set_training_pattern(
238         struct dc_link *link,
239         enum dc_dp_training_pattern training_pattern)
240 {
241         union dpcd_training_pattern dpcd_pattern = {0};
242
243         dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
244                         dc_dp_training_pattern_to_dpcd_training_pattern(
245                                         link, training_pattern);
246
247         core_link_write_dpcd(
248                 link,
249                 DP_TRAINING_PATTERN_SET,
250                 &dpcd_pattern.raw,
251                 1);
252
253         DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
254                 __func__,
255                 DP_TRAINING_PATTERN_SET,
256                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
257 }
258
259 static enum dc_dp_training_pattern decide_cr_training_pattern(
260                 const struct dc_link_settings *link_settings)
261 {
262         switch (dp_get_link_encoding_format(link_settings)) {
263         case DP_8b_10b_ENCODING:
264         default:
265                 return DP_TRAINING_PATTERN_SEQUENCE_1;
266         case DP_128b_132b_ENCODING:
267                 return DP_128b_132b_TPS1;
268         }
269 }
270
271 static enum dc_dp_training_pattern decide_eq_training_pattern(struct dc_link *link,
272                 const struct dc_link_settings *link_settings)
273 {
274         struct link_encoder *link_enc;
275         struct encoder_feature_support *enc_caps;
276         struct dpcd_caps *rx_caps = &link->dpcd_caps;
277         enum dc_dp_training_pattern pattern = DP_TRAINING_PATTERN_SEQUENCE_2;
278
279         link_enc = link_enc_cfg_get_link_enc(link);
280         ASSERT(link_enc);
281         enc_caps = &link_enc->features;
282
283         switch (dp_get_link_encoding_format(link_settings)) {
284         case DP_8b_10b_ENCODING:
285                 if (enc_caps->flags.bits.IS_TPS4_CAPABLE &&
286                                 rx_caps->max_down_spread.bits.TPS4_SUPPORTED)
287                         pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
288                 else if (enc_caps->flags.bits.IS_TPS3_CAPABLE &&
289                                 rx_caps->max_ln_count.bits.TPS3_SUPPORTED)
290                         pattern = DP_TRAINING_PATTERN_SEQUENCE_3;
291                 else
292                         pattern = DP_TRAINING_PATTERN_SEQUENCE_2;
293                 break;
294         case DP_128b_132b_ENCODING:
295                 pattern = DP_128b_132b_TPS2;
296                 break;
297         default:
298                 pattern = DP_TRAINING_PATTERN_SEQUENCE_2;
299                 break;
300         }
301         return pattern;
302 }
303
304 static uint8_t get_dpcd_link_rate(const struct dc_link_settings *link_settings)
305 {
306         uint8_t link_rate = 0;
307         enum dp_link_encoding encoding = dp_get_link_encoding_format(link_settings);
308
309         if (encoding == DP_128b_132b_ENCODING)
310                 switch (link_settings->link_rate) {
311                 case LINK_RATE_UHBR10:
312                         link_rate = 0x1;
313                         break;
314                 case LINK_RATE_UHBR20:
315                         link_rate = 0x2;
316                         break;
317                 case LINK_RATE_UHBR13_5:
318                         link_rate = 0x4;
319                         break;
320                 default:
321                         link_rate = 0;
322                         break;
323                 }
324         else if (encoding == DP_8b_10b_ENCODING)
325                 link_rate = (uint8_t) link_settings->link_rate;
326         else
327                 link_rate = 0;
328
329         return link_rate;
330 }
331
332 static void vendor_specific_lttpr_wa_one_start(struct dc_link *link)
333 {
334         const uint8_t vendor_lttpr_write_data[4] = {0x1, 0x50, 0x63, 0xff};
335         const uint8_t offset = dp_convert_to_count(
336                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
337         uint32_t vendor_lttpr_write_address = 0xF004F;
338
339         if (offset != 0xFF)
340                 vendor_lttpr_write_address +=
341                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
342
343         /* W/A for certain LTTPR to reset their lane settings, part one of two */
344         core_link_write_dpcd(
345                         link,
346                         vendor_lttpr_write_address,
347                         &vendor_lttpr_write_data[0],
348                         sizeof(vendor_lttpr_write_data));
349 }
350
351 static void vendor_specific_lttpr_wa_one_two(
352         struct dc_link *link,
353         const uint8_t rate)
354 {
355         if (link->apply_vendor_specific_lttpr_link_rate_wa) {
356                 uint8_t toggle_rate = 0x0;
357
358                 if (rate == 0x6)
359                         toggle_rate = 0xA;
360                 else
361                         toggle_rate = 0x6;
362
363                 if (link->vendor_specific_lttpr_link_rate_wa == rate) {
364                         /* W/A for certain LTTPR to reset internal state for link training */
365                         core_link_write_dpcd(
366                                         link,
367                                         DP_LINK_BW_SET,
368                                         &toggle_rate,
369                                         1);
370                 }
371
372                 /* Store the last attempted link rate for this link */
373                 link->vendor_specific_lttpr_link_rate_wa = rate;
374         }
375 }
376
377 static void dp_fixed_vs_pe_read_lane_adjust(
378         struct dc_link *link,
379         union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX])
380 {
381         const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63};
382         const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63};
383         const uint8_t offset = dp_convert_to_count(
384                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
385         uint32_t vendor_lttpr_write_address = 0xF004F;
386         uint32_t vendor_lttpr_read_address = 0xF0053;
387         uint8_t dprx_vs = 0;
388         uint8_t dprx_pe = 0;
389         uint8_t lane;
390
391         if (offset != 0xFF) {
392                 vendor_lttpr_write_address +=
393                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
394                 vendor_lttpr_read_address +=
395                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
396         }
397
398         /* W/A to read lane settings requested by DPRX */
399         core_link_write_dpcd(
400                         link,
401                         vendor_lttpr_write_address,
402                         &vendor_lttpr_write_data_vs[0],
403                         sizeof(vendor_lttpr_write_data_vs));
404         core_link_read_dpcd(
405                         link,
406                         vendor_lttpr_read_address,
407                         &dprx_vs,
408                         1);
409         core_link_write_dpcd(
410                         link,
411                         vendor_lttpr_write_address,
412                         &vendor_lttpr_write_data_pe[0],
413                         sizeof(vendor_lttpr_write_data_pe));
414         core_link_read_dpcd(
415                         link,
416                         vendor_lttpr_read_address,
417                         &dprx_pe,
418                         1);
419
420         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
421                 dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET  = (dprx_vs >> (2 * lane)) & 0x3;
422                 dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET = (dprx_pe >> (2 * lane)) & 0x3;
423         }
424 }
425
426 static void vendor_specific_lttpr_wa_four(
427         struct dc_link *link,
428         bool apply_wa)
429 {
430         const uint8_t vendor_lttpr_write_data_one[4] = {0x1, 0x55, 0x63, 0x8};
431         const uint8_t vendor_lttpr_write_data_two[4] = {0x1, 0x55, 0x63, 0x0};
432         const uint8_t offset = dp_convert_to_count(
433                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
434         uint32_t vendor_lttpr_write_address = 0xF004F;
435         uint8_t sink_status = 0;
436         uint8_t i;
437
438         if (offset != 0xFF)
439                 vendor_lttpr_write_address +=
440                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
441
442         /* W/A to pass through DPCD write of TPS=0 to DPRX */
443         if (apply_wa) {
444                 core_link_write_dpcd(
445                                 link,
446                                 vendor_lttpr_write_address,
447                                 &vendor_lttpr_write_data_one[0],
448                                 sizeof(vendor_lttpr_write_data_one));
449         }
450
451         /* clear training pattern set */
452         dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
453
454         if (apply_wa) {
455                 core_link_write_dpcd(
456                                 link,
457                                 vendor_lttpr_write_address,
458                                 &vendor_lttpr_write_data_two[0],
459                                 sizeof(vendor_lttpr_write_data_two));
460         }
461
462         /* poll for intra-hop disable */
463         for (i = 0; i < 10; i++) {
464                 if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) &&
465                                 (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0)
466                         break;
467                 udelay(1000);
468         }
469 }
470
471 static void dp_fixed_vs_pe_set_retimer_lane_settings(
472         struct dc_link *link,
473         const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX],
474         uint8_t lane_count)
475 {
476         const uint8_t offset = dp_convert_to_count(
477                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
478         const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
479         uint32_t vendor_lttpr_write_address = 0xF004F;
480         uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0};
481         uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0};
482         uint8_t lane = 0;
483
484         if (offset != 0xFF) {
485                 vendor_lttpr_write_address +=
486                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
487         }
488
489         for (lane = 0; lane < lane_count; lane++) {
490                 vendor_lttpr_write_data_vs[3] |=
491                                 dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
492                 vendor_lttpr_write_data_pe[3] |=
493                                 dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
494         }
495
496         /* Force LTTPR to output desired VS and PE */
497         core_link_write_dpcd(
498                         link,
499                         vendor_lttpr_write_address,
500                         &vendor_lttpr_write_data_reset[0],
501                         sizeof(vendor_lttpr_write_data_reset));
502         core_link_write_dpcd(
503                         link,
504                         vendor_lttpr_write_address,
505                         &vendor_lttpr_write_data_vs[0],
506                         sizeof(vendor_lttpr_write_data_vs));
507         core_link_write_dpcd(
508                         link,
509                         vendor_lttpr_write_address,
510                         &vendor_lttpr_write_data_pe[0],
511                         sizeof(vendor_lttpr_write_data_pe));
512 }
513
514 enum dc_status dpcd_set_link_settings(
515         struct dc_link *link,
516         const struct link_training_settings *lt_settings)
517 {
518         uint8_t rate;
519         enum dc_status status;
520
521         union down_spread_ctrl downspread = {0};
522         union lane_count_set lane_count_set = {0};
523
524         downspread.raw = (uint8_t)
525         (lt_settings->link_settings.link_spread);
526
527         lane_count_set.bits.LANE_COUNT_SET =
528         lt_settings->link_settings.lane_count;
529
530         lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
531         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
532
533
534         if (link->ep_type == DISPLAY_ENDPOINT_PHY &&
535                         lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) {
536                 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
537                                 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
538         }
539
540         status = core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
541                 &downspread.raw, sizeof(downspread));
542
543         status = core_link_write_dpcd(link, DP_LANE_COUNT_SET,
544                 &lane_count_set.raw, 1);
545
546         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
547                         lt_settings->link_settings.use_link_rate_set == true) {
548                 rate = 0;
549                 /* WA for some MUX chips that will power down with eDP and lose supported
550                  * link rate set for eDP 1.4. Source reads DPCD 0x010 again to ensure
551                  * MUX chip gets link rate set back before link training.
552                  */
553                 if (link->connector_signal == SIGNAL_TYPE_EDP) {
554                         uint8_t supported_link_rates[16];
555
556                         core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
557                                         supported_link_rates, sizeof(supported_link_rates));
558                 }
559                 status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
560                 status = core_link_write_dpcd(link, DP_LINK_RATE_SET,
561                                 &lt_settings->link_settings.link_rate_set, 1);
562         } else {
563                 rate = get_dpcd_link_rate(&lt_settings->link_settings);
564                 if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
565                                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
566                                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
567                         vendor_specific_lttpr_wa_one_start(link);
568
569                 if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
570                                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN))
571                         vendor_specific_lttpr_wa_one_two(link, rate);
572
573                 status = core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
574         }
575
576         if (rate) {
577                 DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
578                         __func__,
579                         DP_LINK_BW_SET,
580                         lt_settings->link_settings.link_rate,
581                         DP_LANE_COUNT_SET,
582                         lt_settings->link_settings.lane_count,
583                         lt_settings->enhanced_framing,
584                         DP_DOWNSPREAD_CTRL,
585                         lt_settings->link_settings.link_spread);
586         } else {
587                 DC_LOG_HW_LINK_TRAINING("%s\n %x rate set = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
588                         __func__,
589                         DP_LINK_RATE_SET,
590                         lt_settings->link_settings.link_rate_set,
591                         DP_LANE_COUNT_SET,
592                         lt_settings->link_settings.lane_count,
593                         lt_settings->enhanced_framing,
594                         DP_DOWNSPREAD_CTRL,
595                         lt_settings->link_settings.link_spread);
596         }
597
598         return status;
599 }
600
601 uint8_t dc_dp_initialize_scrambling_data_symbols(
602         struct dc_link *link,
603         enum dc_dp_training_pattern pattern)
604 {
605         uint8_t disable_scrabled_data_symbols = 0;
606
607         switch (pattern) {
608         case DP_TRAINING_PATTERN_SEQUENCE_1:
609         case DP_TRAINING_PATTERN_SEQUENCE_2:
610         case DP_TRAINING_PATTERN_SEQUENCE_3:
611                 disable_scrabled_data_symbols = 1;
612                 break;
613         case DP_TRAINING_PATTERN_SEQUENCE_4:
614         case DP_128b_132b_TPS1:
615         case DP_128b_132b_TPS2:
616                 disable_scrabled_data_symbols = 0;
617                 break;
618         default:
619                 ASSERT(0);
620                 DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
621                         __func__, pattern);
622                 break;
623         }
624         return disable_scrabled_data_symbols;
625 }
626
627 static inline bool is_repeater(struct dc_link *link, uint32_t offset)
628 {
629         return (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (offset != 0);
630 }
631
632 static void dpcd_set_lt_pattern_and_lane_settings(
633         struct dc_link *link,
634         const struct link_training_settings *lt_settings,
635         enum dc_dp_training_pattern pattern,
636         uint32_t offset)
637 {
638         uint32_t dpcd_base_lt_offset;
639
640         uint8_t dpcd_lt_buffer[5] = {0};
641         union dpcd_training_pattern dpcd_pattern = { 0 };
642         uint32_t size_in_bytes;
643         bool edp_workaround = false; /* TODO link_prop.INTERNAL */
644         dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET;
645
646         if (is_repeater(link, offset))
647                 dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
648                         ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
649
650         /*****************************************************************
651         * DpcdAddress_TrainingPatternSet
652         *****************************************************************/
653         dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
654                 dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
655
656         dpcd_pattern.v1_4.SCRAMBLING_DISABLE =
657                 dc_dp_initialize_scrambling_data_symbols(link, pattern);
658
659         dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
660                 = dpcd_pattern.raw;
661
662         if (is_repeater(link, offset)) {
663                 DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n 0x%X pattern = %x\n",
664                         __func__,
665                         offset,
666                         dpcd_base_lt_offset,
667                         dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
668         } else {
669                 DC_LOG_HW_LINK_TRAINING("%s\n 0x%X pattern = %x\n",
670                         __func__,
671                         dpcd_base_lt_offset,
672                         dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
673         }
674
675         /* concatenate everything into one buffer*/
676         size_in_bytes = lt_settings->link_settings.lane_count *
677                         sizeof(lt_settings->dpcd_lane_settings[0]);
678
679          // 0x00103 - 0x00102
680         memmove(
681                 &dpcd_lt_buffer[DP_TRAINING_LANE0_SET - DP_TRAINING_PATTERN_SET],
682                 lt_settings->dpcd_lane_settings,
683                 size_in_bytes);
684
685         if (is_repeater(link, offset)) {
686                 if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
687                                 DP_128b_132b_ENCODING)
688                         DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
689                                         " 0x%X TX_FFE_PRESET_VALUE = %x\n",
690                                         __func__,
691                                         offset,
692                                         dpcd_base_lt_offset,
693                                         lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
694                 else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
695                                 DP_8b_10b_ENCODING)
696                 DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
697                                 " 0x%X VS set = %x PE set = %x max VS Reached = %x  max PE Reached = %x\n",
698                         __func__,
699                         offset,
700                         dpcd_base_lt_offset,
701                         lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
702                         lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
703                         lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
704                         lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
705         } else {
706                 if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
707                                 DP_128b_132b_ENCODING)
708                         DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
709                                         __func__,
710                                         dpcd_base_lt_offset,
711                                         lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
712                 else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
713                                 DP_8b_10b_ENCODING)
714                         DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
715                                         __func__,
716                                         dpcd_base_lt_offset,
717                                         lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
718                                         lt_settings->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
719                                         lt_settings->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
720                                         lt_settings->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
721         }
722         if (edp_workaround) {
723                 /* for eDP write in 2 parts because the 5-byte burst is
724                 * causing issues on some eDP panels (EPR#366724)
725                 */
726                 core_link_write_dpcd(
727                         link,
728                         DP_TRAINING_PATTERN_SET,
729                         &dpcd_pattern.raw,
730                         sizeof(dpcd_pattern.raw));
731
732                 core_link_write_dpcd(
733                         link,
734                         DP_TRAINING_LANE0_SET,
735                         (uint8_t *)(lt_settings->dpcd_lane_settings),
736                         size_in_bytes);
737
738         } else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
739                         DP_128b_132b_ENCODING) {
740                 core_link_write_dpcd(
741                                 link,
742                                 dpcd_base_lt_offset,
743                                 dpcd_lt_buffer,
744                                 sizeof(dpcd_lt_buffer));
745         } else
746                 /* write it all in (1 + number-of-lanes)-byte burst*/
747                 core_link_write_dpcd(
748                                 link,
749                                 dpcd_base_lt_offset,
750                                 dpcd_lt_buffer,
751                                 size_in_bytes + sizeof(dpcd_pattern.raw));
752 }
753
754 bool dp_is_cr_done(enum dc_lane_count ln_count,
755         union lane_status *dpcd_lane_status)
756 {
757         uint32_t lane;
758         /*LANEx_CR_DONE bits All 1's?*/
759         for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
760                 if (!dpcd_lane_status[lane].bits.CR_DONE_0)
761                         return false;
762         }
763         return true;
764 }
765
766 bool dp_is_ch_eq_done(enum dc_lane_count ln_count,
767                 union lane_status *dpcd_lane_status)
768 {
769         bool done = true;
770         uint32_t lane;
771         for (lane = 0; lane < (uint32_t)(ln_count); lane++)
772                 if (!dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
773                         done = false;
774         return done;
775 }
776
777 bool dp_is_symbol_locked(enum dc_lane_count ln_count,
778                 union lane_status *dpcd_lane_status)
779 {
780         bool locked = true;
781         uint32_t lane;
782         for (lane = 0; lane < (uint32_t)(ln_count); lane++)
783                 if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0)
784                         locked = false;
785         return locked;
786 }
787
788 bool dp_is_interlane_aligned(union lane_align_status_updated align_status)
789 {
790         return align_status.bits.INTERLANE_ALIGN_DONE == 1;
791 }
792
793 void dp_hw_to_dpcd_lane_settings(
794                 const struct link_training_settings *lt_settings,
795                 const struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
796                 union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX])
797 {
798         uint8_t lane = 0;
799
800         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
801                 if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
802                                 DP_8b_10b_ENCODING) {
803                         dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET =
804                                         (uint8_t)(hw_lane_settings[lane].VOLTAGE_SWING);
805                         dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET =
806                                         (uint8_t)(hw_lane_settings[lane].PRE_EMPHASIS);
807                         dpcd_lane_settings[lane].bits.MAX_SWING_REACHED =
808                                         (hw_lane_settings[lane].VOLTAGE_SWING ==
809                                                         VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
810                         dpcd_lane_settings[lane].bits.MAX_PRE_EMPHASIS_REACHED =
811                                         (hw_lane_settings[lane].PRE_EMPHASIS ==
812                                                         PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
813                 }
814                 else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
815                                 DP_128b_132b_ENCODING) {
816                         dpcd_lane_settings[lane].tx_ffe.PRESET_VALUE =
817                                         hw_lane_settings[lane].FFE_PRESET.settings.level;
818                 }
819         }
820 }
821
822 void dp_decide_lane_settings(
823                 const struct link_training_settings *lt_settings,
824                 const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
825                 struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX],
826                 union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX])
827 {
828         uint32_t lane;
829
830         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
831                 if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
832                                 DP_8b_10b_ENCODING) {
833                         hw_lane_settings[lane].VOLTAGE_SWING =
834                                         (enum dc_voltage_swing)(ln_adjust[lane].bits.
835                                                         VOLTAGE_SWING_LANE);
836                         hw_lane_settings[lane].PRE_EMPHASIS =
837                                         (enum dc_pre_emphasis)(ln_adjust[lane].bits.
838                                                         PRE_EMPHASIS_LANE);
839                 }
840                 else if (dp_get_link_encoding_format(&lt_settings->link_settings) ==
841                                 DP_128b_132b_ENCODING) {
842                         hw_lane_settings[lane].FFE_PRESET.raw =
843                                         ln_adjust[lane].tx_ffe.PRESET_VALUE;
844                 }
845         }
846         dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
847
848         if (lt_settings->disallow_per_lane_settings) {
849                 /* we find the maximum of the requested settings across all lanes*/
850                 /* and set this maximum for all lanes*/
851                 maximize_lane_settings(lt_settings, hw_lane_settings);
852                 override_lane_settings(lt_settings, hw_lane_settings);
853
854                 if (lt_settings->always_match_dpcd_with_hw_lane_settings)
855                         dp_hw_to_dpcd_lane_settings(lt_settings, hw_lane_settings, dpcd_lane_settings);
856         }
857
858 }
859
860 static uint8_t get_nibble_at_index(const uint8_t *buf,
861         uint32_t index)
862 {
863         uint8_t nibble;
864         nibble = buf[index / 2];
865
866         if (index % 2)
867                 nibble >>= 4;
868         else
869                 nibble &= 0x0F;
870
871         return nibble;
872 }
873
874 static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
875         enum dc_voltage_swing voltage)
876 {
877         enum dc_pre_emphasis pre_emphasis;
878         pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
879
880         if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
881                 pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
882
883         return pre_emphasis;
884
885 }
886
887 static void maximize_lane_settings(const struct link_training_settings *lt_settings,
888                 struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
889 {
890         uint32_t lane;
891         struct dc_lane_settings max_requested;
892
893         max_requested.VOLTAGE_SWING = lane_settings[0].VOLTAGE_SWING;
894         max_requested.PRE_EMPHASIS = lane_settings[0].PRE_EMPHASIS;
895         max_requested.FFE_PRESET = lane_settings[0].FFE_PRESET;
896
897         /* Determine what the maximum of the requested settings are*/
898         for (lane = 1; lane < lt_settings->link_settings.lane_count; lane++) {
899                 if (lane_settings[lane].VOLTAGE_SWING > max_requested.VOLTAGE_SWING)
900                         max_requested.VOLTAGE_SWING = lane_settings[lane].VOLTAGE_SWING;
901
902                 if (lane_settings[lane].PRE_EMPHASIS > max_requested.PRE_EMPHASIS)
903                         max_requested.PRE_EMPHASIS = lane_settings[lane].PRE_EMPHASIS;
904                 if (lane_settings[lane].FFE_PRESET.settings.level >
905                                 max_requested.FFE_PRESET.settings.level)
906                         max_requested.FFE_PRESET.settings.level =
907                                         lane_settings[lane].FFE_PRESET.settings.level;
908         }
909
910         /* make sure the requested settings are
911          * not higher than maximum settings*/
912         if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
913                 max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
914
915         if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
916                 max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
917         if (max_requested.FFE_PRESET.settings.level > DP_FFE_PRESET_MAX_LEVEL)
918                 max_requested.FFE_PRESET.settings.level = DP_FFE_PRESET_MAX_LEVEL;
919
920         /* make sure the pre-emphasis matches the voltage swing*/
921         if (max_requested.PRE_EMPHASIS >
922                 get_max_pre_emphasis_for_voltage_swing(
923                         max_requested.VOLTAGE_SWING))
924                 max_requested.PRE_EMPHASIS =
925                 get_max_pre_emphasis_for_voltage_swing(
926                         max_requested.VOLTAGE_SWING);
927
928         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
929                 lane_settings[lane].VOLTAGE_SWING = max_requested.VOLTAGE_SWING;
930                 lane_settings[lane].PRE_EMPHASIS = max_requested.PRE_EMPHASIS;
931                 lane_settings[lane].FFE_PRESET = max_requested.FFE_PRESET;
932         }
933 }
934
935 static void override_lane_settings(const struct link_training_settings *lt_settings,
936                 struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
937 {
938         uint32_t lane;
939
940         if (lt_settings->voltage_swing == NULL &&
941             lt_settings->pre_emphasis == NULL &&
942             lt_settings->ffe_preset == NULL &&
943             lt_settings->post_cursor2 == NULL)
944
945                 return;
946
947         for (lane = 1; lane < LANE_COUNT_DP_MAX; lane++) {
948                 if (lt_settings->voltage_swing)
949                         lane_settings[lane].VOLTAGE_SWING = *lt_settings->voltage_swing;
950                 if (lt_settings->pre_emphasis)
951                         lane_settings[lane].PRE_EMPHASIS = *lt_settings->pre_emphasis;
952                 if (lt_settings->post_cursor2)
953                         lane_settings[lane].POST_CURSOR2 = *lt_settings->post_cursor2;
954                 if (lt_settings->ffe_preset)
955                         lane_settings[lane].FFE_PRESET = *lt_settings->ffe_preset;
956         }
957 }
958
959 enum dc_status dp_get_lane_status_and_lane_adjust(
960         struct dc_link *link,
961         const struct link_training_settings *link_training_setting,
962         union lane_status ln_status[LANE_COUNT_DP_MAX],
963         union lane_align_status_updated *ln_align,
964         union lane_adjust ln_adjust[LANE_COUNT_DP_MAX],
965         uint32_t offset)
966 {
967         unsigned int lane01_status_address = DP_LANE0_1_STATUS;
968         uint8_t lane_adjust_offset = 4;
969         unsigned int lane01_adjust_address;
970         uint8_t dpcd_buf[6] = {0};
971         uint32_t lane;
972         enum dc_status status;
973
974         if (is_repeater(link, offset)) {
975                 lane01_status_address =
976                                 DP_LANE0_1_STATUS_PHY_REPEATER1 +
977                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
978                 lane_adjust_offset = 3;
979         }
980
981         status = core_link_read_dpcd(
982                 link,
983                 lane01_status_address,
984                 (uint8_t *)(dpcd_buf),
985                 sizeof(dpcd_buf));
986
987         if (status != DC_OK) {
988                 DC_LOG_HW_LINK_TRAINING("%s:\n Failed to read from address 0x%X,"
989                         " keep current lane status and lane adjust unchanged",
990                         __func__,
991                         lane01_status_address);
992                 return status;
993         }
994
995         for (lane = 0; lane <
996                 (uint32_t)(link_training_setting->link_settings.lane_count);
997                 lane++) {
998
999                 ln_status[lane].raw =
1000                         get_nibble_at_index(&dpcd_buf[0], lane);
1001                 ln_adjust[lane].raw =
1002                         get_nibble_at_index(&dpcd_buf[lane_adjust_offset], lane);
1003         }
1004
1005         ln_align->raw = dpcd_buf[2];
1006
1007         if (is_repeater(link, offset)) {
1008                 DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
1009                                 " 0x%X Lane01Status = %x\n 0x%X Lane23Status = %x\n ",
1010                         __func__,
1011                         offset,
1012                         lane01_status_address, dpcd_buf[0],
1013                         lane01_status_address + 1, dpcd_buf[1]);
1014         } else {
1015                 DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X Lane01Status = %x\n 0x%X Lane23Status = %x\n ",
1016                         __func__,
1017                         lane01_status_address, dpcd_buf[0],
1018                         lane01_status_address + 1, dpcd_buf[1]);
1019         }
1020         lane01_adjust_address = DP_ADJUST_REQUEST_LANE0_1;
1021
1022         if (is_repeater(link, offset))
1023                 lane01_adjust_address = DP_ADJUST_REQUEST_LANE0_1_PHY_REPEATER1 +
1024                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
1025
1026         if (is_repeater(link, offset)) {
1027                 DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
1028                                 " 0x%X Lane01AdjustRequest = %x\n 0x%X Lane23AdjustRequest = %x\n",
1029                                         __func__,
1030                                         offset,
1031                                         lane01_adjust_address,
1032                                         dpcd_buf[lane_adjust_offset],
1033                                         lane01_adjust_address + 1,
1034                                         dpcd_buf[lane_adjust_offset + 1]);
1035         } else {
1036                 DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X Lane01AdjustRequest = %x\n 0x%X Lane23AdjustRequest = %x\n",
1037                         __func__,
1038                         lane01_adjust_address,
1039                         dpcd_buf[lane_adjust_offset],
1040                         lane01_adjust_address + 1,
1041                         dpcd_buf[lane_adjust_offset + 1]);
1042         }
1043
1044         return status;
1045 }
1046
1047 enum dc_status dpcd_set_lane_settings(
1048         struct dc_link *link,
1049         const struct link_training_settings *link_training_setting,
1050         uint32_t offset)
1051 {
1052         unsigned int lane0_set_address;
1053         enum dc_status status;
1054
1055         lane0_set_address = DP_TRAINING_LANE0_SET;
1056
1057         if (is_repeater(link, offset))
1058                 lane0_set_address = DP_TRAINING_LANE0_SET_PHY_REPEATER1 +
1059                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
1060
1061         status = core_link_write_dpcd(link,
1062                 lane0_set_address,
1063                 (uint8_t *)(link_training_setting->dpcd_lane_settings),
1064                 link_training_setting->link_settings.lane_count);
1065
1066         if (is_repeater(link, offset)) {
1067                 if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
1068                                 DP_128b_132b_ENCODING)
1069                         DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
1070                                         " 0x%X TX_FFE_PRESET_VALUE = %x\n",
1071                                         __func__,
1072                                         offset,
1073                                         lane0_set_address,
1074                                         link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
1075                 else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
1076                                 DP_8b_10b_ENCODING)
1077                 DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n"
1078                                 " 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
1079                         __func__,
1080                         offset,
1081                         lane0_set_address,
1082                         link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
1083                         link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
1084                         link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
1085                         link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
1086
1087         } else {
1088                 if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
1089                                 DP_128b_132b_ENCODING)
1090                         DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X TX_FFE_PRESET_VALUE = %x\n",
1091                                         __func__,
1092                                         lane0_set_address,
1093                                         link_training_setting->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE);
1094                 else if (dp_get_link_encoding_format(&link_training_setting->link_settings) ==
1095                                 DP_8b_10b_ENCODING)
1096                 DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
1097                         __func__,
1098                         lane0_set_address,
1099                         link_training_setting->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET,
1100                         link_training_setting->dpcd_lane_settings[0].bits.PRE_EMPHASIS_SET,
1101                         link_training_setting->dpcd_lane_settings[0].bits.MAX_SWING_REACHED,
1102                         link_training_setting->dpcd_lane_settings[0].bits.MAX_PRE_EMPHASIS_REACHED);
1103         }
1104
1105         return status;
1106 }
1107
1108 bool dp_is_max_vs_reached(
1109         const struct link_training_settings *lt_settings)
1110 {
1111         uint32_t lane;
1112         for (lane = 0; lane <
1113                 (uint32_t)(lt_settings->link_settings.lane_count);
1114                 lane++) {
1115                 if (lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET
1116                         == VOLTAGE_SWING_MAX_LEVEL)
1117                         return true;
1118         }
1119         return false;
1120
1121 }
1122
1123 static bool perform_post_lt_adj_req_sequence(
1124         struct dc_link *link,
1125         const struct link_resource *link_res,
1126         struct link_training_settings *lt_settings)
1127 {
1128         enum dc_lane_count lane_count =
1129         lt_settings->link_settings.lane_count;
1130
1131         uint32_t adj_req_count;
1132         uint32_t adj_req_timer;
1133         bool req_drv_setting_changed;
1134         uint32_t lane;
1135         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
1136         union lane_align_status_updated dpcd_lane_status_updated = {0};
1137         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
1138
1139         req_drv_setting_changed = false;
1140         for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
1141         adj_req_count++) {
1142
1143                 req_drv_setting_changed = false;
1144
1145                 for (adj_req_timer = 0;
1146                         adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
1147                         adj_req_timer++) {
1148
1149                         dp_get_lane_status_and_lane_adjust(
1150                                 link,
1151                                 lt_settings,
1152                                 dpcd_lane_status,
1153                                 &dpcd_lane_status_updated,
1154                                 dpcd_lane_adjust,
1155                                 DPRX);
1156
1157                         if (dpcd_lane_status_updated.bits.
1158                                         POST_LT_ADJ_REQ_IN_PROGRESS == 0)
1159                                 return true;
1160
1161                         if (!dp_is_cr_done(lane_count, dpcd_lane_status))
1162                                 return false;
1163
1164                         if (!dp_is_ch_eq_done(lane_count, dpcd_lane_status) ||
1165                                         !dp_is_symbol_locked(lane_count, dpcd_lane_status) ||
1166                                         !dp_is_interlane_aligned(dpcd_lane_status_updated))
1167                                 return false;
1168
1169                         for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
1170
1171                                 if (lt_settings->
1172                                 dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET !=
1173                                 dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_LANE ||
1174                                 lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET !=
1175                                 dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_LANE) {
1176
1177                                         req_drv_setting_changed = true;
1178                                         break;
1179                                 }
1180                         }
1181
1182                         if (req_drv_setting_changed) {
1183                                 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
1184                                                 lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1185
1186                                 dc_link_dp_set_drive_settings(link,
1187                                                 link_res,
1188                                                 lt_settings);
1189                                 break;
1190                         }
1191
1192                         msleep(1);
1193                 }
1194
1195                 if (!req_drv_setting_changed) {
1196                         DC_LOG_WARNING("%s: Post Link Training Adjust Request Timed out\n",
1197                                 __func__);
1198
1199                         ASSERT(0);
1200                         return true;
1201                 }
1202         }
1203         DC_LOG_WARNING("%s: Post Link Training Adjust Request limit reached\n",
1204                 __func__);
1205
1206         ASSERT(0);
1207         return true;
1208
1209 }
1210
1211 /* Only used for channel equalization */
1212 uint32_t dp_translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval)
1213 {
1214         unsigned int aux_rd_interval_us = 400;
1215
1216         switch (dpcd_aux_read_interval) {
1217         case 0x01:
1218                 aux_rd_interval_us = 4000;
1219                 break;
1220         case 0x02:
1221                 aux_rd_interval_us = 8000;
1222                 break;
1223         case 0x03:
1224                 aux_rd_interval_us = 12000;
1225                 break;
1226         case 0x04:
1227                 aux_rd_interval_us = 16000;
1228                 break;
1229         case 0x05:
1230                 aux_rd_interval_us = 32000;
1231                 break;
1232         case 0x06:
1233                 aux_rd_interval_us = 64000;
1234                 break;
1235         default:
1236                 break;
1237         }
1238
1239         return aux_rd_interval_us;
1240 }
1241
1242 enum link_training_result dp_get_cr_failure(enum dc_lane_count ln_count,
1243                                         union lane_status *dpcd_lane_status)
1244 {
1245         enum link_training_result result = LINK_TRAINING_SUCCESS;
1246
1247         if (ln_count >= LANE_COUNT_ONE && !dpcd_lane_status[0].bits.CR_DONE_0)
1248                 result = LINK_TRAINING_CR_FAIL_LANE0;
1249         else if (ln_count >= LANE_COUNT_TWO && !dpcd_lane_status[1].bits.CR_DONE_0)
1250                 result = LINK_TRAINING_CR_FAIL_LANE1;
1251         else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[2].bits.CR_DONE_0)
1252                 result = LINK_TRAINING_CR_FAIL_LANE23;
1253         else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[3].bits.CR_DONE_0)
1254                 result = LINK_TRAINING_CR_FAIL_LANE23;
1255         return result;
1256 }
1257
1258 static enum link_training_result perform_channel_equalization_sequence(
1259         struct dc_link *link,
1260         const struct link_resource *link_res,
1261         struct link_training_settings *lt_settings,
1262         uint32_t offset)
1263 {
1264         enum dc_dp_training_pattern tr_pattern;
1265         uint32_t retries_ch_eq;
1266         uint32_t wait_time_microsec;
1267         enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
1268         union lane_align_status_updated dpcd_lane_status_updated = {0};
1269         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
1270         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
1271
1272         /* Note: also check that TPS4 is a supported feature*/
1273         tr_pattern = lt_settings->pattern_for_eq;
1274
1275         if (is_repeater(link, offset) && dp_get_link_encoding_format(&lt_settings->link_settings) == DP_8b_10b_ENCODING)
1276                 tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
1277
1278         dp_set_hw_training_pattern(link, link_res, tr_pattern, offset);
1279
1280         for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
1281                 retries_ch_eq++) {
1282
1283                 dp_set_hw_lane_settings(link, link_res, lt_settings, offset);
1284
1285                 /* 2. update DPCD*/
1286                 if (!retries_ch_eq)
1287                         /* EPR #361076 - write as a 5-byte burst,
1288                          * but only for the 1-st iteration
1289                          */
1290
1291                         dpcd_set_lt_pattern_and_lane_settings(
1292                                 link,
1293                                 lt_settings,
1294                                 tr_pattern, offset);
1295                 else
1296                         dpcd_set_lane_settings(link, lt_settings, offset);
1297
1298                 /* 3. wait for receiver to lock-on*/
1299                 wait_time_microsec = lt_settings->eq_pattern_time;
1300
1301                 if (is_repeater(link, offset))
1302                         wait_time_microsec =
1303                                         dp_translate_training_aux_read_interval(
1304                                                 link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]);
1305
1306                 if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
1307                                 (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
1308                                 link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
1309                         wait_time_microsec = 16000;
1310                 }
1311
1312                 dp_wait_for_training_aux_rd_interval(
1313                                 link,
1314                                 wait_time_microsec);
1315
1316                 /* 4. Read lane status and requested
1317                  * drive settings as set by the sink*/
1318
1319                 dp_get_lane_status_and_lane_adjust(
1320                         link,
1321                         lt_settings,
1322                         dpcd_lane_status,
1323                         &dpcd_lane_status_updated,
1324                         dpcd_lane_adjust,
1325                         offset);
1326
1327                 /* 5. check CR done*/
1328                 if (!dp_is_cr_done(lane_count, dpcd_lane_status))
1329                         return LINK_TRAINING_EQ_FAIL_CR;
1330
1331                 /* 6. check CHEQ done*/
1332                 if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
1333                                 dp_is_symbol_locked(lane_count, dpcd_lane_status) &&
1334                                 dp_is_interlane_aligned(dpcd_lane_status_updated))
1335                         return LINK_TRAINING_SUCCESS;
1336
1337                 /* 7. update VS/PE/PC2 in lt_settings*/
1338                 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
1339                                 lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1340         }
1341
1342         return LINK_TRAINING_EQ_FAIL_EQ;
1343
1344 }
1345
1346 static void start_clock_recovery_pattern_early(struct dc_link *link,
1347                 const struct link_resource *link_res,
1348                 struct link_training_settings *lt_settings,
1349                 uint32_t offset)
1350 {
1351         DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS1. Wait 400us.\n",
1352                         __func__);
1353         dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset);
1354         dp_set_hw_lane_settings(link, link_res, lt_settings, offset);
1355         udelay(400);
1356 }
1357
1358 static enum link_training_result perform_clock_recovery_sequence(
1359         struct dc_link *link,
1360         const struct link_resource *link_res,
1361         struct link_training_settings *lt_settings,
1362         uint32_t offset)
1363 {
1364         uint32_t retries_cr;
1365         uint32_t retry_count;
1366         uint32_t wait_time_microsec;
1367         enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
1368         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
1369         union lane_align_status_updated dpcd_lane_status_updated;
1370         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
1371
1372         retries_cr = 0;
1373         retry_count = 0;
1374
1375         memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
1376         memset(&dpcd_lane_status_updated, '\0',
1377         sizeof(dpcd_lane_status_updated));
1378
1379         if (!link->ctx->dc->work_arounds.lt_early_cr_pattern)
1380                 dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, offset);
1381
1382         /* najeeb - The synaptics MST hub can put the LT in
1383         * infinite loop by switching the VS
1384         */
1385         /* between level 0 and level 1 continuously, here
1386         * we try for CR lock for LinkTrainingMaxCRRetry count*/
1387         while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
1388                 (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
1389
1390
1391                 /* 1. call HWSS to set lane settings*/
1392                 dp_set_hw_lane_settings(
1393                                 link,
1394                                 link_res,
1395                                 lt_settings,
1396                                 offset);
1397
1398                 /* 2. update DPCD of the receiver*/
1399                 if (!retry_count)
1400                         /* EPR #361076 - write as a 5-byte burst,
1401                          * but only for the 1-st iteration.*/
1402                         dpcd_set_lt_pattern_and_lane_settings(
1403                                         link,
1404                                         lt_settings,
1405                                         lt_settings->pattern_for_cr,
1406                                         offset);
1407                 else
1408                         dpcd_set_lane_settings(
1409                                         link,
1410                                         lt_settings,
1411                                         offset);
1412
1413                 /* 3. wait receiver to lock-on*/
1414                 wait_time_microsec = lt_settings->cr_pattern_time;
1415
1416                 if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
1417                                 (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) {
1418                         wait_time_microsec = 16000;
1419                 }
1420
1421                 dp_wait_for_training_aux_rd_interval(
1422                                 link,
1423                                 wait_time_microsec);
1424
1425                 /* 4. Read lane status and requested drive
1426                 * settings as set by the sink
1427                 */
1428                 dp_get_lane_status_and_lane_adjust(
1429                                 link,
1430                                 lt_settings,
1431                                 dpcd_lane_status,
1432                                 &dpcd_lane_status_updated,
1433                                 dpcd_lane_adjust,
1434                                 offset);
1435
1436                 /* 5. check CR done*/
1437                 if (dp_is_cr_done(lane_count, dpcd_lane_status))
1438                         return LINK_TRAINING_SUCCESS;
1439
1440                 /* 6. max VS reached*/
1441                 if ((dp_get_link_encoding_format(&lt_settings->link_settings) ==
1442                                 DP_8b_10b_ENCODING) &&
1443                                 dp_is_max_vs_reached(lt_settings))
1444                         break;
1445
1446                 /* 7. same lane settings*/
1447                 /* Note: settings are the same for all lanes,
1448                  * so comparing first lane is sufficient*/
1449                 if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_8b_10b_ENCODING) &&
1450                                 lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
1451                                                 dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
1452                         retries_cr++;
1453                 else if ((dp_get_link_encoding_format(&lt_settings->link_settings) == DP_128b_132b_ENCODING) &&
1454                                 lt_settings->dpcd_lane_settings[0].tx_ffe.PRESET_VALUE ==
1455                                                 dpcd_lane_adjust[0].tx_ffe.PRESET_VALUE)
1456                         retries_cr++;
1457                 else
1458                         retries_cr = 0;
1459
1460                 /* 8. update VS/PE/PC2 in lt_settings*/
1461                 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
1462                                 lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1463                 retry_count++;
1464         }
1465
1466         if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
1467                 ASSERT(0);
1468                 DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
1469                         __func__,
1470                         LINK_TRAINING_MAX_CR_RETRY);
1471
1472         }
1473
1474         return dp_get_cr_failure(lane_count, dpcd_lane_status);
1475 }
1476
1477 static inline enum link_training_result dp_transition_to_video_idle(
1478         struct dc_link *link,
1479         const struct link_resource *link_res,
1480         struct link_training_settings *lt_settings,
1481         enum link_training_result status)
1482 {
1483         union lane_count_set lane_count_set = {0};
1484
1485         /* 4. mainlink output idle pattern*/
1486         dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
1487
1488         /*
1489          * 5. post training adjust if required
1490          * If the upstream DPTX and downstream DPRX both support TPS4,
1491          * TPS4 must be used instead of POST_LT_ADJ_REQ.
1492          */
1493         if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
1494                         lt_settings->pattern_for_eq >= DP_TRAINING_PATTERN_SEQUENCE_4) {
1495                 /* delay 5ms after Main Link output idle pattern and then check
1496                  * DPCD 0202h.
1497                  */
1498                 if (link->connector_signal != SIGNAL_TYPE_EDP && status == LINK_TRAINING_SUCCESS) {
1499                         msleep(5);
1500                         status = dp_check_link_loss_status(link, lt_settings);
1501                 }
1502                 return status;
1503         }
1504
1505         if (status == LINK_TRAINING_SUCCESS &&
1506                 perform_post_lt_adj_req_sequence(link, link_res, lt_settings) == false)
1507                 status = LINK_TRAINING_LQA_FAIL;
1508
1509         lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
1510         lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
1511         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
1512
1513         core_link_write_dpcd(
1514                 link,
1515                 DP_LANE_COUNT_SET,
1516                 &lane_count_set.raw,
1517                 sizeof(lane_count_set));
1518
1519         return status;
1520 }
1521
1522 enum link_training_result dp_check_link_loss_status(
1523         struct dc_link *link,
1524         const struct link_training_settings *link_training_setting)
1525 {
1526         enum link_training_result status = LINK_TRAINING_SUCCESS;
1527         union lane_status lane_status;
1528         uint8_t dpcd_buf[6] = {0};
1529         uint32_t lane;
1530
1531         core_link_read_dpcd(
1532                         link,
1533                         DP_SINK_COUNT,
1534                         (uint8_t *)(dpcd_buf),
1535                         sizeof(dpcd_buf));
1536
1537         /*parse lane status*/
1538         for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
1539                 /*
1540                  * check lanes status
1541                  */
1542                 lane_status.raw = get_nibble_at_index(&dpcd_buf[2], lane);
1543
1544                 if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1545                         !lane_status.bits.CR_DONE_0 ||
1546                         !lane_status.bits.SYMBOL_LOCKED_0) {
1547                         /* if one of the channel equalization, clock
1548                          * recovery or symbol lock is dropped
1549                          * consider it as (link has been
1550                          * dropped) dp sink status has changed
1551                          */
1552                         status = LINK_TRAINING_LINK_LOSS;
1553                         break;
1554                 }
1555         }
1556
1557         return status;
1558 }
1559
1560 static inline void decide_8b_10b_training_settings(
1561          struct dc_link *link,
1562         const struct dc_link_settings *link_setting,
1563         struct link_training_settings *lt_settings)
1564 {
1565         memset(lt_settings, '\0', sizeof(struct link_training_settings));
1566
1567         /* Initialize link settings */
1568         lt_settings->link_settings.use_link_rate_set = link_setting->use_link_rate_set;
1569         lt_settings->link_settings.link_rate_set = link_setting->link_rate_set;
1570         lt_settings->link_settings.link_rate = link_setting->link_rate;
1571         lt_settings->link_settings.lane_count = link_setting->lane_count;
1572         /* TODO hard coded to SS for now
1573          * lt_settings.link_settings.link_spread =
1574          * dal_display_path_is_ss_supported(
1575          * path_mode->display_path) ?
1576          * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
1577          * LINK_SPREAD_DISABLED;
1578          */
1579         lt_settings->link_settings.link_spread = link->dp_ss_off ?
1580                         LINK_SPREAD_DISABLED : LINK_SPREAD_05_DOWNSPREAD_30KHZ;
1581         lt_settings->lttpr_mode = link->lttpr_mode;
1582         lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting);
1583         lt_settings->eq_pattern_time = get_eq_training_aux_rd_interval(link, link_setting);
1584         lt_settings->pattern_for_cr = decide_cr_training_pattern(link_setting);
1585         lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_setting);
1586         lt_settings->enhanced_framing = 1;
1587         lt_settings->should_set_fec_ready = true;
1588         lt_settings->disallow_per_lane_settings = true;
1589         lt_settings->always_match_dpcd_with_hw_lane_settings = true;
1590         dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1591 }
1592
1593 static inline void decide_128b_132b_training_settings(struct dc_link *link,
1594                 const struct dc_link_settings *link_settings,
1595                 struct link_training_settings *lt_settings)
1596 {
1597         memset(lt_settings, 0, sizeof(*lt_settings));
1598
1599         lt_settings->link_settings = *link_settings;
1600         /* TODO: should decide link spread when populating link_settings */
1601         lt_settings->link_settings.link_spread = link->dp_ss_off ? LINK_SPREAD_DISABLED :
1602                         LINK_SPREAD_05_DOWNSPREAD_30KHZ;
1603
1604         lt_settings->pattern_for_cr = decide_cr_training_pattern(link_settings);
1605         lt_settings->pattern_for_eq = decide_eq_training_pattern(link, link_settings);
1606         lt_settings->eq_pattern_time = 2500;
1607         lt_settings->eq_wait_time_limit = 400000;
1608         lt_settings->eq_loop_count_limit = 20;
1609         lt_settings->pattern_for_cds = DP_128b_132b_TPS2_CDS;
1610         lt_settings->cds_pattern_time = 2500;
1611         lt_settings->cds_wait_time_limit = (dp_convert_to_count(
1612                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt) + 1) * 20000;
1613         lt_settings->lttpr_mode = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) ?
1614                         LTTPR_MODE_NON_TRANSPARENT : LTTPR_MODE_TRANSPARENT;
1615         lt_settings->disallow_per_lane_settings = true;
1616         dp_hw_to_dpcd_lane_settings(lt_settings,
1617                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1618 }
1619
1620 void dp_decide_training_settings(
1621                 struct dc_link *link,
1622                 const struct dc_link_settings *link_settings,
1623                 struct link_training_settings *lt_settings)
1624 {
1625         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING)
1626                 decide_8b_10b_training_settings(link, link_settings, lt_settings);
1627         else if (dp_get_link_encoding_format(link_settings) == DP_128b_132b_ENCODING)
1628                 decide_128b_132b_training_settings(link, link_settings, lt_settings);
1629 }
1630
1631 static void override_training_settings(
1632                 struct dc_link *link,
1633                 const struct dc_link_training_overrides *overrides,
1634                 struct link_training_settings *lt_settings)
1635 {
1636         uint32_t lane;
1637
1638         /* Override link spread */
1639         if (!link->dp_ss_off && overrides->downspread != NULL)
1640                 lt_settings->link_settings.link_spread = *overrides->downspread ?
1641                                 LINK_SPREAD_05_DOWNSPREAD_30KHZ
1642                                 : LINK_SPREAD_DISABLED;
1643
1644         /* Override lane settings */
1645         if (overrides->voltage_swing != NULL)
1646                 lt_settings->voltage_swing = overrides->voltage_swing;
1647         if (overrides->pre_emphasis != NULL)
1648                 lt_settings->pre_emphasis = overrides->pre_emphasis;
1649         if (overrides->post_cursor2 != NULL)
1650                 lt_settings->post_cursor2 = overrides->post_cursor2;
1651         if (overrides->ffe_preset != NULL)
1652                 lt_settings->ffe_preset = overrides->ffe_preset;
1653         /* Override HW lane settings with BIOS forced values if present */
1654         if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN &&
1655                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
1656                 lt_settings->voltage_swing = &link->bios_forced_drive_settings.VOLTAGE_SWING;
1657                 lt_settings->pre_emphasis = &link->bios_forced_drive_settings.PRE_EMPHASIS;
1658                 lt_settings->always_match_dpcd_with_hw_lane_settings = false;
1659         }
1660         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
1661                 lt_settings->lane_settings[lane].VOLTAGE_SWING =
1662                         lt_settings->voltage_swing != NULL ?
1663                         *lt_settings->voltage_swing :
1664                         VOLTAGE_SWING_LEVEL0;
1665                 lt_settings->lane_settings[lane].PRE_EMPHASIS =
1666                         lt_settings->pre_emphasis != NULL ?
1667                         *lt_settings->pre_emphasis
1668                         : PRE_EMPHASIS_DISABLED;
1669                 lt_settings->lane_settings[lane].POST_CURSOR2 =
1670                         lt_settings->post_cursor2 != NULL ?
1671                         *lt_settings->post_cursor2
1672                         : POST_CURSOR2_DISABLED;
1673         }
1674
1675         dp_hw_to_dpcd_lane_settings(lt_settings,
1676                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1677
1678         /* Initialize training timings */
1679         if (overrides->cr_pattern_time != NULL)
1680                 lt_settings->cr_pattern_time = *overrides->cr_pattern_time;
1681
1682         if (overrides->eq_pattern_time != NULL)
1683                 lt_settings->eq_pattern_time = *overrides->eq_pattern_time;
1684
1685         if (overrides->pattern_for_cr != NULL)
1686                 lt_settings->pattern_for_cr = *overrides->pattern_for_cr;
1687         if (overrides->pattern_for_eq != NULL)
1688                 lt_settings->pattern_for_eq = *overrides->pattern_for_eq;
1689
1690         if (overrides->enhanced_framing != NULL)
1691                 lt_settings->enhanced_framing = *overrides->enhanced_framing;
1692
1693         if (link->preferred_training_settings.fec_enable != NULL)
1694                 lt_settings->should_set_fec_ready = *link->preferred_training_settings.fec_enable;
1695 }
1696
1697 uint8_t dp_convert_to_count(uint8_t lttpr_repeater_count)
1698 {
1699         switch (lttpr_repeater_count) {
1700         case 0x80: // 1 lttpr repeater
1701                 return 1;
1702         case 0x40: // 2 lttpr repeaters
1703                 return 2;
1704         case 0x20: // 3 lttpr repeaters
1705                 return 3;
1706         case 0x10: // 4 lttpr repeaters
1707                 return 4;
1708         case 0x08: // 5 lttpr repeaters
1709                 return 5;
1710         case 0x04: // 6 lttpr repeaters
1711                 return 6;
1712         case 0x02: // 7 lttpr repeaters
1713                 return 7;
1714         case 0x01: // 8 lttpr repeaters
1715                 return 8;
1716         default:
1717                 break;
1718         }
1719         return 0; // invalid value
1720 }
1721
1722 static enum dc_status configure_lttpr_mode_transparent(struct dc_link *link)
1723 {
1724         uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
1725
1726         DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
1727         return core_link_write_dpcd(link,
1728                         DP_PHY_REPEATER_MODE,
1729                         (uint8_t *)&repeater_mode,
1730                         sizeof(repeater_mode));
1731 }
1732
1733 static enum dc_status configure_lttpr_mode_non_transparent(
1734                 struct dc_link *link,
1735                 const struct link_training_settings *lt_settings)
1736 {
1737         /* aux timeout is already set to extended */
1738         /* RESET/SET lttpr mode to enable non transparent mode */
1739         uint8_t repeater_cnt;
1740         uint32_t aux_interval_address;
1741         uint8_t repeater_id;
1742         enum dc_status result = DC_ERROR_UNEXPECTED;
1743         uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
1744
1745         enum dp_link_encoding encoding = dp_get_link_encoding_format(&lt_settings->link_settings);
1746
1747         if (encoding == DP_8b_10b_ENCODING) {
1748                 DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
1749                 result = core_link_write_dpcd(link,
1750                                 DP_PHY_REPEATER_MODE,
1751                                 (uint8_t *)&repeater_mode,
1752                                 sizeof(repeater_mode));
1753
1754         }
1755
1756         if (result == DC_OK) {
1757                 link->dpcd_caps.lttpr_caps.mode = repeater_mode;
1758         }
1759
1760         if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
1761
1762                 DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__);
1763
1764                 repeater_mode = DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
1765                 result = core_link_write_dpcd(link,
1766                                 DP_PHY_REPEATER_MODE,
1767                                 (uint8_t *)&repeater_mode,
1768                                 sizeof(repeater_mode));
1769
1770                 if (result == DC_OK) {
1771                         link->dpcd_caps.lttpr_caps.mode = repeater_mode;
1772                 }
1773
1774                 if (encoding == DP_8b_10b_ENCODING) {
1775                         repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
1776
1777                         /* Driver does not need to train the first hop. Skip DPCD read and clear
1778                          * AUX_RD_INTERVAL for DPTX-to-DPIA hop.
1779                          */
1780                         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA)
1781                                 link->dpcd_caps.lttpr_caps.aux_rd_interval[--repeater_cnt] = 0;
1782
1783                         for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
1784                                 aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
1785                                                         ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
1786                                 core_link_read_dpcd(
1787                                         link,
1788                                         aux_interval_address,
1789                                         (uint8_t *)&link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1],
1790                                         sizeof(link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1]));
1791                                 link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1] &= 0x7F;
1792                         }
1793                 }
1794         }
1795
1796         return result;
1797 }
1798
1799 static void repeater_training_done(struct dc_link *link, uint32_t offset)
1800 {
1801         union dpcd_training_pattern dpcd_pattern = {0};
1802
1803         const uint32_t dpcd_base_lt_offset =
1804                         DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
1805                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
1806         /* Set training not in progress*/
1807         dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
1808
1809         core_link_write_dpcd(
1810                 link,
1811                 dpcd_base_lt_offset,
1812                 &dpcd_pattern.raw,
1813                 1);
1814
1815         DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Id: %d 0x%X pattern = %x\n",
1816                 __func__,
1817                 offset,
1818                 dpcd_base_lt_offset,
1819                 dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
1820 }
1821
1822 static void print_status_message(
1823         struct dc_link *link,
1824         const struct link_training_settings *lt_settings,
1825         enum link_training_result status)
1826 {
1827         char *link_rate = "Unknown";
1828         char *lt_result = "Unknown";
1829         char *lt_spread = "Disabled";
1830
1831         switch (lt_settings->link_settings.link_rate) {
1832         case LINK_RATE_LOW:
1833                 link_rate = "RBR";
1834                 break;
1835         case LINK_RATE_RATE_2:
1836                 link_rate = "R2";
1837                 break;
1838         case LINK_RATE_RATE_3:
1839                 link_rate = "R3";
1840                 break;
1841         case LINK_RATE_HIGH:
1842                 link_rate = "HBR";
1843                 break;
1844         case LINK_RATE_RBR2:
1845                 link_rate = "RBR2";
1846                 break;
1847         case LINK_RATE_RATE_6:
1848                 link_rate = "R6";
1849                 break;
1850         case LINK_RATE_HIGH2:
1851                 link_rate = "HBR2";
1852                 break;
1853         case LINK_RATE_HIGH3:
1854                 link_rate = "HBR3";
1855                 break;
1856         case LINK_RATE_UHBR10:
1857                 link_rate = "UHBR10";
1858                 break;
1859         case LINK_RATE_UHBR13_5:
1860                 link_rate = "UHBR13.5";
1861                 break;
1862         case LINK_RATE_UHBR20:
1863                 link_rate = "UHBR20";
1864                 break;
1865         default:
1866                 break;
1867         }
1868
1869         switch (status) {
1870         case LINK_TRAINING_SUCCESS:
1871                 lt_result = "pass";
1872                 break;
1873         case LINK_TRAINING_CR_FAIL_LANE0:
1874                 lt_result = "CR failed lane0";
1875                 break;
1876         case LINK_TRAINING_CR_FAIL_LANE1:
1877                 lt_result = "CR failed lane1";
1878                 break;
1879         case LINK_TRAINING_CR_FAIL_LANE23:
1880                 lt_result = "CR failed lane23";
1881                 break;
1882         case LINK_TRAINING_EQ_FAIL_CR:
1883                 lt_result = "CR failed in EQ";
1884                 break;
1885         case LINK_TRAINING_EQ_FAIL_EQ:
1886                 lt_result = "EQ failed";
1887                 break;
1888         case LINK_TRAINING_LQA_FAIL:
1889                 lt_result = "LQA failed";
1890                 break;
1891         case LINK_TRAINING_LINK_LOSS:
1892                 lt_result = "Link loss";
1893                 break;
1894         case DP_128b_132b_LT_FAILED:
1895                 lt_result = "LT_FAILED received";
1896                 break;
1897         case DP_128b_132b_MAX_LOOP_COUNT_REACHED:
1898                 lt_result = "max loop count reached";
1899                 break;
1900         case DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT:
1901                 lt_result = "channel EQ timeout";
1902                 break;
1903         case DP_128b_132b_CDS_DONE_TIMEOUT:
1904                 lt_result = "CDS timeout";
1905                 break;
1906         default:
1907                 break;
1908         }
1909
1910         switch (lt_settings->link_settings.link_spread) {
1911         case LINK_SPREAD_DISABLED:
1912                 lt_spread = "Disabled";
1913                 break;
1914         case LINK_SPREAD_05_DOWNSPREAD_30KHZ:
1915                 lt_spread = "0.5% 30KHz";
1916                 break;
1917         case LINK_SPREAD_05_DOWNSPREAD_33KHZ:
1918                 lt_spread = "0.5% 33KHz";
1919                 break;
1920         default:
1921                 break;
1922         }
1923
1924         /* Connectivity log: link training */
1925
1926         /* TODO - DP2.0 Log: add connectivity log for FFE PRESET */
1927
1928         CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s",
1929                                 link_rate,
1930                                 lt_settings->link_settings.lane_count,
1931                                 lt_result,
1932                                 lt_settings->lane_settings[0].VOLTAGE_SWING,
1933                                 lt_settings->lane_settings[0].PRE_EMPHASIS,
1934                                 lt_spread);
1935 }
1936
1937 void dc_link_dp_set_drive_settings(
1938         struct dc_link *link,
1939         const struct link_resource *link_res,
1940         struct link_training_settings *lt_settings)
1941 {
1942         /* program ASIC PHY settings*/
1943         dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
1944
1945         dp_hw_to_dpcd_lane_settings(lt_settings,
1946                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
1947
1948         /* Notify DP sink the PHY settings from source */
1949         dpcd_set_lane_settings(link, lt_settings, DPRX);
1950 }
1951
1952 bool dc_link_dp_perform_link_training_skip_aux(
1953         struct dc_link *link,
1954         const struct link_resource *link_res,
1955         const struct dc_link_settings *link_setting)
1956 {
1957         struct link_training_settings lt_settings = {0};
1958
1959         dp_decide_training_settings(
1960                         link,
1961                         link_setting,
1962                         &lt_settings);
1963         override_training_settings(
1964                         link,
1965                         &link->preferred_training_settings,
1966                         &lt_settings);
1967
1968         /* 1. Perform_clock_recovery_sequence. */
1969
1970         /* transmit training pattern for clock recovery */
1971         dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_cr, DPRX);
1972
1973         /* call HWSS to set lane settings*/
1974         dp_set_hw_lane_settings(link, link_res, &lt_settings, DPRX);
1975
1976         /* wait receiver to lock-on*/
1977         dp_wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
1978
1979         /* 2. Perform_channel_equalization_sequence. */
1980
1981         /* transmit training pattern for channel equalization. */
1982         dp_set_hw_training_pattern(link, link_res, lt_settings.pattern_for_eq, DPRX);
1983
1984         /* call HWSS to set lane settings*/
1985         dp_set_hw_lane_settings(link, link_res, &lt_settings, DPRX);
1986
1987         /* wait receiver to lock-on. */
1988         dp_wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
1989
1990         /* 3. Perform_link_training_int. */
1991
1992         /* Mainlink output idle pattern. */
1993         dp_set_hw_test_pattern(link, link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
1994
1995         print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS);
1996
1997         return true;
1998 }
1999
2000 enum dc_status dpcd_configure_lttpr_mode(struct dc_link *link, struct link_training_settings *lt_settings)
2001 {
2002         enum dc_status status = DC_OK;
2003
2004         if (lt_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT)
2005                 status = configure_lttpr_mode_transparent(link);
2006
2007         else if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT)
2008                 status = configure_lttpr_mode_non_transparent(link, lt_settings);
2009
2010         return status;
2011 }
2012
2013 static void dpcd_exit_training_mode(struct dc_link *link)
2014 {
2015         uint8_t sink_status = 0;
2016         uint8_t i;
2017
2018         /* clear training pattern set */
2019         dpcd_set_training_pattern(link, DP_TRAINING_PATTERN_VIDEOIDLE);
2020
2021         /* poll for intra-hop disable */
2022         for (i = 0; i < 10; i++) {
2023                 if ((core_link_read_dpcd(link, DP_SINK_STATUS, &sink_status, 1) == DC_OK) &&
2024                                 (sink_status & DP_INTRA_HOP_AUX_REPLY_INDICATION) == 0)
2025                         break;
2026                 udelay(1000);
2027         }
2028 }
2029
2030 enum dc_status dpcd_configure_channel_coding(struct dc_link *link,
2031                 struct link_training_settings *lt_settings)
2032 {
2033         enum dp_link_encoding encoding =
2034                         dp_get_link_encoding_format(
2035                                         &lt_settings->link_settings);
2036         enum dc_status status;
2037
2038         status = core_link_write_dpcd(
2039                         link,
2040                         DP_MAIN_LINK_CHANNEL_CODING_SET,
2041                         (uint8_t *) &encoding,
2042                         1);
2043         DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X MAIN_LINK_CHANNEL_CODING_SET = %x\n",
2044                                         __func__,
2045                                         DP_MAIN_LINK_CHANNEL_CODING_SET,
2046                                         encoding);
2047
2048         return status;
2049 }
2050
2051 static void dpcd_128b_132b_get_aux_rd_interval(struct dc_link *link,
2052                 uint32_t *interval_in_us)
2053 {
2054         union dp_128b_132b_training_aux_rd_interval dpcd_interval;
2055         uint32_t interval_unit = 0;
2056
2057         dpcd_interval.raw = 0;
2058         core_link_read_dpcd(link, DP_128b_132b_TRAINING_AUX_RD_INTERVAL,
2059                         &dpcd_interval.raw, sizeof(dpcd_interval.raw));
2060         interval_unit = dpcd_interval.bits.UNIT ? 1 : 2; /* 0b = 2 ms, 1b = 1 ms */
2061         /* (128b/132b_TRAINING_AUX_RD_INTERVAL value + 1) *
2062          * INTERVAL_UNIT. The maximum is 256 ms
2063          */
2064         *interval_in_us = (dpcd_interval.bits.VALUE + 1) * interval_unit * 1000;
2065 }
2066
2067 static enum link_training_result dp_perform_128b_132b_channel_eq_done_sequence(
2068                 struct dc_link *link,
2069                 const struct link_resource *link_res,
2070                 struct link_training_settings *lt_settings)
2071 {
2072         uint8_t loop_count;
2073         uint32_t aux_rd_interval = 0;
2074         uint32_t wait_time = 0;
2075         union lane_align_status_updated dpcd_lane_status_updated = {0};
2076         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
2077         enum link_training_result status = LINK_TRAINING_SUCCESS;
2078         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
2079
2080         /* Transmit 128b/132b_TPS1 over Main-Link */
2081         dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_cr, DPRX);
2082         /* Set TRAINING_PATTERN_SET to 01h */
2083         dpcd_set_training_pattern(link, lt_settings->pattern_for_cr);
2084
2085         /* Adjust TX_FFE_PRESET_VALUE and Transmit 128b/132b_TPS2 over Main-Link */
2086         dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
2087         dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
2088                         &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
2089         dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
2090                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
2091         dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
2092         dp_set_hw_training_pattern(link, link_res, lt_settings->pattern_for_eq, DPRX);
2093
2094         /* Set loop counter to start from 1 */
2095         loop_count = 1;
2096
2097         /* Set TRAINING_PATTERN_SET to 02h and TX_FFE_PRESET_VALUE in one AUX transaction */
2098         dpcd_set_lt_pattern_and_lane_settings(link, lt_settings,
2099                         lt_settings->pattern_for_eq, DPRX);
2100
2101         /* poll for channel EQ done */
2102         while (status == LINK_TRAINING_SUCCESS) {
2103                 dp_wait_for_training_aux_rd_interval(link, aux_rd_interval);
2104                 wait_time += aux_rd_interval;
2105                 dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
2106                                 &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
2107                 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
2108                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
2109                 dpcd_128b_132b_get_aux_rd_interval(link, &aux_rd_interval);
2110                 if (dp_is_ch_eq_done(lt_settings->link_settings.lane_count,
2111                                 dpcd_lane_status)) {
2112                         /* pass */
2113                         break;
2114                 } else if (loop_count >= lt_settings->eq_loop_count_limit) {
2115                         status = DP_128b_132b_MAX_LOOP_COUNT_REACHED;
2116                 } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
2117                         status = DP_128b_132b_LT_FAILED;
2118                 } else {
2119                         dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX);
2120                         dpcd_set_lane_settings(link, lt_settings, DPRX);
2121                 }
2122                 loop_count++;
2123         }
2124
2125         /* poll for EQ interlane align done */
2126         while (status == LINK_TRAINING_SUCCESS) {
2127                 if (dpcd_lane_status_updated.bits.EQ_INTERLANE_ALIGN_DONE_128b_132b) {
2128                         /* pass */
2129                         break;
2130                 } else if (wait_time >= lt_settings->eq_wait_time_limit) {
2131                         status = DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT;
2132                 } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
2133                         status = DP_128b_132b_LT_FAILED;
2134                 } else {
2135                         dp_wait_for_training_aux_rd_interval(link,
2136                                         lt_settings->eq_pattern_time);
2137                         wait_time += lt_settings->eq_pattern_time;
2138                         dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
2139                                         &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
2140                 }
2141         }
2142
2143         return status;
2144 }
2145
2146 static enum link_training_result dp_perform_128b_132b_cds_done_sequence(
2147                 struct dc_link *link,
2148                 const struct link_resource *link_res,
2149                 struct link_training_settings *lt_settings)
2150 {
2151         /* Assumption: assume hardware has transmitted eq pattern */
2152         enum link_training_result status = LINK_TRAINING_SUCCESS;
2153         union lane_align_status_updated dpcd_lane_status_updated = {0};
2154         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
2155         union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
2156         uint32_t wait_time = 0;
2157
2158         /* initiate CDS done sequence */
2159         dpcd_set_training_pattern(link, lt_settings->pattern_for_cds);
2160
2161         /* poll for CDS interlane align done and symbol lock */
2162         while (status == LINK_TRAINING_SUCCESS) {
2163                 dp_wait_for_training_aux_rd_interval(link,
2164                                 lt_settings->cds_pattern_time);
2165                 wait_time += lt_settings->cds_pattern_time;
2166                 dp_get_lane_status_and_lane_adjust(link, lt_settings, dpcd_lane_status,
2167                                                 &dpcd_lane_status_updated, dpcd_lane_adjust, DPRX);
2168                 if (dp_is_symbol_locked(lt_settings->link_settings.lane_count, dpcd_lane_status) &&
2169                                 dpcd_lane_status_updated.bits.CDS_INTERLANE_ALIGN_DONE_128b_132b) {
2170                         /* pass */
2171                         break;
2172                 } else if (dpcd_lane_status_updated.bits.LT_FAILED_128b_132b) {
2173                         status = DP_128b_132b_LT_FAILED;
2174                 } else if (wait_time >= lt_settings->cds_wait_time_limit) {
2175                         status = DP_128b_132b_CDS_DONE_TIMEOUT;
2176                 }
2177         }
2178
2179         return status;
2180 }
2181
2182 static enum link_training_result dp_perform_8b_10b_link_training(
2183                 struct dc_link *link,
2184                 const struct link_resource *link_res,
2185                 struct link_training_settings *lt_settings)
2186 {
2187         enum link_training_result status = LINK_TRAINING_SUCCESS;
2188
2189         uint8_t repeater_cnt;
2190         uint8_t repeater_id;
2191         uint8_t lane = 0;
2192
2193         if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
2194                 start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
2195
2196         /* 1. set link rate, lane count and spread. */
2197         dpcd_set_link_settings(link, lt_settings);
2198
2199         if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
2200
2201                 /* 2. perform link training (set link training done
2202                  *  to false is done as well)
2203                  */
2204                 repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
2205
2206                 for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
2207                                 repeater_id--) {
2208                         status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
2209
2210                         if (status != LINK_TRAINING_SUCCESS) {
2211                                 repeater_training_done(link, repeater_id);
2212                                 break;
2213                         }
2214
2215                         status = perform_channel_equalization_sequence(link,
2216                                         link_res,
2217                                         lt_settings,
2218                                         repeater_id);
2219
2220                         repeater_training_done(link, repeater_id);
2221
2222                         if (status != LINK_TRAINING_SUCCESS)
2223                                 break;
2224
2225                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
2226                                 lt_settings->dpcd_lane_settings[lane].raw = 0;
2227                                 lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
2228                                 lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
2229                         }
2230                 }
2231         }
2232
2233         if (status == LINK_TRAINING_SUCCESS) {
2234                 status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
2235                 if (status == LINK_TRAINING_SUCCESS) {
2236                         status = perform_channel_equalization_sequence(link,
2237                                                                        link_res,
2238                                                                        lt_settings,
2239                                                                        DPRX);
2240                 }
2241         }
2242
2243         return status;
2244 }
2245
2246 static enum link_training_result dp_perform_128b_132b_link_training(
2247                 struct dc_link *link,
2248                 const struct link_resource *link_res,
2249                 struct link_training_settings *lt_settings)
2250 {
2251         enum link_training_result result = LINK_TRAINING_SUCCESS;
2252
2253         /* TODO - DP2.0 Link: remove legacy_dp2_lt logic */
2254         if (link->dc->debug.legacy_dp2_lt) {
2255                 struct link_training_settings legacy_settings;
2256
2257                 decide_8b_10b_training_settings(link,
2258                                 &lt_settings->link_settings,
2259                                 &legacy_settings);
2260                 return dp_perform_8b_10b_link_training(link, link_res, &legacy_settings);
2261         }
2262
2263         dpcd_set_link_settings(link, lt_settings);
2264
2265         if (result == LINK_TRAINING_SUCCESS)
2266                 result = dp_perform_128b_132b_channel_eq_done_sequence(link, link_res, lt_settings);
2267
2268         if (result == LINK_TRAINING_SUCCESS)
2269                 result = dp_perform_128b_132b_cds_done_sequence(link, link_res, lt_settings);
2270
2271         return result;
2272 }
2273
2274 static enum link_training_result perform_fixed_vs_pe_nontransparent_training_sequence(
2275                 struct dc_link *link,
2276                 const struct link_resource *link_res,
2277                 struct link_training_settings *lt_settings)
2278 {
2279         enum link_training_result status = LINK_TRAINING_SUCCESS;
2280         uint8_t lane = 0;
2281         uint8_t toggle_rate = 0x6;
2282         uint8_t target_rate = 0x6;
2283         bool apply_toggle_rate_wa = false;
2284         uint8_t repeater_cnt;
2285         uint8_t repeater_id;
2286
2287         /* Fixed VS/PE specific: Force CR AUX RD Interval to at least 16ms */
2288         if (lt_settings->cr_pattern_time < 16000)
2289                 lt_settings->cr_pattern_time = 16000;
2290
2291         /* Fixed VS/PE specific: Toggle link rate */
2292         apply_toggle_rate_wa = (link->vendor_specific_lttpr_link_rate_wa == target_rate);
2293         target_rate = get_dpcd_link_rate(&lt_settings->link_settings);
2294         toggle_rate = (target_rate == 0x6) ? 0xA : 0x6;
2295
2296         if (apply_toggle_rate_wa)
2297                 lt_settings->link_settings.link_rate = toggle_rate;
2298
2299         if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
2300                 start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
2301
2302         /* 1. set link rate, lane count and spread. */
2303         dpcd_set_link_settings(link, lt_settings);
2304
2305         /* Fixed VS/PE specific: Toggle link rate back*/
2306         if (apply_toggle_rate_wa) {
2307                 core_link_write_dpcd(
2308                                 link,
2309                                 DP_LINK_BW_SET,
2310                                 &target_rate,
2311                                 1);
2312         }
2313
2314         link->vendor_specific_lttpr_link_rate_wa = target_rate;
2315
2316         if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
2317
2318                 /* 2. perform link training (set link training done
2319                  *  to false is done as well)
2320                  */
2321                 repeater_cnt = dp_convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
2322
2323                 for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
2324                                 repeater_id--) {
2325                         status = perform_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
2326
2327                         if (status != LINK_TRAINING_SUCCESS) {
2328                                 repeater_training_done(link, repeater_id);
2329                                 break;
2330                         }
2331
2332                         status = perform_channel_equalization_sequence(link,
2333                                         link_res,
2334                                         lt_settings,
2335                                         repeater_id);
2336
2337                         repeater_training_done(link, repeater_id);
2338
2339                         if (status != LINK_TRAINING_SUCCESS)
2340                                 break;
2341
2342                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
2343                                 lt_settings->dpcd_lane_settings[lane].raw = 0;
2344                                 lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
2345                                 lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
2346                         }
2347                 }
2348         }
2349
2350         if (status == LINK_TRAINING_SUCCESS) {
2351                 status = perform_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
2352                 if (status == LINK_TRAINING_SUCCESS) {
2353                         status = perform_channel_equalization_sequence(link,
2354                                                                        link_res,
2355                                                                        lt_settings,
2356                                                                        DPRX);
2357                 }
2358         }
2359
2360         return status;
2361 }
2362
2363 static enum link_training_result dp_perform_fixed_vs_pe_training_sequence(
2364         struct dc_link *link,
2365         const struct link_resource *link_res,
2366         struct link_training_settings *lt_settings)
2367 {
2368         const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
2369         const uint8_t offset = dp_convert_to_count(
2370                         link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
2371         const uint8_t vendor_lttpr_write_data_intercept_en[4] = {0x1, 0x55, 0x63, 0x0};
2372         const uint8_t vendor_lttpr_write_data_intercept_dis[4] = {0x1, 0x55, 0x63, 0x68};
2373         uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0};
2374         uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0};
2375         uint32_t vendor_lttpr_write_address = 0xF004F;
2376         enum link_training_result status = LINK_TRAINING_SUCCESS;
2377         uint8_t lane = 0;
2378         union down_spread_ctrl downspread = {0};
2379         union lane_count_set lane_count_set = {0};
2380         uint8_t toggle_rate;
2381         uint8_t rate;
2382
2383         /* Only 8b/10b is supported */
2384         ASSERT(dp_get_link_encoding_format(&lt_settings->link_settings) ==
2385                         DP_8b_10b_ENCODING);
2386
2387         if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
2388                 status = perform_fixed_vs_pe_nontransparent_training_sequence(link, link_res, lt_settings);
2389                 return status;
2390         }
2391
2392         if (offset != 0xFF) {
2393                 vendor_lttpr_write_address +=
2394                                 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
2395         }
2396
2397         /* Vendor specific: Reset lane settings */
2398         core_link_write_dpcd(
2399                         link,
2400                         vendor_lttpr_write_address,
2401                         &vendor_lttpr_write_data_reset[0],
2402                         sizeof(vendor_lttpr_write_data_reset));
2403         core_link_write_dpcd(
2404                         link,
2405                         vendor_lttpr_write_address,
2406                         &vendor_lttpr_write_data_vs[0],
2407                         sizeof(vendor_lttpr_write_data_vs));
2408         core_link_write_dpcd(
2409                         link,
2410                         vendor_lttpr_write_address,
2411                         &vendor_lttpr_write_data_pe[0],
2412                         sizeof(vendor_lttpr_write_data_pe));
2413
2414         /* Vendor specific: Enable intercept */
2415         core_link_write_dpcd(
2416                         link,
2417                         vendor_lttpr_write_address,
2418                         &vendor_lttpr_write_data_intercept_en[0],
2419                         sizeof(vendor_lttpr_write_data_intercept_en));
2420
2421         /* 1. set link rate, lane count and spread. */
2422
2423         downspread.raw = (uint8_t)(lt_settings->link_settings.link_spread);
2424
2425         lane_count_set.bits.LANE_COUNT_SET =
2426         lt_settings->link_settings.lane_count;
2427
2428         lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
2429         lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
2430
2431
2432         if (lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) {
2433                 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
2434                                 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
2435         }
2436
2437         core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
2438                 &downspread.raw, sizeof(downspread));
2439
2440         core_link_write_dpcd(link, DP_LANE_COUNT_SET,
2441                 &lane_count_set.raw, 1);
2442
2443         rate = get_dpcd_link_rate(&lt_settings->link_settings);
2444
2445         /* Vendor specific: Toggle link rate */
2446         toggle_rate = (rate == 0x6) ? 0xA : 0x6;
2447
2448         if (link->vendor_specific_lttpr_link_rate_wa == rate) {
2449                 core_link_write_dpcd(
2450                                 link,
2451                                 DP_LINK_BW_SET,
2452                                 &toggle_rate,
2453                                 1);
2454         }
2455
2456         link->vendor_specific_lttpr_link_rate_wa = rate;
2457
2458         core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
2459
2460         DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
2461                 __func__,
2462                 DP_LINK_BW_SET,
2463                 lt_settings->link_settings.link_rate,
2464                 DP_LANE_COUNT_SET,
2465                 lt_settings->link_settings.lane_count,
2466                 lt_settings->enhanced_framing,
2467                 DP_DOWNSPREAD_CTRL,
2468                 lt_settings->link_settings.link_spread);
2469
2470         /* 2. Perform link training */
2471
2472         /* Perform Clock Recovery Sequence */
2473         if (status == LINK_TRAINING_SUCCESS) {
2474                 uint32_t retries_cr;
2475                 uint32_t retry_count;
2476                 uint32_t wait_time_microsec;
2477                 enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
2478                 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
2479                 union lane_align_status_updated dpcd_lane_status_updated;
2480                 union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
2481
2482                 retries_cr = 0;
2483                 retry_count = 0;
2484
2485                 memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
2486                 memset(&dpcd_lane_status_updated, '\0',
2487                 sizeof(dpcd_lane_status_updated));
2488
2489                 while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
2490                         (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
2491
2492
2493                         /* 1. call HWSS to set lane settings */
2494                         dp_set_hw_lane_settings(
2495                                         link,
2496                                         link_res,
2497                                         lt_settings,
2498                                         0);
2499
2500                         /* 2. update DPCD of the receiver */
2501                         if (!retry_count) {
2502                                 /* EPR #361076 - write as a 5-byte burst,
2503                                  * but only for the 1-st iteration.
2504                                  */
2505                                 dpcd_set_lt_pattern_and_lane_settings(
2506                                                 link,
2507                                                 lt_settings,
2508                                                 lt_settings->pattern_for_cr,
2509                                                 0);
2510                                 /* Vendor specific: Disable intercept */
2511                                 core_link_write_dpcd(
2512                                                 link,
2513                                                 vendor_lttpr_write_address,
2514                                                 &vendor_lttpr_write_data_intercept_dis[0],
2515                                                 sizeof(vendor_lttpr_write_data_intercept_dis));
2516                         } else {
2517                                 vendor_lttpr_write_data_vs[3] = 0;
2518                                 vendor_lttpr_write_data_pe[3] = 0;
2519
2520                                 for (lane = 0; lane < lane_count; lane++) {
2521                                         vendor_lttpr_write_data_vs[3] |=
2522                                                         lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
2523                                         vendor_lttpr_write_data_pe[3] |=
2524                                                         lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
2525                                 }
2526
2527                                 /* Vendor specific: Update VS and PE to DPRX requested value */
2528                                 core_link_write_dpcd(
2529                                                 link,
2530                                                 vendor_lttpr_write_address,
2531                                                 &vendor_lttpr_write_data_vs[0],
2532                                                 sizeof(vendor_lttpr_write_data_vs));
2533                                 core_link_write_dpcd(
2534                                                 link,
2535                                                 vendor_lttpr_write_address,
2536                                                 &vendor_lttpr_write_data_pe[0],
2537                                                 sizeof(vendor_lttpr_write_data_pe));
2538
2539                                 dpcd_set_lane_settings(
2540                                                 link,
2541                                                 lt_settings,
2542                                                 0);
2543                         }
2544
2545                         /* 3. wait receiver to lock-on*/
2546                         wait_time_microsec = lt_settings->cr_pattern_time;
2547
2548                         dp_wait_for_training_aux_rd_interval(
2549                                         link,
2550                                         wait_time_microsec);
2551
2552                         /* 4. Read lane status and requested drive
2553                          * settings as set by the sink
2554                          */
2555                         dp_get_lane_status_and_lane_adjust(
2556                                         link,
2557                                         lt_settings,
2558                                         dpcd_lane_status,
2559                                         &dpcd_lane_status_updated,
2560                                         dpcd_lane_adjust,
2561                                         0);
2562
2563                         /* 5. check CR done*/
2564                         if (dp_is_cr_done(lane_count, dpcd_lane_status)) {
2565                                 status = LINK_TRAINING_SUCCESS;
2566                                 break;
2567                         }
2568
2569                         /* 6. max VS reached*/
2570                         if (dp_is_max_vs_reached(lt_settings))
2571                                 break;
2572
2573                         /* 7. same lane settings */
2574                         /* Note: settings are the same for all lanes,
2575                          * so comparing first lane is sufficient
2576                          */
2577                         if (lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
2578                                         dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
2579                                 retries_cr++;
2580                         else
2581                                 retries_cr = 0;
2582
2583                         /* 8. update VS/PE/PC2 in lt_settings*/
2584                         dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
2585                                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
2586                         retry_count++;
2587                 }
2588
2589                 if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
2590                         ASSERT(0);
2591                         DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
2592                                 __func__,
2593                                 LINK_TRAINING_MAX_CR_RETRY);
2594
2595                 }
2596
2597                 status = dp_get_cr_failure(lane_count, dpcd_lane_status);
2598         }
2599
2600         /* Perform Channel EQ Sequence */
2601         if (status == LINK_TRAINING_SUCCESS) {
2602                 enum dc_dp_training_pattern tr_pattern;
2603                 uint32_t retries_ch_eq;
2604                 uint32_t wait_time_microsec;
2605                 enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
2606                 union lane_align_status_updated dpcd_lane_status_updated = {0};
2607                 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
2608                 union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
2609
2610                 /* Note: also check that TPS4 is a supported feature*/
2611                 tr_pattern = lt_settings->pattern_for_eq;
2612
2613                 dp_set_hw_training_pattern(link, link_res, tr_pattern, 0);
2614
2615                 status = LINK_TRAINING_EQ_FAIL_EQ;
2616
2617                 for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
2618                         retries_ch_eq++) {
2619
2620                         dp_set_hw_lane_settings(link, link_res, lt_settings, 0);
2621
2622                         vendor_lttpr_write_data_vs[3] = 0;
2623                         vendor_lttpr_write_data_pe[3] = 0;
2624
2625                         for (lane = 0; lane < lane_count; lane++) {
2626                                 vendor_lttpr_write_data_vs[3] |=
2627                                                 lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
2628                                 vendor_lttpr_write_data_pe[3] |=
2629                                                 lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
2630                         }
2631
2632                         /* Vendor specific: Update VS and PE to DPRX requested value */
2633                         core_link_write_dpcd(
2634                                         link,
2635                                         vendor_lttpr_write_address,
2636                                         &vendor_lttpr_write_data_vs[0],
2637                                         sizeof(vendor_lttpr_write_data_vs));
2638                         core_link_write_dpcd(
2639                                         link,
2640                                         vendor_lttpr_write_address,
2641                                         &vendor_lttpr_write_data_pe[0],
2642                                         sizeof(vendor_lttpr_write_data_pe));
2643
2644                         /* 2. update DPCD*/
2645                         if (!retries_ch_eq)
2646                                 /* EPR #361076 - write as a 5-byte burst,
2647                                  * but only for the 1-st iteration
2648                                  */
2649
2650                                 dpcd_set_lt_pattern_and_lane_settings(
2651                                         link,
2652                                         lt_settings,
2653                                         tr_pattern, 0);
2654                         else
2655                                 dpcd_set_lane_settings(link, lt_settings, 0);
2656
2657                         /* 3. wait for receiver to lock-on*/
2658                         wait_time_microsec = lt_settings->eq_pattern_time;
2659
2660                         dp_wait_for_training_aux_rd_interval(
2661                                         link,
2662                                         wait_time_microsec);
2663
2664                         /* 4. Read lane status and requested
2665                          * drive settings as set by the sink
2666                          */
2667                         dp_get_lane_status_and_lane_adjust(
2668                                 link,
2669                                 lt_settings,
2670                                 dpcd_lane_status,
2671                                 &dpcd_lane_status_updated,
2672                                 dpcd_lane_adjust,
2673                                 0);
2674
2675                         /* 5. check CR done*/
2676                         if (!dp_is_cr_done(lane_count, dpcd_lane_status)) {
2677                                 status = LINK_TRAINING_EQ_FAIL_CR;
2678                                 break;
2679                         }
2680
2681                         /* 6. check CHEQ done*/
2682                         if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
2683                                         dp_is_symbol_locked(lane_count, dpcd_lane_status) &&
2684                                         dp_is_interlane_aligned(dpcd_lane_status_updated)) {
2685                                 status = LINK_TRAINING_SUCCESS;
2686                                 break;
2687                         }
2688
2689                         /* 7. update VS/PE/PC2 in lt_settings*/
2690                         dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
2691                                         lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
2692                 }
2693         }
2694
2695         return status;
2696 }
2697
2698
2699 enum link_training_result dc_link_dp_perform_link_training(
2700         struct dc_link *link,
2701         const struct link_resource *link_res,
2702         const struct dc_link_settings *link_settings,
2703         bool skip_video_pattern)
2704 {
2705         enum link_training_result status = LINK_TRAINING_SUCCESS;
2706         struct link_training_settings lt_settings = {0};
2707         enum dp_link_encoding encoding =
2708                         dp_get_link_encoding_format(link_settings);
2709
2710         /* decide training settings */
2711         dp_decide_training_settings(
2712                         link,
2713                         link_settings,
2714                         &lt_settings);
2715         override_training_settings(
2716                         link,
2717                         &link->preferred_training_settings,
2718                         &lt_settings);
2719
2720         /* reset previous training states */
2721         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
2722                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
2723                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
2724                 link->apply_vendor_specific_lttpr_link_rate_wa = true;
2725                 vendor_specific_lttpr_wa_four(link, true);
2726         } else {
2727                 dpcd_exit_training_mode(link);
2728         }
2729
2730         /* configure link prior to entering training mode */
2731         dpcd_configure_lttpr_mode(link, &lt_settings);
2732         dp_set_fec_ready(link, link_res, lt_settings.should_set_fec_ready);
2733         dpcd_configure_channel_coding(link, &lt_settings);
2734
2735         /* enter training mode:
2736          * Per DP specs starting from here, DPTX device shall not issue
2737          * Non-LT AUX transactions inside training mode.
2738          */
2739         if (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)
2740                 status = dp_perform_fixed_vs_pe_training_sequence(link, link_res, &lt_settings);
2741         else if (encoding == DP_8b_10b_ENCODING)
2742                 status = dp_perform_8b_10b_link_training(link, link_res, &lt_settings);
2743         else if (encoding == DP_128b_132b_ENCODING)
2744                 status = dp_perform_128b_132b_link_training(link, link_res, &lt_settings);
2745         else
2746                 ASSERT(0);
2747
2748         /* exit training mode */
2749         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
2750                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
2751                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
2752                 link->apply_vendor_specific_lttpr_link_rate_wa = false;
2753                 vendor_specific_lttpr_wa_four(link, (status != LINK_TRAINING_SUCCESS));
2754         } else {
2755                 dpcd_exit_training_mode(link);
2756         }
2757
2758         /* switch to video idle */
2759         if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern)
2760                 status = dp_transition_to_video_idle(link,
2761                                 link_res,
2762                                 &lt_settings,
2763                                 status);
2764
2765         /* dump debug data */
2766         print_status_message(link, &lt_settings, status);
2767         if (status != LINK_TRAINING_SUCCESS)
2768                 link->ctx->dc->debug_data.ltFailCount++;
2769         return status;
2770 }
2771
2772 bool perform_link_training_with_retries(
2773         const struct dc_link_settings *link_setting,
2774         bool skip_video_pattern,
2775         int attempts,
2776         struct pipe_ctx *pipe_ctx,
2777         enum signal_type signal,
2778         bool do_fallback)
2779 {
2780         int j;
2781         uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY;
2782         struct dc_stream_state *stream = pipe_ctx->stream;
2783         struct dc_link *link = stream->link;
2784         enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
2785         enum link_training_result status = LINK_TRAINING_CR_FAIL_LANE0;
2786         struct dc_link_settings cur_link_settings = *link_setting;
2787         const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
2788         int fail_count = 0;
2789         bool is_link_bw_low = false; /* link bandwidth < stream bandwidth */
2790         bool is_link_bw_min = /* RBR x 1 */
2791                 (cur_link_settings.link_rate <= LINK_RATE_LOW) &&
2792                 (cur_link_settings.lane_count <= LANE_COUNT_ONE);
2793
2794         dp_trace_commit_lt_init(link);
2795
2796
2797         if (dp_get_link_encoding_format(&cur_link_settings) == DP_8b_10b_ENCODING)
2798                 /* We need to do this before the link training to ensure the idle
2799                  * pattern in SST mode will be sent right after the link training
2800                  */
2801                 link_hwss->setup_stream_encoder(pipe_ctx);
2802
2803         dp_trace_set_lt_start_timestamp(link, false);
2804         j = 0;
2805         while (j < attempts && fail_count < (attempts * 10)) {
2806
2807                 DC_LOG_HW_LINK_TRAINING("%s: Beginning link training attempt %u of %d @ rate(%d) x lane(%d)\n",
2808                         __func__, (unsigned int)j + 1, attempts, cur_link_settings.link_rate,
2809                         cur_link_settings.lane_count);
2810
2811                 dp_enable_link_phy(
2812                         link,
2813                         &pipe_ctx->link_res,
2814                         signal,
2815                         pipe_ctx->clock_source->id,
2816                         &cur_link_settings);
2817
2818                 if (stream->sink_patches.dppowerup_delay > 0) {
2819                         int delay_dp_power_up_in_ms = stream->sink_patches.dppowerup_delay;
2820
2821                         msleep(delay_dp_power_up_in_ms);
2822                 }
2823
2824 #ifdef CONFIG_DRM_AMD_DC_HDCP
2825                 if (panel_mode == DP_PANEL_MODE_EDP) {
2826                         struct cp_psp *cp_psp = &stream->ctx->cp_psp;
2827
2828                         if (cp_psp && cp_psp->funcs.enable_assr)
2829                                 /* ASSR is bound to fail with unsigned PSP
2830                                  * verstage used during devlopment phase.
2831                                  * Report and continue with eDP panel mode to
2832                                  * perform eDP link training with right settings
2833                                  */
2834                                 cp_psp->funcs.enable_assr(cp_psp->handle, link);
2835                 }
2836 #endif
2837
2838                 dp_set_panel_mode(link, panel_mode);
2839
2840                 if (link->aux_access_disabled) {
2841                         dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &cur_link_settings);
2842                         return true;
2843                 } else {
2844                         /** @todo Consolidate USB4 DP and DPx.x training. */
2845                         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
2846                                 status = dc_link_dpia_perform_link_training(link,
2847                                                 &pipe_ctx->link_res,
2848                                                 &cur_link_settings,
2849                                                 skip_video_pattern);
2850
2851                                 /* Transmit idle pattern once training successful. */
2852                                 if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low)
2853                                         dp_set_hw_test_pattern(link, &pipe_ctx->link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
2854                         } else {
2855                                 status = dc_link_dp_perform_link_training(link,
2856                                                 &pipe_ctx->link_res,
2857                                                 &cur_link_settings,
2858                                                 skip_video_pattern);
2859                         }
2860
2861                         dp_trace_lt_total_count_increment(link, false);
2862                         dp_trace_lt_result_update(link, status, false);
2863                         dp_trace_set_lt_end_timestamp(link, false);
2864                         if (status == LINK_TRAINING_SUCCESS && !is_link_bw_low)
2865                                 return true;
2866                 }
2867
2868                 fail_count++;
2869                 dp_trace_lt_fail_count_update(link, fail_count, false);
2870                 /* latest link training still fail, skip delay and keep PHY on
2871                  */
2872                 if (j == (attempts - 1) && link->ep_type == DISPLAY_ENDPOINT_PHY)
2873                         break;
2874
2875                 DC_LOG_WARNING("%s: Link training attempt %u of %d failed @ rate(%d) x lane(%d)\n",
2876                         __func__, (unsigned int)j + 1, attempts, cur_link_settings.link_rate,
2877                         cur_link_settings.lane_count);
2878
2879                 dp_disable_link_phy(link, &pipe_ctx->link_res, signal);
2880
2881                 /* Abort link training if failure due to sink being unplugged. */
2882                 if (status == LINK_TRAINING_ABORT) {
2883                         enum dc_connection_type type = dc_connection_none;
2884
2885                         dc_link_detect_sink(link, &type);
2886                         if (type == dc_connection_none) {
2887                                 DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__);
2888                                 break;
2889                         }
2890                 }
2891
2892                 /* Try to train again at original settings if:
2893                  * - not falling back between training attempts;
2894                  * - aborted previous attempt due to reasons other than sink unplug;
2895                  * - successfully trained but at a link rate lower than that required by stream;
2896                  * - reached minimum link bandwidth.
2897                  */
2898                 if (!do_fallback || (status == LINK_TRAINING_ABORT) ||
2899                                 (status == LINK_TRAINING_SUCCESS && is_link_bw_low) ||
2900                                 is_link_bw_min) {
2901                         j++;
2902                         cur_link_settings = *link_setting;
2903                         delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
2904                         is_link_bw_low = false;
2905                         is_link_bw_min = (cur_link_settings.link_rate <= LINK_RATE_LOW) &&
2906                                 (cur_link_settings.lane_count <= LANE_COUNT_ONE);
2907
2908                 } else if (do_fallback) { /* Try training at lower link bandwidth if doing fallback. */
2909                         uint32_t req_bw;
2910                         uint32_t link_bw;
2911
2912                         decide_fallback_link_setting(link, *link_setting, &cur_link_settings, status);
2913                         /* Flag if reduced link bandwidth no longer meets stream requirements or fallen back to
2914                          * minimum link bandwidth.
2915                          */
2916                         req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
2917                         link_bw = dc_link_bandwidth_kbps(link, &cur_link_settings);
2918                         is_link_bw_low = (req_bw > link_bw);
2919                         is_link_bw_min = ((cur_link_settings.link_rate <= LINK_RATE_LOW) &&
2920                                 (cur_link_settings.lane_count <= LANE_COUNT_ONE));
2921
2922                         if (is_link_bw_low)
2923                                 DC_LOG_WARNING("%s: Link bandwidth too low after fallback req_bw(%d) > link_bw(%d)\n",
2924                                         __func__, req_bw, link_bw);
2925                 }
2926
2927                 msleep(delay_between_attempts);
2928         }
2929         return false;
2930 }
2931
2932 static enum clock_source_id get_clock_source_id(struct dc_link *link)
2933 {
2934         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_UNDEFINED;
2935         struct clock_source *dp_cs = link->dc->res_pool->dp_clock_source;
2936
2937         if (dp_cs != NULL) {
2938                 dp_cs_id = dp_cs->id;
2939         } else {
2940                 /*
2941                  * dp clock source is not initialized for some reason.
2942                  * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
2943                  */
2944                 ASSERT(dp_cs);
2945         }
2946
2947         return dp_cs_id;
2948 }
2949
2950 static void set_dp_mst_mode(struct dc_link *link, const struct link_resource *link_res,
2951                 bool mst_enable)
2952 {
2953         if (mst_enable == false &&
2954                 link->type == dc_connection_mst_branch) {
2955                 /* Disable MST on link. Use only local sink. */
2956                 dp_disable_link_phy_mst(link, link_res, link->connector_signal);
2957
2958                 link->type = dc_connection_single;
2959                 link->local_sink = link->remote_sinks[0];
2960                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
2961                 dc_sink_retain(link->local_sink);
2962                 dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
2963         } else if (mst_enable == true &&
2964                         link->type == dc_connection_single &&
2965                         link->remote_sinks[0] != NULL) {
2966                 /* Re-enable MST on link. */
2967                 dp_disable_link_phy(link, link_res, link->connector_signal);
2968                 dp_enable_mst_on_sink(link, true);
2969
2970                 link->type = dc_connection_mst_branch;
2971                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
2972         }
2973 }
2974
2975 bool dc_link_dp_sync_lt_begin(struct dc_link *link)
2976 {
2977         /* Begin Sync LT. During this time,
2978          * DPCD:600h must not be powered down.
2979          */
2980         link->sync_lt_in_progress = true;
2981
2982         /*Clear any existing preferred settings.*/
2983         memset(&link->preferred_training_settings, 0,
2984                 sizeof(struct dc_link_training_overrides));
2985         memset(&link->preferred_link_setting, 0,
2986                 sizeof(struct dc_link_settings));
2987
2988         return true;
2989 }
2990
2991 enum link_training_result dc_link_dp_sync_lt_attempt(
2992     struct dc_link *link,
2993     const struct link_resource *link_res,
2994     struct dc_link_settings *link_settings,
2995     struct dc_link_training_overrides *lt_overrides)
2996 {
2997         struct link_training_settings lt_settings = {0};
2998         enum link_training_result lt_status = LINK_TRAINING_SUCCESS;
2999         enum dp_panel_mode panel_mode = DP_PANEL_MODE_DEFAULT;
3000         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
3001         bool fec_enable = false;
3002
3003         dp_decide_training_settings(
3004                         link,
3005                         link_settings,
3006                         &lt_settings);
3007         override_training_settings(
3008                         link,
3009                         lt_overrides,
3010                         &lt_settings);
3011         /* Setup MST Mode */
3012         if (lt_overrides->mst_enable)
3013                 set_dp_mst_mode(link, link_res, *lt_overrides->mst_enable);
3014
3015         /* Disable link */
3016         dp_disable_link_phy(link, link_res, link->connector_signal);
3017
3018         /* Enable link */
3019         dp_cs_id = get_clock_source_id(link);
3020         dp_enable_link_phy(link, link_res, link->connector_signal,
3021                 dp_cs_id, link_settings);
3022
3023         /* Set FEC enable */
3024         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
3025                 fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
3026                 dp_set_fec_ready(link, NULL, fec_enable);
3027         }
3028
3029         if (lt_overrides->alternate_scrambler_reset) {
3030                 if (*lt_overrides->alternate_scrambler_reset)
3031                         panel_mode = DP_PANEL_MODE_EDP;
3032                 else
3033                         panel_mode = DP_PANEL_MODE_DEFAULT;
3034         } else
3035                 panel_mode = dp_get_panel_mode(link);
3036
3037         dp_set_panel_mode(link, panel_mode);
3038
3039         /* Attempt to train with given link training settings */
3040         if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
3041                 start_clock_recovery_pattern_early(link, link_res, &lt_settings, DPRX);
3042
3043         /* Set link rate, lane count and spread. */
3044         dpcd_set_link_settings(link, &lt_settings);
3045
3046         /* 2. perform link training (set link training done
3047          *  to false is done as well)
3048          */
3049         lt_status = perform_clock_recovery_sequence(link, link_res, &lt_settings, DPRX);
3050         if (lt_status == LINK_TRAINING_SUCCESS) {
3051                 lt_status = perform_channel_equalization_sequence(link,
3052                                                 link_res,
3053                                                 &lt_settings,
3054                                                 DPRX);
3055         }
3056
3057         /* 3. Sync LT must skip TRAINING_PATTERN_SET:0 (video pattern)*/
3058         /* 4. print status message*/
3059         print_status_message(link, &lt_settings, lt_status);
3060
3061         return lt_status;
3062 }
3063
3064 bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
3065 {
3066         /* If input parameter is set, shut down phy.
3067          * Still shouldn't turn off dp_receiver (DPCD:600h)
3068          */
3069         if (link_down == true) {
3070                 struct dc_link_settings link_settings = link->cur_link_settings;
3071                 dp_disable_link_phy(link, NULL, link->connector_signal);
3072                 if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
3073                         dp_set_fec_ready(link, NULL, false);
3074         }
3075
3076         link->sync_lt_in_progress = false;
3077         return true;
3078 }
3079
3080 static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
3081 {
3082         enum dc_link_rate lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
3083
3084         if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20)
3085                 lttpr_max_link_rate = LINK_RATE_UHBR20;
3086         else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
3087                 lttpr_max_link_rate = LINK_RATE_UHBR13_5;
3088         else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR10)
3089                 lttpr_max_link_rate = LINK_RATE_UHBR10;
3090
3091         return lttpr_max_link_rate;
3092 }
3093
3094 static enum dc_link_rate get_cable_max_link_rate(struct dc_link *link)
3095 {
3096         enum dc_link_rate cable_max_link_rate = LINK_RATE_HIGH3;
3097
3098         if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR20)
3099                 cable_max_link_rate = LINK_RATE_UHBR20;
3100         else if (link->dpcd_caps.cable_id.bits.UHBR13_5_CAPABILITY)
3101                 cable_max_link_rate = LINK_RATE_UHBR13_5;
3102         else if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR10)
3103                 cable_max_link_rate = LINK_RATE_UHBR10;
3104
3105         return cable_max_link_rate;
3106 }
3107
3108 bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
3109 {
3110         struct link_encoder *link_enc = NULL;
3111
3112         if (!max_link_enc_cap) {
3113                 DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
3114                 return false;
3115         }
3116
3117         link_enc = link_enc_cfg_get_link_enc(link);
3118         ASSERT(link_enc);
3119
3120         if (link_enc && link_enc->funcs->get_max_link_cap) {
3121                 link_enc->funcs->get_max_link_cap(link_enc, max_link_enc_cap);
3122                 return true;
3123         }
3124
3125         DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
3126         max_link_enc_cap->lane_count = 1;
3127         max_link_enc_cap->link_rate = 6;
3128         return false;
3129 }
3130
3131
3132 struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
3133 {
3134         struct dc_link_settings max_link_cap = {0};
3135         enum dc_link_rate lttpr_max_link_rate;
3136         enum dc_link_rate cable_max_link_rate;
3137         struct link_encoder *link_enc = NULL;
3138
3139
3140         link_enc = link_enc_cfg_get_link_enc(link);
3141         ASSERT(link_enc);
3142
3143         /* get max link encoder capability */
3144         if (link_enc)
3145                 link_enc->funcs->get_max_link_cap(link_enc, &max_link_cap);
3146
3147         /* Lower link settings based on sink's link cap */
3148         if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
3149                 max_link_cap.lane_count =
3150                                 link->reported_link_cap.lane_count;
3151         if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
3152                 max_link_cap.link_rate =
3153                                 link->reported_link_cap.link_rate;
3154         if (link->reported_link_cap.link_spread <
3155                         max_link_cap.link_spread)
3156                 max_link_cap.link_spread =
3157                                 link->reported_link_cap.link_spread;
3158
3159         /* Lower link settings based on cable attributes */
3160         cable_max_link_rate = get_cable_max_link_rate(link);
3161
3162         if (!link->dc->debug.ignore_cable_id &&
3163                         cable_max_link_rate < max_link_cap.link_rate)
3164                 max_link_cap.link_rate = cable_max_link_rate;
3165
3166         /*
3167          * account for lttpr repeaters cap
3168          * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
3169          */
3170         if (link->lttpr_mode != LTTPR_MODE_NON_LTTPR) {
3171                 if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
3172                         max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
3173                 lttpr_max_link_rate = get_lttpr_max_link_rate(link);
3174
3175                 if (lttpr_max_link_rate < max_link_cap.link_rate)
3176                         max_link_cap.link_rate = lttpr_max_link_rate;
3177
3178                 DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane count %d max_link rate %d \n",
3179                                                 __func__,
3180                                                 max_link_cap.lane_count,
3181                                                 max_link_cap.link_rate);
3182         }
3183
3184         if (dp_get_link_encoding_format(&max_link_cap) == DP_128b_132b_ENCODING &&
3185                         link->dc->debug.disable_uhbr)
3186                 max_link_cap.link_rate = LINK_RATE_HIGH3;
3187
3188         return max_link_cap;
3189 }
3190
3191 static enum dc_status read_hpd_rx_irq_data(
3192         struct dc_link *link,
3193         union hpd_irq_data *irq_data)
3194 {
3195         static enum dc_status retval;
3196
3197         /* The HW reads 16 bytes from 200h on HPD,
3198          * but if we get an AUX_DEFER, the HW cannot retry
3199          * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
3200          * fail, so we now explicitly read 6 bytes which is
3201          * the req from the above mentioned test cases.
3202          *
3203          * For DP 1.4 we need to read those from 2002h range.
3204          */
3205         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
3206                 retval = core_link_read_dpcd(
3207                         link,
3208                         DP_SINK_COUNT,
3209                         irq_data->raw,
3210                         sizeof(union hpd_irq_data));
3211         else {
3212                 /* Read 14 bytes in a single read and then copy only the required fields.
3213                  * This is more efficient than doing it in two separate AUX reads. */
3214
3215                 uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
3216
3217                 retval = core_link_read_dpcd(
3218                         link,
3219                         DP_SINK_COUNT_ESI,
3220                         tmp,
3221                         sizeof(tmp));
3222
3223                 if (retval != DC_OK)
3224                         return retval;
3225
3226                 irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
3227                 irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
3228                 irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
3229                 irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
3230                 irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
3231                 irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
3232         }
3233
3234         return retval;
3235 }
3236
3237 bool hpd_rx_irq_check_link_loss_status(
3238         struct dc_link *link,
3239         union hpd_irq_data *hpd_irq_dpcd_data)
3240 {
3241         uint8_t irq_reg_rx_power_state = 0;
3242         enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
3243         union lane_status lane_status;
3244         uint32_t lane;
3245         bool sink_status_changed;
3246         bool return_code;
3247
3248         sink_status_changed = false;
3249         return_code = false;
3250
3251         if (link->cur_link_settings.lane_count == 0)
3252                 return return_code;
3253
3254         /*1. Check that Link Status changed, before re-training.*/
3255
3256         /*parse lane status*/
3257         for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
3258                 /* check status of lanes 0,1
3259                  * changed DpcdAddress_Lane01Status (0x202)
3260                  */
3261                 lane_status.raw = get_nibble_at_index(
3262                         &hpd_irq_dpcd_data->bytes.lane01_status.raw,
3263                         lane);
3264
3265                 if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
3266                         !lane_status.bits.CR_DONE_0 ||
3267                         !lane_status.bits.SYMBOL_LOCKED_0) {
3268                         /* if one of the channel equalization, clock
3269                          * recovery or symbol lock is dropped
3270                          * consider it as (link has been
3271                          * dropped) dp sink status has changed
3272                          */
3273                         sink_status_changed = true;
3274                         break;
3275                 }
3276         }
3277
3278         /* Check interlane align.*/
3279         if (sink_status_changed ||
3280                 !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
3281
3282                 DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
3283
3284                 return_code = true;
3285
3286                 /*2. Check that we can handle interrupt: Not in FS DOS,
3287                  *  Not in "Display Timeout" state, Link is trained.
3288                  */
3289                 dpcd_result = core_link_read_dpcd(link,
3290                         DP_SET_POWER,
3291                         &irq_reg_rx_power_state,
3292                         sizeof(irq_reg_rx_power_state));
3293
3294                 if (dpcd_result != DC_OK) {
3295                         DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
3296                                 __func__);
3297                 } else {
3298                         if (irq_reg_rx_power_state != DP_SET_POWER_D0)
3299                                 return_code = false;
3300                 }
3301         }
3302
3303         return return_code;
3304 }
3305
3306 static bool dp_verify_link_cap(
3307         struct dc_link *link,
3308         struct dc_link_settings *known_limit_link_setting,
3309         int *fail_count)
3310 {
3311         struct dc_link_settings cur_link_settings = {0};
3312         struct dc_link_settings initial_link_settings = *known_limit_link_setting;
3313         bool success = false;
3314         bool skip_video_pattern;
3315         enum clock_source_id dp_cs_id = get_clock_source_id(link);
3316         enum link_training_result status = LINK_TRAINING_SUCCESS;
3317         union hpd_irq_data irq_data;
3318         struct link_resource link_res;
3319
3320         memset(&irq_data, 0, sizeof(irq_data));
3321         cur_link_settings = initial_link_settings;
3322
3323         /* Grant extended timeout request */
3324         if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) {
3325                 uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80;
3326
3327                 core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
3328         }
3329
3330         do {
3331                 if (!get_temp_dp_link_res(link, &link_res, &cur_link_settings))
3332                         continue;
3333
3334                 skip_video_pattern = cur_link_settings.link_rate != LINK_RATE_LOW;
3335                 dp_enable_link_phy(
3336                                 link,
3337                                 &link_res,
3338                                 link->connector_signal,
3339                                 dp_cs_id,
3340                                 &cur_link_settings);
3341
3342                 status = dc_link_dp_perform_link_training(
3343                                 link,
3344                                 &link_res,
3345                                 &cur_link_settings,
3346                                 skip_video_pattern);
3347
3348                 if (status == LINK_TRAINING_SUCCESS) {
3349                         success = true;
3350                         udelay(1000);
3351                         if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK &&
3352                                         hpd_rx_irq_check_link_loss_status(
3353                                                         link,
3354                                                         &irq_data))
3355                                 (*fail_count)++;
3356
3357                 } else {
3358                         (*fail_count)++;
3359                 }
3360                 dp_trace_lt_total_count_increment(link, true);
3361                 dp_trace_lt_result_update(link, status, true);
3362                 dp_disable_link_phy(link, &link_res, link->connector_signal);
3363         } while (!success && decide_fallback_link_setting(link,
3364                         initial_link_settings, &cur_link_settings, status));
3365
3366         link->verified_link_cap = success ?
3367                         cur_link_settings : fail_safe_link_settings;
3368         return success;
3369 }
3370
3371 static void apply_usbc_combo_phy_reset_wa(struct dc_link *link,
3372                 struct dc_link_settings *link_settings)
3373 {
3374         /* Temporary Renoir-specific workaround PHY will sometimes be in bad
3375          * state on hotplugging display from certain USB-C dongle, so add extra
3376          * cycle of enabling and disabling the PHY before first link training.
3377          */
3378         struct link_resource link_res = {0};
3379         enum clock_source_id dp_cs_id = get_clock_source_id(link);
3380
3381         dp_enable_link_phy(link, &link_res, link->connector_signal,
3382                         dp_cs_id, link_settings);
3383         dp_disable_link_phy(link, &link_res, link->connector_signal);
3384 }
3385
3386 bool dp_verify_link_cap_with_retries(
3387         struct dc_link *link,
3388         struct dc_link_settings *known_limit_link_setting,
3389         int attempts)
3390 {
3391         int i = 0;
3392         bool success = false;
3393         int fail_count = 0;
3394
3395         dp_trace_detect_lt_init(link);
3396
3397         if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
3398                         link->dc->debug.usbc_combo_phy_reset_wa)
3399                 apply_usbc_combo_phy_reset_wa(link, known_limit_link_setting);
3400
3401         dp_trace_set_lt_start_timestamp(link, false);
3402         for (i = 0; i < attempts; i++) {
3403                 enum dc_connection_type type = dc_connection_none;
3404
3405                 memset(&link->verified_link_cap, 0,
3406                                 sizeof(struct dc_link_settings));
3407                 if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
3408                         link->verified_link_cap = fail_safe_link_settings;
3409                         break;
3410                 } else if (dp_verify_link_cap(link, known_limit_link_setting,
3411                                 &fail_count) && fail_count == 0) {
3412                         success = true;
3413                         break;
3414                 }
3415                 msleep(10);
3416         }
3417
3418         dp_trace_lt_fail_count_update(link, fail_count, true);
3419         dp_trace_set_lt_end_timestamp(link, true);
3420
3421         return success;
3422 }
3423
3424 /* in DP compliance test, DPR-120 may have
3425  * a random value in its MAX_LINK_BW dpcd field.
3426  * We map it to the maximum supported link rate that
3427  * is smaller than MAX_LINK_BW in this case.
3428  */
3429 static enum dc_link_rate get_link_rate_from_max_link_bw(
3430                  uint8_t max_link_bw)
3431 {
3432         enum dc_link_rate link_rate;
3433
3434         if (max_link_bw >= LINK_RATE_HIGH3) {
3435                 link_rate = LINK_RATE_HIGH3;
3436         } else if (max_link_bw < LINK_RATE_HIGH3
3437                         && max_link_bw >= LINK_RATE_HIGH2) {
3438                 link_rate = LINK_RATE_HIGH2;
3439         } else if (max_link_bw < LINK_RATE_HIGH2
3440                         && max_link_bw >= LINK_RATE_HIGH) {
3441                 link_rate = LINK_RATE_HIGH;
3442         } else if (max_link_bw < LINK_RATE_HIGH
3443                         && max_link_bw >= LINK_RATE_LOW) {
3444                 link_rate = LINK_RATE_LOW;
3445         } else {
3446                 link_rate = LINK_RATE_UNKNOWN;
3447         }
3448
3449         return link_rate;
3450 }
3451
3452 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
3453 {
3454         return lane_count <= LANE_COUNT_ONE;
3455 }
3456
3457 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
3458 {
3459         return link_rate <= LINK_RATE_LOW;
3460 }
3461
3462 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
3463 {
3464         switch (lane_count) {
3465         case LANE_COUNT_FOUR:
3466                 return LANE_COUNT_TWO;
3467         case LANE_COUNT_TWO:
3468                 return LANE_COUNT_ONE;
3469         case LANE_COUNT_ONE:
3470                 return LANE_COUNT_UNKNOWN;
3471         default:
3472                 return LANE_COUNT_UNKNOWN;
3473         }
3474 }
3475
3476 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
3477 {
3478         switch (link_rate) {
3479         case LINK_RATE_UHBR20:
3480                 return LINK_RATE_UHBR13_5;
3481         case LINK_RATE_UHBR13_5:
3482                 return LINK_RATE_UHBR10;
3483         case LINK_RATE_UHBR10:
3484                 return LINK_RATE_HIGH3;
3485         case LINK_RATE_HIGH3:
3486                 return LINK_RATE_HIGH2;
3487         case LINK_RATE_HIGH2:
3488                 return LINK_RATE_HIGH;
3489         case LINK_RATE_HIGH:
3490                 return LINK_RATE_LOW;
3491         case LINK_RATE_LOW:
3492                 return LINK_RATE_UNKNOWN;
3493         default:
3494                 return LINK_RATE_UNKNOWN;
3495         }
3496 }
3497
3498 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
3499 {
3500         switch (lane_count) {
3501         case LANE_COUNT_ONE:
3502                 return LANE_COUNT_TWO;
3503         case LANE_COUNT_TWO:
3504                 return LANE_COUNT_FOUR;
3505         default:
3506                 return LANE_COUNT_UNKNOWN;
3507         }
3508 }
3509
3510 static enum dc_link_rate increase_link_rate(struct dc_link *link,
3511                 enum dc_link_rate link_rate)
3512 {
3513         switch (link_rate) {
3514         case LINK_RATE_LOW:
3515                 return LINK_RATE_HIGH;
3516         case LINK_RATE_HIGH:
3517                 return LINK_RATE_HIGH2;
3518         case LINK_RATE_HIGH2:
3519                 return LINK_RATE_HIGH3;
3520         case LINK_RATE_HIGH3:
3521                 return LINK_RATE_UHBR10;
3522         case LINK_RATE_UHBR10:
3523                 /* upto DP2.x specs UHBR13.5 is the only link rate that could be
3524                  * not supported by DPRX when higher link rate is supported.
3525                  * so we treat it as a special case for code simplicity. When we
3526                  * have new specs with more link rates like this, we should
3527                  * consider a more generic solution to handle discrete link
3528                  * rate capabilities.
3529                  */
3530                 return link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 ?
3531                                 LINK_RATE_UHBR13_5 : LINK_RATE_UHBR20;
3532         case LINK_RATE_UHBR13_5:
3533                 return LINK_RATE_UHBR20;
3534         default:
3535                 return LINK_RATE_UNKNOWN;
3536         }
3537 }
3538
3539 static bool decide_fallback_link_setting_max_bw_policy(
3540                 struct dc_link *link,
3541                 const struct dc_link_settings *max,
3542                 struct dc_link_settings *cur,
3543                 enum link_training_result training_result)
3544 {
3545         uint8_t cur_idx = 0, next_idx;
3546         bool found = false;
3547
3548         if (training_result == LINK_TRAINING_ABORT)
3549                 return false;
3550
3551         while (cur_idx < ARRAY_SIZE(dp_lt_fallbacks))
3552                 /* find current index */
3553                 if (dp_lt_fallbacks[cur_idx].lane_count == cur->lane_count &&
3554                                 dp_lt_fallbacks[cur_idx].link_rate == cur->link_rate)
3555                         break;
3556                 else
3557                         cur_idx++;
3558
3559         next_idx = cur_idx + 1;
3560
3561         while (next_idx < ARRAY_SIZE(dp_lt_fallbacks))
3562                 /* find next index */
3563                 if (dp_lt_fallbacks[next_idx].lane_count > max->lane_count ||
3564                                 dp_lt_fallbacks[next_idx].link_rate > max->link_rate)
3565                         next_idx++;
3566                 else if (dp_lt_fallbacks[next_idx].link_rate == LINK_RATE_UHBR13_5 &&
3567                                 link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 == 0)
3568                         /* upto DP2.x specs UHBR13.5 is the only link rate that
3569                          * could be not supported by DPRX when higher link rate
3570                          * is supported. so we treat it as a special case for
3571                          * code simplicity. When we have new specs with more
3572                          * link rates like this, we should consider a more
3573                          * generic solution to handle discrete link rate
3574                          * capabilities.
3575                          */
3576                         next_idx++;
3577                 else
3578                         break;
3579
3580         if (next_idx < ARRAY_SIZE(dp_lt_fallbacks)) {
3581                 cur->lane_count = dp_lt_fallbacks[next_idx].lane_count;
3582                 cur->link_rate = dp_lt_fallbacks[next_idx].link_rate;
3583                 found = true;
3584         }
3585
3586         return found;
3587 }
3588
3589 /*
3590  * function: set link rate and lane count fallback based
3591  * on current link setting and last link training result
3592  * return value:
3593  *                      true - link setting could be set
3594  *                      false - has reached minimum setting
3595  *                                      and no further fallback could be done
3596  */
3597 static bool decide_fallback_link_setting(
3598                 struct dc_link *link,
3599                 struct dc_link_settings initial_link_settings,
3600                 struct dc_link_settings *current_link_setting,
3601                 enum link_training_result training_result)
3602 {
3603         if (!current_link_setting)
3604                 return false;
3605         if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING ||
3606                         link->dc->debug.force_dp2_lt_fallback_method)
3607                 return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings,
3608                                 current_link_setting, training_result);
3609
3610         switch (training_result) {
3611         case LINK_TRAINING_CR_FAIL_LANE0:
3612         case LINK_TRAINING_CR_FAIL_LANE1:
3613         case LINK_TRAINING_CR_FAIL_LANE23:
3614         case LINK_TRAINING_LQA_FAIL:
3615         {
3616                 if (!reached_minimum_link_rate
3617                                 (current_link_setting->link_rate)) {
3618                         current_link_setting->link_rate =
3619                                 reduce_link_rate(
3620                                         current_link_setting->link_rate);
3621                 } else if (!reached_minimum_lane_count
3622                                 (current_link_setting->lane_count)) {
3623                         current_link_setting->link_rate =
3624                                 initial_link_settings.link_rate;
3625                         if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
3626                                 return false;
3627                         else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
3628                                 current_link_setting->lane_count =
3629                                                 LANE_COUNT_ONE;
3630                         else if (training_result ==
3631                                         LINK_TRAINING_CR_FAIL_LANE23)
3632                                 current_link_setting->lane_count =
3633                                                 LANE_COUNT_TWO;
3634                         else
3635                                 current_link_setting->lane_count =
3636                                         reduce_lane_count(
3637                                         current_link_setting->lane_count);
3638                 } else {
3639                         return false;
3640                 }
3641                 break;
3642         }
3643         case LINK_TRAINING_EQ_FAIL_EQ:
3644         {
3645                 if (!reached_minimum_lane_count
3646                                 (current_link_setting->lane_count)) {
3647                         current_link_setting->lane_count =
3648                                 reduce_lane_count(
3649                                         current_link_setting->lane_count);
3650                 } else if (!reached_minimum_link_rate
3651                                 (current_link_setting->link_rate)) {
3652                         current_link_setting->link_rate =
3653                                 reduce_link_rate(
3654                                         current_link_setting->link_rate);
3655                         current_link_setting->lane_count = initial_link_settings.lane_count;
3656                 } else {
3657                         return false;
3658                 }
3659                 break;
3660         }
3661         case LINK_TRAINING_EQ_FAIL_CR:
3662         {
3663                 if (!reached_minimum_link_rate
3664                                 (current_link_setting->link_rate)) {
3665                         current_link_setting->link_rate =
3666                                 reduce_link_rate(
3667                                         current_link_setting->link_rate);
3668                         current_link_setting->lane_count = initial_link_settings.lane_count;
3669                 } else {
3670                         return false;
3671                 }
3672                 break;
3673         }
3674         default:
3675                 return false;
3676         }
3677         return true;
3678 }
3679
3680 bool dp_validate_mode_timing(
3681         struct dc_link *link,
3682         const struct dc_crtc_timing *timing)
3683 {
3684         uint32_t req_bw;
3685         uint32_t max_bw;
3686
3687         const struct dc_link_settings *link_setting;
3688
3689         /* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
3690         if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
3691                         !link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
3692                         dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
3693                 return false;
3694
3695         /*always DP fail safe mode*/
3696         if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
3697                 timing->h_addressable == (uint32_t) 640 &&
3698                 timing->v_addressable == (uint32_t) 480)
3699                 return true;
3700
3701         link_setting = dc_link_get_link_cap(link);
3702
3703         /* TODO: DYNAMIC_VALIDATION needs to be implemented */
3704         /*if (flags.DYNAMIC_VALIDATION == 1 &&
3705                 link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
3706                 link_setting = &link->verified_link_cap;
3707         */
3708
3709         req_bw = dc_bandwidth_in_kbps_from_timing(timing);
3710         max_bw = dc_link_bandwidth_kbps(link, link_setting);
3711
3712         if (req_bw <= max_bw) {
3713                 /* remember the biggest mode here, during
3714                  * initial link training (to get
3715                  * verified_link_cap), LS sends event about
3716                  * cannot train at reported cap to upper
3717                  * layer and upper layer will re-enumerate modes.
3718                  * this is not necessary if the lower
3719                  * verified_link_cap is enough to drive
3720                  * all the modes */
3721
3722                 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
3723                 /* if (flags.DYNAMIC_VALIDATION == 1)
3724                         dpsst->max_req_bw_for_verified_linkcap = dal_max(
3725                                 dpsst->max_req_bw_for_verified_linkcap, req_bw); */
3726                 return true;
3727         } else
3728                 return false;
3729 }
3730
3731 static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
3732 {
3733         struct dc_link_settings initial_link_setting = {
3734                 LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
3735         struct dc_link_settings current_link_setting =
3736                         initial_link_setting;
3737         uint32_t link_bw;
3738
3739         if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
3740                 return false;
3741
3742         /* search for the minimum link setting that:
3743          * 1. is supported according to the link training result
3744          * 2. could support the b/w requested by the timing
3745          */
3746         while (current_link_setting.link_rate <=
3747                         link->verified_link_cap.link_rate) {
3748                 link_bw = dc_link_bandwidth_kbps(
3749                                 link,
3750                                 &current_link_setting);
3751                 if (req_bw <= link_bw) {
3752                         *link_setting = current_link_setting;
3753                         return true;
3754                 }
3755
3756                 if (current_link_setting.lane_count <
3757                                 link->verified_link_cap.lane_count) {
3758                         current_link_setting.lane_count =
3759                                         increase_lane_count(
3760                                                         current_link_setting.lane_count);
3761                 } else {
3762                         current_link_setting.link_rate =
3763                                         increase_link_rate(link,
3764                                                         current_link_setting.link_rate);
3765                         current_link_setting.lane_count =
3766                                         initial_link_setting.lane_count;
3767                 }
3768         }
3769
3770         return false;
3771 }
3772
3773 bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
3774 {
3775         struct dc_link_settings initial_link_setting;
3776         struct dc_link_settings current_link_setting;
3777         uint32_t link_bw;
3778
3779         /*
3780          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
3781          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
3782          */
3783         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 ||
3784                         link->dpcd_caps.edp_supported_link_rates_count == 0) {
3785                 *link_setting = link->verified_link_cap;
3786                 return true;
3787         }
3788
3789         memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3790         initial_link_setting.lane_count = LANE_COUNT_ONE;
3791         initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
3792         initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3793         initial_link_setting.use_link_rate_set = true;
3794         initial_link_setting.link_rate_set = 0;
3795         current_link_setting = initial_link_setting;
3796
3797         /* search for the minimum link setting that:
3798          * 1. is supported according to the link training result
3799          * 2. could support the b/w requested by the timing
3800          */
3801         while (current_link_setting.link_rate <=
3802                         link->verified_link_cap.link_rate) {
3803                 link_bw = dc_link_bandwidth_kbps(
3804                                 link,
3805                                 &current_link_setting);
3806                 if (req_bw <= link_bw) {
3807                         *link_setting = current_link_setting;
3808                         return true;
3809                 }
3810
3811                 if (current_link_setting.lane_count <
3812                                 link->verified_link_cap.lane_count) {
3813                         current_link_setting.lane_count =
3814                                         increase_lane_count(
3815                                                         current_link_setting.lane_count);
3816                 } else {
3817                         if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
3818                                 current_link_setting.link_rate_set++;
3819                                 current_link_setting.link_rate =
3820                                         link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3821                                 current_link_setting.lane_count =
3822                                                                         initial_link_setting.lane_count;
3823                         } else
3824                                 break;
3825                 }
3826         }
3827         return false;
3828 }
3829
3830 static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
3831                 struct dc_link_settings *link_setting,
3832                 uint32_t req_bw,
3833                 enum dc_link_rate max_link_rate)
3834 {
3835         struct dc_link_settings initial_link_setting;
3836         struct dc_link_settings current_link_setting;
3837         uint32_t link_bw;
3838
3839         unsigned int policy = 0;
3840
3841         policy = link->ctx->dc->debug.force_dsc_edp_policy;
3842         if (max_link_rate == LINK_RATE_UNKNOWN)
3843                 max_link_rate = link->verified_link_cap.link_rate;
3844         /*
3845          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
3846          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
3847          */
3848         if ((link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 ||
3849                         link->dpcd_caps.edp_supported_link_rates_count == 0)) {
3850                 /* for DSC enabled case, we search for minimum lane count */
3851                 memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3852                 initial_link_setting.lane_count = LANE_COUNT_ONE;
3853                 initial_link_setting.link_rate = LINK_RATE_LOW;
3854                 initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3855                 initial_link_setting.use_link_rate_set = false;
3856                 initial_link_setting.link_rate_set = 0;
3857                 current_link_setting = initial_link_setting;
3858                 if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
3859                         return false;
3860
3861                 /* search for the minimum link setting that:
3862                  * 1. is supported according to the link training result
3863                  * 2. could support the b/w requested by the timing
3864                  */
3865                 while (current_link_setting.link_rate <=
3866                                 max_link_rate) {
3867                         link_bw = dc_link_bandwidth_kbps(
3868                                         link,
3869                                         &current_link_setting);
3870                         if (req_bw <= link_bw) {
3871                                 *link_setting = current_link_setting;
3872                                 return true;
3873                         }
3874                         if (policy) {
3875                                 /* minimize lane */
3876                                 if (current_link_setting.link_rate < max_link_rate) {
3877                                         current_link_setting.link_rate =
3878                                                         increase_link_rate(link,
3879                                                                         current_link_setting.link_rate);
3880                                 } else {
3881                                         if (current_link_setting.lane_count <
3882                                                                         link->verified_link_cap.lane_count) {
3883                                                 current_link_setting.lane_count =
3884                                                                 increase_lane_count(
3885                                                                                 current_link_setting.lane_count);
3886                                                 current_link_setting.link_rate = initial_link_setting.link_rate;
3887                                         } else
3888                                                 break;
3889                                 }
3890                         } else {
3891                                 /* minimize link rate */
3892                                 if (current_link_setting.lane_count <
3893                                                 link->verified_link_cap.lane_count) {
3894                                         current_link_setting.lane_count =
3895                                                         increase_lane_count(
3896                                                                         current_link_setting.lane_count);
3897                                 } else {
3898                                         current_link_setting.link_rate =
3899                                                         increase_link_rate(link,
3900                                                                         current_link_setting.link_rate);
3901                                         current_link_setting.lane_count =
3902                                                         initial_link_setting.lane_count;
3903                                 }
3904                         }
3905                 }
3906                 return false;
3907         }
3908
3909         /* if optimize edp link is supported */
3910         memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3911         initial_link_setting.lane_count = LANE_COUNT_ONE;
3912         initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
3913         initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3914         initial_link_setting.use_link_rate_set = true;
3915         initial_link_setting.link_rate_set = 0;
3916         current_link_setting = initial_link_setting;
3917
3918         /* search for the minimum link setting that:
3919          * 1. is supported according to the link training result
3920          * 2. could support the b/w requested by the timing
3921          */
3922         while (current_link_setting.link_rate <=
3923                         max_link_rate) {
3924                 link_bw = dc_link_bandwidth_kbps(
3925                                 link,
3926                                 &current_link_setting);
3927                 if (req_bw <= link_bw) {
3928                         *link_setting = current_link_setting;
3929                         return true;
3930                 }
3931                 if (policy) {
3932                         /* minimize lane */
3933                         if (current_link_setting.link_rate_set <
3934                                         link->dpcd_caps.edp_supported_link_rates_count
3935                                         && current_link_setting.link_rate < max_link_rate) {
3936                                 current_link_setting.link_rate_set++;
3937                                 current_link_setting.link_rate =
3938                                         link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3939                         } else {
3940                                 if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
3941                                         current_link_setting.lane_count =
3942                                                         increase_lane_count(
3943                                                                         current_link_setting.lane_count);
3944                                         current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
3945                                         current_link_setting.link_rate =
3946                                                 link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3947                                 } else
3948                                         break;
3949                         }
3950                 } else {
3951                         /* minimize link rate */
3952                         if (current_link_setting.lane_count <
3953                                         link->verified_link_cap.lane_count) {
3954                                 current_link_setting.lane_count =
3955                                                 increase_lane_count(
3956                                                                 current_link_setting.lane_count);
3957                         } else {
3958                                 if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
3959                                         current_link_setting.link_rate_set++;
3960                                         current_link_setting.link_rate =
3961                                                 link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3962                                         current_link_setting.lane_count =
3963                                                 initial_link_setting.lane_count;
3964                                 } else
3965                                         break;
3966                         }
3967                 }
3968         }
3969         return false;
3970 }
3971
3972 static bool decide_mst_link_settings(const struct dc_link *link, struct dc_link_settings *link_setting)
3973 {
3974         *link_setting = link->verified_link_cap;
3975         return true;
3976 }
3977
3978 void decide_link_settings(struct dc_stream_state *stream,
3979         struct dc_link_settings *link_setting)
3980 {
3981         struct dc_link *link;
3982         uint32_t req_bw;
3983
3984         req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
3985
3986         link = stream->link;
3987
3988         /* if preferred is specified through AMDDP, use it, if it's enough
3989          * to drive the mode
3990          */
3991         if (link->preferred_link_setting.lane_count !=
3992                         LANE_COUNT_UNKNOWN &&
3993                         link->preferred_link_setting.link_rate !=
3994                                         LINK_RATE_UNKNOWN) {
3995                 *link_setting =  link->preferred_link_setting;
3996                 return;
3997         }
3998
3999         /* MST doesn't perform link training for now
4000          * TODO: add MST specific link training routine
4001          */
4002         if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
4003                 if (decide_mst_link_settings(link, link_setting))
4004                         return;
4005         } else if (link->connector_signal == SIGNAL_TYPE_EDP) {
4006                 /* enable edp link optimization for DSC eDP case */
4007                 if (stream->timing.flags.DSC) {
4008                         enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
4009
4010                         if (link->ctx->dc->debug.force_dsc_edp_policy) {
4011                                 /* calculate link max link rate cap*/
4012                                 struct dc_link_settings tmp_link_setting;
4013                                 struct dc_crtc_timing tmp_timing = stream->timing;
4014                                 uint32_t orig_req_bw;
4015
4016                                 tmp_link_setting.link_rate = LINK_RATE_UNKNOWN;
4017                                 tmp_timing.flags.DSC = 0;
4018                                 orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing);
4019                                 decide_edp_link_settings(link, &tmp_link_setting, orig_req_bw);
4020                                 max_link_rate = tmp_link_setting.link_rate;
4021                         }
4022                         if (decide_edp_link_settings_with_dsc(link, link_setting, req_bw, max_link_rate))
4023                                 return;
4024                 } else if (decide_edp_link_settings(link, link_setting, req_bw))
4025                         return;
4026         } else if (decide_dp_link_settings(link, link_setting, req_bw))
4027                 return;
4028
4029         BREAK_TO_DEBUGGER();
4030         ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
4031
4032         *link_setting = link->verified_link_cap;
4033 }
4034
4035 /*************************Short Pulse IRQ***************************/
4036 bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link)
4037 {
4038         /*
4039          * Don't handle RX IRQ unless one of following is met:
4040          * 1) The link is established (cur_link_settings != unknown)
4041          * 2) We know we're dealing with a branch device, SST or MST
4042          */
4043
4044         if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
4045                 is_dp_branch_device(link))
4046                 return true;
4047
4048         return false;
4049 }
4050
4051 static bool handle_hpd_irq_psr_sink(struct dc_link *link)
4052 {
4053         union dpcd_psr_configuration psr_configuration;
4054
4055         if (!link->psr_settings.psr_feature_enabled)
4056                 return false;
4057
4058         dm_helpers_dp_read_dpcd(
4059                 link->ctx,
4060                 link,
4061                 368,/*DpcdAddress_PSR_Enable_Cfg*/
4062                 &psr_configuration.raw,
4063                 sizeof(psr_configuration.raw));
4064
4065         if (psr_configuration.bits.ENABLE) {
4066                 unsigned char dpcdbuf[3] = {0};
4067                 union psr_error_status psr_error_status;
4068                 union psr_sink_psr_status psr_sink_psr_status;
4069
4070                 dm_helpers_dp_read_dpcd(
4071                         link->ctx,
4072                         link,
4073                         0x2006, /*DpcdAddress_PSR_Error_Status*/
4074                         (unsigned char *) dpcdbuf,
4075                         sizeof(dpcdbuf));
4076
4077                 /*DPCD 2006h   ERROR STATUS*/
4078                 psr_error_status.raw = dpcdbuf[0];
4079                 /*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
4080                 psr_sink_psr_status.raw = dpcdbuf[2];
4081
4082                 if (psr_error_status.bits.LINK_CRC_ERROR ||
4083                                 psr_error_status.bits.RFB_STORAGE_ERROR ||
4084                                 psr_error_status.bits.VSC_SDP_ERROR) {
4085                         bool allow_active;
4086
4087                         /* Acknowledge and clear error bits */
4088                         dm_helpers_dp_write_dpcd(
4089                                 link->ctx,
4090                                 link,
4091                                 8198,/*DpcdAddress_PSR_Error_Status*/
4092                                 &psr_error_status.raw,
4093                                 sizeof(psr_error_status.raw));
4094
4095                         /* PSR error, disable and re-enable PSR */
4096                         if (link->psr_settings.psr_allow_active) {
4097                                 allow_active = false;
4098                                 dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
4099                                 allow_active = true;
4100                                 dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
4101                         }
4102
4103                         return true;
4104                 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
4105                                 PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
4106                         /* No error is detect, PSR is active.
4107                          * We should return with IRQ_HPD handled without
4108                          * checking for loss of sync since PSR would have
4109                          * powered down main link.
4110                          */
4111                         return true;
4112                 }
4113         }
4114         return false;
4115 }
4116
4117 static enum dc_link_rate get_link_rate_from_test_link_rate(uint8_t test_rate)
4118 {
4119         switch (test_rate) {
4120         case DP_TEST_LINK_RATE_RBR:
4121                 return LINK_RATE_LOW;
4122         case DP_TEST_LINK_RATE_HBR:
4123                 return LINK_RATE_HIGH;
4124         case DP_TEST_LINK_RATE_HBR2:
4125                 return LINK_RATE_HIGH2;
4126         case DP_TEST_LINK_RATE_HBR3:
4127                 return LINK_RATE_HIGH3;
4128         case DP_TEST_LINK_RATE_UHBR10:
4129                 return LINK_RATE_UHBR10;
4130         case DP_TEST_LINK_RATE_UHBR20:
4131                 return LINK_RATE_UHBR20;
4132         case DP_TEST_LINK_RATE_UHBR13_5:
4133                 return LINK_RATE_UHBR13_5;
4134         default:
4135                 return LINK_RATE_UNKNOWN;
4136         }
4137 }
4138
4139 static void dp_test_send_link_training(struct dc_link *link)
4140 {
4141         struct dc_link_settings link_settings = {0};
4142         uint8_t test_rate = 0;
4143
4144         core_link_read_dpcd(
4145                         link,
4146                         DP_TEST_LANE_COUNT,
4147                         (unsigned char *)(&link_settings.lane_count),
4148                         1);
4149         core_link_read_dpcd(
4150                         link,
4151                         DP_TEST_LINK_RATE,
4152                         &test_rate,
4153                         1);
4154         link_settings.link_rate = get_link_rate_from_test_link_rate(test_rate);
4155
4156         /* Set preferred link settings */
4157         link->verified_link_cap.lane_count = link_settings.lane_count;
4158         link->verified_link_cap.link_rate = link_settings.link_rate;
4159
4160         dp_retrain_link_dp_test(link, &link_settings, false);
4161 }
4162
4163 /* TODO Raven hbr2 compliance eye output is unstable
4164  * (toggling on and off) with debugger break
4165  * This caueses intermittent PHY automation failure
4166  * Need to look into the root cause */
4167 static void dp_test_send_phy_test_pattern(struct dc_link *link)
4168 {
4169         union phy_test_pattern dpcd_test_pattern;
4170         union lane_adjust dpcd_lane_adjustment[2];
4171         unsigned char dpcd_post_cursor_2_adjustment = 0;
4172         unsigned char test_pattern_buffer[
4173                         (DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
4174                         DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
4175         unsigned int test_pattern_size = 0;
4176         enum dp_test_pattern test_pattern;
4177         union lane_adjust dpcd_lane_adjust;
4178         unsigned int lane;
4179         struct link_training_settings link_training_settings;
4180
4181         dpcd_test_pattern.raw = 0;
4182         memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
4183         memset(&link_training_settings, 0, sizeof(link_training_settings));
4184
4185         /* get phy test pattern and pattern parameters from DP receiver */
4186         core_link_read_dpcd(
4187                         link,
4188                         DP_PHY_TEST_PATTERN,
4189                         &dpcd_test_pattern.raw,
4190                         sizeof(dpcd_test_pattern));
4191         core_link_read_dpcd(
4192                         link,
4193                         DP_ADJUST_REQUEST_LANE0_1,
4194                         &dpcd_lane_adjustment[0].raw,
4195                         sizeof(dpcd_lane_adjustment));
4196
4197         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
4198                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
4199                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
4200                 dp_fixed_vs_pe_read_lane_adjust(
4201                                 link,
4202                                 link_training_settings.dpcd_lane_settings);
4203
4204         /*get post cursor 2 parameters
4205          * For DP 1.1a or eariler, this DPCD register's value is 0
4206          * For DP 1.2 or later:
4207          * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
4208          * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
4209          */
4210         core_link_read_dpcd(
4211                         link,
4212                         DP_ADJUST_REQUEST_POST_CURSOR2,
4213                         &dpcd_post_cursor_2_adjustment,
4214                         sizeof(dpcd_post_cursor_2_adjustment));
4215
4216         /* translate request */
4217         switch (dpcd_test_pattern.bits.PATTERN) {
4218         case PHY_TEST_PATTERN_D10_2:
4219                 test_pattern = DP_TEST_PATTERN_D102;
4220                 break;
4221         case PHY_TEST_PATTERN_SYMBOL_ERROR:
4222                 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
4223                 break;
4224         case PHY_TEST_PATTERN_PRBS7:
4225                 test_pattern = DP_TEST_PATTERN_PRBS7;
4226                 break;
4227         case PHY_TEST_PATTERN_80BIT_CUSTOM:
4228                 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
4229                 break;
4230         case PHY_TEST_PATTERN_CP2520_1:
4231                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
4232                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
4233                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
4234                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
4235                 break;
4236         case PHY_TEST_PATTERN_CP2520_2:
4237                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
4238                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
4239                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
4240                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
4241                 break;
4242         case PHY_TEST_PATTERN_CP2520_3:
4243                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
4244                 break;
4245         case PHY_TEST_PATTERN_128b_132b_TPS1:
4246                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
4247                 break;
4248         case PHY_TEST_PATTERN_128b_132b_TPS2:
4249                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS2;
4250                 break;
4251         case PHY_TEST_PATTERN_PRBS9:
4252                 test_pattern = DP_TEST_PATTERN_PRBS9;
4253                 break;
4254         case PHY_TEST_PATTERN_PRBS11:
4255                 test_pattern = DP_TEST_PATTERN_PRBS11;
4256                 break;
4257         case PHY_TEST_PATTERN_PRBS15:
4258                 test_pattern = DP_TEST_PATTERN_PRBS15;
4259                 break;
4260         case PHY_TEST_PATTERN_PRBS23:
4261                 test_pattern = DP_TEST_PATTERN_PRBS23;
4262                 break;
4263         case PHY_TEST_PATTERN_PRBS31:
4264                 test_pattern = DP_TEST_PATTERN_PRBS31;
4265                 break;
4266         case PHY_TEST_PATTERN_264BIT_CUSTOM:
4267                 test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
4268                 break;
4269         case PHY_TEST_PATTERN_SQUARE_PULSE:
4270                 test_pattern = DP_TEST_PATTERN_SQUARE_PULSE;
4271                 break;
4272         default:
4273                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
4274         break;
4275         }
4276
4277         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
4278                 test_pattern_size = (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
4279                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0) + 1;
4280                 core_link_read_dpcd(
4281                                 link,
4282                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
4283                                 test_pattern_buffer,
4284                                 test_pattern_size);
4285         }
4286
4287         if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) {
4288                 test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
4289                 core_link_read_dpcd(
4290                                 link,
4291                                 DP_PHY_SQUARE_PATTERN,
4292                                 test_pattern_buffer,
4293                                 test_pattern_size);
4294         }
4295
4296         if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) {
4297                 test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256-
4298                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1;
4299                 core_link_read_dpcd(
4300                                 link,
4301                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0,
4302                                 test_pattern_buffer,
4303                                 test_pattern_size);
4304         }
4305
4306         /* prepare link training settings */
4307         link_training_settings.link_settings = link->cur_link_settings;
4308
4309         for (lane = 0; lane <
4310                 (unsigned int)(link->cur_link_settings.lane_count);
4311                 lane++) {
4312                 dpcd_lane_adjust.raw =
4313                         get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
4314                 if (dp_get_link_encoding_format(&link->cur_link_settings) ==
4315                                 DP_8b_10b_ENCODING) {
4316                         link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
4317                                 (enum dc_voltage_swing)
4318                                 (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
4319                         link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
4320                                 (enum dc_pre_emphasis)
4321                                 (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
4322                         link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
4323                                 (enum dc_post_cursor2)
4324                                 ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
4325                 } else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
4326                                 DP_128b_132b_ENCODING) {
4327                         link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw =
4328                                         dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
4329                 }
4330         }
4331
4332         dp_hw_to_dpcd_lane_settings(&link_training_settings,
4333                         link_training_settings.hw_lane_settings,
4334                         link_training_settings.dpcd_lane_settings);
4335         /*Usage: Measure DP physical lane signal
4336          * by DP SI test equipment automatically.
4337          * PHY test pattern request is generated by equipment via HPD interrupt.
4338          * HPD needs to be active all the time. HPD should be active
4339          * all the time. Do not touch it.
4340          * forward request to DS
4341          */
4342         dc_link_dp_set_test_pattern(
4343                 link,
4344                 test_pattern,
4345                 DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
4346                 &link_training_settings,
4347                 test_pattern_buffer,
4348                 test_pattern_size);
4349 }
4350
4351 static void dp_test_send_link_test_pattern(struct dc_link *link)
4352 {
4353         union link_test_pattern dpcd_test_pattern;
4354         union test_misc dpcd_test_params;
4355         enum dp_test_pattern test_pattern;
4356         enum dp_test_pattern_color_space test_pattern_color_space =
4357                         DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED;
4358         enum dc_color_depth requestColorDepth = COLOR_DEPTH_UNDEFINED;
4359         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
4360         struct pipe_ctx *pipe_ctx = NULL;
4361         int i;
4362
4363         memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
4364         memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
4365
4366         for (i = 0; i < MAX_PIPES; i++) {
4367                 if (pipes[i].stream == NULL)
4368                         continue;
4369
4370                 if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
4371                         pipe_ctx = &pipes[i];
4372                         break;
4373                 }
4374         }
4375
4376         if (pipe_ctx == NULL)
4377                 return;
4378
4379         /* get link test pattern and pattern parameters */
4380         core_link_read_dpcd(
4381                         link,
4382                         DP_TEST_PATTERN,
4383                         &dpcd_test_pattern.raw,
4384                         sizeof(dpcd_test_pattern));
4385         core_link_read_dpcd(
4386                         link,
4387                         DP_TEST_MISC0,
4388                         &dpcd_test_params.raw,
4389                         sizeof(dpcd_test_params));
4390
4391         switch (dpcd_test_pattern.bits.PATTERN) {
4392         case LINK_TEST_PATTERN_COLOR_RAMP:
4393                 test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
4394         break;
4395         case LINK_TEST_PATTERN_VERTICAL_BARS:
4396                 test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
4397         break; /* black and white */
4398         case LINK_TEST_PATTERN_COLOR_SQUARES:
4399                 test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
4400                                 TEST_DYN_RANGE_VESA ?
4401                                 DP_TEST_PATTERN_COLOR_SQUARES :
4402                                 DP_TEST_PATTERN_COLOR_SQUARES_CEA);
4403         break;
4404         default:
4405                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
4406         break;
4407         }
4408
4409         if (dpcd_test_params.bits.CLR_FORMAT == 0)
4410                 test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_RGB;
4411         else
4412                 test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ?
4413                                 DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 :
4414                                 DP_TEST_PATTERN_COLOR_SPACE_YCBCR601;
4415
4416         switch (dpcd_test_params.bits.BPC) {
4417         case 0: // 6 bits
4418                 requestColorDepth = COLOR_DEPTH_666;
4419                 break;
4420         case 1: // 8 bits
4421                 requestColorDepth = COLOR_DEPTH_888;
4422                 break;
4423         case 2: // 10 bits
4424                 requestColorDepth = COLOR_DEPTH_101010;
4425                 break;
4426         case 3: // 12 bits
4427                 requestColorDepth = COLOR_DEPTH_121212;
4428                 break;
4429         default:
4430                 break;
4431         }
4432
4433         switch (dpcd_test_params.bits.CLR_FORMAT) {
4434         case 0:
4435                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB;
4436                 break;
4437         case 1:
4438                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR422;
4439                 break;
4440         case 2:
4441                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
4442                 break;
4443         default:
4444                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB;
4445                 break;
4446         }
4447
4448
4449         if (requestColorDepth != COLOR_DEPTH_UNDEFINED
4450                         && pipe_ctx->stream->timing.display_color_depth != requestColorDepth) {
4451                 DC_LOG_DEBUG("%s: original bpc %d, changing to %d\n",
4452                                 __func__,
4453                                 pipe_ctx->stream->timing.display_color_depth,
4454                                 requestColorDepth);
4455                 pipe_ctx->stream->timing.display_color_depth = requestColorDepth;
4456         }
4457
4458         dp_update_dsc_config(pipe_ctx);
4459
4460         dc_link_dp_set_test_pattern(
4461                         link,
4462                         test_pattern,
4463                         test_pattern_color_space,
4464                         NULL,
4465                         NULL,
4466                         0);
4467 }
4468
4469 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
4470 {
4471         union audio_test_mode            dpcd_test_mode = {0};
4472         struct audio_test_pattern_type   dpcd_pattern_type = {0};
4473         union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
4474         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
4475
4476         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
4477         struct pipe_ctx *pipe_ctx = &pipes[0];
4478         unsigned int channel_count;
4479         unsigned int channel = 0;
4480         unsigned int modes = 0;
4481         unsigned int sampling_rate_in_hz = 0;
4482
4483         // get audio test mode and test pattern parameters
4484         core_link_read_dpcd(
4485                 link,
4486                 DP_TEST_AUDIO_MODE,
4487                 &dpcd_test_mode.raw,
4488                 sizeof(dpcd_test_mode));
4489
4490         core_link_read_dpcd(
4491                 link,
4492                 DP_TEST_AUDIO_PATTERN_TYPE,
4493                 &dpcd_pattern_type.value,
4494                 sizeof(dpcd_pattern_type));
4495
4496         channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT);
4497
4498         // read pattern periods for requested channels when sawTooth pattern is requested
4499         if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
4500                         dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
4501
4502                 test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
4503                                 DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
4504                 // read period for each channel
4505                 for (channel = 0; channel < channel_count; channel++) {
4506                         core_link_read_dpcd(
4507                                                         link,
4508                                                         DP_TEST_AUDIO_PERIOD_CH1 + channel,
4509                                                         &dpcd_pattern_period[channel].raw,
4510                                                         sizeof(dpcd_pattern_period[channel]));
4511                 }
4512         }
4513
4514         // translate sampling rate
4515         switch (dpcd_test_mode.bits.sampling_rate) {
4516         case AUDIO_SAMPLING_RATE_32KHZ:
4517                 sampling_rate_in_hz = 32000;
4518                 break;
4519         case AUDIO_SAMPLING_RATE_44_1KHZ:
4520                 sampling_rate_in_hz = 44100;
4521                 break;
4522         case AUDIO_SAMPLING_RATE_48KHZ:
4523                 sampling_rate_in_hz = 48000;
4524                 break;
4525         case AUDIO_SAMPLING_RATE_88_2KHZ:
4526                 sampling_rate_in_hz = 88200;
4527                 break;
4528         case AUDIO_SAMPLING_RATE_96KHZ:
4529                 sampling_rate_in_hz = 96000;
4530                 break;
4531         case AUDIO_SAMPLING_RATE_176_4KHZ:
4532                 sampling_rate_in_hz = 176400;
4533                 break;
4534         case AUDIO_SAMPLING_RATE_192KHZ:
4535                 sampling_rate_in_hz = 192000;
4536                 break;
4537         default:
4538                 sampling_rate_in_hz = 0;
4539                 break;
4540         }
4541
4542         link->audio_test_data.flags.test_requested = 1;
4543         link->audio_test_data.flags.disable_video = disable_video;
4544         link->audio_test_data.sampling_rate = sampling_rate_in_hz;
4545         link->audio_test_data.channel_count = channel_count;
4546         link->audio_test_data.pattern_type = test_pattern;
4547
4548         if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
4549                 for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
4550                         link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
4551                 }
4552         }
4553 }
4554
4555 void dc_link_dp_handle_automated_test(struct dc_link *link)
4556 {
4557         union test_request test_request;
4558         union test_response test_response;
4559
4560         memset(&test_request, 0, sizeof(test_request));
4561         memset(&test_response, 0, sizeof(test_response));
4562
4563         core_link_read_dpcd(
4564                 link,
4565                 DP_TEST_REQUEST,
4566                 &test_request.raw,
4567                 sizeof(union test_request));
4568         if (test_request.bits.LINK_TRAINING) {
4569                 /* ACK first to let DP RX test box monitor LT sequence */
4570                 test_response.bits.ACK = 1;
4571                 core_link_write_dpcd(
4572                         link,
4573                         DP_TEST_RESPONSE,
4574                         &test_response.raw,
4575                         sizeof(test_response));
4576                 dp_test_send_link_training(link);
4577                 /* no acknowledge request is needed again */
4578                 test_response.bits.ACK = 0;
4579         }
4580         if (test_request.bits.LINK_TEST_PATTRN) {
4581                 dp_test_send_link_test_pattern(link);
4582                 test_response.bits.ACK = 1;
4583         }
4584
4585         if (test_request.bits.AUDIO_TEST_PATTERN) {
4586                 dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
4587                 test_response.bits.ACK = 1;
4588         }
4589
4590         if (test_request.bits.PHY_TEST_PATTERN) {
4591                 dp_test_send_phy_test_pattern(link);
4592                 test_response.bits.ACK = 1;
4593         }
4594
4595         /* send request acknowledgment */
4596         if (test_response.bits.ACK)
4597                 core_link_write_dpcd(
4598                         link,
4599                         DP_TEST_RESPONSE,
4600                         &test_response.raw,
4601                         sizeof(test_response));
4602 }
4603
4604 void dc_link_dp_handle_link_loss(struct dc_link *link)
4605 {
4606         int i;
4607         struct pipe_ctx *pipe_ctx;
4608         struct dc_link_settings prev_link_settings = link->preferred_link_setting;
4609
4610         for (i = 0; i < MAX_PIPES; i++) {
4611                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4612                 if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
4613                         break;
4614         }
4615
4616         if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
4617                 return;
4618
4619         /* toggle stream state with the preference for current link settings */
4620         dc_link_set_preferred_training_settings((struct dc *)link->dc,
4621                                         &link->cur_link_settings, NULL, link, true);
4622
4623         for (i = 0; i < MAX_PIPES; i++) {
4624                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4625                 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
4626                                 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
4627                         core_link_disable_stream(pipe_ctx);
4628                 }
4629         }
4630
4631         for (i = 0; i < MAX_PIPES; i++) {
4632                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4633                 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
4634                                 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
4635                         core_link_enable_stream(link->dc->current_state, pipe_ctx);
4636                 }
4637         }
4638
4639         /* restore previous link settings preference */
4640         dc_link_set_preferred_training_settings((struct dc *)link->dc,
4641                                         &prev_link_settings, NULL, link, true);
4642 }
4643
4644 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
4645                                                         bool defer_handling, bool *has_left_work)
4646 {
4647         union hpd_irq_data hpd_irq_dpcd_data = {0};
4648         union device_service_irq device_service_clear = {0};
4649         enum dc_status result;
4650         bool status = false;
4651
4652         if (out_link_loss)
4653                 *out_link_loss = false;
4654
4655         if (has_left_work)
4656                 *has_left_work = false;
4657         /* For use cases related to down stream connection status change,
4658          * PSR and device auto test, refer to function handle_sst_hpd_irq
4659          * in DAL2.1*/
4660
4661         DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
4662                 __func__, link->link_index);
4663
4664
4665          /* All the "handle_hpd_irq_xxx()" methods
4666                  * should be called only after
4667                  * dal_dpsst_ls_read_hpd_irq_data
4668                  * Order of calls is important too
4669                  */
4670         result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
4671         if (out_hpd_irq_dpcd_data)
4672                 *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
4673
4674         if (result != DC_OK) {
4675                 DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
4676                         __func__);
4677                 return false;
4678         }
4679
4680         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
4681                 device_service_clear.bits.AUTOMATED_TEST = 1;
4682                 core_link_write_dpcd(
4683                         link,
4684                         DP_DEVICE_SERVICE_IRQ_VECTOR,
4685                         &device_service_clear.raw,
4686                         sizeof(device_service_clear.raw));
4687                 device_service_clear.raw = 0;
4688                 if (defer_handling && has_left_work)
4689                         *has_left_work = true;
4690                 else
4691                         dc_link_dp_handle_automated_test(link);
4692                 return false;
4693         }
4694
4695         if (!dc_link_dp_allow_hpd_rx_irq(link)) {
4696                 DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
4697                         __func__, link->link_index);
4698                 return false;
4699         }
4700
4701         if (handle_hpd_irq_psr_sink(link))
4702                 /* PSR-related error was detected and handled */
4703                 return true;
4704
4705         /* If PSR-related error handled, Main link may be off,
4706          * so do not handle as a normal sink status change interrupt.
4707          */
4708
4709         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) {
4710                 if (defer_handling && has_left_work)
4711                         *has_left_work = true;
4712                 return true;
4713         }
4714
4715         /* check if we have MST msg and return since we poll for it */
4716         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) {
4717                 if (defer_handling && has_left_work)
4718                         *has_left_work = true;
4719                 return false;
4720         }
4721
4722         /* For now we only handle 'Downstream port status' case.
4723          * If we got sink count changed it means
4724          * Downstream port status changed,
4725          * then DM should call DC to do the detection.
4726          * NOTE: Do not handle link loss on eDP since it is internal link*/
4727         if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
4728                 hpd_rx_irq_check_link_loss_status(
4729                         link,
4730                         &hpd_irq_dpcd_data)) {
4731                 /* Connectivity log: link loss */
4732                 CONN_DATA_LINK_LOSS(link,
4733                                         hpd_irq_dpcd_data.raw,
4734                                         sizeof(hpd_irq_dpcd_data),
4735                                         "Status: ");
4736
4737                 if (defer_handling && has_left_work)
4738                         *has_left_work = true;
4739                 else
4740                         dc_link_dp_handle_link_loss(link);
4741
4742                 status = false;
4743                 if (out_link_loss)
4744                         *out_link_loss = true;
4745
4746                 dp_trace_link_loss_increment(link);
4747         }
4748
4749         if (link->type == dc_connection_sst_branch &&
4750                 hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
4751                         != link->dpcd_sink_count)
4752                 status = true;
4753
4754         /* reasons for HPD RX:
4755          * 1. Link Loss - ie Re-train the Link
4756          * 2. MST sideband message
4757          * 3. Automated Test - ie. Internal Commit
4758          * 4. CP (copy protection) - (not interesting for DM???)
4759          * 5. DRR
4760          * 6. Downstream Port status changed
4761          * -ie. Detect - this the only one
4762          * which is interesting for DM because
4763          * it must call dc_link_detect.
4764          */
4765         return status;
4766 }
4767
4768 /*query dpcd for version and mst cap addresses*/
4769 bool is_mst_supported(struct dc_link *link)
4770 {
4771         bool mst          = false;
4772         enum dc_status st = DC_OK;
4773         union dpcd_rev rev;
4774         union mstm_cap cap;
4775
4776         if (link->preferred_training_settings.mst_enable &&
4777                 *link->preferred_training_settings.mst_enable == false) {
4778                 return false;
4779         }
4780
4781         rev.raw  = 0;
4782         cap.raw  = 0;
4783
4784         st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
4785                         sizeof(rev));
4786
4787         if (st == DC_OK && rev.raw >= DPCD_REV_12) {
4788
4789                 st = core_link_read_dpcd(link, DP_MSTM_CAP,
4790                                 &cap.raw, sizeof(cap));
4791                 if (st == DC_OK && cap.bits.MST_CAP == 1)
4792                         mst = true;
4793         }
4794         return mst;
4795
4796 }
4797
4798 bool is_dp_active_dongle(const struct dc_link *link)
4799 {
4800         return (link->dpcd_caps.dongle_type >= DISPLAY_DONGLE_DP_VGA_CONVERTER) &&
4801                                 (link->dpcd_caps.dongle_type <= DISPLAY_DONGLE_DP_HDMI_CONVERTER);
4802 }
4803
4804 bool is_dp_branch_device(const struct dc_link *link)
4805 {
4806         return link->dpcd_caps.is_branch_dev;
4807 }
4808
4809 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
4810 {
4811         switch (bpc) {
4812         case DOWN_STREAM_MAX_8BPC:
4813                 return 8;
4814         case DOWN_STREAM_MAX_10BPC:
4815                 return 10;
4816         case DOWN_STREAM_MAX_12BPC:
4817                 return 12;
4818         case DOWN_STREAM_MAX_16BPC:
4819                 return 16;
4820         default:
4821                 break;
4822         }
4823
4824         return -1;
4825 }
4826
4827 #if defined(CONFIG_DRM_AMD_DC_DCN)
4828 uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw)
4829 {
4830         switch (bw) {
4831         case 0b001:
4832                 return 9000000;
4833         case 0b010:
4834                 return 18000000;
4835         case 0b011:
4836                 return 24000000;
4837         case 0b100:
4838                 return 32000000;
4839         case 0b101:
4840                 return 40000000;
4841         case 0b110:
4842                 return 48000000;
4843         }
4844
4845         return 0;
4846 }
4847
4848 /*
4849  * Return PCON's post FRL link training supported BW if its non-zero, otherwise return max_supported_frl_bw.
4850  */
4851 static uint32_t intersect_frl_link_bw_support(
4852         const uint32_t max_supported_frl_bw_in_kbps,
4853         const union hdmi_encoded_link_bw hdmi_encoded_link_bw)
4854 {
4855         uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps;
4856
4857         // HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode)
4858         if (hdmi_encoded_link_bw.bits.FRL_MODE) {
4859                 if (hdmi_encoded_link_bw.bits.BW_48Gbps)
4860                         supported_bw_in_kbps = 48000000;
4861                 else if (hdmi_encoded_link_bw.bits.BW_40Gbps)
4862                         supported_bw_in_kbps = 40000000;
4863                 else if (hdmi_encoded_link_bw.bits.BW_32Gbps)
4864                         supported_bw_in_kbps = 32000000;
4865                 else if (hdmi_encoded_link_bw.bits.BW_24Gbps)
4866                         supported_bw_in_kbps = 24000000;
4867                 else if (hdmi_encoded_link_bw.bits.BW_18Gbps)
4868                         supported_bw_in_kbps = 18000000;
4869                 else if (hdmi_encoded_link_bw.bits.BW_9Gbps)
4870                         supported_bw_in_kbps = 9000000;
4871         }
4872
4873         return supported_bw_in_kbps;
4874 }
4875 #endif
4876
4877 static void read_dp_device_vendor_id(struct dc_link *link)
4878 {
4879         struct dp_device_vendor_id dp_id;
4880
4881         /* read IEEE branch device id */
4882         core_link_read_dpcd(
4883                 link,
4884                 DP_BRANCH_OUI,
4885                 (uint8_t *)&dp_id,
4886                 sizeof(dp_id));
4887
4888         link->dpcd_caps.branch_dev_id =
4889                 (dp_id.ieee_oui[0] << 16) +
4890                 (dp_id.ieee_oui[1] << 8) +
4891                 dp_id.ieee_oui[2];
4892
4893         memmove(
4894                 link->dpcd_caps.branch_dev_name,
4895                 dp_id.ieee_device_id,
4896                 sizeof(dp_id.ieee_device_id));
4897 }
4898
4899
4900
4901 static void get_active_converter_info(
4902         uint8_t data, struct dc_link *link)
4903 {
4904         union dp_downstream_port_present ds_port = { .byte = data };
4905         memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
4906
4907         /* decode converter info*/
4908         if (!ds_port.fields.PORT_PRESENT) {
4909                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4910                 ddc_service_set_dongle_type(link->ddc,
4911                                 link->dpcd_caps.dongle_type);
4912                 link->dpcd_caps.is_branch_dev = false;
4913                 return;
4914         }
4915
4916         /* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
4917         link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
4918
4919         switch (ds_port.fields.PORT_TYPE) {
4920         case DOWNSTREAM_VGA:
4921                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
4922                 break;
4923         case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
4924                 /* At this point we don't know is it DVI or HDMI or DP++,
4925                  * assume DVI.*/
4926                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
4927                 break;
4928         default:
4929                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4930                 break;
4931         }
4932
4933         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
4934                 uint8_t det_caps[16]; /* CTS 4.2.2.7 expects source to read Detailed Capabilities Info : 00080h-0008F.*/
4935                 union dwnstream_port_caps_byte0 *port_caps =
4936                         (union dwnstream_port_caps_byte0 *)det_caps;
4937                 if (core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
4938                                 det_caps, sizeof(det_caps)) == DC_OK) {
4939
4940                         switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
4941                         /*Handle DP case as DONGLE_NONE*/
4942                         case DOWN_STREAM_DETAILED_DP:
4943                                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4944                                 break;
4945                         case DOWN_STREAM_DETAILED_VGA:
4946                                 link->dpcd_caps.dongle_type =
4947                                         DISPLAY_DONGLE_DP_VGA_CONVERTER;
4948                                 break;
4949                         case DOWN_STREAM_DETAILED_DVI:
4950                                 link->dpcd_caps.dongle_type =
4951                                         DISPLAY_DONGLE_DP_DVI_CONVERTER;
4952                                 break;
4953                         case DOWN_STREAM_DETAILED_HDMI:
4954                         case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
4955                                 /*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
4956                                 link->dpcd_caps.dongle_type =
4957                                         DISPLAY_DONGLE_DP_HDMI_CONVERTER;
4958
4959                                 link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
4960                                 if (ds_port.fields.DETAILED_CAPS) {
4961
4962                                         union dwnstream_port_caps_byte3_hdmi
4963                                                 hdmi_caps = {.raw = det_caps[3] };
4964                                         union dwnstream_port_caps_byte2
4965                                                 hdmi_color_caps = {.raw = det_caps[2] };
4966                                         link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz =
4967                                                 det_caps[1] * 2500;
4968
4969                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
4970                                                 hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
4971                                         /*YCBCR capability only for HDMI case*/
4972                                         if (port_caps->bits.DWN_STRM_PORTX_TYPE
4973                                                         == DOWN_STREAM_DETAILED_HDMI) {
4974                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
4975                                                                 hdmi_caps.bits.YCrCr422_PASS_THROUGH;
4976                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
4977                                                                 hdmi_caps.bits.YCrCr420_PASS_THROUGH;
4978                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
4979                                                                 hdmi_caps.bits.YCrCr422_CONVERSION;
4980                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
4981                                                                 hdmi_caps.bits.YCrCr420_CONVERSION;
4982                                         }
4983
4984                                         link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
4985                                                 translate_dpcd_max_bpc(
4986                                                         hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
4987
4988 #if defined(CONFIG_DRM_AMD_DC_DCN)
4989                                         if (link->dc->caps.hdmi_frl_pcon_support) {
4990                                                 union hdmi_encoded_link_bw hdmi_encoded_link_bw;
4991
4992                                                 link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps =
4993                                                                 dc_link_bw_kbps_from_raw_frl_link_rate_data(
4994                                                                                 hdmi_color_caps.bits.MAX_ENCODED_LINK_BW_SUPPORT);
4995
4996                                                 // Intersect reported max link bw support with the supported link rate post FRL link training
4997                                                 if (core_link_read_dpcd(link, DP_PCON_HDMI_POST_FRL_STATUS,
4998                                                                 &hdmi_encoded_link_bw.raw, sizeof(hdmi_encoded_link_bw)) == DC_OK) {
4999                                                         link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = intersect_frl_link_bw_support(
5000                                                                         link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps,
5001                                                                         hdmi_encoded_link_bw);
5002                                                 }
5003
5004                                                 if (link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps > 0)
5005                                                         link->dpcd_caps.dongle_caps.extendedCapValid = true;
5006                                         }
5007 #endif
5008
5009                                         if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
5010                                                 link->dpcd_caps.dongle_caps.extendedCapValid = true;
5011                                 }
5012
5013                                 break;
5014                         }
5015                 }
5016         }
5017
5018         ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
5019
5020         {
5021                 struct dp_sink_hw_fw_revision dp_hw_fw_revision;
5022
5023                 core_link_read_dpcd(
5024                         link,
5025                         DP_BRANCH_REVISION_START,
5026                         (uint8_t *)&dp_hw_fw_revision,
5027                         sizeof(dp_hw_fw_revision));
5028
5029                 link->dpcd_caps.branch_hw_revision =
5030                         dp_hw_fw_revision.ieee_hw_rev;
5031
5032                 memmove(
5033                         link->dpcd_caps.branch_fw_revision,
5034                         dp_hw_fw_revision.ieee_fw_rev,
5035                         sizeof(dp_hw_fw_revision.ieee_fw_rev));
5036         }
5037         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
5038                         link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
5039                 union dp_dfp_cap_ext dfp_cap_ext;
5040                 memset(&dfp_cap_ext, '\0', sizeof (dfp_cap_ext));
5041                 core_link_read_dpcd(
5042                                 link,
5043                                 DP_DFP_CAPABILITY_EXTENSION_SUPPORT,
5044                                 dfp_cap_ext.raw,
5045                                 sizeof(dfp_cap_ext.raw));
5046                 link->dpcd_caps.dongle_caps.dfp_cap_ext.supported = dfp_cap_ext.fields.supported;
5047                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_pixel_rate_in_mps =
5048                                 dfp_cap_ext.fields.max_pixel_rate_in_mps[0] +
5049                                 (dfp_cap_ext.fields.max_pixel_rate_in_mps[1] << 8);
5050                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width =
5051                                 dfp_cap_ext.fields.max_video_h_active_width[0] +
5052                                 (dfp_cap_ext.fields.max_video_h_active_width[1] << 8);
5053                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height =
5054                                 dfp_cap_ext.fields.max_video_v_active_height[0] +
5055                                 (dfp_cap_ext.fields.max_video_v_active_height[1] << 8);
5056                 link->dpcd_caps.dongle_caps.dfp_cap_ext.encoding_format_caps =
5057                                 dfp_cap_ext.fields.encoding_format_caps;
5058                 link->dpcd_caps.dongle_caps.dfp_cap_ext.rgb_color_depth_caps =
5059                                 dfp_cap_ext.fields.rgb_color_depth_caps;
5060                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr444_color_depth_caps =
5061                                 dfp_cap_ext.fields.ycbcr444_color_depth_caps;
5062                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr422_color_depth_caps =
5063                                 dfp_cap_ext.fields.ycbcr422_color_depth_caps;
5064                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr420_color_depth_caps =
5065                                 dfp_cap_ext.fields.ycbcr420_color_depth_caps;
5066                 DC_LOG_DP2("DFP capability extension is read at link %d", link->link_index);
5067                 DC_LOG_DP2("\tdfp_cap_ext.supported = %s", link->dpcd_caps.dongle_caps.dfp_cap_ext.supported ? "true" : "false");
5068                 DC_LOG_DP2("\tdfp_cap_ext.max_pixel_rate_in_mps = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_pixel_rate_in_mps);
5069                 DC_LOG_DP2("\tdfp_cap_ext.max_video_h_active_width = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width);
5070                 DC_LOG_DP2("\tdfp_cap_ext.max_video_v_active_height = %d", link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height);
5071         }
5072 }
5073
5074 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
5075                 int length)
5076 {
5077         int retry = 0;
5078
5079         if (!link->dpcd_caps.dpcd_rev.raw) {
5080                 do {
5081                         dp_receiver_power_ctrl(link, true);
5082                         core_link_read_dpcd(link, DP_DPCD_REV,
5083                                                         dpcd_data, length);
5084                         link->dpcd_caps.dpcd_rev.raw = dpcd_data[
5085                                 DP_DPCD_REV -
5086                                 DP_DPCD_REV];
5087                 } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
5088         }
5089
5090         if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
5091                 switch (link->dpcd_caps.branch_dev_id) {
5092                 /* 0010FA active dongles (DP-VGA, DP-DLDVI converters) power down
5093                  * all internal circuits including AUX communication preventing
5094                  * reading DPCD table and EDID (spec violation).
5095                  * Encoder will skip DP RX power down on disable_output to
5096                  * keep receiver powered all the time.*/
5097                 case DP_BRANCH_DEVICE_ID_0010FA:
5098                 case DP_BRANCH_DEVICE_ID_0080E1:
5099                 case DP_BRANCH_DEVICE_ID_00E04C:
5100                         link->wa_flags.dp_keep_receiver_powered = true;
5101                         break;
5102
5103                 /* TODO: May need work around for other dongles. */
5104                 default:
5105                         link->wa_flags.dp_keep_receiver_powered = false;
5106                         break;
5107                 }
5108         } else
5109                 link->wa_flags.dp_keep_receiver_powered = false;
5110 }
5111
5112 /* Read additional sink caps defined in source specific DPCD area
5113  * This function currently only reads from SinkCapability address (DP_SOURCE_SINK_CAP)
5114  */
5115 static bool dpcd_read_sink_ext_caps(struct dc_link *link)
5116 {
5117         uint8_t dpcd_data;
5118
5119         if (!link)
5120                 return false;
5121
5122         if (core_link_read_dpcd(link, DP_SOURCE_SINK_CAP, &dpcd_data, 1) != DC_OK)
5123                 return false;
5124
5125         link->dpcd_sink_ext_caps.raw = dpcd_data;
5126         return true;
5127 }
5128
5129 void dp_retrieve_lttpr_cap(struct dc_link *link)
5130 {
5131         bool allow_lttpr_non_transparent_mode = 0;
5132         bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
5133         enum dc_status status = DC_ERROR_UNEXPECTED;
5134
5135         memset(link->lttpr_dpcd_data, '\0', sizeof(link->lttpr_dpcd_data));
5136
5137         if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
5138                         link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
5139                 allow_lttpr_non_transparent_mode = 1;
5140         } else if (link->dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A &&
5141                         !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
5142                 allow_lttpr_non_transparent_mode = 1;
5143         }
5144
5145         link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5146         link->lttpr_support = LTTPR_UNSUPPORTED;
5147
5148         /*
5149          * Logic to determine LTTPR support
5150          */
5151         if (vbios_lttpr_interop)
5152                 link->lttpr_support = LTTPR_SUPPORTED;
5153         else if (link->dc->config.allow_lttpr_non_transparent_mode.raw == 0
5154                         || !link->dc->caps.extended_aux_timeout_support)
5155                         link->lttpr_support = LTTPR_UNSUPPORTED;
5156         else
5157                 link->lttpr_support = LTTPR_CHECK_EXT_SUPPORT;
5158
5159         /* Check DP tunnel LTTPR mode debug option. */
5160         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
5161             link->dc->debug.dpia_debug.bits.force_non_lttpr)
5162                 link->lttpr_support = LTTPR_UNSUPPORTED;
5163
5164         if (link->lttpr_support > LTTPR_UNSUPPORTED) {
5165                 /* By reading LTTPR capability, RX assumes that we will enable
5166                  * LTTPR extended aux timeout if LTTPR is present.
5167                  */
5168                 status = core_link_read_dpcd(
5169                                 link,
5170                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
5171                                 link->lttpr_dpcd_data,
5172                                 sizeof(link->lttpr_dpcd_data));
5173         }
5174 }
5175
5176 bool dp_parse_lttpr_mode(struct dc_link *link)
5177 {
5178         bool dpcd_allow_lttpr_non_transparent_mode = false;
5179         bool is_lttpr_present = false;
5180
5181         bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
5182
5183         if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
5184                         link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
5185                 dpcd_allow_lttpr_non_transparent_mode = true;
5186         } else if (link->dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A &&
5187                         !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
5188                 dpcd_allow_lttpr_non_transparent_mode = true;
5189         }
5190
5191         /*
5192          * Logic to determine LTTPR mode
5193          */
5194         if (link->lttpr_support == LTTPR_SUPPORTED)
5195                 if (vbios_lttpr_enable)
5196                         link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5197                 else if (dpcd_allow_lttpr_non_transparent_mode)
5198                         link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5199                 else
5200                         link->lttpr_mode = LTTPR_MODE_TRANSPARENT;
5201         else    // lttpr_support == LTTPR_CHECK_EXT_SUPPORT
5202                 if (dpcd_allow_lttpr_non_transparent_mode) {
5203                         link->lttpr_support = LTTPR_SUPPORTED;
5204                         link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5205                 } else {
5206                         link->lttpr_support = LTTPR_UNSUPPORTED;
5207                 }
5208
5209         if (link->lttpr_support == LTTPR_UNSUPPORTED)
5210                 return false;
5211
5212         link->dpcd_caps.lttpr_caps.revision.raw =
5213                         link->lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV -
5214                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5215
5216         link->dpcd_caps.lttpr_caps.max_link_rate =
5217                         link->lttpr_dpcd_data[DP_MAX_LINK_RATE_PHY_REPEATER -
5218                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5219
5220         link->dpcd_caps.lttpr_caps.phy_repeater_cnt =
5221                         link->lttpr_dpcd_data[DP_PHY_REPEATER_CNT -
5222                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5223
5224         link->dpcd_caps.lttpr_caps.max_lane_count =
5225                         link->lttpr_dpcd_data[DP_MAX_LANE_COUNT_PHY_REPEATER -
5226                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5227
5228         link->dpcd_caps.lttpr_caps.mode =
5229                         link->lttpr_dpcd_data[DP_PHY_REPEATER_MODE -
5230                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5231
5232         link->dpcd_caps.lttpr_caps.max_ext_timeout =
5233                         link->lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
5234                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5235
5236         link->dpcd_caps.lttpr_caps.main_link_channel_coding.raw =
5237                         link->lttpr_dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER -
5238                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5239
5240         link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw =
5241                         link->lttpr_dpcd_data[DP_PHY_REPEATER_128B132B_RATES -
5242                                                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5243
5244
5245         /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
5246         is_lttpr_present = (link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
5247                         link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
5248                         link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
5249         if (is_lttpr_present) {
5250                 CONN_DATA_DETECT(link, link->lttpr_dpcd_data, sizeof(link->lttpr_dpcd_data), "LTTPR Caps: ");
5251                 configure_lttpr_mode_transparent(link);
5252         } else
5253                 link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5254
5255         return is_lttpr_present;
5256 }
5257
5258 static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
5259 {
5260         union dmub_rb_cmd cmd;
5261
5262         if (!link->ctx->dmub_srv ||
5263                         link->ep_type != DISPLAY_ENDPOINT_PHY ||
5264                         link->link_enc->features.flags.bits.DP_IS_USB_C == 0)
5265                 return false;
5266
5267         memset(&cmd, 0, sizeof(cmd));
5268         cmd.cable_id.header.type = DMUB_CMD_GET_USBC_CABLE_ID;
5269         cmd.cable_id.header.payload_bytes = sizeof(cmd.cable_id.data);
5270         cmd.cable_id.data.input.phy_inst = resource_transmitter_to_phy_idx(
5271                         link->dc, link->link_enc->transmitter);
5272         if (dc_dmub_srv_cmd_with_reply_data(link->ctx->dmub_srv, &cmd) &&
5273                         cmd.cable_id.header.ret_status == 1)
5274                 cable_id->raw = cmd.cable_id.data.output_raw;
5275
5276         return cmd.cable_id.header.ret_status == 1;
5277 }
5278
5279 static union dp_cable_id intersect_cable_id(
5280                 union dp_cable_id *a, union dp_cable_id *b)
5281 {
5282         union dp_cable_id out;
5283
5284         out.bits.UHBR10_20_CAPABILITY = MIN(a->bits.UHBR10_20_CAPABILITY,
5285                         b->bits.UHBR10_20_CAPABILITY);
5286         out.bits.UHBR13_5_CAPABILITY = MIN(a->bits.UHBR13_5_CAPABILITY,
5287                         b->bits.UHBR13_5_CAPABILITY);
5288         out.bits.CABLE_TYPE = MAX(a->bits.CABLE_TYPE, b->bits.CABLE_TYPE);
5289
5290         return out;
5291 }
5292
5293 static void retrieve_cable_id(struct dc_link *link)
5294 {
5295         union dp_cable_id usbc_cable_id;
5296
5297         link->dpcd_caps.cable_id.raw = 0;
5298         core_link_read_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX,
5299                         &link->dpcd_caps.cable_id.raw, sizeof(uint8_t));
5300
5301         if (get_usbc_cable_id(link, &usbc_cable_id))
5302                 link->dpcd_caps.cable_id = intersect_cable_id(
5303                                 &link->dpcd_caps.cable_id, &usbc_cable_id);
5304 }
5305
5306 /* DPRX may take some time to respond to AUX messages after HPD asserted.
5307  * If AUX read unsuccessful, try to wake unresponsive DPRX by toggling DPCD SET_POWER (0x600).
5308  */
5309 static enum dc_status wa_try_to_wake_dprx(struct dc_link *link, uint64_t timeout_ms)
5310 {
5311         enum dc_status status = DC_ERROR_UNEXPECTED;
5312         uint8_t dpcd_data = 0;
5313         uint64_t start_ts = 0;
5314         uint64_t current_ts = 0;
5315         uint64_t time_taken_ms = 0;
5316         enum dc_connection_type type = dc_connection_none;
5317
5318         status = core_link_read_dpcd(
5319                         link,
5320                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
5321                         &dpcd_data,
5322                         sizeof(dpcd_data));
5323
5324         if (status != DC_OK) {
5325                 DC_LOG_WARNING("%s: Read DPCD LTTPR_CAP failed - try to toggle DPCD SET_POWER for %lld ms.",
5326                                 __func__,
5327                                 timeout_ms);
5328                 start_ts = dm_get_timestamp(link->ctx);
5329
5330                 do {
5331                         if (!dc_link_detect_sink(link, &type) || type == dc_connection_none)
5332                                 break;
5333
5334                         dpcd_data = DP_SET_POWER_D3;
5335                         status = core_link_write_dpcd(
5336                                         link,
5337                                         DP_SET_POWER,
5338                                         &dpcd_data,
5339                                         sizeof(dpcd_data));
5340
5341                         dpcd_data = DP_SET_POWER_D0;
5342                         status = core_link_write_dpcd(
5343                                         link,
5344                                         DP_SET_POWER,
5345                                         &dpcd_data,
5346                                         sizeof(dpcd_data));
5347
5348                         current_ts = dm_get_timestamp(link->ctx);
5349                         time_taken_ms = div_u64(dm_get_elapse_time_in_ns(link->ctx, current_ts, start_ts), 1000000);
5350                 } while (status != DC_OK && time_taken_ms < timeout_ms);
5351
5352                 DC_LOG_WARNING("%s: DPCD SET_POWER %s after %lld ms%s",
5353                                 __func__,
5354                                 (status == DC_OK) ? "succeeded" : "failed",
5355                                 time_taken_ms,
5356                                 (type == dc_connection_none) ? ". Unplugged." : ".");
5357         }
5358
5359         return status;
5360 }
5361
5362 static bool retrieve_link_cap(struct dc_link *link)
5363 {
5364         /* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
5365          * which means size 16 will be good for both of those DPCD register block reads
5366          */
5367         uint8_t dpcd_data[16];
5368         /*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
5369          */
5370         uint8_t dpcd_dprx_data = '\0';
5371         uint8_t dpcd_power_state = '\0';
5372
5373         struct dp_device_vendor_id sink_id;
5374         union down_stream_port_count down_strm_port_count;
5375         union edp_configuration_cap edp_config_cap;
5376         union dp_downstream_port_present ds_port = { 0 };
5377         enum dc_status status = DC_ERROR_UNEXPECTED;
5378         uint32_t read_dpcd_retry_cnt = 3;
5379         int i;
5380         struct dp_sink_hw_fw_revision dp_hw_fw_revision;
5381         const uint32_t post_oui_delay = 30; // 30ms
5382         bool is_lttpr_present = false;
5383
5384         memset(dpcd_data, '\0', sizeof(dpcd_data));
5385         memset(&down_strm_port_count,
5386                 '\0', sizeof(union down_stream_port_count));
5387         memset(&edp_config_cap, '\0',
5388                 sizeof(union edp_configuration_cap));
5389
5390         /* if extended timeout is supported in hardware,
5391          * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
5392          * CTS 4.2.1.1 regression introduced by CTS specs requirement update.
5393          */
5394         dc_link_aux_try_to_configure_timeout(link->ddc,
5395                         LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
5396
5397         /* Try to ensure AUX channel active before proceeding. */
5398         if (link->dc->debug.aux_wake_wa.bits.enable_wa) {
5399                 uint64_t timeout_ms = link->dc->debug.aux_wake_wa.bits.timeout_ms;
5400
5401                 if (link->dc->debug.aux_wake_wa.bits.use_default_timeout)
5402                         timeout_ms = LINK_AUX_WAKE_TIMEOUT_MS;
5403                 status = wa_try_to_wake_dprx(link, timeout_ms);
5404         }
5405
5406         dp_retrieve_lttpr_cap(link);
5407
5408         /* Read DP tunneling information. */
5409         status = dpcd_get_tunneling_device_data(link);
5410
5411         status = core_link_read_dpcd(link, DP_SET_POWER,
5412                         &dpcd_power_state, sizeof(dpcd_power_state));
5413
5414         /* Delay 1 ms if AUX CH is in power down state. Based on spec
5415          * section 2.3.1.2, if AUX CH may be powered down due to
5416          * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
5417          * signal and may need up to 1 ms before being able to reply.
5418          */
5419         if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
5420                 udelay(1000);
5421
5422         dpcd_set_source_specific_data(link);
5423         /* Sink may need to configure internals based on vendor, so allow some
5424          * time before proceeding with possibly vendor specific transactions
5425          */
5426         msleep(post_oui_delay);
5427
5428         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5429                 status = core_link_read_dpcd(
5430                                 link,
5431                                 DP_DPCD_REV,
5432                                 dpcd_data,
5433                                 sizeof(dpcd_data));
5434                 if (status == DC_OK)
5435                         break;
5436         }
5437
5438         if (status != DC_OK) {
5439                 dm_error("%s: Read receiver caps dpcd data failed.\n", __func__);
5440                 return false;
5441         }
5442
5443         if (link->lttpr_support > LTTPR_UNSUPPORTED)
5444                 is_lttpr_present = dp_parse_lttpr_mode(link);
5445
5446         if (!is_lttpr_present)
5447                 dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
5448
5449         {
5450                 union training_aux_rd_interval aux_rd_interval;
5451
5452                 aux_rd_interval.raw =
5453                         dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
5454
5455                 link->dpcd_caps.ext_receiver_cap_field_present =
5456                                 aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1;
5457
5458                 if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
5459                         uint8_t ext_cap_data[16];
5460
5461                         memset(ext_cap_data, '\0', sizeof(ext_cap_data));
5462                         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5463                                 status = core_link_read_dpcd(
5464                                 link,
5465                                 DP_DP13_DPCD_REV,
5466                                 ext_cap_data,
5467                                 sizeof(ext_cap_data));
5468                                 if (status == DC_OK) {
5469                                         memcpy(dpcd_data, ext_cap_data, sizeof(dpcd_data));
5470                                         break;
5471                                 }
5472                         }
5473                         if (status != DC_OK)
5474                                 dm_error("%s: Read extend caps data failed, use cap from dpcd 0.\n", __func__);
5475                 }
5476         }
5477
5478         link->dpcd_caps.dpcd_rev.raw =
5479                         dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
5480
5481         if (link->dpcd_caps.ext_receiver_cap_field_present) {
5482                 for (i = 0; i < read_dpcd_retry_cnt; i++) {
5483                         status = core_link_read_dpcd(
5484                                         link,
5485                                         DP_DPRX_FEATURE_ENUMERATION_LIST,
5486                                         &dpcd_dprx_data,
5487                                         sizeof(dpcd_dprx_data));
5488                         if (status == DC_OK)
5489                                 break;
5490                 }
5491
5492                 link->dpcd_caps.dprx_feature.raw = dpcd_dprx_data;
5493
5494                 if (status != DC_OK)
5495                         dm_error("%s: Read DPRX caps data failed.\n", __func__);
5496         }
5497
5498         else {
5499                 link->dpcd_caps.dprx_feature.raw = 0;
5500         }
5501
5502
5503         /* Error condition checking...
5504          * It is impossible for Sink to report Max Lane Count = 0.
5505          * It is possible for Sink to report Max Link Rate = 0, if it is
5506          * an eDP device that is reporting specialized link rates in the
5507          * SUPPORTED_LINK_RATE table.
5508          */
5509         if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
5510                 return false;
5511
5512         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
5513                                  DP_DPCD_REV];
5514
5515         read_dp_device_vendor_id(link);
5516
5517         /* TODO - decouple raw mst capability from policy decision */
5518         link->dpcd_caps.is_mst_capable = is_mst_supported(link);
5519
5520         get_active_converter_info(ds_port.byte, link);
5521
5522         dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
5523
5524         down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
5525                                  DP_DPCD_REV];
5526
5527         link->dpcd_caps.allow_invalid_MSA_timing_param =
5528                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
5529
5530         link->dpcd_caps.max_ln_count.raw = dpcd_data[
5531                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
5532
5533         link->dpcd_caps.max_down_spread.raw = dpcd_data[
5534                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
5535
5536         link->reported_link_cap.lane_count =
5537                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
5538         link->reported_link_cap.link_rate = get_link_rate_from_max_link_bw(
5539                         dpcd_data[DP_MAX_LINK_RATE - DP_DPCD_REV]);
5540         link->reported_link_cap.link_spread =
5541                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
5542                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
5543
5544         edp_config_cap.raw = dpcd_data[
5545                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
5546         link->dpcd_caps.panel_mode_edp =
5547                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
5548         link->dpcd_caps.dpcd_display_control_capable =
5549                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
5550         link->dpcd_caps.channel_coding_cap.raw =
5551                         dpcd_data[DP_MAIN_LINK_CHANNEL_CODING - DP_DPCD_REV];
5552         link->test_pattern_enabled = false;
5553         link->compliance_test_state.raw = 0;
5554
5555         /* read sink count */
5556         core_link_read_dpcd(link,
5557                         DP_SINK_COUNT,
5558                         &link->dpcd_caps.sink_count.raw,
5559                         sizeof(link->dpcd_caps.sink_count.raw));
5560
5561         /* read sink ieee oui */
5562         core_link_read_dpcd(link,
5563                         DP_SINK_OUI,
5564                         (uint8_t *)(&sink_id),
5565                         sizeof(sink_id));
5566
5567         link->dpcd_caps.sink_dev_id =
5568                         (sink_id.ieee_oui[0] << 16) +
5569                         (sink_id.ieee_oui[1] << 8) +
5570                         (sink_id.ieee_oui[2]);
5571
5572         memmove(
5573                 link->dpcd_caps.sink_dev_id_str,
5574                 sink_id.ieee_device_id,
5575                 sizeof(sink_id.ieee_device_id));
5576
5577         /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */
5578         {
5579                 uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 };
5580
5581                 if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
5582                     !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017,
5583                             sizeof(str_mbp_2017))) {
5584                         link->reported_link_cap.link_rate = 0x0c;
5585                 }
5586         }
5587
5588         core_link_read_dpcd(
5589                 link,
5590                 DP_SINK_HW_REVISION_START,
5591                 (uint8_t *)&dp_hw_fw_revision,
5592                 sizeof(dp_hw_fw_revision));
5593
5594         link->dpcd_caps.sink_hw_revision =
5595                 dp_hw_fw_revision.ieee_hw_rev;
5596
5597         memmove(
5598                 link->dpcd_caps.sink_fw_revision,
5599                 dp_hw_fw_revision.ieee_fw_rev,
5600                 sizeof(dp_hw_fw_revision.ieee_fw_rev));
5601
5602         /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */
5603         {
5604                 uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 };
5605                 uint8_t fwrev_mbp_2018[] = { 7, 4 };
5606                 uint8_t fwrev_mbp_2018_vega[] = { 8, 4 };
5607
5608                 /* We also check for the firmware revision as 16,1 models have an
5609                  * identical device id and are incorrectly quirked otherwise.
5610                  */
5611                 if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
5612                     !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018,
5613                              sizeof(str_mbp_2018)) &&
5614                     (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018,
5615                              sizeof(fwrev_mbp_2018)) ||
5616                     !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega,
5617                              sizeof(fwrev_mbp_2018_vega)))) {
5618                         link->reported_link_cap.link_rate = LINK_RATE_RBR2;
5619                 }
5620         }
5621
5622         memset(&link->dpcd_caps.dsc_caps, '\0',
5623                         sizeof(link->dpcd_caps.dsc_caps));
5624         memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
5625         /* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */
5626         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
5627                 status = core_link_read_dpcd(
5628                                 link,
5629                                 DP_FEC_CAPABILITY,
5630                                 &link->dpcd_caps.fec_cap.raw,
5631                                 sizeof(link->dpcd_caps.fec_cap.raw));
5632                 status = core_link_read_dpcd(
5633                                 link,
5634                                 DP_DSC_SUPPORT,
5635                                 link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
5636                                 sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
5637                 if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
5638                         status = core_link_read_dpcd(
5639                                         link,
5640                                         DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
5641                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
5642                                         sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw));
5643                         DC_LOG_DSC("DSC branch decoder capability is read at link %d", link->link_index);
5644                         DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_0 = 0x%02x",
5645                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_0);
5646                         DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_1 = 0x%02x",
5647                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_1);
5648                         DC_LOG_DSC("\tBRANCH_MAX_LINE_WIDTH 0x%02x",
5649                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_MAX_LINE_WIDTH);
5650                 }
5651
5652                 /* Apply work around to disable FEC and DSC for USB4 tunneling in TBT3 compatibility mode
5653                  * only if required.
5654                  */
5655                 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
5656                                 !link->dc->debug.dpia_debug.bits.disable_force_tbt3_work_around &&
5657                                 link->dpcd_caps.is_branch_dev &&
5658                                 link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
5659                                 link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_10 &&
5660                                 (link->dpcd_caps.fec_cap.bits.FEC_CAPABLE ||
5661                                 link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT)) {
5662                         /* A TBT3 device is expected to report no support for FEC or DSC to a USB4 DPIA.
5663                          * Clear FEC and DSC capabilities as a work around if that is not the case.
5664                          */
5665                         link->wa_flags.dpia_forced_tbt3_mode = true;
5666                         memset(&link->dpcd_caps.dsc_caps, '\0', sizeof(link->dpcd_caps.dsc_caps));
5667                         memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
5668                         DC_LOG_DSC("Clear DSC SUPPORT for USB4 link(%d) in TBT3 compatibility mode", link->link_index);
5669                 } else
5670                         link->wa_flags.dpia_forced_tbt3_mode = false;
5671         }
5672
5673         if (!dpcd_read_sink_ext_caps(link))
5674                 link->dpcd_sink_ext_caps.raw = 0;
5675
5676         if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
5677                 DC_LOG_DP2("128b/132b encoding is supported at link %d", link->link_index);
5678
5679                 core_link_read_dpcd(link,
5680                                 DP_128b_132b_SUPPORTED_LINK_RATES,
5681                                 &link->dpcd_caps.dp_128b_132b_supported_link_rates.raw,
5682                                 sizeof(link->dpcd_caps.dp_128b_132b_supported_link_rates.raw));
5683                 if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR20)
5684                         link->reported_link_cap.link_rate = LINK_RATE_UHBR20;
5685                 else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5)
5686                         link->reported_link_cap.link_rate = LINK_RATE_UHBR13_5;
5687                 else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR10)
5688                         link->reported_link_cap.link_rate = LINK_RATE_UHBR10;
5689                 else
5690                         dm_error("%s: Invalid RX 128b_132b_supported_link_rates\n", __func__);
5691                 DC_LOG_DP2("128b/132b supported link rates is read at link %d", link->link_index);
5692                 DC_LOG_DP2("\tmax 128b/132b link rate support is %d.%d GHz",
5693                                 link->reported_link_cap.link_rate / 100,
5694                                 link->reported_link_cap.link_rate % 100);
5695
5696                 core_link_read_dpcd(link,
5697                                 DP_SINK_VIDEO_FALLBACK_FORMATS,
5698                                 &link->dpcd_caps.fallback_formats.raw,
5699                                 sizeof(link->dpcd_caps.fallback_formats.raw));
5700                 DC_LOG_DP2("sink video fallback format is read at link %d", link->link_index);
5701                 if (link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support)
5702                         DC_LOG_DP2("\t1920x1080@60Hz 24bpp fallback format supported");
5703                 if (link->dpcd_caps.fallback_formats.bits.dp_1280x720_60Hz_24bpp_support)
5704                         DC_LOG_DP2("\t1280x720@60Hz 24bpp fallback format supported");
5705                 if (link->dpcd_caps.fallback_formats.bits.dp_1024x768_60Hz_24bpp_support)
5706                         DC_LOG_DP2("\t1024x768@60Hz 24bpp fallback format supported");
5707                 if (link->dpcd_caps.fallback_formats.raw == 0) {
5708                         DC_LOG_DP2("\tno supported fallback formats, assume 1920x1080@60Hz 24bpp is supported");
5709                         link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support = 1;
5710                 }
5711
5712                 core_link_read_dpcd(link,
5713                                 DP_FEC_CAPABILITY_1,
5714                                 &link->dpcd_caps.fec_cap1.raw,
5715                                 sizeof(link->dpcd_caps.fec_cap1.raw));
5716                 DC_LOG_DP2("FEC CAPABILITY 1 is read at link %d", link->link_index);
5717                 if (link->dpcd_caps.fec_cap1.bits.AGGREGATED_ERROR_COUNTERS_CAPABLE)
5718                         DC_LOG_DP2("\tFEC aggregated error counters are supported");
5719         }
5720
5721         retrieve_cable_id(link);
5722         dpcd_write_cable_id_to_dprx(link);
5723
5724         /* Connectivity log: detection */
5725         CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
5726
5727         return true;
5728 }
5729
5730 bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
5731 {
5732         uint8_t dpcd_data[16];
5733         uint32_t read_dpcd_retry_cnt = 3;
5734         enum dc_status status = DC_ERROR_UNEXPECTED;
5735         union dp_downstream_port_present ds_port = { 0 };
5736         union down_stream_port_count down_strm_port_count;
5737         union edp_configuration_cap edp_config_cap;
5738
5739         int i;
5740
5741         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5742                 status = core_link_read_dpcd(
5743                                 link,
5744                                 DP_DPCD_REV,
5745                                 dpcd_data,
5746                                 sizeof(dpcd_data));
5747                 if (status == DC_OK)
5748                         break;
5749         }
5750
5751         link->dpcd_caps.dpcd_rev.raw =
5752                 dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
5753
5754         if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
5755                 return false;
5756
5757         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
5758                         DP_DPCD_REV];
5759
5760         get_active_converter_info(ds_port.byte, link);
5761
5762         down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
5763                         DP_DPCD_REV];
5764
5765         link->dpcd_caps.allow_invalid_MSA_timing_param =
5766                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
5767
5768         link->dpcd_caps.max_ln_count.raw = dpcd_data[
5769                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
5770
5771         link->dpcd_caps.max_down_spread.raw = dpcd_data[
5772                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
5773
5774         link->reported_link_cap.lane_count =
5775                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
5776         link->reported_link_cap.link_rate = dpcd_data[
5777                 DP_MAX_LINK_RATE - DP_DPCD_REV];
5778         link->reported_link_cap.link_spread =
5779                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
5780                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
5781
5782         edp_config_cap.raw = dpcd_data[
5783                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
5784         link->dpcd_caps.panel_mode_edp =
5785                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
5786         link->dpcd_caps.dpcd_display_control_capable =
5787                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
5788
5789         return true;
5790 }
5791
5792 bool detect_dp_sink_caps(struct dc_link *link)
5793 {
5794         return retrieve_link_cap(link);
5795 }
5796
5797 static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
5798 {
5799         enum dc_link_rate link_rate;
5800         // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
5801         switch (link_rate_in_khz) {
5802         case 1620000:
5803                 link_rate = LINK_RATE_LOW;              // Rate_1 (RBR)         - 1.62 Gbps/Lane
5804                 break;
5805         case 2160000:
5806                 link_rate = LINK_RATE_RATE_2;   // Rate_2                       - 2.16 Gbps/Lane
5807                 break;
5808         case 2430000:
5809                 link_rate = LINK_RATE_RATE_3;   // Rate_3                       - 2.43 Gbps/Lane
5810                 break;
5811         case 2700000:
5812                 link_rate = LINK_RATE_HIGH;             // Rate_4 (HBR)         - 2.70 Gbps/Lane
5813                 break;
5814         case 3240000:
5815                 link_rate = LINK_RATE_RBR2;             // Rate_5 (RBR2)        - 3.24 Gbps/Lane
5816                 break;
5817         case 4320000:
5818                 link_rate = LINK_RATE_RATE_6;   // Rate_6                       - 4.32 Gbps/Lane
5819                 break;
5820         case 5400000:
5821                 link_rate = LINK_RATE_HIGH2;    // Rate_7 (HBR2)        - 5.40 Gbps/Lane
5822                 break;
5823         case 8100000:
5824                 link_rate = LINK_RATE_HIGH3;    // Rate_8 (HBR3)        - 8.10 Gbps/Lane
5825                 break;
5826         default:
5827                 link_rate = LINK_RATE_UNKNOWN;
5828                 break;
5829         }
5830         return link_rate;
5831 }
5832
5833 void detect_edp_sink_caps(struct dc_link *link)
5834 {
5835         uint8_t supported_link_rates[16];
5836         uint32_t entry;
5837         uint32_t link_rate_in_khz;
5838         enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
5839         uint8_t backlight_adj_cap;
5840
5841         retrieve_link_cap(link);
5842         link->dpcd_caps.edp_supported_link_rates_count = 0;
5843         memset(supported_link_rates, 0, sizeof(supported_link_rates));
5844
5845         /*
5846          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
5847          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
5848          */
5849         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
5850                         (link->dc->debug.optimize_edp_link_rate ||
5851                         link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
5852                 // Read DPCD 00010h - 0001Fh 16 bytes at one shot
5853                 core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
5854                                                         supported_link_rates, sizeof(supported_link_rates));
5855
5856                 for (entry = 0; entry < 16; entry += 2) {
5857                         // DPCD register reports per-lane link rate = 16-bit link rate capability
5858                         // value X 200 kHz. Need multiplier to find link rate in kHz.
5859                         link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
5860                                                                                 supported_link_rates[entry]) * 200;
5861
5862                         if (link_rate_in_khz != 0) {
5863                                 link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
5864                                 link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate;
5865                                 link->dpcd_caps.edp_supported_link_rates_count++;
5866
5867                                 if (link->reported_link_cap.link_rate < link_rate)
5868                                         link->reported_link_cap.link_rate = link_rate;
5869                         }
5870                 }
5871         }
5872         core_link_read_dpcd(link, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP,
5873                                                 &backlight_adj_cap, sizeof(backlight_adj_cap));
5874
5875         link->dpcd_caps.dynamic_backlight_capable_edp =
5876                                 (backlight_adj_cap & DP_EDP_DYNAMIC_BACKLIGHT_CAP) ? true:false;
5877
5878         dc_link_set_default_brightness_aux(link);
5879
5880         core_link_read_dpcd(link, DP_EDP_DPCD_REV,
5881                 &link->dpcd_caps.edp_rev,
5882                 sizeof(link->dpcd_caps.edp_rev));
5883         /*
5884          * PSR is only valid for eDP v1.3 or higher.
5885          */
5886         if (link->dpcd_caps.edp_rev >= DP_EDP_13) {
5887                 core_link_read_dpcd(link, DP_PSR_SUPPORT,
5888                         &link->dpcd_caps.psr_info.psr_version,
5889                         sizeof(link->dpcd_caps.psr_info.psr_version));
5890                 if (link->dpcd_caps.sink_dev_id == DP_BRANCH_DEVICE_ID_001CF8)
5891                         core_link_read_dpcd(link, DP_FORCE_PSRSU_CAPABILITY,
5892                                                 &link->dpcd_caps.psr_info.force_psrsu_cap,
5893                                                 sizeof(link->dpcd_caps.psr_info.force_psrsu_cap));
5894                 core_link_read_dpcd(link, DP_PSR_CAPS,
5895                         &link->dpcd_caps.psr_info.psr_dpcd_caps.raw,
5896                         sizeof(link->dpcd_caps.psr_info.psr_dpcd_caps.raw));
5897                 if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED) {
5898                         core_link_read_dpcd(link, DP_PSR2_SU_Y_GRANULARITY,
5899                                 &link->dpcd_caps.psr_info.psr2_su_y_granularity_cap,
5900                                 sizeof(link->dpcd_caps.psr_info.psr2_su_y_granularity_cap));
5901                 }
5902         }
5903
5904         /*
5905          * ALPM is only valid for eDP v1.4 or higher.
5906          */
5907         if (link->dpcd_caps.dpcd_rev.raw >= DP_EDP_14)
5908                 core_link_read_dpcd(link, DP_RECEIVER_ALPM_CAP,
5909                         &link->dpcd_caps.alpm_caps.raw,
5910                         sizeof(link->dpcd_caps.alpm_caps.raw));
5911 }
5912
5913 void dc_link_dp_enable_hpd(const struct dc_link *link)
5914 {
5915         struct link_encoder *encoder = link->link_enc;
5916
5917         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
5918                 encoder->funcs->enable_hpd(encoder);
5919 }
5920
5921 void dc_link_dp_disable_hpd(const struct dc_link *link)
5922 {
5923         struct link_encoder *encoder = link->link_enc;
5924
5925         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
5926                 encoder->funcs->disable_hpd(encoder);
5927 }
5928
5929 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
5930 {
5931         if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
5932                         test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
5933                         test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
5934                 return true;
5935         else
5936                 return false;
5937 }
5938
5939 static void set_crtc_test_pattern(struct dc_link *link,
5940                                 struct pipe_ctx *pipe_ctx,
5941                                 enum dp_test_pattern test_pattern,
5942                                 enum dp_test_pattern_color_space test_pattern_color_space)
5943 {
5944         enum controller_dp_test_pattern controller_test_pattern;
5945         enum dc_color_depth color_depth = pipe_ctx->
5946                 stream->timing.display_color_depth;
5947         struct bit_depth_reduction_params params;
5948         struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
5949         int width = pipe_ctx->stream->timing.h_addressable +
5950                 pipe_ctx->stream->timing.h_border_left +
5951                 pipe_ctx->stream->timing.h_border_right;
5952         int height = pipe_ctx->stream->timing.v_addressable +
5953                 pipe_ctx->stream->timing.v_border_bottom +
5954                 pipe_ctx->stream->timing.v_border_top;
5955
5956         memset(&params, 0, sizeof(params));
5957
5958         switch (test_pattern) {
5959         case DP_TEST_PATTERN_COLOR_SQUARES:
5960                 controller_test_pattern =
5961                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
5962         break;
5963         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
5964                 controller_test_pattern =
5965                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
5966         break;
5967         case DP_TEST_PATTERN_VERTICAL_BARS:
5968                 controller_test_pattern =
5969                                 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
5970         break;
5971         case DP_TEST_PATTERN_HORIZONTAL_BARS:
5972                 controller_test_pattern =
5973                                 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
5974         break;
5975         case DP_TEST_PATTERN_COLOR_RAMP:
5976                 controller_test_pattern =
5977                                 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
5978         break;
5979         default:
5980                 controller_test_pattern =
5981                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
5982         break;
5983         }
5984
5985         switch (test_pattern) {
5986         case DP_TEST_PATTERN_COLOR_SQUARES:
5987         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
5988         case DP_TEST_PATTERN_VERTICAL_BARS:
5989         case DP_TEST_PATTERN_HORIZONTAL_BARS:
5990         case DP_TEST_PATTERN_COLOR_RAMP:
5991         {
5992                 /* disable bit depth reduction */
5993                 pipe_ctx->stream->bit_depth_params = params;
5994                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
5995                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
5996                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
5997                                 controller_test_pattern, color_depth);
5998                 else if (link->dc->hwss.set_disp_pattern_generator) {
5999                         struct pipe_ctx *odm_pipe;
6000                         enum controller_dp_color_space controller_color_space;
6001                         int opp_cnt = 1;
6002                         int offset = 0;
6003                         int dpg_width = width;
6004
6005                         switch (test_pattern_color_space) {
6006                         case DP_TEST_PATTERN_COLOR_SPACE_RGB:
6007                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
6008                                 break;
6009                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
6010                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
6011                                 break;
6012                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
6013                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
6014                                 break;
6015                         case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
6016                         default:
6017                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
6018                                 DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
6019                                 ASSERT(0);
6020                                 break;
6021                         }
6022
6023                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
6024                                 opp_cnt++;
6025                         dpg_width = width / opp_cnt;
6026                         offset = dpg_width;
6027
6028                         link->dc->hwss.set_disp_pattern_generator(link->dc,
6029                                         pipe_ctx,
6030                                         controller_test_pattern,
6031                                         controller_color_space,
6032                                         color_depth,
6033                                         NULL,
6034                                         dpg_width,
6035                                         height,
6036                                         0);
6037
6038                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
6039                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
6040
6041                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
6042                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
6043                                                 odm_pipe,
6044                                                 controller_test_pattern,
6045                                                 controller_color_space,
6046                                                 color_depth,
6047                                                 NULL,
6048                                                 dpg_width,
6049                                                 height,
6050                                                 offset);
6051                                 offset += offset;
6052                         }
6053                 }
6054         }
6055         break;
6056         case DP_TEST_PATTERN_VIDEO_MODE:
6057         {
6058                 /* restore bitdepth reduction */
6059                 resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
6060                 pipe_ctx->stream->bit_depth_params = params;
6061                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
6062                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
6063                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
6064                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
6065                                 color_depth);
6066                 else if (link->dc->hwss.set_disp_pattern_generator) {
6067                         struct pipe_ctx *odm_pipe;
6068                         int opp_cnt = 1;
6069                         int dpg_width;
6070
6071                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
6072                                 opp_cnt++;
6073
6074                         dpg_width = width / opp_cnt;
6075                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
6076                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
6077
6078                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
6079                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
6080                                                 odm_pipe,
6081                                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
6082                                                 CONTROLLER_DP_COLOR_SPACE_UDEFINED,
6083                                                 color_depth,
6084                                                 NULL,
6085                                                 dpg_width,
6086                                                 height,
6087                                                 0);
6088                         }
6089                         link->dc->hwss.set_disp_pattern_generator(link->dc,
6090                                         pipe_ctx,
6091                                         CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
6092                                         CONTROLLER_DP_COLOR_SPACE_UDEFINED,
6093                                         color_depth,
6094                                         NULL,
6095                                         dpg_width,
6096                                         height,
6097                                         0);
6098                 }
6099         }
6100         break;
6101
6102         default:
6103         break;
6104         }
6105 }
6106
6107 bool dc_link_dp_set_test_pattern(
6108         struct dc_link *link,
6109         enum dp_test_pattern test_pattern,
6110         enum dp_test_pattern_color_space test_pattern_color_space,
6111         const struct link_training_settings *p_link_settings,
6112         const unsigned char *p_custom_pattern,
6113         unsigned int cust_pattern_size)
6114 {
6115         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
6116         struct pipe_ctx *pipe_ctx = NULL;
6117         unsigned int lane;
6118         unsigned int i;
6119         unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
6120         union dpcd_training_pattern training_pattern;
6121         enum dpcd_phy_test_patterns pattern;
6122
6123         memset(&training_pattern, 0, sizeof(training_pattern));
6124
6125         for (i = 0; i < MAX_PIPES; i++) {
6126                 if (pipes[i].stream == NULL)
6127                         continue;
6128
6129                 if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
6130                         pipe_ctx = &pipes[i];
6131                         break;
6132                 }
6133         }
6134
6135         if (pipe_ctx == NULL)
6136                 return false;
6137
6138         /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
6139         if (link->test_pattern_enabled && test_pattern ==
6140                         DP_TEST_PATTERN_VIDEO_MODE) {
6141                 /* Set CRTC Test Pattern */
6142                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
6143                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
6144                                 (uint8_t *)p_custom_pattern,
6145                                 (uint32_t)cust_pattern_size);
6146
6147                 /* Unblank Stream */
6148                 link->dc->hwss.unblank_stream(
6149                         pipe_ctx,
6150                         &link->verified_link_cap);
6151                 /* TODO:m_pHwss->MuteAudioEndpoint
6152                  * (pPathMode->pDisplayPath, false);
6153                  */
6154
6155                 /* Reset Test Pattern state */
6156                 link->test_pattern_enabled = false;
6157
6158                 return true;
6159         }
6160
6161         /* Check for PHY Test Patterns */
6162         if (is_dp_phy_pattern(test_pattern)) {
6163                 /* Set DPCD Lane Settings before running test pattern */
6164                 if (p_link_settings != NULL) {
6165                         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
6166                                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
6167                                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
6168                                 dp_fixed_vs_pe_set_retimer_lane_settings(
6169                                                 link,
6170                                                 p_link_settings->dpcd_lane_settings,
6171                                                 p_link_settings->link_settings.lane_count);
6172                         } else {
6173                                 dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
6174                         }
6175                         dpcd_set_lane_settings(link, p_link_settings, DPRX);
6176                 }
6177
6178                 /* Blank stream if running test pattern */
6179                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
6180                         /*TODO:
6181                          * m_pHwss->
6182                          * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
6183                          */
6184                         /* Blank stream */
6185                         pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
6186                 }
6187
6188                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
6189                                 (uint8_t *)p_custom_pattern,
6190                                 (uint32_t)cust_pattern_size);
6191
6192                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
6193                         /* Set Test Pattern state */
6194                         link->test_pattern_enabled = true;
6195                         if (p_link_settings != NULL)
6196                                 dpcd_set_link_settings(link,
6197                                                 p_link_settings);
6198                 }
6199
6200                 switch (test_pattern) {
6201                 case DP_TEST_PATTERN_VIDEO_MODE:
6202                         pattern = PHY_TEST_PATTERN_NONE;
6203                         break;
6204                 case DP_TEST_PATTERN_D102:
6205                         pattern = PHY_TEST_PATTERN_D10_2;
6206                         break;
6207                 case DP_TEST_PATTERN_SYMBOL_ERROR:
6208                         pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
6209                         break;
6210                 case DP_TEST_PATTERN_PRBS7:
6211                         pattern = PHY_TEST_PATTERN_PRBS7;
6212                         break;
6213                 case DP_TEST_PATTERN_80BIT_CUSTOM:
6214                         pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
6215                         break;
6216                 case DP_TEST_PATTERN_CP2520_1:
6217                         pattern = PHY_TEST_PATTERN_CP2520_1;
6218                         break;
6219                 case DP_TEST_PATTERN_CP2520_2:
6220                         pattern = PHY_TEST_PATTERN_CP2520_2;
6221                         break;
6222                 case DP_TEST_PATTERN_CP2520_3:
6223                         pattern = PHY_TEST_PATTERN_CP2520_3;
6224                         break;
6225                 case DP_TEST_PATTERN_128b_132b_TPS1:
6226                         pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
6227                         break;
6228                 case DP_TEST_PATTERN_128b_132b_TPS2:
6229                         pattern = PHY_TEST_PATTERN_128b_132b_TPS2;
6230                         break;
6231                 case DP_TEST_PATTERN_PRBS9:
6232                         pattern = PHY_TEST_PATTERN_PRBS9;
6233                         break;
6234                 case DP_TEST_PATTERN_PRBS11:
6235                         pattern = PHY_TEST_PATTERN_PRBS11;
6236                         break;
6237                 case DP_TEST_PATTERN_PRBS15:
6238                         pattern = PHY_TEST_PATTERN_PRBS15;
6239                         break;
6240                 case DP_TEST_PATTERN_PRBS23:
6241                         pattern = PHY_TEST_PATTERN_PRBS23;
6242                         break;
6243                 case DP_TEST_PATTERN_PRBS31:
6244                         pattern = PHY_TEST_PATTERN_PRBS31;
6245                         break;
6246                 case DP_TEST_PATTERN_264BIT_CUSTOM:
6247                         pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
6248                         break;
6249                 case DP_TEST_PATTERN_SQUARE_PULSE:
6250                         pattern = PHY_TEST_PATTERN_SQUARE_PULSE;
6251                         break;
6252                 default:
6253                         return false;
6254                 }
6255
6256                 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
6257                 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
6258                         return false;
6259
6260                 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
6261 #if defined(CONFIG_DRM_AMD_DC_DCN)
6262                         if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE)
6263                                 core_link_write_dpcd(link,
6264                                                 DP_LINK_SQUARE_PATTERN,
6265                                                 p_custom_pattern,
6266                                                 1);
6267
6268 #endif
6269                         /* tell receiver that we are sending qualification
6270                          * pattern DP 1.2 or later - DP receiver's link quality
6271                          * pattern is set using DPCD LINK_QUAL_LANEx_SET
6272                          * register (0x10B~0x10E)\
6273                          */
6274                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
6275                                 link_qual_pattern[lane] =
6276                                                 (unsigned char)(pattern);
6277
6278                         core_link_write_dpcd(link,
6279                                         DP_LINK_QUAL_LANE0_SET,
6280                                         link_qual_pattern,
6281                                         sizeof(link_qual_pattern));
6282                 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
6283                            link->dpcd_caps.dpcd_rev.raw == 0) {
6284                         /* tell receiver that we are sending qualification
6285                          * pattern DP 1.1a or earlier - DP receiver's link
6286                          * quality pattern is set using
6287                          * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
6288                          * register (0x102). We will use v_1.3 when we are
6289                          * setting test pattern for DP 1.1.
6290                          */
6291                         core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
6292                                             &training_pattern.raw,
6293                                             sizeof(training_pattern));
6294                         training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
6295                         core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
6296                                              &training_pattern.raw,
6297                                              sizeof(training_pattern));
6298                 }
6299         } else {
6300                 enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
6301
6302                 switch (test_pattern_color_space) {
6303                 case DP_TEST_PATTERN_COLOR_SPACE_RGB:
6304                         color_space = COLOR_SPACE_SRGB;
6305                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6306                                 color_space = COLOR_SPACE_SRGB_LIMITED;
6307                         break;
6308
6309                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
6310                         color_space = COLOR_SPACE_YCBCR601;
6311                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6312                                 color_space = COLOR_SPACE_YCBCR601_LIMITED;
6313                         break;
6314                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
6315                         color_space = COLOR_SPACE_YCBCR709;
6316                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6317                                 color_space = COLOR_SPACE_YCBCR709_LIMITED;
6318                         break;
6319                 default:
6320                         break;
6321                 }
6322
6323                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
6324                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
6325                                 union dmub_hw_lock_flags hw_locks = { 0 };
6326                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
6327
6328                                 hw_locks.bits.lock_dig = 1;
6329                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
6330
6331                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
6332                                                         true,
6333                                                         &hw_locks,
6334                                                         &inst_flags);
6335                         } else
6336                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
6337                                                 pipe_ctx->stream_res.tg);
6338                 }
6339
6340                 pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
6341                 /* update MSA to requested color space */
6342                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
6343                                 &pipe_ctx->stream->timing,
6344                                 color_space,
6345                                 pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
6346                                 link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
6347
6348                 if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
6349                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6350                                 pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
6351                         else
6352                                 pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
6353                         resource_build_info_frame(pipe_ctx);
6354                         link->dc->hwss.update_info_frame(pipe_ctx);
6355                 }
6356
6357                 /* CRTC Patterns */
6358                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
6359                 pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
6360                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6361                                 CRTC_STATE_VACTIVE);
6362                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6363                                 CRTC_STATE_VBLANK);
6364                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6365                                 CRTC_STATE_VACTIVE);
6366
6367                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
6368                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
6369                                 union dmub_hw_lock_flags hw_locks = { 0 };
6370                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
6371
6372                                 hw_locks.bits.lock_dig = 1;
6373                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
6374
6375                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
6376                                                         false,
6377                                                         &hw_locks,
6378                                                         &inst_flags);
6379                         } else
6380                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
6381                                                 pipe_ctx->stream_res.tg);
6382                 }
6383
6384                 /* Set Test Pattern state */
6385                 link->test_pattern_enabled = true;
6386         }
6387
6388         return true;
6389 }
6390
6391 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
6392 {
6393         unsigned char mstmCntl;
6394
6395         core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
6396         if (enable)
6397                 mstmCntl |= DP_MST_EN;
6398         else
6399                 mstmCntl &= (~DP_MST_EN);
6400
6401         core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
6402 }
6403
6404 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
6405 {
6406         union dpcd_edp_config edp_config_set;
6407         bool panel_mode_edp = false;
6408
6409         memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
6410
6411         if (panel_mode != DP_PANEL_MODE_DEFAULT) {
6412
6413                 switch (panel_mode) {
6414                 case DP_PANEL_MODE_EDP:
6415                 case DP_PANEL_MODE_SPECIAL:
6416                         panel_mode_edp = true;
6417                         break;
6418
6419                 default:
6420                                 break;
6421                 }
6422
6423                 /*set edp panel mode in receiver*/
6424                 core_link_read_dpcd(
6425                         link,
6426                         DP_EDP_CONFIGURATION_SET,
6427                         &edp_config_set.raw,
6428                         sizeof(edp_config_set.raw));
6429
6430                 if (edp_config_set.bits.PANEL_MODE_EDP
6431                         != panel_mode_edp) {
6432                         enum dc_status result;
6433
6434                         edp_config_set.bits.PANEL_MODE_EDP =
6435                         panel_mode_edp;
6436                         result = core_link_write_dpcd(
6437                                 link,
6438                                 DP_EDP_CONFIGURATION_SET,
6439                                 &edp_config_set.raw,
6440                                 sizeof(edp_config_set.raw));
6441
6442                         ASSERT(result == DC_OK);
6443                 }
6444         }
6445         DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
6446                  "eDP panel mode enabled: %d \n",
6447                  link->link_index,
6448                  link->dpcd_caps.panel_mode_edp,
6449                  panel_mode_edp);
6450 }
6451
6452 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
6453 {
6454         /* We need to explicitly check that connector
6455          * is not DP. Some Travis_VGA get reported
6456          * by video bios as DP.
6457          */
6458         if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
6459
6460                 switch (link->dpcd_caps.branch_dev_id) {
6461                 case DP_BRANCH_DEVICE_ID_0022B9:
6462                         /* alternate scrambler reset is required for Travis
6463                          * for the case when external chip does not
6464                          * provide sink device id, alternate scrambler
6465                          * scheme will  be overriden later by querying
6466                          * Encoder features
6467                          */
6468                         if (strncmp(
6469                                 link->dpcd_caps.branch_dev_name,
6470                                 DP_VGA_LVDS_CONVERTER_ID_2,
6471                                 sizeof(
6472                                 link->dpcd_caps.
6473                                 branch_dev_name)) == 0) {
6474                                         return DP_PANEL_MODE_SPECIAL;
6475                         }
6476                         break;
6477                 case DP_BRANCH_DEVICE_ID_00001A:
6478                         /* alternate scrambler reset is required for Travis
6479                          * for the case when external chip does not provide
6480                          * sink device id, alternate scrambler scheme will
6481                          * be overriden later by querying Encoder feature
6482                          */
6483                         if (strncmp(link->dpcd_caps.branch_dev_name,
6484                                 DP_VGA_LVDS_CONVERTER_ID_3,
6485                                 sizeof(
6486                                 link->dpcd_caps.
6487                                 branch_dev_name)) == 0) {
6488                                         return DP_PANEL_MODE_SPECIAL;
6489                         }
6490                         break;
6491                 default:
6492                         break;
6493                 }
6494         }
6495
6496         if (link->dpcd_caps.panel_mode_edp &&
6497                 (link->connector_signal == SIGNAL_TYPE_EDP ||
6498                  (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
6499                   link->is_internal_display))) {
6500                 return DP_PANEL_MODE_EDP;
6501         }
6502
6503         return DP_PANEL_MODE_DEFAULT;
6504 }
6505
6506 enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready)
6507 {
6508         /* FEC has to be "set ready" before the link training.
6509          * The policy is to always train with FEC
6510          * if the sink supports it and leave it enabled on link.
6511          * If FEC is not supported, disable it.
6512          */
6513         struct link_encoder *link_enc = NULL;
6514         enum dc_status status = DC_OK;
6515         uint8_t fec_config = 0;
6516
6517         link_enc = link_enc_cfg_get_link_enc(link);
6518         ASSERT(link_enc);
6519
6520         if (!dc_link_should_enable_fec(link))
6521                 return status;
6522
6523         if (link_enc->funcs->fec_set_ready &&
6524                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
6525                 if (ready) {
6526                         fec_config = 1;
6527                         status = core_link_write_dpcd(link,
6528                                         DP_FEC_CONFIGURATION,
6529                                         &fec_config,
6530                                         sizeof(fec_config));
6531                         if (status == DC_OK) {
6532                                 link_enc->funcs->fec_set_ready(link_enc, true);
6533                                 link->fec_state = dc_link_fec_ready;
6534                         } else {
6535                                 link_enc->funcs->fec_set_ready(link_enc, false);
6536                                 link->fec_state = dc_link_fec_not_ready;
6537                                 dm_error("dpcd write failed to set fec_ready");
6538                         }
6539                 } else if (link->fec_state == dc_link_fec_ready) {
6540                         fec_config = 0;
6541                         status = core_link_write_dpcd(link,
6542                                         DP_FEC_CONFIGURATION,
6543                                         &fec_config,
6544                                         sizeof(fec_config));
6545                         link_enc->funcs->fec_set_ready(link_enc, false);
6546                         link->fec_state = dc_link_fec_not_ready;
6547                 }
6548         }
6549
6550         return status;
6551 }
6552
6553 void dp_set_fec_enable(struct dc_link *link, bool enable)
6554 {
6555         struct link_encoder *link_enc = NULL;
6556
6557         link_enc = link_enc_cfg_get_link_enc(link);
6558         ASSERT(link_enc);
6559
6560         if (!dc_link_should_enable_fec(link))
6561                 return;
6562
6563         if (link_enc->funcs->fec_set_enable &&
6564                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
6565                 if (link->fec_state == dc_link_fec_ready && enable) {
6566                         /* Accord to DP spec, FEC enable sequence can first
6567                          * be transmitted anytime after 1000 LL codes have
6568                          * been transmitted on the link after link training
6569                          * completion. Using 1 lane RBR should have the maximum
6570                          * time for transmitting 1000 LL codes which is 6.173 us.
6571                          * So use 7 microseconds delay instead.
6572                          */
6573                         udelay(7);
6574                         link_enc->funcs->fec_set_enable(link_enc, true);
6575                         link->fec_state = dc_link_fec_enabled;
6576                 } else if (link->fec_state == dc_link_fec_enabled && !enable) {
6577                         link_enc->funcs->fec_set_enable(link_enc, false);
6578                         link->fec_state = dc_link_fec_ready;
6579                 }
6580         }
6581 }
6582
6583 void dpcd_set_source_specific_data(struct dc_link *link)
6584 {
6585         if (!link->dc->vendor_signature.is_valid) {
6586                 enum dc_status __maybe_unused result_write_min_hblank = DC_NOT_SUPPORTED;
6587                 struct dpcd_amd_signature amd_signature = {0};
6588                 struct dpcd_amd_device_id amd_device_id = {0};
6589
6590                 amd_device_id.device_id_byte1 =
6591                                 (uint8_t)(link->ctx->asic_id.chip_id);
6592                 amd_device_id.device_id_byte2 =
6593                                 (uint8_t)(link->ctx->asic_id.chip_id >> 8);
6594                 amd_device_id.dce_version =
6595                                 (uint8_t)(link->ctx->dce_version);
6596                 amd_device_id.dal_version_byte1 = 0x0; // needed? where to get?
6597                 amd_device_id.dal_version_byte2 = 0x0; // needed? where to get?
6598
6599                 core_link_read_dpcd(link, DP_SOURCE_OUI,
6600                                 (uint8_t *)(&amd_signature),
6601                                 sizeof(amd_signature));
6602
6603                 if (!((amd_signature.AMD_IEEE_TxSignature_byte1 == 0x0) &&
6604                         (amd_signature.AMD_IEEE_TxSignature_byte2 == 0x0) &&
6605                         (amd_signature.AMD_IEEE_TxSignature_byte3 == 0x1A))) {
6606
6607                         amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0;
6608                         amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0;
6609                         amd_signature.AMD_IEEE_TxSignature_byte3 = 0x1A;
6610
6611                         core_link_write_dpcd(link, DP_SOURCE_OUI,
6612                                 (uint8_t *)(&amd_signature),
6613                                 sizeof(amd_signature));
6614                 }
6615
6616                 core_link_write_dpcd(link, DP_SOURCE_OUI+0x03,
6617                                 (uint8_t *)(&amd_device_id),
6618                                 sizeof(amd_device_id));
6619
6620                 if (link->ctx->dce_version >= DCN_VERSION_2_0 &&
6621                         link->dc->caps.min_horizontal_blanking_period != 0) {
6622
6623                         uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period;
6624
6625                         if (link->preferred_link_setting.dpcd_source_device_specific_field_support) {
6626                                 result_write_min_hblank = core_link_write_dpcd(link,
6627                                         DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size),
6628                                         sizeof(hblank_size));
6629
6630                                 if (result_write_min_hblank == DC_ERROR_UNEXPECTED)
6631                                         link->preferred_link_setting.dpcd_source_device_specific_field_support = false;
6632                         } else {
6633                                 DC_LOG_DC("Sink device does not support 00340h DPCD write. Skipping on purpose.\n");
6634                         }
6635                 }
6636
6637                 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
6638                                                         WPP_BIT_FLAG_DC_DETECTION_DP_CAPS,
6639                                                         "result=%u link_index=%u enum dce_version=%d DPCD=0x%04X min_hblank=%u branch_dev_id=0x%x branch_dev_name='%c%c%c%c%c%c'",
6640                                                         result_write_min_hblank,
6641                                                         link->link_index,
6642                                                         link->ctx->dce_version,
6643                                                         DP_SOURCE_MINIMUM_HBLANK_SUPPORTED,
6644                                                         link->dc->caps.min_horizontal_blanking_period,
6645                                                         link->dpcd_caps.branch_dev_id,
6646                                                         link->dpcd_caps.branch_dev_name[0],
6647                                                         link->dpcd_caps.branch_dev_name[1],
6648                                                         link->dpcd_caps.branch_dev_name[2],
6649                                                         link->dpcd_caps.branch_dev_name[3],
6650                                                         link->dpcd_caps.branch_dev_name[4],
6651                                                         link->dpcd_caps.branch_dev_name[5]);
6652         } else {
6653                 core_link_write_dpcd(link, DP_SOURCE_OUI,
6654                                 link->dc->vendor_signature.data.raw,
6655                                 sizeof(link->dc->vendor_signature.data.raw));
6656         }
6657 }
6658
6659 void dpcd_write_cable_id_to_dprx(struct dc_link *link)
6660 {
6661         if (!link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED ||
6662                         link->dpcd_caps.cable_id.raw == 0 ||
6663                         link->dprx_states.cable_id_written)
6664                 return;
6665
6666         core_link_write_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX,
6667                         &link->dpcd_caps.cable_id.raw,
6668                         sizeof(link->dpcd_caps.cable_id.raw));
6669
6670         link->dprx_states.cable_id_written = 1;
6671 }
6672
6673 bool dc_link_set_backlight_level_nits(struct dc_link *link,
6674                 bool isHDR,
6675                 uint32_t backlight_millinits,
6676                 uint32_t transition_time_in_ms)
6677 {
6678         struct dpcd_source_backlight_set dpcd_backlight_set;
6679         uint8_t backlight_control = isHDR ? 1 : 0;
6680
6681         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6682                         link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6683                 return false;
6684
6685         // OLEDs have no PWM, they can only use AUX
6686         if (link->dpcd_sink_ext_caps.bits.oled == 1)
6687                 backlight_control = 1;
6688
6689         *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits;
6690         *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms;
6691
6692
6693         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
6694                         (uint8_t *)(&dpcd_backlight_set),
6695                         sizeof(dpcd_backlight_set)) != DC_OK)
6696                 return false;
6697
6698         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
6699                         &backlight_control, 1) != DC_OK)
6700                 return false;
6701
6702         return true;
6703 }
6704
6705 bool dc_link_get_backlight_level_nits(struct dc_link *link,
6706                 uint32_t *backlight_millinits_avg,
6707                 uint32_t *backlight_millinits_peak)
6708 {
6709         union dpcd_source_backlight_get dpcd_backlight_get;
6710
6711         memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get));
6712
6713         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6714                         link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6715                 return false;
6716
6717         if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
6718                         dpcd_backlight_get.raw,
6719                         sizeof(union dpcd_source_backlight_get)) != DC_OK)
6720                 return false;
6721
6722         *backlight_millinits_avg =
6723                 dpcd_backlight_get.bytes.backlight_millinits_avg;
6724         *backlight_millinits_peak =
6725                 dpcd_backlight_get.bytes.backlight_millinits_peak;
6726
6727         /* On non-supported panels dpcd_read usually succeeds with 0 returned */
6728         if (*backlight_millinits_avg == 0 ||
6729                         *backlight_millinits_avg > *backlight_millinits_peak)
6730                 return false;
6731
6732         return true;
6733 }
6734
6735 bool dc_link_backlight_enable_aux(struct dc_link *link, bool enable)
6736 {
6737         uint8_t backlight_enable = enable ? 1 : 0;
6738
6739         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6740                 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6741                 return false;
6742
6743         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
6744                 &backlight_enable, 1) != DC_OK)
6745                 return false;
6746
6747         return true;
6748 }
6749
6750 // we read default from 0x320 because we expect BIOS wrote it there
6751 // regular get_backlight_nit reads from panel set at 0x326
6752 bool dc_link_read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits)
6753 {
6754         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6755                 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6756                 return false;
6757
6758         if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
6759                 (uint8_t *) backlight_millinits,
6760                 sizeof(uint32_t)) != DC_OK)
6761                 return false;
6762
6763         return true;
6764 }
6765
6766 bool dc_link_set_default_brightness_aux(struct dc_link *link)
6767 {
6768         uint32_t default_backlight;
6769
6770         if (link && link->dpcd_sink_ext_caps.bits.oled == 1) {
6771                 if (!dc_link_read_default_bl_aux(link, &default_backlight))
6772                         default_backlight = 150000;
6773                 // if < 5 nits or > 5000, it might be wrong readback
6774                 if (default_backlight < 5000 || default_backlight > 5000000)
6775                         default_backlight = 150000; //
6776
6777                 return dc_link_set_backlight_level_nits(link, true,
6778                                 default_backlight, 0);
6779         }
6780         return false;
6781 }
6782
6783 bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing)
6784 {
6785         struct dc_link_settings link_setting;
6786         uint8_t link_bw_set;
6787         uint8_t link_rate_set;
6788         uint32_t req_bw;
6789         union lane_count_set lane_count_set = {0};
6790
6791         ASSERT(link || crtc_timing); // invalid input
6792
6793         if (link->dpcd_caps.edp_supported_link_rates_count == 0 ||
6794                         !link->dc->debug.optimize_edp_link_rate)
6795                 return false;
6796
6797
6798         // Read DPCD 00100h to find if standard link rates are set
6799         core_link_read_dpcd(link, DP_LINK_BW_SET,
6800                                 &link_bw_set, sizeof(link_bw_set));
6801
6802         if (link_bw_set) {
6803                 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS used link_bw_set\n");
6804                 return true;
6805         }
6806
6807         // Read DPCD 00115h to find the edp link rate set used
6808         core_link_read_dpcd(link, DP_LINK_RATE_SET,
6809                             &link_rate_set, sizeof(link_rate_set));
6810
6811         // Read DPCD 00101h to find out the number of lanes currently set
6812         core_link_read_dpcd(link, DP_LANE_COUNT_SET,
6813                                 &lane_count_set.raw, sizeof(lane_count_set));
6814
6815         req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing);
6816
6817         if (!crtc_timing->flags.DSC)
6818                 decide_edp_link_settings(link, &link_setting, req_bw);
6819         else
6820                 decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN);
6821
6822         if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate ||
6823                         lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) {
6824                 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS link_rate_set not optimal\n");
6825                 return true;
6826         }
6827
6828         DC_LOG_EVENT_LINK_TRAINING("eDP ILR: No optimization required, VBIOS set optimal link_rate_set\n");
6829         return false;
6830 }
6831
6832 enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings)
6833 {
6834         if ((link_settings->link_rate >= LINK_RATE_LOW) &&
6835                         (link_settings->link_rate <= LINK_RATE_HIGH3))
6836                 return DP_8b_10b_ENCODING;
6837         else if ((link_settings->link_rate >= LINK_RATE_UHBR10) &&
6838                         (link_settings->link_rate <= LINK_RATE_UHBR20))
6839                 return DP_128b_132b_ENCODING;
6840         return DP_UNKNOWN_ENCODING;
6841 }
6842
6843 enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
6844 {
6845         struct dc_link_settings link_settings = {0};
6846
6847         if (!dc_is_dp_signal(link->connector_signal))
6848                 return DP_UNKNOWN_ENCODING;
6849
6850         if (link->preferred_link_setting.lane_count !=
6851                         LANE_COUNT_UNKNOWN &&
6852                         link->preferred_link_setting.link_rate !=
6853                                         LINK_RATE_UNKNOWN) {
6854                 link_settings = link->preferred_link_setting;
6855         } else {
6856                 decide_mst_link_settings(link, &link_settings);
6857         }
6858
6859         return dp_get_link_encoding_format(&link_settings);
6860 }
6861
6862 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
6863 static void get_lane_status(
6864         struct dc_link *link,
6865         uint32_t lane_count,
6866         union lane_status *status,
6867         union lane_align_status_updated *status_updated)
6868 {
6869         unsigned int lane;
6870         uint8_t dpcd_buf[3] = {0};
6871
6872         if (status == NULL || status_updated == NULL) {
6873                 return;
6874         }
6875
6876         core_link_read_dpcd(
6877                         link,
6878                         DP_LANE0_1_STATUS,
6879                         dpcd_buf,
6880                         sizeof(dpcd_buf));
6881
6882         for (lane = 0; lane < lane_count; lane++) {
6883                 status[lane].raw = get_nibble_at_index(&dpcd_buf[0], lane);
6884         }
6885
6886         status_updated->raw = dpcd_buf[2];
6887 }
6888
6889 bool dpcd_write_128b_132b_sst_payload_allocation_table(
6890                 const struct dc_stream_state *stream,
6891                 struct dc_link *link,
6892                 struct link_mst_stream_allocation_table *proposed_table,
6893                 bool allocate)
6894 {
6895         const uint8_t vc_id = 1; /// VC ID always 1 for SST
6896         const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST
6897         bool result = false;
6898         uint8_t req_slot_count = 0;
6899         struct fixed31_32 avg_time_slots_per_mtp = { 0 };
6900         union payload_table_update_status update_status = { 0 };
6901         const uint32_t max_retries = 30;
6902         uint32_t retries = 0;
6903
6904         if (allocate)   {
6905                 avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
6906                 req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
6907         } else {
6908                 /// Leave req_slot_count = 0 if allocate is false.
6909         }
6910
6911         /// Write DPCD 2C0 = 1 to start updating
6912         update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1;
6913         core_link_write_dpcd(
6914                         link,
6915                         DP_PAYLOAD_TABLE_UPDATE_STATUS,
6916                         &update_status.raw,
6917                         1);
6918
6919         /// Program the changes in DPCD 1C0 - 1C2
6920         ASSERT(vc_id == 1);
6921         core_link_write_dpcd(
6922                         link,
6923                         DP_PAYLOAD_ALLOCATE_SET,
6924                         &vc_id,
6925                         1);
6926
6927         ASSERT(start_time_slot == 0);
6928         core_link_write_dpcd(
6929                         link,
6930                         DP_PAYLOAD_ALLOCATE_START_TIME_SLOT,
6931                         &start_time_slot,
6932                         1);
6933
6934         ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT); /// Validation should filter out modes that exceed link BW
6935         core_link_write_dpcd(
6936                         link,
6937                         DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
6938                         &req_slot_count,
6939                         1);
6940
6941         /// Poll till DPCD 2C0 read 1
6942         /// Try for at least 150ms (30 retries, with 5ms delay after each attempt)
6943
6944         while (retries < max_retries) {
6945                 if (core_link_read_dpcd(
6946                                 link,
6947                                 DP_PAYLOAD_TABLE_UPDATE_STATUS,
6948                                 &update_status.raw,
6949                                 1) == DC_OK) {
6950                         if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) {
6951                                 DC_LOG_DP2("SST Update Payload: downstream payload table updated.");
6952                                 result = true;
6953                                 break;
6954                         }
6955                 } else {
6956                         union dpcd_rev dpcdRev;
6957
6958                         if (core_link_read_dpcd(
6959                                         link,
6960                                         DP_DPCD_REV,
6961                                         &dpcdRev.raw,
6962                                         1) != DC_OK) {
6963                                 DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision "
6964                                                 "of sink while polling payload table "
6965                                                 "updated status bit.");
6966                                 break;
6967                         }
6968                 }
6969                 retries++;
6970                 msleep(5);
6971         }
6972
6973         if (!result && retries == max_retries) {
6974                 DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, "
6975                                 "continue on. Something is wrong with the branch.");
6976                 // TODO - DP2.0 Payload: Read and log the payload table from downstream branch
6977         }
6978
6979         proposed_table->stream_count = 1; /// Always 1 stream for SST
6980         proposed_table->stream_allocations[0].slot_count = req_slot_count;
6981         proposed_table->stream_allocations[0].vcp_id = vc_id;
6982
6983         return result;
6984 }
6985
6986 bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link)
6987 {
6988         /*
6989          * wait for ACT handled
6990          */
6991         int i;
6992         const int act_retries = 30;
6993         enum act_return_status result = ACT_FAILED;
6994         union payload_table_update_status update_status = {0};
6995         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
6996         union lane_align_status_updated lane_status_updated;
6997
6998         for (i = 0; i < act_retries; i++) {
6999                 get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated);
7000
7001                 if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
7002                                 !dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
7003                                 !dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) ||
7004                                 !dp_is_interlane_aligned(lane_status_updated)) {
7005                         DC_LOG_ERROR("SST Update Payload: Link loss occurred while "
7006                                         "polling for ACT handled.");
7007                         result = ACT_LINK_LOST;
7008                         break;
7009                 }
7010                 core_link_read_dpcd(
7011                                 link,
7012                                 DP_PAYLOAD_TABLE_UPDATE_STATUS,
7013                                 &update_status.raw,
7014                                 1);
7015
7016                 if (update_status.bits.ACT_HANDLED == 1) {
7017                         DC_LOG_DP2("SST Update Payload: ACT handled by downstream.");
7018                         result = ACT_SUCCESS;
7019                         break;
7020                 }
7021
7022                 msleep(5);
7023         }
7024
7025         if (result == ACT_FAILED) {
7026                 DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, "
7027                                 "continue on. Something is wrong with the branch.");
7028         }
7029
7030         return (result == ACT_SUCCESS);
7031 }
7032
7033 struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
7034                 const struct dc_stream_state *stream,
7035                 const struct dc_link *link)
7036 {
7037         struct fixed31_32 link_bw_effective =
7038                         dc_fixpt_from_int(
7039                                         dc_link_bandwidth_kbps(link, &link->cur_link_settings));
7040         struct fixed31_32 timeslot_bw_effective =
7041                         dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
7042         struct fixed31_32 timing_bw =
7043                         dc_fixpt_from_int(
7044                                         dc_bandwidth_in_kbps_from_timing(&stream->timing));
7045         struct fixed31_32 avg_time_slots_per_mtp =
7046                         dc_fixpt_div(timing_bw, timeslot_bw_effective);
7047
7048         return avg_time_slots_per_mtp;
7049 }
7050
7051 bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx)
7052 {
7053         /* If this assert is hit then we have a link encoder dynamic management issue */
7054         ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
7055         return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
7056                         pipe_ctx->link_res.hpo_dp_link_enc &&
7057                         dc_is_dp_signal(pipe_ctx->stream->signal));
7058 }
7059
7060 void edp_panel_backlight_power_on(struct dc_link *link)
7061 {
7062         if (link->connector_signal != SIGNAL_TYPE_EDP)
7063                 return;
7064
7065         link->dc->hwss.edp_power_control(link, true);
7066         link->dc->hwss.edp_wait_for_hpd_ready(link, true);
7067         if (link->dc->hwss.edp_backlight_control)
7068                 link->dc->hwss.edp_backlight_control(link, true);
7069 }
7070
7071 void dc_link_clear_dprx_states(struct dc_link *link)
7072 {
7073         memset(&link->dprx_states, 0, sizeof(link->dprx_states));
7074 }
7075
7076 void dp_receiver_power_ctrl(struct dc_link *link, bool on)
7077 {
7078         uint8_t state;
7079
7080         state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
7081
7082         if (link->sync_lt_in_progress)
7083                 return;
7084
7085         core_link_write_dpcd(link, DP_SET_POWER, &state,
7086                                                  sizeof(state));
7087
7088 }
7089
7090 void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
7091 {
7092         if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
7093                 core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
7094                                         &dp_test_mode, sizeof(dp_test_mode));
7095 }
7096
7097
7098 static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
7099 {
7100         switch (lttpr_repeater_count) {
7101         case 0x80: // 1 lttpr repeater
7102                 return 1;
7103         case 0x40: // 2 lttpr repeaters
7104                 return 2;
7105         case 0x20: // 3 lttpr repeaters
7106                 return 3;
7107         case 0x10: // 4 lttpr repeaters
7108                 return 4;
7109         case 0x08: // 5 lttpr repeaters
7110                 return 5;
7111         case 0x04: // 6 lttpr repeaters
7112                 return 6;
7113         case 0x02: // 7 lttpr repeaters
7114                 return 7;
7115         case 0x01: // 8 lttpr repeaters
7116                 return 8;
7117         default:
7118                 break;
7119         }
7120         return 0; // invalid value
7121 }
7122
7123 static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
7124 {
7125         return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
7126 }
7127
7128 void dp_enable_link_phy(
7129         struct dc_link *link,
7130         const struct link_resource *link_res,
7131         enum signal_type signal,
7132         enum clock_source_id clock_source,
7133         const struct dc_link_settings *link_settings)
7134 {
7135         struct dc  *dc = link->ctx->dc;
7136         struct dmcu *dmcu = dc->res_pool->dmcu;
7137         struct pipe_ctx *pipes =
7138                         link->dc->current_state->res_ctx.pipe_ctx;
7139         struct clock_source *dp_cs =
7140                         link->dc->res_pool->dp_clock_source;
7141         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7142         unsigned int i;
7143
7144         if (link->connector_signal == SIGNAL_TYPE_EDP) {
7145                 link->dc->hwss.edp_power_control(link, true);
7146                 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
7147         }
7148
7149         /* If the current pixel clock source is not DTO(happens after
7150          * switching from HDMI passive dongle to DP on the same connector),
7151          * switch the pixel clock source to DTO.
7152          */
7153         for (i = 0; i < MAX_PIPES; i++) {
7154                 if (pipes[i].stream != NULL &&
7155                         pipes[i].stream->link == link) {
7156                         if (pipes[i].clock_source != NULL &&
7157                                         pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
7158                                 pipes[i].clock_source = dp_cs;
7159                                 pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
7160                                                 pipes[i].stream->timing.pix_clk_100hz;
7161                                 pipes[i].clock_source->funcs->program_pix_clk(
7162                                                         pipes[i].clock_source,
7163                                                         &pipes[i].stream_res.pix_clk_params,
7164                                                         &pipes[i].pll_settings);
7165                         }
7166                 }
7167         }
7168
7169         link->cur_link_settings = *link_settings;
7170
7171         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
7172                 if (dc->clk_mgr->funcs->notify_link_rate_change)
7173                         dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
7174         }
7175
7176         if (dmcu != NULL && dmcu->funcs->lock_phy)
7177                 dmcu->funcs->lock_phy(dmcu);
7178
7179         if (link_hwss->ext.enable_dp_link_output)
7180                 link_hwss->ext.enable_dp_link_output(link, link_res, signal,
7181                                 clock_source, link_settings);
7182
7183         if (dmcu != NULL && dmcu->funcs->unlock_phy)
7184                 dmcu->funcs->unlock_phy(dmcu);
7185
7186         dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
7187         dp_receiver_power_ctrl(link, true);
7188 }
7189
7190 void edp_add_delay_for_T9(struct dc_link *link)
7191 {
7192         if (link->local_sink &&
7193                         link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
7194                 udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
7195 }
7196
7197 bool edp_receiver_ready_T9(struct dc_link *link)
7198 {
7199         unsigned int tries = 0;
7200         unsigned char sinkstatus = 0;
7201         unsigned char edpRev = 0;
7202         enum dc_status result = DC_OK;
7203
7204         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
7205
7206         /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
7207         if (result == DC_OK && edpRev >= DP_EDP_12) {
7208                 do {
7209                         sinkstatus = 1;
7210                         result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
7211                         if (sinkstatus == 0)
7212                                 break;
7213                         if (result != DC_OK)
7214                                 break;
7215                         udelay(100); //MAx T9
7216                 } while (++tries < 50);
7217         }
7218
7219         return result;
7220 }
7221 bool edp_receiver_ready_T7(struct dc_link *link)
7222 {
7223         unsigned char sinkstatus = 0;
7224         unsigned char edpRev = 0;
7225         enum dc_status result = DC_OK;
7226
7227         /* use absolute time stamp to constrain max T7*/
7228         unsigned long long enter_timestamp = 0;
7229         unsigned long long finish_timestamp = 0;
7230         unsigned long long time_taken_in_ns = 0;
7231
7232         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
7233
7234         if (result == DC_OK && edpRev >= DP_EDP_12) {
7235                 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
7236                 enter_timestamp = dm_get_timestamp(link->ctx);
7237                 do {
7238                         sinkstatus = 0;
7239                         result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
7240                         if (sinkstatus == 1)
7241                                 break;
7242                         if (result != DC_OK)
7243                                 break;
7244                         udelay(25);
7245                         finish_timestamp = dm_get_timestamp(link->ctx);
7246                         time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
7247                 } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
7248         }
7249
7250         if (link->local_sink &&
7251                         link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
7252                 udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
7253
7254         return result;
7255 }
7256
7257 void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
7258                 enum signal_type signal)
7259 {
7260         struct dc  *dc = link->ctx->dc;
7261         struct dmcu *dmcu = dc->res_pool->dmcu;
7262         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7263
7264         if (!link->wa_flags.dp_keep_receiver_powered)
7265                 dp_receiver_power_ctrl(link, false);
7266
7267         if (signal == SIGNAL_TYPE_EDP) {
7268                 if (link->dc->hwss.edp_backlight_control)
7269                         link->dc->hwss.edp_backlight_control(link, false);
7270                 if (link_hwss->ext.disable_dp_link_output)
7271                         link_hwss->ext.disable_dp_link_output(link, link_res, signal);
7272                 link->dc->hwss.edp_power_control(link, false);
7273         } else {
7274                 if (dmcu != NULL && dmcu->funcs->lock_phy)
7275                         dmcu->funcs->lock_phy(dmcu);
7276                 if (link_hwss->ext.disable_dp_link_output)
7277                         link_hwss->ext.disable_dp_link_output(link, link_res, signal);
7278                 if (dmcu != NULL && dmcu->funcs->unlock_phy)
7279                         dmcu->funcs->unlock_phy(dmcu);
7280         }
7281
7282         dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
7283
7284         /* Clear current link setting.*/
7285         memset(&link->cur_link_settings, 0,
7286                         sizeof(link->cur_link_settings));
7287
7288         if (dc->clk_mgr->funcs->notify_link_rate_change)
7289                 dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
7290 }
7291
7292 void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
7293                 enum signal_type signal)
7294 {
7295         /* MST disable link only when no stream use the link */
7296         if (link->mst_stream_alloc_table.stream_count > 0)
7297                 return;
7298
7299         dp_disable_link_phy(link, link_res, signal);
7300
7301         /* set the sink to SST mode after disabling the link */
7302         dp_enable_mst_on_sink(link, false);
7303 }
7304
7305 bool dp_set_hw_training_pattern(
7306         struct dc_link *link,
7307         const struct link_resource *link_res,
7308         enum dc_dp_training_pattern pattern,
7309         uint32_t offset)
7310 {
7311         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
7312
7313         switch (pattern) {
7314         case DP_TRAINING_PATTERN_SEQUENCE_1:
7315                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
7316                 break;
7317         case DP_TRAINING_PATTERN_SEQUENCE_2:
7318                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
7319                 break;
7320         case DP_TRAINING_PATTERN_SEQUENCE_3:
7321                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
7322                 break;
7323         case DP_TRAINING_PATTERN_SEQUENCE_4:
7324                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
7325                 break;
7326         case DP_128b_132b_TPS1:
7327                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE;
7328                 break;
7329         case DP_128b_132b_TPS2:
7330                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE;
7331                 break;
7332         default:
7333                 break;
7334         }
7335
7336         dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0);
7337
7338         return true;
7339 }
7340
7341 void dp_set_hw_lane_settings(
7342         struct dc_link *link,
7343         const struct link_resource *link_res,
7344         const struct link_training_settings *link_settings,
7345         uint32_t offset)
7346 {
7347         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7348
7349         if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && !is_immediate_downstream(link, offset))
7350                 return;
7351
7352         if (link_hwss->ext.set_dp_lane_settings)
7353                 link_hwss->ext.set_dp_lane_settings(link, link_res,
7354                                 &link_settings->link_settings,
7355                                 link_settings->hw_lane_settings);
7356
7357         memmove(link->cur_lane_setting,
7358                         link_settings->hw_lane_settings,
7359                         sizeof(link->cur_lane_setting));
7360 }
7361
7362 void dp_set_hw_test_pattern(
7363         struct dc_link *link,
7364         const struct link_resource *link_res,
7365         enum dp_test_pattern test_pattern,
7366         uint8_t *custom_pattern,
7367         uint32_t custom_pattern_size)
7368 {
7369         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7370         struct encoder_set_dp_phy_pattern_param pattern_param = {0};
7371
7372         pattern_param.dp_phy_pattern = test_pattern;
7373         pattern_param.custom_pattern = custom_pattern;
7374         pattern_param.custom_pattern_size = custom_pattern_size;
7375         pattern_param.dp_panel_mode = dp_get_panel_mode(link);
7376
7377         if (link_hwss->ext.set_dp_link_test_pattern)
7378                 link_hwss->ext.set_dp_link_test_pattern(link, link_res, &pattern_param);
7379 }
7380
7381 void dp_retrain_link_dp_test(struct dc_link *link,
7382                         struct dc_link_settings *link_setting,
7383                         bool skip_video_pattern)
7384 {
7385         struct pipe_ctx *pipes =
7386                         &link->dc->current_state->res_ctx.pipe_ctx[0];
7387         unsigned int i;
7388
7389
7390         for (i = 0; i < MAX_PIPES; i++) {
7391                 if (pipes[i].stream != NULL &&
7392                         !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
7393                         pipes[i].stream->link != NULL &&
7394                         pipes[i].stream_res.stream_enc != NULL &&
7395                         pipes[i].stream->link == link) {
7396                         udelay(100);
7397
7398                         pipes[i].stream_res.stream_enc->funcs->dp_blank(link,
7399                                         pipes[i].stream_res.stream_enc);
7400
7401                         /* disable any test pattern that might be active */
7402                         dp_set_hw_test_pattern(link, &pipes[i].link_res,
7403                                         DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
7404
7405                         dp_receiver_power_ctrl(link, false);
7406
7407                         link->dc->hwss.disable_stream(&pipes[i]);
7408                         if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
7409                                 (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
7410
7411                         if (link->link_enc)
7412                                 link->link_enc->funcs->disable_output(
7413                                                 link->link_enc,
7414                                                 SIGNAL_TYPE_DISPLAY_PORT);
7415
7416                         /* Clear current link setting. */
7417                         memset(&link->cur_link_settings, 0,
7418                                 sizeof(link->cur_link_settings));
7419
7420                         perform_link_training_with_retries(
7421                                         link_setting,
7422                                         skip_video_pattern,
7423                                         LINK_TRAINING_ATTEMPTS,
7424                                         &pipes[i],
7425                                         SIGNAL_TYPE_DISPLAY_PORT,
7426                                         false);
7427
7428                         link->dc->hwss.enable_stream(&pipes[i]);
7429
7430                         link->dc->hwss.unblank_stream(&pipes[i],
7431                                         link_setting);
7432
7433                         if (pipes[i].stream_res.audio) {
7434                                 /* notify audio driver for
7435                                  * audio modes of monitor */
7436                                 pipes[i].stream_res.audio->funcs->az_enable(
7437                                                 pipes[i].stream_res.audio);
7438
7439                                 /* un-mute audio */
7440                                 /* TODO: audio should be per stream rather than
7441                                  * per link */
7442                                 pipes[i].stream_res.stream_enc->funcs->
7443                                 audio_mute_control(
7444                                         pipes[i].stream_res.stream_enc, false);
7445                         }
7446                 }
7447         }
7448 }
7449
7450 #undef DC_LOGGER
7451 #define DC_LOGGER \
7452         dsc->ctx->logger
7453 static void dsc_optc_config_log(struct display_stream_compressor *dsc,
7454                 struct dsc_optc_config *config)
7455 {
7456         uint32_t precision = 1 << 28;
7457         uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
7458         uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
7459         uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
7460
7461         /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
7462          * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
7463          * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
7464          */
7465         ll_bytes_per_pix_fraq *= 10000000;
7466         ll_bytes_per_pix_fraq /= precision;
7467
7468         DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
7469                         config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
7470         DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
7471         DC_LOG_DSC("\tslice_width %d", config->slice_width);
7472 }
7473
7474 bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
7475 {
7476         struct dc *dc = pipe_ctx->stream->ctx->dc;
7477         struct dc_stream_state *stream = pipe_ctx->stream;
7478         bool result = false;
7479
7480         if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
7481                 result = true;
7482         else
7483                 result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
7484         return result;
7485 }
7486
7487 /* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
7488  * i.e. after dp_enable_dsc_on_rx() had been called
7489  */
7490 void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
7491 {
7492         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7493         struct dc *dc = pipe_ctx->stream->ctx->dc;
7494         struct dc_stream_state *stream = pipe_ctx->stream;
7495         struct pipe_ctx *odm_pipe;
7496         int opp_cnt = 1;
7497
7498         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
7499                 opp_cnt++;
7500
7501         if (enable) {
7502                 struct dsc_config dsc_cfg;
7503                 struct dsc_optc_config dsc_optc_cfg;
7504                 enum optc_dsc_mode optc_dsc_mode;
7505
7506                 /* Enable DSC hw block */
7507                 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
7508                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
7509                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
7510                 dsc_cfg.color_depth = stream->timing.display_color_depth;
7511                 dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
7512                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
7513                 ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
7514                 dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
7515
7516                 dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
7517                 dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
7518                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
7519                         struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
7520
7521                         odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
7522                         odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
7523                 }
7524                 dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
7525                 dsc_cfg.pic_width *= opp_cnt;
7526
7527                 optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
7528
7529                 /* Enable DSC in encoder */
7530                 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
7531                                 && !is_dp_128b_132b_signal(pipe_ctx)) {
7532                         DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
7533                         dsc_optc_config_log(dsc, &dsc_optc_cfg);
7534                         pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
7535                                                                         optc_dsc_mode,
7536                                                                         dsc_optc_cfg.bytes_per_pixel,
7537                                                                         dsc_optc_cfg.slice_width);
7538
7539                         /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
7540                 }
7541
7542                 /* Enable DSC in OPTC */
7543                 DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
7544                 dsc_optc_config_log(dsc, &dsc_optc_cfg);
7545                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
7546                                                         optc_dsc_mode,
7547                                                         dsc_optc_cfg.bytes_per_pixel,
7548                                                         dsc_optc_cfg.slice_width);
7549         } else {
7550                 /* disable DSC in OPTC */
7551                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
7552                                 pipe_ctx->stream_res.tg,
7553                                 OPTC_DSC_DISABLED, 0, 0);
7554
7555                 /* disable DSC in stream encoder */
7556                 if (dc_is_dp_signal(stream->signal)) {
7557                         if (is_dp_128b_132b_signal(pipe_ctx))
7558                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7559                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7560                                                                                 false,
7561                                                                                 NULL,
7562                                                                                 true);
7563                         else if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
7564                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
7565                                                 pipe_ctx->stream_res.stream_enc,
7566                                                 OPTC_DSC_DISABLED, 0, 0);
7567                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7568                                                         pipe_ctx->stream_res.stream_enc, false, NULL, true);
7569                         }
7570                 }
7571
7572                 /* disable DSC block */
7573                 pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
7574                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
7575                         odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
7576         }
7577 }
7578
7579 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
7580 {
7581         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7582         bool result = false;
7583
7584         if (!pipe_ctx->stream->timing.flags.DSC)
7585                 goto out;
7586         if (!dsc)
7587                 goto out;
7588
7589         if (enable) {
7590                 {
7591                         dp_set_dsc_on_stream(pipe_ctx, true);
7592                         result = true;
7593                 }
7594         } else {
7595                 dp_set_dsc_on_rx(pipe_ctx, false);
7596                 dp_set_dsc_on_stream(pipe_ctx, false);
7597                 result = true;
7598         }
7599 out:
7600         return result;
7601 }
7602
7603 /*
7604  * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
7605  * hence PPS info packet update need to use frame update instead of immediate update.
7606  * Added parameter immediate_update for this purpose.
7607  * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
7608  * which is the only place where a "false" would be passed in for param immediate_update.
7609  *
7610  * immediate_update is only applicable when DSC is enabled.
7611  */
7612 bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
7613 {
7614         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7615         struct dc_stream_state *stream = pipe_ctx->stream;
7616
7617         if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
7618                 return false;
7619
7620         if (enable) {
7621                 struct dsc_config dsc_cfg;
7622                 uint8_t dsc_packed_pps[128];
7623
7624                 memset(&dsc_cfg, 0, sizeof(dsc_cfg));
7625                 memset(dsc_packed_pps, 0, 128);
7626
7627                 /* Enable DSC hw block */
7628                 dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
7629                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
7630                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
7631                 dsc_cfg.color_depth = stream->timing.display_color_depth;
7632                 dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
7633                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
7634
7635                 DC_LOG_DSC(" ");
7636                 dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
7637                 memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
7638                 if (dc_is_dp_signal(stream->signal)) {
7639                         DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
7640                         if (is_dp_128b_132b_signal(pipe_ctx))
7641                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7642                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7643                                                                                 true,
7644                                                                                 &dsc_packed_pps[0],
7645                                                                                 immediate_update);
7646                         else
7647                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7648                                                 pipe_ctx->stream_res.stream_enc,
7649                                                 true,
7650                                                 &dsc_packed_pps[0],
7651                                                 immediate_update);
7652                 }
7653         } else {
7654                 /* disable DSC PPS in stream encoder */
7655                 memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps));
7656                 if (dc_is_dp_signal(stream->signal)) {
7657                         if (is_dp_128b_132b_signal(pipe_ctx))
7658                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7659                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7660                                                                                 false,
7661                                                                                 NULL,
7662                                                                                 true);
7663                         else
7664                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7665                                                 pipe_ctx->stream_res.stream_enc, false, NULL, true);
7666                 }
7667         }
7668
7669         return true;
7670 }
7671
7672
7673 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
7674 {
7675         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7676
7677         if (!pipe_ctx->stream->timing.flags.DSC)
7678                 return false;
7679         if (!dsc)
7680                 return false;
7681
7682         dp_set_dsc_on_stream(pipe_ctx, true);
7683         dp_set_dsc_pps_sdp(pipe_ctx, true, false);
7684         return true;
7685 }
7686
7687 #undef DC_LOGGER
7688 #define DC_LOGGER \
7689         link->ctx->logger