Merge tag 'asoc-v5.19' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.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 current_setting = *link_setting;
2787         const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
2788         int fail_count = 0;
2789
2790         dp_trace_commit_lt_init(link);
2791
2792
2793         if (dp_get_link_encoding_format(&current_setting) == DP_8b_10b_ENCODING)
2794                 /* We need to do this before the link training to ensure the idle
2795                  * pattern in SST mode will be sent right after the link training
2796                  */
2797                 link_hwss->setup_stream_encoder(pipe_ctx);
2798
2799         dp_trace_set_lt_start_timestamp(link, false);
2800         for (j = 0; j < attempts; ++j) {
2801
2802                 DC_LOG_HW_LINK_TRAINING("%s: Beginning link training attempt %u of %d\n",
2803                         __func__, (unsigned int)j + 1, attempts);
2804
2805                 dp_enable_link_phy(
2806                         link,
2807                         &pipe_ctx->link_res,
2808                         signal,
2809                         pipe_ctx->clock_source->id,
2810                         &current_setting);
2811
2812                 if (stream->sink_patches.dppowerup_delay > 0) {
2813                         int delay_dp_power_up_in_ms = stream->sink_patches.dppowerup_delay;
2814
2815                         msleep(delay_dp_power_up_in_ms);
2816                 }
2817
2818 #ifdef CONFIG_DRM_AMD_DC_HDCP
2819                 if (panel_mode == DP_PANEL_MODE_EDP) {
2820                         struct cp_psp *cp_psp = &stream->ctx->cp_psp;
2821
2822                         if (cp_psp && cp_psp->funcs.enable_assr)
2823                                 /* ASSR is bound to fail with unsigned PSP
2824                                  * verstage used during devlopment phase.
2825                                  * Report and continue with eDP panel mode to
2826                                  * perform eDP link training with right settings
2827                                  */
2828                                 cp_psp->funcs.enable_assr(cp_psp->handle, link);
2829                 }
2830 #endif
2831
2832                 dp_set_panel_mode(link, panel_mode);
2833
2834                 if (link->aux_access_disabled) {
2835                         dc_link_dp_perform_link_training_skip_aux(link, &pipe_ctx->link_res, &current_setting);
2836                         return true;
2837                 } else {
2838                         /** @todo Consolidate USB4 DP and DPx.x training. */
2839                         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA) {
2840                                 status = dc_link_dpia_perform_link_training(link,
2841                                                 &pipe_ctx->link_res,
2842                                                 &current_setting,
2843                                                 skip_video_pattern);
2844
2845                                 /* Transmit idle pattern once training successful. */
2846                                 if (status == LINK_TRAINING_SUCCESS)
2847                                         dp_set_hw_test_pattern(link, &pipe_ctx->link_res, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
2848                         } else {
2849                                 status = dc_link_dp_perform_link_training(link,
2850                                                 &pipe_ctx->link_res,
2851                                                 &current_setting,
2852                                                 skip_video_pattern);
2853                         }
2854
2855                         dp_trace_lt_total_count_increment(link, false);
2856                         dp_trace_lt_result_update(link, status, false);
2857                         dp_trace_set_lt_end_timestamp(link, false);
2858                         if (status == LINK_TRAINING_SUCCESS)
2859                                 return true;
2860                 }
2861
2862                 fail_count++;
2863                 dp_trace_lt_fail_count_update(link, fail_count, false);
2864                 /* latest link training still fail, skip delay and keep PHY on
2865                  */
2866                 if (j == (attempts - 1) && link->ep_type == DISPLAY_ENDPOINT_PHY)
2867                         break;
2868
2869                 DC_LOG_WARNING("%s: Link training attempt %u of %d failed\n",
2870                         __func__, (unsigned int)j + 1, attempts);
2871
2872                 dp_disable_link_phy(link, &pipe_ctx->link_res, signal);
2873
2874                 /* Abort link training if failure due to sink being unplugged. */
2875                 if (status == LINK_TRAINING_ABORT) {
2876                         enum dc_connection_type type = dc_connection_none;
2877
2878                         dc_link_detect_sink(link, &type);
2879                         if (type == dc_connection_none)
2880                                 break;
2881                 } else if (do_fallback) {
2882                         uint32_t req_bw;
2883                         uint32_t link_bw;
2884
2885                         decide_fallback_link_setting(link, *link_setting, &current_setting, status);
2886                         /* Fail link training if reduced link bandwidth no longer meets
2887                          * stream requirements.
2888                          */
2889                         req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
2890                         link_bw = dc_link_bandwidth_kbps(link, &current_setting);
2891                         if (req_bw > link_bw)
2892                                 break;
2893                 }
2894
2895                 msleep(delay_between_attempts);
2896
2897                 delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
2898         }
2899
2900         return false;
2901 }
2902
2903 static enum clock_source_id get_clock_source_id(struct dc_link *link)
2904 {
2905         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_UNDEFINED;
2906         struct clock_source *dp_cs = link->dc->res_pool->dp_clock_source;
2907
2908         if (dp_cs != NULL) {
2909                 dp_cs_id = dp_cs->id;
2910         } else {
2911                 /*
2912                  * dp clock source is not initialized for some reason.
2913                  * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
2914                  */
2915                 ASSERT(dp_cs);
2916         }
2917
2918         return dp_cs_id;
2919 }
2920
2921 static void set_dp_mst_mode(struct dc_link *link, const struct link_resource *link_res,
2922                 bool mst_enable)
2923 {
2924         if (mst_enable == false &&
2925                 link->type == dc_connection_mst_branch) {
2926                 /* Disable MST on link. Use only local sink. */
2927                 dp_disable_link_phy_mst(link, link_res, link->connector_signal);
2928
2929                 link->type = dc_connection_single;
2930                 link->local_sink = link->remote_sinks[0];
2931                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
2932                 dc_sink_retain(link->local_sink);
2933                 dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
2934         } else if (mst_enable == true &&
2935                         link->type == dc_connection_single &&
2936                         link->remote_sinks[0] != NULL) {
2937                 /* Re-enable MST on link. */
2938                 dp_disable_link_phy(link, link_res, link->connector_signal);
2939                 dp_enable_mst_on_sink(link, true);
2940
2941                 link->type = dc_connection_mst_branch;
2942                 link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
2943         }
2944 }
2945
2946 bool dc_link_dp_sync_lt_begin(struct dc_link *link)
2947 {
2948         /* Begin Sync LT. During this time,
2949          * DPCD:600h must not be powered down.
2950          */
2951         link->sync_lt_in_progress = true;
2952
2953         /*Clear any existing preferred settings.*/
2954         memset(&link->preferred_training_settings, 0,
2955                 sizeof(struct dc_link_training_overrides));
2956         memset(&link->preferred_link_setting, 0,
2957                 sizeof(struct dc_link_settings));
2958
2959         return true;
2960 }
2961
2962 enum link_training_result dc_link_dp_sync_lt_attempt(
2963     struct dc_link *link,
2964     const struct link_resource *link_res,
2965     struct dc_link_settings *link_settings,
2966     struct dc_link_training_overrides *lt_overrides)
2967 {
2968         struct link_training_settings lt_settings = {0};
2969         enum link_training_result lt_status = LINK_TRAINING_SUCCESS;
2970         enum dp_panel_mode panel_mode = DP_PANEL_MODE_DEFAULT;
2971         enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
2972         bool fec_enable = false;
2973
2974         dp_decide_training_settings(
2975                         link,
2976                         link_settings,
2977                         &lt_settings);
2978         override_training_settings(
2979                         link,
2980                         lt_overrides,
2981                         &lt_settings);
2982         /* Setup MST Mode */
2983         if (lt_overrides->mst_enable)
2984                 set_dp_mst_mode(link, link_res, *lt_overrides->mst_enable);
2985
2986         /* Disable link */
2987         dp_disable_link_phy(link, link_res, link->connector_signal);
2988
2989         /* Enable link */
2990         dp_cs_id = get_clock_source_id(link);
2991         dp_enable_link_phy(link, link_res, link->connector_signal,
2992                 dp_cs_id, link_settings);
2993
2994         /* Set FEC enable */
2995         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
2996                 fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
2997                 dp_set_fec_ready(link, NULL, fec_enable);
2998         }
2999
3000         if (lt_overrides->alternate_scrambler_reset) {
3001                 if (*lt_overrides->alternate_scrambler_reset)
3002                         panel_mode = DP_PANEL_MODE_EDP;
3003                 else
3004                         panel_mode = DP_PANEL_MODE_DEFAULT;
3005         } else
3006                 panel_mode = dp_get_panel_mode(link);
3007
3008         dp_set_panel_mode(link, panel_mode);
3009
3010         /* Attempt to train with given link training settings */
3011         if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
3012                 start_clock_recovery_pattern_early(link, link_res, &lt_settings, DPRX);
3013
3014         /* Set link rate, lane count and spread. */
3015         dpcd_set_link_settings(link, &lt_settings);
3016
3017         /* 2. perform link training (set link training done
3018          *  to false is done as well)
3019          */
3020         lt_status = perform_clock_recovery_sequence(link, link_res, &lt_settings, DPRX);
3021         if (lt_status == LINK_TRAINING_SUCCESS) {
3022                 lt_status = perform_channel_equalization_sequence(link,
3023                                                 link_res,
3024                                                 &lt_settings,
3025                                                 DPRX);
3026         }
3027
3028         /* 3. Sync LT must skip TRAINING_PATTERN_SET:0 (video pattern)*/
3029         /* 4. print status message*/
3030         print_status_message(link, &lt_settings, lt_status);
3031
3032         return lt_status;
3033 }
3034
3035 bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
3036 {
3037         /* If input parameter is set, shut down phy.
3038          * Still shouldn't turn off dp_receiver (DPCD:600h)
3039          */
3040         if (link_down == true) {
3041                 struct dc_link_settings link_settings = link->cur_link_settings;
3042                 dp_disable_link_phy(link, NULL, link->connector_signal);
3043                 if (dp_get_link_encoding_format(&link_settings) == DP_8b_10b_ENCODING)
3044                         dp_set_fec_ready(link, NULL, false);
3045         }
3046
3047         link->sync_lt_in_progress = false;
3048         return true;
3049 }
3050
3051 static enum dc_link_rate get_lttpr_max_link_rate(struct dc_link *link)
3052 {
3053         enum dc_link_rate lttpr_max_link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
3054
3055         if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR20)
3056                 lttpr_max_link_rate = LINK_RATE_UHBR20;
3057         else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR13_5)
3058                 lttpr_max_link_rate = LINK_RATE_UHBR13_5;
3059         else if (link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.bits.UHBR10)
3060                 lttpr_max_link_rate = LINK_RATE_UHBR10;
3061
3062         return lttpr_max_link_rate;
3063 }
3064
3065 static enum dc_link_rate get_cable_max_link_rate(struct dc_link *link)
3066 {
3067         enum dc_link_rate cable_max_link_rate = LINK_RATE_HIGH3;
3068
3069         if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR20)
3070                 cable_max_link_rate = LINK_RATE_UHBR20;
3071         else if (link->dpcd_caps.cable_id.bits.UHBR13_5_CAPABILITY)
3072                 cable_max_link_rate = LINK_RATE_UHBR13_5;
3073         else if (link->dpcd_caps.cable_id.bits.UHBR10_20_CAPABILITY & DP_UHBR10)
3074                 cable_max_link_rate = LINK_RATE_UHBR10;
3075
3076         return cable_max_link_rate;
3077 }
3078
3079 bool dc_link_dp_get_max_link_enc_cap(const struct dc_link *link, struct dc_link_settings *max_link_enc_cap)
3080 {
3081         struct link_encoder *link_enc = NULL;
3082
3083         if (!max_link_enc_cap) {
3084                 DC_LOG_ERROR("%s: Could not return max link encoder caps", __func__);
3085                 return false;
3086         }
3087
3088         link_enc = link_enc_cfg_get_link_enc(link);
3089         ASSERT(link_enc);
3090
3091         if (link_enc && link_enc->funcs->get_max_link_cap) {
3092                 link_enc->funcs->get_max_link_cap(link_enc, max_link_enc_cap);
3093                 return true;
3094         }
3095
3096         DC_LOG_ERROR("%s: Max link encoder caps unknown", __func__);
3097         max_link_enc_cap->lane_count = 1;
3098         max_link_enc_cap->link_rate = 6;
3099         return false;
3100 }
3101
3102
3103 struct dc_link_settings dp_get_max_link_cap(struct dc_link *link)
3104 {
3105         struct dc_link_settings max_link_cap = {0};
3106         enum dc_link_rate lttpr_max_link_rate;
3107         enum dc_link_rate cable_max_link_rate;
3108         struct link_encoder *link_enc = NULL;
3109
3110
3111         link_enc = link_enc_cfg_get_link_enc(link);
3112         ASSERT(link_enc);
3113
3114         /* get max link encoder capability */
3115         if (link_enc)
3116                 link_enc->funcs->get_max_link_cap(link_enc, &max_link_cap);
3117
3118         /* Lower link settings based on sink's link cap */
3119         if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
3120                 max_link_cap.lane_count =
3121                                 link->reported_link_cap.lane_count;
3122         if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
3123                 max_link_cap.link_rate =
3124                                 link->reported_link_cap.link_rate;
3125         if (link->reported_link_cap.link_spread <
3126                         max_link_cap.link_spread)
3127                 max_link_cap.link_spread =
3128                                 link->reported_link_cap.link_spread;
3129
3130         /* Lower link settings based on cable attributes */
3131         cable_max_link_rate = get_cable_max_link_rate(link);
3132
3133         if (!link->dc->debug.ignore_cable_id &&
3134                         cable_max_link_rate < max_link_cap.link_rate)
3135                 max_link_cap.link_rate = cable_max_link_rate;
3136
3137         /*
3138          * account for lttpr repeaters cap
3139          * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
3140          */
3141         if (link->lttpr_mode != LTTPR_MODE_NON_LTTPR) {
3142                 if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
3143                         max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
3144                 lttpr_max_link_rate = get_lttpr_max_link_rate(link);
3145
3146                 if (lttpr_max_link_rate < max_link_cap.link_rate)
3147                         max_link_cap.link_rate = lttpr_max_link_rate;
3148
3149                 DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane count %d max_link rate %d \n",
3150                                                 __func__,
3151                                                 max_link_cap.lane_count,
3152                                                 max_link_cap.link_rate);
3153         }
3154
3155         if (dp_get_link_encoding_format(&max_link_cap) == DP_128b_132b_ENCODING &&
3156                         link->dc->debug.disable_uhbr)
3157                 max_link_cap.link_rate = LINK_RATE_HIGH3;
3158
3159         return max_link_cap;
3160 }
3161
3162 static enum dc_status read_hpd_rx_irq_data(
3163         struct dc_link *link,
3164         union hpd_irq_data *irq_data)
3165 {
3166         static enum dc_status retval;
3167
3168         /* The HW reads 16 bytes from 200h on HPD,
3169          * but if we get an AUX_DEFER, the HW cannot retry
3170          * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
3171          * fail, so we now explicitly read 6 bytes which is
3172          * the req from the above mentioned test cases.
3173          *
3174          * For DP 1.4 we need to read those from 2002h range.
3175          */
3176         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
3177                 retval = core_link_read_dpcd(
3178                         link,
3179                         DP_SINK_COUNT,
3180                         irq_data->raw,
3181                         sizeof(union hpd_irq_data));
3182         else {
3183                 /* Read 14 bytes in a single read and then copy only the required fields.
3184                  * This is more efficient than doing it in two separate AUX reads. */
3185
3186                 uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
3187
3188                 retval = core_link_read_dpcd(
3189                         link,
3190                         DP_SINK_COUNT_ESI,
3191                         tmp,
3192                         sizeof(tmp));
3193
3194                 if (retval != DC_OK)
3195                         return retval;
3196
3197                 irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
3198                 irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
3199                 irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
3200                 irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
3201                 irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
3202                 irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
3203         }
3204
3205         return retval;
3206 }
3207
3208 bool hpd_rx_irq_check_link_loss_status(
3209         struct dc_link *link,
3210         union hpd_irq_data *hpd_irq_dpcd_data)
3211 {
3212         uint8_t irq_reg_rx_power_state = 0;
3213         enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
3214         union lane_status lane_status;
3215         uint32_t lane;
3216         bool sink_status_changed;
3217         bool return_code;
3218
3219         sink_status_changed = false;
3220         return_code = false;
3221
3222         if (link->cur_link_settings.lane_count == 0)
3223                 return return_code;
3224
3225         /*1. Check that Link Status changed, before re-training.*/
3226
3227         /*parse lane status*/
3228         for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
3229                 /* check status of lanes 0,1
3230                  * changed DpcdAddress_Lane01Status (0x202)
3231                  */
3232                 lane_status.raw = get_nibble_at_index(
3233                         &hpd_irq_dpcd_data->bytes.lane01_status.raw,
3234                         lane);
3235
3236                 if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
3237                         !lane_status.bits.CR_DONE_0 ||
3238                         !lane_status.bits.SYMBOL_LOCKED_0) {
3239                         /* if one of the channel equalization, clock
3240                          * recovery or symbol lock is dropped
3241                          * consider it as (link has been
3242                          * dropped) dp sink status has changed
3243                          */
3244                         sink_status_changed = true;
3245                         break;
3246                 }
3247         }
3248
3249         /* Check interlane align.*/
3250         if (sink_status_changed ||
3251                 !hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
3252
3253                 DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
3254
3255                 return_code = true;
3256
3257                 /*2. Check that we can handle interrupt: Not in FS DOS,
3258                  *  Not in "Display Timeout" state, Link is trained.
3259                  */
3260                 dpcd_result = core_link_read_dpcd(link,
3261                         DP_SET_POWER,
3262                         &irq_reg_rx_power_state,
3263                         sizeof(irq_reg_rx_power_state));
3264
3265                 if (dpcd_result != DC_OK) {
3266                         DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
3267                                 __func__);
3268                 } else {
3269                         if (irq_reg_rx_power_state != DP_SET_POWER_D0)
3270                                 return_code = false;
3271                 }
3272         }
3273
3274         return return_code;
3275 }
3276
3277 static bool dp_verify_link_cap(
3278         struct dc_link *link,
3279         struct dc_link_settings *known_limit_link_setting,
3280         int *fail_count)
3281 {
3282         struct dc_link_settings cur_link_settings = {0};
3283         struct dc_link_settings initial_link_settings = *known_limit_link_setting;
3284         bool success = false;
3285         bool skip_video_pattern;
3286         enum clock_source_id dp_cs_id = get_clock_source_id(link);
3287         enum link_training_result status = LINK_TRAINING_SUCCESS;
3288         union hpd_irq_data irq_data;
3289         struct link_resource link_res;
3290
3291         memset(&irq_data, 0, sizeof(irq_data));
3292         cur_link_settings = initial_link_settings;
3293
3294         /* Grant extended timeout request */
3295         if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && (link->dpcd_caps.lttpr_caps.max_ext_timeout > 0)) {
3296                 uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80;
3297
3298                 core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
3299         }
3300
3301         do {
3302                 if (!get_temp_dp_link_res(link, &link_res, &cur_link_settings))
3303                         continue;
3304
3305                 skip_video_pattern = cur_link_settings.link_rate != LINK_RATE_LOW;
3306                 dp_enable_link_phy(
3307                                 link,
3308                                 &link_res,
3309                                 link->connector_signal,
3310                                 dp_cs_id,
3311                                 &cur_link_settings);
3312
3313                 status = dc_link_dp_perform_link_training(
3314                                 link,
3315                                 &link_res,
3316                                 &cur_link_settings,
3317                                 skip_video_pattern);
3318
3319                 if (status == LINK_TRAINING_SUCCESS) {
3320                         success = true;
3321                         udelay(1000);
3322                         if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK &&
3323                                         hpd_rx_irq_check_link_loss_status(
3324                                                         link,
3325                                                         &irq_data))
3326                                 (*fail_count)++;
3327
3328                 } else {
3329                         (*fail_count)++;
3330                 }
3331                 dp_trace_lt_total_count_increment(link, true);
3332                 dp_trace_lt_result_update(link, status, true);
3333                 dp_disable_link_phy(link, &link_res, link->connector_signal);
3334         } while (!success && decide_fallback_link_setting(link,
3335                         initial_link_settings, &cur_link_settings, status));
3336
3337         link->verified_link_cap = success ?
3338                         cur_link_settings : fail_safe_link_settings;
3339         return success;
3340 }
3341
3342 static void apply_usbc_combo_phy_reset_wa(struct dc_link *link,
3343                 struct dc_link_settings *link_settings)
3344 {
3345         /* Temporary Renoir-specific workaround PHY will sometimes be in bad
3346          * state on hotplugging display from certain USB-C dongle, so add extra
3347          * cycle of enabling and disabling the PHY before first link training.
3348          */
3349         struct link_resource link_res = {0};
3350         enum clock_source_id dp_cs_id = get_clock_source_id(link);
3351
3352         dp_enable_link_phy(link, &link_res, link->connector_signal,
3353                         dp_cs_id, link_settings);
3354         dp_disable_link_phy(link, &link_res, link->connector_signal);
3355 }
3356
3357 bool dp_verify_link_cap_with_retries(
3358         struct dc_link *link,
3359         struct dc_link_settings *known_limit_link_setting,
3360         int attempts)
3361 {
3362         int i = 0;
3363         bool success = false;
3364         int fail_count = 0;
3365
3366         dp_trace_detect_lt_init(link);
3367
3368         if (link->link_enc && link->link_enc->features.flags.bits.DP_IS_USB_C &&
3369                         link->dc->debug.usbc_combo_phy_reset_wa)
3370                 apply_usbc_combo_phy_reset_wa(link, known_limit_link_setting);
3371
3372         dp_trace_set_lt_start_timestamp(link, false);
3373         for (i = 0; i < attempts; i++) {
3374                 enum dc_connection_type type = dc_connection_none;
3375
3376                 memset(&link->verified_link_cap, 0,
3377                                 sizeof(struct dc_link_settings));
3378                 if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
3379                         link->verified_link_cap = fail_safe_link_settings;
3380                         break;
3381                 } else if (dp_verify_link_cap(link, known_limit_link_setting,
3382                                 &fail_count) && fail_count == 0) {
3383                         success = true;
3384                         break;
3385                 }
3386                 msleep(10);
3387         }
3388
3389         dp_trace_lt_fail_count_update(link, fail_count, true);
3390         dp_trace_set_lt_end_timestamp(link, true);
3391
3392         return success;
3393 }
3394
3395 /* in DP compliance test, DPR-120 may have
3396  * a random value in its MAX_LINK_BW dpcd field.
3397  * We map it to the maximum supported link rate that
3398  * is smaller than MAX_LINK_BW in this case.
3399  */
3400 static enum dc_link_rate get_link_rate_from_max_link_bw(
3401                  uint8_t max_link_bw)
3402 {
3403         enum dc_link_rate link_rate;
3404
3405         if (max_link_bw >= LINK_RATE_HIGH3) {
3406                 link_rate = LINK_RATE_HIGH3;
3407         } else if (max_link_bw < LINK_RATE_HIGH3
3408                         && max_link_bw >= LINK_RATE_HIGH2) {
3409                 link_rate = LINK_RATE_HIGH2;
3410         } else if (max_link_bw < LINK_RATE_HIGH2
3411                         && max_link_bw >= LINK_RATE_HIGH) {
3412                 link_rate = LINK_RATE_HIGH;
3413         } else if (max_link_bw < LINK_RATE_HIGH
3414                         && max_link_bw >= LINK_RATE_LOW) {
3415                 link_rate = LINK_RATE_LOW;
3416         } else {
3417                 link_rate = LINK_RATE_UNKNOWN;
3418         }
3419
3420         return link_rate;
3421 }
3422
3423 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
3424 {
3425         return lane_count <= LANE_COUNT_ONE;
3426 }
3427
3428 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
3429 {
3430         return link_rate <= LINK_RATE_LOW;
3431 }
3432
3433 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
3434 {
3435         switch (lane_count) {
3436         case LANE_COUNT_FOUR:
3437                 return LANE_COUNT_TWO;
3438         case LANE_COUNT_TWO:
3439                 return LANE_COUNT_ONE;
3440         case LANE_COUNT_ONE:
3441                 return LANE_COUNT_UNKNOWN;
3442         default:
3443                 return LANE_COUNT_UNKNOWN;
3444         }
3445 }
3446
3447 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
3448 {
3449         switch (link_rate) {
3450         case LINK_RATE_UHBR20:
3451                 return LINK_RATE_UHBR13_5;
3452         case LINK_RATE_UHBR13_5:
3453                 return LINK_RATE_UHBR10;
3454         case LINK_RATE_UHBR10:
3455                 return LINK_RATE_HIGH3;
3456         case LINK_RATE_HIGH3:
3457                 return LINK_RATE_HIGH2;
3458         case LINK_RATE_HIGH2:
3459                 return LINK_RATE_HIGH;
3460         case LINK_RATE_HIGH:
3461                 return LINK_RATE_LOW;
3462         case LINK_RATE_LOW:
3463                 return LINK_RATE_UNKNOWN;
3464         default:
3465                 return LINK_RATE_UNKNOWN;
3466         }
3467 }
3468
3469 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
3470 {
3471         switch (lane_count) {
3472         case LANE_COUNT_ONE:
3473                 return LANE_COUNT_TWO;
3474         case LANE_COUNT_TWO:
3475                 return LANE_COUNT_FOUR;
3476         default:
3477                 return LANE_COUNT_UNKNOWN;
3478         }
3479 }
3480
3481 static enum dc_link_rate increase_link_rate(struct dc_link *link,
3482                 enum dc_link_rate link_rate)
3483 {
3484         switch (link_rate) {
3485         case LINK_RATE_LOW:
3486                 return LINK_RATE_HIGH;
3487         case LINK_RATE_HIGH:
3488                 return LINK_RATE_HIGH2;
3489         case LINK_RATE_HIGH2:
3490                 return LINK_RATE_HIGH3;
3491         case LINK_RATE_HIGH3:
3492                 return LINK_RATE_UHBR10;
3493         case LINK_RATE_UHBR10:
3494                 /* upto DP2.x specs UHBR13.5 is the only link rate that could be
3495                  * not supported by DPRX when higher link rate is supported.
3496                  * so we treat it as a special case for code simplicity. When we
3497                  * have new specs with more link rates like this, we should
3498                  * consider a more generic solution to handle discrete link
3499                  * rate capabilities.
3500                  */
3501                 return link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 ?
3502                                 LINK_RATE_UHBR13_5 : LINK_RATE_UHBR20;
3503         case LINK_RATE_UHBR13_5:
3504                 return LINK_RATE_UHBR20;
3505         default:
3506                 return LINK_RATE_UNKNOWN;
3507         }
3508 }
3509
3510 static bool decide_fallback_link_setting_max_bw_policy(
3511                 struct dc_link *link,
3512                 const struct dc_link_settings *max,
3513                 struct dc_link_settings *cur,
3514                 enum link_training_result training_result)
3515 {
3516         uint8_t cur_idx = 0, next_idx;
3517         bool found = false;
3518
3519         if (training_result == LINK_TRAINING_ABORT)
3520                 return false;
3521
3522         while (cur_idx < ARRAY_SIZE(dp_lt_fallbacks))
3523                 /* find current index */
3524                 if (dp_lt_fallbacks[cur_idx].lane_count == cur->lane_count &&
3525                                 dp_lt_fallbacks[cur_idx].link_rate == cur->link_rate)
3526                         break;
3527                 else
3528                         cur_idx++;
3529
3530         next_idx = cur_idx + 1;
3531
3532         while (next_idx < ARRAY_SIZE(dp_lt_fallbacks))
3533                 /* find next index */
3534                 if (dp_lt_fallbacks[next_idx].lane_count > max->lane_count ||
3535                                 dp_lt_fallbacks[next_idx].link_rate > max->link_rate)
3536                         next_idx++;
3537                 else if (dp_lt_fallbacks[next_idx].link_rate == LINK_RATE_UHBR13_5 &&
3538                                 link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5 == 0)
3539                         /* upto DP2.x specs UHBR13.5 is the only link rate that
3540                          * could be not supported by DPRX when higher link rate
3541                          * is supported. so we treat it as a special case for
3542                          * code simplicity. When we have new specs with more
3543                          * link rates like this, we should consider a more
3544                          * generic solution to handle discrete link rate
3545                          * capabilities.
3546                          */
3547                         next_idx++;
3548                 else
3549                         break;
3550
3551         if (next_idx < ARRAY_SIZE(dp_lt_fallbacks)) {
3552                 cur->lane_count = dp_lt_fallbacks[next_idx].lane_count;
3553                 cur->link_rate = dp_lt_fallbacks[next_idx].link_rate;
3554                 found = true;
3555         }
3556
3557         return found;
3558 }
3559
3560 /*
3561  * function: set link rate and lane count fallback based
3562  * on current link setting and last link training result
3563  * return value:
3564  *                      true - link setting could be set
3565  *                      false - has reached minimum setting
3566  *                                      and no further fallback could be done
3567  */
3568 static bool decide_fallback_link_setting(
3569                 struct dc_link *link,
3570                 struct dc_link_settings initial_link_settings,
3571                 struct dc_link_settings *current_link_setting,
3572                 enum link_training_result training_result)
3573 {
3574         if (!current_link_setting)
3575                 return false;
3576         if (dp_get_link_encoding_format(&initial_link_settings) == DP_128b_132b_ENCODING ||
3577                         link->dc->debug.force_dp2_lt_fallback_method)
3578                 return decide_fallback_link_setting_max_bw_policy(link, &initial_link_settings,
3579                                 current_link_setting, training_result);
3580
3581         switch (training_result) {
3582         case LINK_TRAINING_CR_FAIL_LANE0:
3583         case LINK_TRAINING_CR_FAIL_LANE1:
3584         case LINK_TRAINING_CR_FAIL_LANE23:
3585         case LINK_TRAINING_LQA_FAIL:
3586         {
3587                 if (!reached_minimum_link_rate
3588                                 (current_link_setting->link_rate)) {
3589                         current_link_setting->link_rate =
3590                                 reduce_link_rate(
3591                                         current_link_setting->link_rate);
3592                 } else if (!reached_minimum_lane_count
3593                                 (current_link_setting->lane_count)) {
3594                         current_link_setting->link_rate =
3595                                 initial_link_settings.link_rate;
3596                         if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
3597                                 return false;
3598                         else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
3599                                 current_link_setting->lane_count =
3600                                                 LANE_COUNT_ONE;
3601                         else if (training_result ==
3602                                         LINK_TRAINING_CR_FAIL_LANE23)
3603                                 current_link_setting->lane_count =
3604                                                 LANE_COUNT_TWO;
3605                         else
3606                                 current_link_setting->lane_count =
3607                                         reduce_lane_count(
3608                                         current_link_setting->lane_count);
3609                 } else {
3610                         return false;
3611                 }
3612                 break;
3613         }
3614         case LINK_TRAINING_EQ_FAIL_EQ:
3615         {
3616                 if (!reached_minimum_lane_count
3617                                 (current_link_setting->lane_count)) {
3618                         current_link_setting->lane_count =
3619                                 reduce_lane_count(
3620                                         current_link_setting->lane_count);
3621                 } else if (!reached_minimum_link_rate
3622                                 (current_link_setting->link_rate)) {
3623                         current_link_setting->link_rate =
3624                                 reduce_link_rate(
3625                                         current_link_setting->link_rate);
3626                         current_link_setting->lane_count = initial_link_settings.lane_count;
3627                 } else {
3628                         return false;
3629                 }
3630                 break;
3631         }
3632         case LINK_TRAINING_EQ_FAIL_CR:
3633         {
3634                 if (!reached_minimum_link_rate
3635                                 (current_link_setting->link_rate)) {
3636                         current_link_setting->link_rate =
3637                                 reduce_link_rate(
3638                                         current_link_setting->link_rate);
3639                         current_link_setting->lane_count = initial_link_settings.lane_count;
3640                 } else {
3641                         return false;
3642                 }
3643                 break;
3644         }
3645         default:
3646                 return false;
3647         }
3648         return true;
3649 }
3650
3651 bool dp_validate_mode_timing(
3652         struct dc_link *link,
3653         const struct dc_crtc_timing *timing)
3654 {
3655         uint32_t req_bw;
3656         uint32_t max_bw;
3657
3658         const struct dc_link_settings *link_setting;
3659
3660         /* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
3661         if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
3662                         !link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
3663                         dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
3664                 return false;
3665
3666         /*always DP fail safe mode*/
3667         if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
3668                 timing->h_addressable == (uint32_t) 640 &&
3669                 timing->v_addressable == (uint32_t) 480)
3670                 return true;
3671
3672         link_setting = dc_link_get_link_cap(link);
3673
3674         /* TODO: DYNAMIC_VALIDATION needs to be implemented */
3675         /*if (flags.DYNAMIC_VALIDATION == 1 &&
3676                 link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
3677                 link_setting = &link->verified_link_cap;
3678         */
3679
3680         req_bw = dc_bandwidth_in_kbps_from_timing(timing);
3681         max_bw = dc_link_bandwidth_kbps(link, link_setting);
3682
3683         if (req_bw <= max_bw) {
3684                 /* remember the biggest mode here, during
3685                  * initial link training (to get
3686                  * verified_link_cap), LS sends event about
3687                  * cannot train at reported cap to upper
3688                  * layer and upper layer will re-enumerate modes.
3689                  * this is not necessary if the lower
3690                  * verified_link_cap is enough to drive
3691                  * all the modes */
3692
3693                 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
3694                 /* if (flags.DYNAMIC_VALIDATION == 1)
3695                         dpsst->max_req_bw_for_verified_linkcap = dal_max(
3696                                 dpsst->max_req_bw_for_verified_linkcap, req_bw); */
3697                 return true;
3698         } else
3699                 return false;
3700 }
3701
3702 static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
3703 {
3704         struct dc_link_settings initial_link_setting = {
3705                 LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
3706         struct dc_link_settings current_link_setting =
3707                         initial_link_setting;
3708         uint32_t link_bw;
3709
3710         if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
3711                 return false;
3712
3713         /* search for the minimum link setting that:
3714          * 1. is supported according to the link training result
3715          * 2. could support the b/w requested by the timing
3716          */
3717         while (current_link_setting.link_rate <=
3718                         link->verified_link_cap.link_rate) {
3719                 link_bw = dc_link_bandwidth_kbps(
3720                                 link,
3721                                 &current_link_setting);
3722                 if (req_bw <= link_bw) {
3723                         *link_setting = current_link_setting;
3724                         return true;
3725                 }
3726
3727                 if (current_link_setting.lane_count <
3728                                 link->verified_link_cap.lane_count) {
3729                         current_link_setting.lane_count =
3730                                         increase_lane_count(
3731                                                         current_link_setting.lane_count);
3732                 } else {
3733                         current_link_setting.link_rate =
3734                                         increase_link_rate(link,
3735                                                         current_link_setting.link_rate);
3736                         current_link_setting.lane_count =
3737                                         initial_link_setting.lane_count;
3738                 }
3739         }
3740
3741         return false;
3742 }
3743
3744 bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
3745 {
3746         struct dc_link_settings initial_link_setting;
3747         struct dc_link_settings current_link_setting;
3748         uint32_t link_bw;
3749
3750         /*
3751          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
3752          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
3753          */
3754         if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 ||
3755                         link->dpcd_caps.edp_supported_link_rates_count == 0) {
3756                 *link_setting = link->verified_link_cap;
3757                 return true;
3758         }
3759
3760         memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3761         initial_link_setting.lane_count = LANE_COUNT_ONE;
3762         initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
3763         initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3764         initial_link_setting.use_link_rate_set = true;
3765         initial_link_setting.link_rate_set = 0;
3766         current_link_setting = initial_link_setting;
3767
3768         /* search for the minimum link setting that:
3769          * 1. is supported according to the link training result
3770          * 2. could support the b/w requested by the timing
3771          */
3772         while (current_link_setting.link_rate <=
3773                         link->verified_link_cap.link_rate) {
3774                 link_bw = dc_link_bandwidth_kbps(
3775                                 link,
3776                                 &current_link_setting);
3777                 if (req_bw <= link_bw) {
3778                         *link_setting = current_link_setting;
3779                         return true;
3780                 }
3781
3782                 if (current_link_setting.lane_count <
3783                                 link->verified_link_cap.lane_count) {
3784                         current_link_setting.lane_count =
3785                                         increase_lane_count(
3786                                                         current_link_setting.lane_count);
3787                 } else {
3788                         if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
3789                                 current_link_setting.link_rate_set++;
3790                                 current_link_setting.link_rate =
3791                                         link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3792                                 current_link_setting.lane_count =
3793                                                                         initial_link_setting.lane_count;
3794                         } else
3795                                 break;
3796                 }
3797         }
3798         return false;
3799 }
3800
3801 static bool decide_edp_link_settings_with_dsc(struct dc_link *link,
3802                 struct dc_link_settings *link_setting,
3803                 uint32_t req_bw,
3804                 enum dc_link_rate max_link_rate)
3805 {
3806         struct dc_link_settings initial_link_setting;
3807         struct dc_link_settings current_link_setting;
3808         uint32_t link_bw;
3809
3810         unsigned int policy = 0;
3811
3812         policy = link->ctx->dc->debug.force_dsc_edp_policy;
3813         if (max_link_rate == LINK_RATE_UNKNOWN)
3814                 max_link_rate = link->verified_link_cap.link_rate;
3815         /*
3816          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
3817          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
3818          */
3819         if ((link->dpcd_caps.dpcd_rev.raw < DPCD_REV_13 ||
3820                         link->dpcd_caps.edp_supported_link_rates_count == 0)) {
3821                 /* for DSC enabled case, we search for minimum lane count */
3822                 memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3823                 initial_link_setting.lane_count = LANE_COUNT_ONE;
3824                 initial_link_setting.link_rate = LINK_RATE_LOW;
3825                 initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3826                 initial_link_setting.use_link_rate_set = false;
3827                 initial_link_setting.link_rate_set = 0;
3828                 current_link_setting = initial_link_setting;
3829                 if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
3830                         return false;
3831
3832                 /* search for the minimum link setting that:
3833                  * 1. is supported according to the link training result
3834                  * 2. could support the b/w requested by the timing
3835                  */
3836                 while (current_link_setting.link_rate <=
3837                                 max_link_rate) {
3838                         link_bw = dc_link_bandwidth_kbps(
3839                                         link,
3840                                         &current_link_setting);
3841                         if (req_bw <= link_bw) {
3842                                 *link_setting = current_link_setting;
3843                                 return true;
3844                         }
3845                         if (policy) {
3846                                 /* minimize lane */
3847                                 if (current_link_setting.link_rate < max_link_rate) {
3848                                         current_link_setting.link_rate =
3849                                                         increase_link_rate(link,
3850                                                                         current_link_setting.link_rate);
3851                                 } else {
3852                                         if (current_link_setting.lane_count <
3853                                                                         link->verified_link_cap.lane_count) {
3854                                                 current_link_setting.lane_count =
3855                                                                 increase_lane_count(
3856                                                                                 current_link_setting.lane_count);
3857                                                 current_link_setting.link_rate = initial_link_setting.link_rate;
3858                                         } else
3859                                                 break;
3860                                 }
3861                         } else {
3862                                 /* minimize link rate */
3863                                 if (current_link_setting.lane_count <
3864                                                 link->verified_link_cap.lane_count) {
3865                                         current_link_setting.lane_count =
3866                                                         increase_lane_count(
3867                                                                         current_link_setting.lane_count);
3868                                 } else {
3869                                         current_link_setting.link_rate =
3870                                                         increase_link_rate(link,
3871                                                                         current_link_setting.link_rate);
3872                                         current_link_setting.lane_count =
3873                                                         initial_link_setting.lane_count;
3874                                 }
3875                         }
3876                 }
3877                 return false;
3878         }
3879
3880         /* if optimize edp link is supported */
3881         memset(&initial_link_setting, 0, sizeof(initial_link_setting));
3882         initial_link_setting.lane_count = LANE_COUNT_ONE;
3883         initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
3884         initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
3885         initial_link_setting.use_link_rate_set = true;
3886         initial_link_setting.link_rate_set = 0;
3887         current_link_setting = initial_link_setting;
3888
3889         /* search for the minimum link setting that:
3890          * 1. is supported according to the link training result
3891          * 2. could support the b/w requested by the timing
3892          */
3893         while (current_link_setting.link_rate <=
3894                         max_link_rate) {
3895                 link_bw = dc_link_bandwidth_kbps(
3896                                 link,
3897                                 &current_link_setting);
3898                 if (req_bw <= link_bw) {
3899                         *link_setting = current_link_setting;
3900                         return true;
3901                 }
3902                 if (policy) {
3903                         /* minimize lane */
3904                         if (current_link_setting.link_rate_set <
3905                                         link->dpcd_caps.edp_supported_link_rates_count
3906                                         && current_link_setting.link_rate < max_link_rate) {
3907                                 current_link_setting.link_rate_set++;
3908                                 current_link_setting.link_rate =
3909                                         link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3910                         } else {
3911                                 if (current_link_setting.lane_count < link->verified_link_cap.lane_count) {
3912                                         current_link_setting.lane_count =
3913                                                         increase_lane_count(
3914                                                                         current_link_setting.lane_count);
3915                                         current_link_setting.link_rate_set = initial_link_setting.link_rate_set;
3916                                         current_link_setting.link_rate =
3917                                                 link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3918                                 } else
3919                                         break;
3920                         }
3921                 } else {
3922                         /* minimize link rate */
3923                         if (current_link_setting.lane_count <
3924                                         link->verified_link_cap.lane_count) {
3925                                 current_link_setting.lane_count =
3926                                                 increase_lane_count(
3927                                                                 current_link_setting.lane_count);
3928                         } else {
3929                                 if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
3930                                         current_link_setting.link_rate_set++;
3931                                         current_link_setting.link_rate =
3932                                                 link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
3933                                         current_link_setting.lane_count =
3934                                                 initial_link_setting.lane_count;
3935                                 } else
3936                                         break;
3937                         }
3938                 }
3939         }
3940         return false;
3941 }
3942
3943 static bool decide_mst_link_settings(const struct dc_link *link, struct dc_link_settings *link_setting)
3944 {
3945         *link_setting = link->verified_link_cap;
3946         return true;
3947 }
3948
3949 void decide_link_settings(struct dc_stream_state *stream,
3950         struct dc_link_settings *link_setting)
3951 {
3952         struct dc_link *link;
3953         uint32_t req_bw;
3954
3955         req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
3956
3957         link = stream->link;
3958
3959         /* if preferred is specified through AMDDP, use it, if it's enough
3960          * to drive the mode
3961          */
3962         if (link->preferred_link_setting.lane_count !=
3963                         LANE_COUNT_UNKNOWN &&
3964                         link->preferred_link_setting.link_rate !=
3965                                         LINK_RATE_UNKNOWN) {
3966                 *link_setting =  link->preferred_link_setting;
3967                 return;
3968         }
3969
3970         /* MST doesn't perform link training for now
3971          * TODO: add MST specific link training routine
3972          */
3973         if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
3974                 if (decide_mst_link_settings(link, link_setting))
3975                         return;
3976         } else if (link->connector_signal == SIGNAL_TYPE_EDP) {
3977                 /* enable edp link optimization for DSC eDP case */
3978                 if (stream->timing.flags.DSC) {
3979                         enum dc_link_rate max_link_rate = LINK_RATE_UNKNOWN;
3980
3981                         if (link->ctx->dc->debug.force_dsc_edp_policy) {
3982                                 /* calculate link max link rate cap*/
3983                                 struct dc_link_settings tmp_link_setting;
3984                                 struct dc_crtc_timing tmp_timing = stream->timing;
3985                                 uint32_t orig_req_bw;
3986
3987                                 tmp_link_setting.link_rate = LINK_RATE_UNKNOWN;
3988                                 tmp_timing.flags.DSC = 0;
3989                                 orig_req_bw = dc_bandwidth_in_kbps_from_timing(&tmp_timing);
3990                                 decide_edp_link_settings(link, &tmp_link_setting, orig_req_bw);
3991                                 max_link_rate = tmp_link_setting.link_rate;
3992                         }
3993                         if (decide_edp_link_settings_with_dsc(link, link_setting, req_bw, max_link_rate))
3994                                 return;
3995                 } else if (decide_edp_link_settings(link, link_setting, req_bw))
3996                         return;
3997         } else if (decide_dp_link_settings(link, link_setting, req_bw))
3998                 return;
3999
4000         BREAK_TO_DEBUGGER();
4001         ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
4002
4003         *link_setting = link->verified_link_cap;
4004 }
4005
4006 /*************************Short Pulse IRQ***************************/
4007 bool dc_link_dp_allow_hpd_rx_irq(const struct dc_link *link)
4008 {
4009         /*
4010          * Don't handle RX IRQ unless one of following is met:
4011          * 1) The link is established (cur_link_settings != unknown)
4012          * 2) We know we're dealing with a branch device, SST or MST
4013          */
4014
4015         if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
4016                 is_dp_branch_device(link))
4017                 return true;
4018
4019         return false;
4020 }
4021
4022 static bool handle_hpd_irq_psr_sink(struct dc_link *link)
4023 {
4024         union dpcd_psr_configuration psr_configuration;
4025
4026         if (!link->psr_settings.psr_feature_enabled)
4027                 return false;
4028
4029         dm_helpers_dp_read_dpcd(
4030                 link->ctx,
4031                 link,
4032                 368,/*DpcdAddress_PSR_Enable_Cfg*/
4033                 &psr_configuration.raw,
4034                 sizeof(psr_configuration.raw));
4035
4036         if (psr_configuration.bits.ENABLE) {
4037                 unsigned char dpcdbuf[3] = {0};
4038                 union psr_error_status psr_error_status;
4039                 union psr_sink_psr_status psr_sink_psr_status;
4040
4041                 dm_helpers_dp_read_dpcd(
4042                         link->ctx,
4043                         link,
4044                         0x2006, /*DpcdAddress_PSR_Error_Status*/
4045                         (unsigned char *) dpcdbuf,
4046                         sizeof(dpcdbuf));
4047
4048                 /*DPCD 2006h   ERROR STATUS*/
4049                 psr_error_status.raw = dpcdbuf[0];
4050                 /*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
4051                 psr_sink_psr_status.raw = dpcdbuf[2];
4052
4053                 if (psr_error_status.bits.LINK_CRC_ERROR ||
4054                                 psr_error_status.bits.RFB_STORAGE_ERROR ||
4055                                 psr_error_status.bits.VSC_SDP_ERROR) {
4056                         bool allow_active;
4057
4058                         /* Acknowledge and clear error bits */
4059                         dm_helpers_dp_write_dpcd(
4060                                 link->ctx,
4061                                 link,
4062                                 8198,/*DpcdAddress_PSR_Error_Status*/
4063                                 &psr_error_status.raw,
4064                                 sizeof(psr_error_status.raw));
4065
4066                         /* PSR error, disable and re-enable PSR */
4067                         if (link->psr_settings.psr_allow_active) {
4068                                 allow_active = false;
4069                                 dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
4070                                 allow_active = true;
4071                                 dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL);
4072                         }
4073
4074                         return true;
4075                 } else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
4076                                 PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
4077                         /* No error is detect, PSR is active.
4078                          * We should return with IRQ_HPD handled without
4079                          * checking for loss of sync since PSR would have
4080                          * powered down main link.
4081                          */
4082                         return true;
4083                 }
4084         }
4085         return false;
4086 }
4087
4088 static void dp_test_send_link_training(struct dc_link *link)
4089 {
4090         struct dc_link_settings link_settings = {0};
4091
4092         core_link_read_dpcd(
4093                         link,
4094                         DP_TEST_LANE_COUNT,
4095                         (unsigned char *)(&link_settings.lane_count),
4096                         1);
4097         core_link_read_dpcd(
4098                         link,
4099                         DP_TEST_LINK_RATE,
4100                         (unsigned char *)(&link_settings.link_rate),
4101                         1);
4102
4103         /* Set preferred link settings */
4104         link->verified_link_cap.lane_count = link_settings.lane_count;
4105         link->verified_link_cap.link_rate = link_settings.link_rate;
4106
4107         dp_retrain_link_dp_test(link, &link_settings, false);
4108 }
4109
4110 /* TODO Raven hbr2 compliance eye output is unstable
4111  * (toggling on and off) with debugger break
4112  * This caueses intermittent PHY automation failure
4113  * Need to look into the root cause */
4114 static void dp_test_send_phy_test_pattern(struct dc_link *link)
4115 {
4116         union phy_test_pattern dpcd_test_pattern;
4117         union lane_adjust dpcd_lane_adjustment[2];
4118         unsigned char dpcd_post_cursor_2_adjustment = 0;
4119         unsigned char test_pattern_buffer[
4120                         (DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
4121                         DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
4122         unsigned int test_pattern_size = 0;
4123         enum dp_test_pattern test_pattern;
4124         union lane_adjust dpcd_lane_adjust;
4125         unsigned int lane;
4126         struct link_training_settings link_training_settings;
4127
4128         dpcd_test_pattern.raw = 0;
4129         memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
4130         memset(&link_training_settings, 0, sizeof(link_training_settings));
4131
4132         /* get phy test pattern and pattern parameters from DP receiver */
4133         core_link_read_dpcd(
4134                         link,
4135                         DP_PHY_TEST_PATTERN,
4136                         &dpcd_test_pattern.raw,
4137                         sizeof(dpcd_test_pattern));
4138         core_link_read_dpcd(
4139                         link,
4140                         DP_ADJUST_REQUEST_LANE0_1,
4141                         &dpcd_lane_adjustment[0].raw,
4142                         sizeof(dpcd_lane_adjustment));
4143
4144         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
4145                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
4146                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT)
4147                 dp_fixed_vs_pe_read_lane_adjust(
4148                                 link,
4149                                 link_training_settings.dpcd_lane_settings);
4150
4151         /*get post cursor 2 parameters
4152          * For DP 1.1a or eariler, this DPCD register's value is 0
4153          * For DP 1.2 or later:
4154          * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
4155          * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
4156          */
4157         core_link_read_dpcd(
4158                         link,
4159                         DP_ADJUST_REQUEST_POST_CURSOR2,
4160                         &dpcd_post_cursor_2_adjustment,
4161                         sizeof(dpcd_post_cursor_2_adjustment));
4162
4163         /* translate request */
4164         switch (dpcd_test_pattern.bits.PATTERN) {
4165         case PHY_TEST_PATTERN_D10_2:
4166                 test_pattern = DP_TEST_PATTERN_D102;
4167                 break;
4168         case PHY_TEST_PATTERN_SYMBOL_ERROR:
4169                 test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
4170                 break;
4171         case PHY_TEST_PATTERN_PRBS7:
4172                 test_pattern = DP_TEST_PATTERN_PRBS7;
4173                 break;
4174         case PHY_TEST_PATTERN_80BIT_CUSTOM:
4175                 test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
4176                 break;
4177         case PHY_TEST_PATTERN_CP2520_1:
4178                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
4179                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
4180                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
4181                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
4182                 break;
4183         case PHY_TEST_PATTERN_CP2520_2:
4184                 /* CP2520 pattern is unstable, temporarily use TPS4 instead */
4185                 test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
4186                                 DP_TEST_PATTERN_TRAINING_PATTERN4 :
4187                                 DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
4188                 break;
4189         case PHY_TEST_PATTERN_CP2520_3:
4190                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
4191                 break;
4192         case PHY_TEST_PATTERN_128b_132b_TPS1:
4193                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
4194                 break;
4195         case PHY_TEST_PATTERN_128b_132b_TPS2:
4196                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS2;
4197                 break;
4198         case PHY_TEST_PATTERN_PRBS9:
4199                 test_pattern = DP_TEST_PATTERN_PRBS9;
4200                 break;
4201         case PHY_TEST_PATTERN_PRBS11:
4202                 test_pattern = DP_TEST_PATTERN_PRBS11;
4203                 break;
4204         case PHY_TEST_PATTERN_PRBS15:
4205                 test_pattern = DP_TEST_PATTERN_PRBS15;
4206                 break;
4207         case PHY_TEST_PATTERN_PRBS23:
4208                 test_pattern = DP_TEST_PATTERN_PRBS23;
4209                 break;
4210         case PHY_TEST_PATTERN_PRBS31:
4211                 test_pattern = DP_TEST_PATTERN_PRBS31;
4212                 break;
4213         case PHY_TEST_PATTERN_264BIT_CUSTOM:
4214                 test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
4215                 break;
4216         case PHY_TEST_PATTERN_SQUARE_PULSE:
4217                 test_pattern = DP_TEST_PATTERN_SQUARE_PULSE;
4218                 break;
4219         default:
4220                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
4221         break;
4222         }
4223
4224         if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
4225                 test_pattern_size = (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
4226                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0) + 1;
4227                 core_link_read_dpcd(
4228                                 link,
4229                                 DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
4230                                 test_pattern_buffer,
4231                                 test_pattern_size);
4232         }
4233
4234         if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE) {
4235                 test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
4236                 core_link_read_dpcd(
4237                                 link,
4238                                 DP_PHY_SQUARE_PATTERN,
4239                                 test_pattern_buffer,
4240                                 test_pattern_size);
4241         }
4242
4243         if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) {
4244                 test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256-
4245                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1;
4246                 core_link_read_dpcd(
4247                                 link,
4248                                 DP_TEST_264BIT_CUSTOM_PATTERN_7_0,
4249                                 test_pattern_buffer,
4250                                 test_pattern_size);
4251         }
4252
4253         /* prepare link training settings */
4254         link_training_settings.link_settings = link->cur_link_settings;
4255
4256         for (lane = 0; lane <
4257                 (unsigned int)(link->cur_link_settings.lane_count);
4258                 lane++) {
4259                 dpcd_lane_adjust.raw =
4260                         get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
4261                 if (dp_get_link_encoding_format(&link->cur_link_settings) ==
4262                                 DP_8b_10b_ENCODING) {
4263                         link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
4264                                 (enum dc_voltage_swing)
4265                                 (dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
4266                         link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
4267                                 (enum dc_pre_emphasis)
4268                                 (dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
4269                         link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
4270                                 (enum dc_post_cursor2)
4271                                 ((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
4272                 } else if (dp_get_link_encoding_format(&link->cur_link_settings) ==
4273                                 DP_128b_132b_ENCODING) {
4274                         link_training_settings.hw_lane_settings[lane].FFE_PRESET.raw =
4275                                         dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
4276                 }
4277         }
4278
4279         dp_hw_to_dpcd_lane_settings(&link_training_settings,
4280                         link_training_settings.hw_lane_settings,
4281                         link_training_settings.dpcd_lane_settings);
4282         /*Usage: Measure DP physical lane signal
4283          * by DP SI test equipment automatically.
4284          * PHY test pattern request is generated by equipment via HPD interrupt.
4285          * HPD needs to be active all the time. HPD should be active
4286          * all the time. Do not touch it.
4287          * forward request to DS
4288          */
4289         dc_link_dp_set_test_pattern(
4290                 link,
4291                 test_pattern,
4292                 DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
4293                 &link_training_settings,
4294                 test_pattern_buffer,
4295                 test_pattern_size);
4296 }
4297
4298 static void dp_test_send_link_test_pattern(struct dc_link *link)
4299 {
4300         union link_test_pattern dpcd_test_pattern;
4301         union test_misc dpcd_test_params;
4302         enum dp_test_pattern test_pattern;
4303         enum dp_test_pattern_color_space test_pattern_color_space =
4304                         DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED;
4305         enum dc_color_depth requestColorDepth = COLOR_DEPTH_UNDEFINED;
4306         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
4307         struct pipe_ctx *pipe_ctx = NULL;
4308         int i;
4309
4310         memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
4311         memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
4312
4313         for (i = 0; i < MAX_PIPES; i++) {
4314                 if (pipes[i].stream == NULL)
4315                         continue;
4316
4317                 if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
4318                         pipe_ctx = &pipes[i];
4319                         break;
4320                 }
4321         }
4322
4323         if (pipe_ctx == NULL)
4324                 return;
4325
4326         /* get link test pattern and pattern parameters */
4327         core_link_read_dpcd(
4328                         link,
4329                         DP_TEST_PATTERN,
4330                         &dpcd_test_pattern.raw,
4331                         sizeof(dpcd_test_pattern));
4332         core_link_read_dpcd(
4333                         link,
4334                         DP_TEST_MISC0,
4335                         &dpcd_test_params.raw,
4336                         sizeof(dpcd_test_params));
4337
4338         switch (dpcd_test_pattern.bits.PATTERN) {
4339         case LINK_TEST_PATTERN_COLOR_RAMP:
4340                 test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
4341         break;
4342         case LINK_TEST_PATTERN_VERTICAL_BARS:
4343                 test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
4344         break; /* black and white */
4345         case LINK_TEST_PATTERN_COLOR_SQUARES:
4346                 test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
4347                                 TEST_DYN_RANGE_VESA ?
4348                                 DP_TEST_PATTERN_COLOR_SQUARES :
4349                                 DP_TEST_PATTERN_COLOR_SQUARES_CEA);
4350         break;
4351         default:
4352                 test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
4353         break;
4354         }
4355
4356         if (dpcd_test_params.bits.CLR_FORMAT == 0)
4357                 test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_RGB;
4358         else
4359                 test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ?
4360                                 DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 :
4361                                 DP_TEST_PATTERN_COLOR_SPACE_YCBCR601;
4362
4363         switch (dpcd_test_params.bits.BPC) {
4364         case 0: // 6 bits
4365                 requestColorDepth = COLOR_DEPTH_666;
4366                 break;
4367         case 1: // 8 bits
4368                 requestColorDepth = COLOR_DEPTH_888;
4369                 break;
4370         case 2: // 10 bits
4371                 requestColorDepth = COLOR_DEPTH_101010;
4372                 break;
4373         case 3: // 12 bits
4374                 requestColorDepth = COLOR_DEPTH_121212;
4375                 break;
4376         default:
4377                 break;
4378         }
4379
4380         switch (dpcd_test_params.bits.CLR_FORMAT) {
4381         case 0:
4382                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB;
4383                 break;
4384         case 1:
4385                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR422;
4386                 break;
4387         case 2:
4388                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_YCBCR444;
4389                 break;
4390         default:
4391                 pipe_ctx->stream->timing.pixel_encoding = PIXEL_ENCODING_RGB;
4392                 break;
4393         }
4394
4395
4396         if (requestColorDepth != COLOR_DEPTH_UNDEFINED
4397                         && pipe_ctx->stream->timing.display_color_depth != requestColorDepth) {
4398                 DC_LOG_DEBUG("%s: original bpc %d, changing to %d\n",
4399                                 __func__,
4400                                 pipe_ctx->stream->timing.display_color_depth,
4401                                 requestColorDepth);
4402                 pipe_ctx->stream->timing.display_color_depth = requestColorDepth;
4403         }
4404
4405         dp_update_dsc_config(pipe_ctx);
4406
4407         dc_link_dp_set_test_pattern(
4408                         link,
4409                         test_pattern,
4410                         test_pattern_color_space,
4411                         NULL,
4412                         NULL,
4413                         0);
4414 }
4415
4416 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
4417 {
4418         union audio_test_mode            dpcd_test_mode = {0};
4419         struct audio_test_pattern_type   dpcd_pattern_type = {0};
4420         union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
4421         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
4422
4423         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
4424         struct pipe_ctx *pipe_ctx = &pipes[0];
4425         unsigned int channel_count;
4426         unsigned int channel = 0;
4427         unsigned int modes = 0;
4428         unsigned int sampling_rate_in_hz = 0;
4429
4430         // get audio test mode and test pattern parameters
4431         core_link_read_dpcd(
4432                 link,
4433                 DP_TEST_AUDIO_MODE,
4434                 &dpcd_test_mode.raw,
4435                 sizeof(dpcd_test_mode));
4436
4437         core_link_read_dpcd(
4438                 link,
4439                 DP_TEST_AUDIO_PATTERN_TYPE,
4440                 &dpcd_pattern_type.value,
4441                 sizeof(dpcd_pattern_type));
4442
4443         channel_count = dpcd_test_mode.bits.channel_count + 1;
4444
4445         // read pattern periods for requested channels when sawTooth pattern is requested
4446         if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
4447                         dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
4448
4449                 test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
4450                                 DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
4451                 // read period for each channel
4452                 for (channel = 0; channel < channel_count; channel++) {
4453                         core_link_read_dpcd(
4454                                                         link,
4455                                                         DP_TEST_AUDIO_PERIOD_CH1 + channel,
4456                                                         &dpcd_pattern_period[channel].raw,
4457                                                         sizeof(dpcd_pattern_period[channel]));
4458                 }
4459         }
4460
4461         // translate sampling rate
4462         switch (dpcd_test_mode.bits.sampling_rate) {
4463         case AUDIO_SAMPLING_RATE_32KHZ:
4464                 sampling_rate_in_hz = 32000;
4465                 break;
4466         case AUDIO_SAMPLING_RATE_44_1KHZ:
4467                 sampling_rate_in_hz = 44100;
4468                 break;
4469         case AUDIO_SAMPLING_RATE_48KHZ:
4470                 sampling_rate_in_hz = 48000;
4471                 break;
4472         case AUDIO_SAMPLING_RATE_88_2KHZ:
4473                 sampling_rate_in_hz = 88200;
4474                 break;
4475         case AUDIO_SAMPLING_RATE_96KHZ:
4476                 sampling_rate_in_hz = 96000;
4477                 break;
4478         case AUDIO_SAMPLING_RATE_176_4KHZ:
4479                 sampling_rate_in_hz = 176400;
4480                 break;
4481         case AUDIO_SAMPLING_RATE_192KHZ:
4482                 sampling_rate_in_hz = 192000;
4483                 break;
4484         default:
4485                 sampling_rate_in_hz = 0;
4486                 break;
4487         }
4488
4489         link->audio_test_data.flags.test_requested = 1;
4490         link->audio_test_data.flags.disable_video = disable_video;
4491         link->audio_test_data.sampling_rate = sampling_rate_in_hz;
4492         link->audio_test_data.channel_count = channel_count;
4493         link->audio_test_data.pattern_type = test_pattern;
4494
4495         if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
4496                 for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
4497                         link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
4498                 }
4499         }
4500 }
4501
4502 void dc_link_dp_handle_automated_test(struct dc_link *link)
4503 {
4504         union test_request test_request;
4505         union test_response test_response;
4506
4507         memset(&test_request, 0, sizeof(test_request));
4508         memset(&test_response, 0, sizeof(test_response));
4509
4510         core_link_read_dpcd(
4511                 link,
4512                 DP_TEST_REQUEST,
4513                 &test_request.raw,
4514                 sizeof(union test_request));
4515         if (test_request.bits.LINK_TRAINING) {
4516                 /* ACK first to let DP RX test box monitor LT sequence */
4517                 test_response.bits.ACK = 1;
4518                 core_link_write_dpcd(
4519                         link,
4520                         DP_TEST_RESPONSE,
4521                         &test_response.raw,
4522                         sizeof(test_response));
4523                 dp_test_send_link_training(link);
4524                 /* no acknowledge request is needed again */
4525                 test_response.bits.ACK = 0;
4526         }
4527         if (test_request.bits.LINK_TEST_PATTRN) {
4528                 dp_test_send_link_test_pattern(link);
4529                 test_response.bits.ACK = 1;
4530         }
4531
4532         if (test_request.bits.AUDIO_TEST_PATTERN) {
4533                 dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
4534                 test_response.bits.ACK = 1;
4535         }
4536
4537         if (test_request.bits.PHY_TEST_PATTERN) {
4538                 dp_test_send_phy_test_pattern(link);
4539                 test_response.bits.ACK = 1;
4540         }
4541
4542         /* send request acknowledgment */
4543         if (test_response.bits.ACK)
4544                 core_link_write_dpcd(
4545                         link,
4546                         DP_TEST_RESPONSE,
4547                         &test_response.raw,
4548                         sizeof(test_response));
4549 }
4550
4551 void dc_link_dp_handle_link_loss(struct dc_link *link)
4552 {
4553         int i;
4554         struct pipe_ctx *pipe_ctx;
4555
4556         for (i = 0; i < MAX_PIPES; i++) {
4557                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4558                 if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
4559                         break;
4560         }
4561
4562         if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
4563                 return;
4564
4565         for (i = 0; i < MAX_PIPES; i++) {
4566                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4567                 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
4568                                 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
4569                         core_link_disable_stream(pipe_ctx);
4570                 }
4571         }
4572
4573         for (i = 0; i < MAX_PIPES; i++) {
4574                 pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
4575                 if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
4576                                 pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe) {
4577                         core_link_enable_stream(link->dc->current_state, pipe_ctx);
4578                 }
4579         }
4580 }
4581
4582 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss,
4583                                                         bool defer_handling, bool *has_left_work)
4584 {
4585         union hpd_irq_data hpd_irq_dpcd_data = {0};
4586         union device_service_irq device_service_clear = {0};
4587         enum dc_status result;
4588         bool status = false;
4589
4590         if (out_link_loss)
4591                 *out_link_loss = false;
4592
4593         if (has_left_work)
4594                 *has_left_work = false;
4595         /* For use cases related to down stream connection status change,
4596          * PSR and device auto test, refer to function handle_sst_hpd_irq
4597          * in DAL2.1*/
4598
4599         DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
4600                 __func__, link->link_index);
4601
4602
4603          /* All the "handle_hpd_irq_xxx()" methods
4604                  * should be called only after
4605                  * dal_dpsst_ls_read_hpd_irq_data
4606                  * Order of calls is important too
4607                  */
4608         result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
4609         if (out_hpd_irq_dpcd_data)
4610                 *out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
4611
4612         if (result != DC_OK) {
4613                 DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
4614                         __func__);
4615                 return false;
4616         }
4617
4618         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
4619                 device_service_clear.bits.AUTOMATED_TEST = 1;
4620                 core_link_write_dpcd(
4621                         link,
4622                         DP_DEVICE_SERVICE_IRQ_VECTOR,
4623                         &device_service_clear.raw,
4624                         sizeof(device_service_clear.raw));
4625                 device_service_clear.raw = 0;
4626                 if (defer_handling && has_left_work)
4627                         *has_left_work = true;
4628                 else
4629                         dc_link_dp_handle_automated_test(link);
4630                 return false;
4631         }
4632
4633         if (!dc_link_dp_allow_hpd_rx_irq(link)) {
4634                 DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
4635                         __func__, link->link_index);
4636                 return false;
4637         }
4638
4639         if (handle_hpd_irq_psr_sink(link))
4640                 /* PSR-related error was detected and handled */
4641                 return true;
4642
4643         /* If PSR-related error handled, Main link may be off,
4644          * so do not handle as a normal sink status change interrupt.
4645          */
4646
4647         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY) {
4648                 if (defer_handling && has_left_work)
4649                         *has_left_work = true;
4650                 return true;
4651         }
4652
4653         /* check if we have MST msg and return since we poll for it */
4654         if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY) {
4655                 if (defer_handling && has_left_work)
4656                         *has_left_work = true;
4657                 return false;
4658         }
4659
4660         /* For now we only handle 'Downstream port status' case.
4661          * If we got sink count changed it means
4662          * Downstream port status changed,
4663          * then DM should call DC to do the detection.
4664          * NOTE: Do not handle link loss on eDP since it is internal link*/
4665         if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
4666                 hpd_rx_irq_check_link_loss_status(
4667                         link,
4668                         &hpd_irq_dpcd_data)) {
4669                 /* Connectivity log: link loss */
4670                 CONN_DATA_LINK_LOSS(link,
4671                                         hpd_irq_dpcd_data.raw,
4672                                         sizeof(hpd_irq_dpcd_data),
4673                                         "Status: ");
4674
4675                 if (defer_handling && has_left_work)
4676                         *has_left_work = true;
4677                 else
4678                         dc_link_dp_handle_link_loss(link);
4679
4680                 status = false;
4681                 if (out_link_loss)
4682                         *out_link_loss = true;
4683
4684                 dp_trace_link_loss_increment(link);
4685         }
4686
4687         if (link->type == dc_connection_sst_branch &&
4688                 hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
4689                         != link->dpcd_sink_count)
4690                 status = true;
4691
4692         /* reasons for HPD RX:
4693          * 1. Link Loss - ie Re-train the Link
4694          * 2. MST sideband message
4695          * 3. Automated Test - ie. Internal Commit
4696          * 4. CP (copy protection) - (not interesting for DM???)
4697          * 5. DRR
4698          * 6. Downstream Port status changed
4699          * -ie. Detect - this the only one
4700          * which is interesting for DM because
4701          * it must call dc_link_detect.
4702          */
4703         return status;
4704 }
4705
4706 /*query dpcd for version and mst cap addresses*/
4707 bool is_mst_supported(struct dc_link *link)
4708 {
4709         bool mst          = false;
4710         enum dc_status st = DC_OK;
4711         union dpcd_rev rev;
4712         union mstm_cap cap;
4713
4714         if (link->preferred_training_settings.mst_enable &&
4715                 *link->preferred_training_settings.mst_enable == false) {
4716                 return false;
4717         }
4718
4719         rev.raw  = 0;
4720         cap.raw  = 0;
4721
4722         st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
4723                         sizeof(rev));
4724
4725         if (st == DC_OK && rev.raw >= DPCD_REV_12) {
4726
4727                 st = core_link_read_dpcd(link, DP_MSTM_CAP,
4728                                 &cap.raw, sizeof(cap));
4729                 if (st == DC_OK && cap.bits.MST_CAP == 1)
4730                         mst = true;
4731         }
4732         return mst;
4733
4734 }
4735
4736 bool is_dp_active_dongle(const struct dc_link *link)
4737 {
4738         return (link->dpcd_caps.dongle_type >= DISPLAY_DONGLE_DP_VGA_CONVERTER) &&
4739                                 (link->dpcd_caps.dongle_type <= DISPLAY_DONGLE_DP_HDMI_CONVERTER);
4740 }
4741
4742 bool is_dp_branch_device(const struct dc_link *link)
4743 {
4744         return link->dpcd_caps.is_branch_dev;
4745 }
4746
4747 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
4748 {
4749         switch (bpc) {
4750         case DOWN_STREAM_MAX_8BPC:
4751                 return 8;
4752         case DOWN_STREAM_MAX_10BPC:
4753                 return 10;
4754         case DOWN_STREAM_MAX_12BPC:
4755                 return 12;
4756         case DOWN_STREAM_MAX_16BPC:
4757                 return 16;
4758         default:
4759                 break;
4760         }
4761
4762         return -1;
4763 }
4764
4765 #if defined(CONFIG_DRM_AMD_DC_DCN)
4766 uint32_t dc_link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw)
4767 {
4768         switch (bw) {
4769         case 0b001:
4770                 return 9000000;
4771         case 0b010:
4772                 return 18000000;
4773         case 0b011:
4774                 return 24000000;
4775         case 0b100:
4776                 return 32000000;
4777         case 0b101:
4778                 return 40000000;
4779         case 0b110:
4780                 return 48000000;
4781         }
4782
4783         return 0;
4784 }
4785
4786 /*
4787  * Return PCON's post FRL link training supported BW if its non-zero, otherwise return max_supported_frl_bw.
4788  */
4789 static uint32_t intersect_frl_link_bw_support(
4790         const uint32_t max_supported_frl_bw_in_kbps,
4791         const union hdmi_encoded_link_bw hdmi_encoded_link_bw)
4792 {
4793         uint32_t supported_bw_in_kbps = max_supported_frl_bw_in_kbps;
4794
4795         // HDMI_ENCODED_LINK_BW bits are only valid if HDMI Link Configuration bit is 1 (FRL mode)
4796         if (hdmi_encoded_link_bw.bits.FRL_MODE) {
4797                 if (hdmi_encoded_link_bw.bits.BW_48Gbps)
4798                         supported_bw_in_kbps = 48000000;
4799                 else if (hdmi_encoded_link_bw.bits.BW_40Gbps)
4800                         supported_bw_in_kbps = 40000000;
4801                 else if (hdmi_encoded_link_bw.bits.BW_32Gbps)
4802                         supported_bw_in_kbps = 32000000;
4803                 else if (hdmi_encoded_link_bw.bits.BW_24Gbps)
4804                         supported_bw_in_kbps = 24000000;
4805                 else if (hdmi_encoded_link_bw.bits.BW_18Gbps)
4806                         supported_bw_in_kbps = 18000000;
4807                 else if (hdmi_encoded_link_bw.bits.BW_9Gbps)
4808                         supported_bw_in_kbps = 9000000;
4809         }
4810
4811         return supported_bw_in_kbps;
4812 }
4813 #endif
4814
4815 static void read_dp_device_vendor_id(struct dc_link *link)
4816 {
4817         struct dp_device_vendor_id dp_id;
4818
4819         /* read IEEE branch device id */
4820         core_link_read_dpcd(
4821                 link,
4822                 DP_BRANCH_OUI,
4823                 (uint8_t *)&dp_id,
4824                 sizeof(dp_id));
4825
4826         link->dpcd_caps.branch_dev_id =
4827                 (dp_id.ieee_oui[0] << 16) +
4828                 (dp_id.ieee_oui[1] << 8) +
4829                 dp_id.ieee_oui[2];
4830
4831         memmove(
4832                 link->dpcd_caps.branch_dev_name,
4833                 dp_id.ieee_device_id,
4834                 sizeof(dp_id.ieee_device_id));
4835 }
4836
4837
4838
4839 static void get_active_converter_info(
4840         uint8_t data, struct dc_link *link)
4841 {
4842         union dp_downstream_port_present ds_port = { .byte = data };
4843         memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
4844
4845         /* decode converter info*/
4846         if (!ds_port.fields.PORT_PRESENT) {
4847                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4848                 ddc_service_set_dongle_type(link->ddc,
4849                                 link->dpcd_caps.dongle_type);
4850                 link->dpcd_caps.is_branch_dev = false;
4851                 return;
4852         }
4853
4854         /* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
4855         link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
4856
4857         switch (ds_port.fields.PORT_TYPE) {
4858         case DOWNSTREAM_VGA:
4859                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
4860                 break;
4861         case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
4862                 /* At this point we don't know is it DVI or HDMI or DP++,
4863                  * assume DVI.*/
4864                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
4865                 break;
4866         default:
4867                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4868                 break;
4869         }
4870
4871         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
4872                 uint8_t det_caps[16]; /* CTS 4.2.2.7 expects source to read Detailed Capabilities Info : 00080h-0008F.*/
4873                 union dwnstream_port_caps_byte0 *port_caps =
4874                         (union dwnstream_port_caps_byte0 *)det_caps;
4875                 if (core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
4876                                 det_caps, sizeof(det_caps)) == DC_OK) {
4877
4878                         switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
4879                         /*Handle DP case as DONGLE_NONE*/
4880                         case DOWN_STREAM_DETAILED_DP:
4881                                 link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
4882                                 break;
4883                         case DOWN_STREAM_DETAILED_VGA:
4884                                 link->dpcd_caps.dongle_type =
4885                                         DISPLAY_DONGLE_DP_VGA_CONVERTER;
4886                                 break;
4887                         case DOWN_STREAM_DETAILED_DVI:
4888                                 link->dpcd_caps.dongle_type =
4889                                         DISPLAY_DONGLE_DP_DVI_CONVERTER;
4890                                 break;
4891                         case DOWN_STREAM_DETAILED_HDMI:
4892                         case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
4893                                 /*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
4894                                 link->dpcd_caps.dongle_type =
4895                                         DISPLAY_DONGLE_DP_HDMI_CONVERTER;
4896
4897                                 link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
4898                                 if (ds_port.fields.DETAILED_CAPS) {
4899
4900                                         union dwnstream_port_caps_byte3_hdmi
4901                                                 hdmi_caps = {.raw = det_caps[3] };
4902                                         union dwnstream_port_caps_byte2
4903                                                 hdmi_color_caps = {.raw = det_caps[2] };
4904                                         link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz =
4905                                                 det_caps[1] * 2500;
4906
4907                                         link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
4908                                                 hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
4909                                         /*YCBCR capability only for HDMI case*/
4910                                         if (port_caps->bits.DWN_STRM_PORTX_TYPE
4911                                                         == DOWN_STREAM_DETAILED_HDMI) {
4912                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
4913                                                                 hdmi_caps.bits.YCrCr422_PASS_THROUGH;
4914                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
4915                                                                 hdmi_caps.bits.YCrCr420_PASS_THROUGH;
4916                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
4917                                                                 hdmi_caps.bits.YCrCr422_CONVERSION;
4918                                                 link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
4919                                                                 hdmi_caps.bits.YCrCr420_CONVERSION;
4920                                         }
4921
4922                                         link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
4923                                                 translate_dpcd_max_bpc(
4924                                                         hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
4925
4926 #if defined(CONFIG_DRM_AMD_DC_DCN)
4927                                         if (link->dc->caps.hdmi_frl_pcon_support) {
4928                                                 union hdmi_encoded_link_bw hdmi_encoded_link_bw;
4929
4930                                                 link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps =
4931                                                                 dc_link_bw_kbps_from_raw_frl_link_rate_data(
4932                                                                                 hdmi_color_caps.bits.MAX_ENCODED_LINK_BW_SUPPORT);
4933
4934                                                 // Intersect reported max link bw support with the supported link rate post FRL link training
4935                                                 if (core_link_read_dpcd(link, DP_PCON_HDMI_POST_FRL_STATUS,
4936                                                                 &hdmi_encoded_link_bw.raw, sizeof(hdmi_encoded_link_bw)) == DC_OK) {
4937                                                         link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps = intersect_frl_link_bw_support(
4938                                                                         link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps,
4939                                                                         hdmi_encoded_link_bw);
4940                                                 }
4941
4942                                                 if (link->dpcd_caps.dongle_caps.dp_hdmi_frl_max_link_bw_in_kbps > 0)
4943                                                         link->dpcd_caps.dongle_caps.extendedCapValid = true;
4944                                         }
4945 #endif
4946
4947                                         if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
4948                                                 link->dpcd_caps.dongle_caps.extendedCapValid = true;
4949                                 }
4950
4951                                 break;
4952                         }
4953                 }
4954         }
4955
4956         ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
4957
4958         {
4959                 struct dp_sink_hw_fw_revision dp_hw_fw_revision;
4960
4961                 core_link_read_dpcd(
4962                         link,
4963                         DP_BRANCH_REVISION_START,
4964                         (uint8_t *)&dp_hw_fw_revision,
4965                         sizeof(dp_hw_fw_revision));
4966
4967                 link->dpcd_caps.branch_hw_revision =
4968                         dp_hw_fw_revision.ieee_hw_rev;
4969
4970                 memmove(
4971                         link->dpcd_caps.branch_fw_revision,
4972                         dp_hw_fw_revision.ieee_fw_rev,
4973                         sizeof(dp_hw_fw_revision.ieee_fw_rev));
4974         }
4975         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
4976                         link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
4977                 union dp_dfp_cap_ext dfp_cap_ext;
4978                 memset(&dfp_cap_ext, '\0', sizeof (dfp_cap_ext));
4979                 core_link_read_dpcd(
4980                                 link,
4981                                 DP_DFP_CAPABILITY_EXTENSION_SUPPORT,
4982                                 dfp_cap_ext.raw,
4983                                 sizeof(dfp_cap_ext.raw));
4984                 link->dpcd_caps.dongle_caps.dfp_cap_ext.supported = dfp_cap_ext.fields.supported;
4985                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_pixel_rate_in_mps =
4986                                 dfp_cap_ext.fields.max_pixel_rate_in_mps[0] +
4987                                 (dfp_cap_ext.fields.max_pixel_rate_in_mps[1] << 8);
4988                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_h_active_width =
4989                                 dfp_cap_ext.fields.max_video_h_active_width[0] +
4990                                 (dfp_cap_ext.fields.max_video_h_active_width[1] << 8);
4991                 link->dpcd_caps.dongle_caps.dfp_cap_ext.max_video_v_active_height =
4992                                 dfp_cap_ext.fields.max_video_v_active_height[0] +
4993                                 (dfp_cap_ext.fields.max_video_v_active_height[1] << 8);
4994                 link->dpcd_caps.dongle_caps.dfp_cap_ext.encoding_format_caps =
4995                                 dfp_cap_ext.fields.encoding_format_caps;
4996                 link->dpcd_caps.dongle_caps.dfp_cap_ext.rgb_color_depth_caps =
4997                                 dfp_cap_ext.fields.rgb_color_depth_caps;
4998                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr444_color_depth_caps =
4999                                 dfp_cap_ext.fields.ycbcr444_color_depth_caps;
5000                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr422_color_depth_caps =
5001                                 dfp_cap_ext.fields.ycbcr422_color_depth_caps;
5002                 link->dpcd_caps.dongle_caps.dfp_cap_ext.ycbcr420_color_depth_caps =
5003                                 dfp_cap_ext.fields.ycbcr420_color_depth_caps;
5004                 DC_LOG_DP2("DFP capability extension is read at link %d", link->link_index);
5005                 DC_LOG_DP2("\tdfp_cap_ext.supported = %s", link->dpcd_caps.dongle_caps.dfp_cap_ext.supported ? "true" : "false");
5006                 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);
5007                 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);
5008                 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);
5009         }
5010 }
5011
5012 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
5013                 int length)
5014 {
5015         int retry = 0;
5016
5017         if (!link->dpcd_caps.dpcd_rev.raw) {
5018                 do {
5019                         dp_receiver_power_ctrl(link, true);
5020                         core_link_read_dpcd(link, DP_DPCD_REV,
5021                                                         dpcd_data, length);
5022                         link->dpcd_caps.dpcd_rev.raw = dpcd_data[
5023                                 DP_DPCD_REV -
5024                                 DP_DPCD_REV];
5025                 } while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
5026         }
5027
5028         if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
5029                 switch (link->dpcd_caps.branch_dev_id) {
5030                 /* 0010FA active dongles (DP-VGA, DP-DLDVI converters) power down
5031                  * all internal circuits including AUX communication preventing
5032                  * reading DPCD table and EDID (spec violation).
5033                  * Encoder will skip DP RX power down on disable_output to
5034                  * keep receiver powered all the time.*/
5035                 case DP_BRANCH_DEVICE_ID_0010FA:
5036                 case DP_BRANCH_DEVICE_ID_0080E1:
5037                 case DP_BRANCH_DEVICE_ID_00E04C:
5038                         link->wa_flags.dp_keep_receiver_powered = true;
5039                         break;
5040
5041                 /* TODO: May need work around for other dongles. */
5042                 default:
5043                         link->wa_flags.dp_keep_receiver_powered = false;
5044                         break;
5045                 }
5046         } else
5047                 link->wa_flags.dp_keep_receiver_powered = false;
5048 }
5049
5050 /* Read additional sink caps defined in source specific DPCD area
5051  * This function currently only reads from SinkCapability address (DP_SOURCE_SINK_CAP)
5052  */
5053 static bool dpcd_read_sink_ext_caps(struct dc_link *link)
5054 {
5055         uint8_t dpcd_data;
5056
5057         if (!link)
5058                 return false;
5059
5060         if (core_link_read_dpcd(link, DP_SOURCE_SINK_CAP, &dpcd_data, 1) != DC_OK)
5061                 return false;
5062
5063         link->dpcd_sink_ext_caps.raw = dpcd_data;
5064         return true;
5065 }
5066
5067 bool dp_retrieve_lttpr_cap(struct dc_link *link)
5068 {
5069         uint8_t lttpr_dpcd_data[8];
5070         bool allow_lttpr_non_transparent_mode = 0;
5071         bool vbios_lttpr_enable = link->dc->caps.vbios_lttpr_enable;
5072         bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware;
5073         enum dc_status status = DC_ERROR_UNEXPECTED;
5074         bool is_lttpr_present = false;
5075
5076         memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
5077
5078         if ((link->dc->config.allow_lttpr_non_transparent_mode.bits.DP2_0 &&
5079                         link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)) {
5080                 allow_lttpr_non_transparent_mode = 1;
5081         } else if (link->dc->config.allow_lttpr_non_transparent_mode.bits.DP1_4A &&
5082                         !link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
5083                 allow_lttpr_non_transparent_mode = 1;
5084         }
5085
5086         /*
5087          * Logic to determine LTTPR mode
5088          */
5089         link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5090         if (vbios_lttpr_enable && vbios_lttpr_interop)
5091                 link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5092         else if (!vbios_lttpr_enable && vbios_lttpr_interop) {
5093                 if (allow_lttpr_non_transparent_mode)
5094                         link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5095                 else
5096                         link->lttpr_mode = LTTPR_MODE_TRANSPARENT;
5097         } else if (!vbios_lttpr_enable && !vbios_lttpr_interop) {
5098                 if (!allow_lttpr_non_transparent_mode || !link->dc->caps.extended_aux_timeout_support)
5099                         link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5100                 else
5101                         link->lttpr_mode = LTTPR_MODE_NON_TRANSPARENT;
5102         }
5103 #if defined(CONFIG_DRM_AMD_DC_DCN)
5104         /* Check DP tunnel LTTPR mode debug option. */
5105         if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
5106             link->dc->debug.dpia_debug.bits.force_non_lttpr)
5107                 link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5108 #endif
5109
5110         if (link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT || link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
5111                 /* By reading LTTPR capability, RX assumes that we will enable
5112                  * LTTPR extended aux timeout if LTTPR is present.
5113                  */
5114                 status = core_link_read_dpcd(
5115                                 link,
5116                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
5117                                 lttpr_dpcd_data,
5118                                 sizeof(lttpr_dpcd_data));
5119                 if (status != DC_OK) {
5120                         DC_LOG_DP2("%s: Read LTTPR caps data failed.\n", __func__);
5121                         link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5122                         return false;
5123                 }
5124
5125                 link->dpcd_caps.lttpr_caps.revision.raw =
5126                                 lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV -
5127                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5128
5129                 link->dpcd_caps.lttpr_caps.max_link_rate =
5130                                 lttpr_dpcd_data[DP_MAX_LINK_RATE_PHY_REPEATER -
5131                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5132
5133                 link->dpcd_caps.lttpr_caps.phy_repeater_cnt =
5134                                 lttpr_dpcd_data[DP_PHY_REPEATER_CNT -
5135                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5136
5137                 link->dpcd_caps.lttpr_caps.max_lane_count =
5138                                 lttpr_dpcd_data[DP_MAX_LANE_COUNT_PHY_REPEATER -
5139                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5140
5141                 link->dpcd_caps.lttpr_caps.mode =
5142                                 lttpr_dpcd_data[DP_PHY_REPEATER_MODE -
5143                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5144
5145                 link->dpcd_caps.lttpr_caps.max_ext_timeout =
5146                                 lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
5147                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5148
5149                 link->dpcd_caps.lttpr_caps.main_link_channel_coding.raw =
5150                                 lttpr_dpcd_data[DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER -
5151                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5152
5153                 link->dpcd_caps.lttpr_caps.supported_128b_132b_rates.raw =
5154                                 lttpr_dpcd_data[DP_PHY_REPEATER_128b_132b_RATES -
5155                                                                 DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
5156
5157                 /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */
5158                 is_lttpr_present = (link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
5159                                 link->dpcd_caps.lttpr_caps.phy_repeater_cnt < 0xff &&
5160                                 link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
5161                                 link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
5162                 if (is_lttpr_present) {
5163                         CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
5164                         configure_lttpr_mode_transparent(link);
5165                 } else
5166                         link->lttpr_mode = LTTPR_MODE_NON_LTTPR;
5167         }
5168         return is_lttpr_present;
5169 }
5170
5171 static bool get_usbc_cable_id(struct dc_link *link, union dp_cable_id *cable_id)
5172 {
5173         union dmub_rb_cmd cmd;
5174
5175         if (!link->ctx->dmub_srv ||
5176                         link->ep_type != DISPLAY_ENDPOINT_PHY ||
5177                         link->link_enc->features.flags.bits.DP_IS_USB_C == 0)
5178                 return false;
5179
5180         memset(&cmd, 0, sizeof(cmd));
5181         cmd.cable_id.header.type = DMUB_CMD_GET_USBC_CABLE_ID;
5182         cmd.cable_id.header.payload_bytes = sizeof(cmd.cable_id.data);
5183         cmd.cable_id.data.input.phy_inst = resource_transmitter_to_phy_idx(
5184                         link->dc, link->link_enc->transmitter);
5185         if (dc_dmub_srv_cmd_with_reply_data(link->ctx->dmub_srv, &cmd) &&
5186                         cmd.cable_id.header.ret_status == 1)
5187                 cable_id->raw = cmd.cable_id.data.output_raw;
5188
5189         return cmd.cable_id.header.ret_status == 1;
5190 }
5191
5192 static union dp_cable_id intersect_cable_id(
5193                 union dp_cable_id *a, union dp_cable_id *b)
5194 {
5195         union dp_cable_id out;
5196
5197         out.bits.UHBR10_20_CAPABILITY = MIN(a->bits.UHBR10_20_CAPABILITY,
5198                         b->bits.UHBR10_20_CAPABILITY);
5199         out.bits.UHBR13_5_CAPABILITY = MIN(a->bits.UHBR13_5_CAPABILITY,
5200                         b->bits.UHBR13_5_CAPABILITY);
5201         out.bits.CABLE_TYPE = MAX(a->bits.CABLE_TYPE, b->bits.CABLE_TYPE);
5202
5203         return out;
5204 }
5205
5206 static void retrieve_cable_id(struct dc_link *link)
5207 {
5208         union dp_cable_id usbc_cable_id;
5209
5210         link->dpcd_caps.cable_id.raw = 0;
5211         core_link_read_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPRX,
5212                         &link->dpcd_caps.cable_id.raw, sizeof(uint8_t));
5213
5214         if (get_usbc_cable_id(link, &usbc_cable_id))
5215                 link->dpcd_caps.cable_id = intersect_cable_id(
5216                                 &link->dpcd_caps.cable_id, &usbc_cable_id);
5217 }
5218
5219 /* DPRX may take some time to respond to AUX messages after HPD asserted.
5220  * If AUX read unsuccessful, try to wake unresponsive DPRX by toggling DPCD SET_POWER (0x600).
5221  */
5222 static enum dc_status wa_try_to_wake_dprx(struct dc_link *link, uint64_t timeout_ms)
5223 {
5224         enum dc_status status = DC_ERROR_UNEXPECTED;
5225         uint8_t dpcd_data = 0;
5226         uint64_t start_ts = 0;
5227         uint64_t current_ts = 0;
5228         uint64_t time_taken_ms = 0;
5229         enum dc_connection_type type = dc_connection_none;
5230
5231         status = core_link_read_dpcd(
5232                         link,
5233                         DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
5234                         &dpcd_data,
5235                         sizeof(dpcd_data));
5236
5237         if (status != DC_OK) {
5238                 DC_LOG_WARNING("%s: Read DPCD LTTPR_CAP failed - try to toggle DPCD SET_POWER for %lld ms.",
5239                                 __func__,
5240                                 timeout_ms);
5241                 start_ts = dm_get_timestamp(link->ctx);
5242
5243                 do {
5244                         if (!dc_link_detect_sink(link, &type) || type == dc_connection_none)
5245                                 break;
5246
5247                         dpcd_data = DP_SET_POWER_D3;
5248                         status = core_link_write_dpcd(
5249                                         link,
5250                                         DP_SET_POWER,
5251                                         &dpcd_data,
5252                                         sizeof(dpcd_data));
5253
5254                         dpcd_data = DP_SET_POWER_D0;
5255                         status = core_link_write_dpcd(
5256                                         link,
5257                                         DP_SET_POWER,
5258                                         &dpcd_data,
5259                                         sizeof(dpcd_data));
5260
5261                         current_ts = dm_get_timestamp(link->ctx);
5262                         time_taken_ms = div_u64(dm_get_elapse_time_in_ns(link->ctx, current_ts, start_ts), 1000000);
5263                 } while (status != DC_OK && time_taken_ms < timeout_ms);
5264
5265                 DC_LOG_WARNING("%s: DPCD SET_POWER %s after %lld ms%s",
5266                                 __func__,
5267                                 (status == DC_OK) ? "succeeded" : "failed",
5268                                 time_taken_ms,
5269                                 (type == dc_connection_none) ? ". Unplugged." : ".");
5270         }
5271
5272         return status;
5273 }
5274
5275 static bool retrieve_link_cap(struct dc_link *link)
5276 {
5277         /* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
5278          * which means size 16 will be good for both of those DPCD register block reads
5279          */
5280         uint8_t dpcd_data[16];
5281         /*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
5282          */
5283         uint8_t dpcd_dprx_data = '\0';
5284         uint8_t dpcd_power_state = '\0';
5285
5286         struct dp_device_vendor_id sink_id;
5287         union down_stream_port_count down_strm_port_count;
5288         union edp_configuration_cap edp_config_cap;
5289         union dp_downstream_port_present ds_port = { 0 };
5290         enum dc_status status = DC_ERROR_UNEXPECTED;
5291         uint32_t read_dpcd_retry_cnt = 3;
5292         int i;
5293         struct dp_sink_hw_fw_revision dp_hw_fw_revision;
5294         const uint32_t post_oui_delay = 30; // 30ms
5295         bool is_lttpr_present = false;
5296
5297         memset(dpcd_data, '\0', sizeof(dpcd_data));
5298         memset(&down_strm_port_count,
5299                 '\0', sizeof(union down_stream_port_count));
5300         memset(&edp_config_cap, '\0',
5301                 sizeof(union edp_configuration_cap));
5302
5303         /* if extended timeout is supported in hardware,
5304          * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
5305          * CTS 4.2.1.1 regression introduced by CTS specs requirement update.
5306          */
5307         dc_link_aux_try_to_configure_timeout(link->ddc,
5308                         LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
5309
5310         /* Try to ensure AUX channel active before proceeding. */
5311         if (link->dc->debug.aux_wake_wa.bits.enable_wa) {
5312                 uint64_t timeout_ms = link->dc->debug.aux_wake_wa.bits.timeout_ms;
5313
5314                 if (link->dc->debug.aux_wake_wa.bits.use_default_timeout)
5315                         timeout_ms = LINK_AUX_WAKE_TIMEOUT_MS;
5316                 status = wa_try_to_wake_dprx(link, timeout_ms);
5317         }
5318
5319         is_lttpr_present = dp_retrieve_lttpr_cap(link);
5320         /* Read DP tunneling information. */
5321         status = dpcd_get_tunneling_device_data(link);
5322
5323         status = core_link_read_dpcd(link, DP_SET_POWER,
5324                         &dpcd_power_state, sizeof(dpcd_power_state));
5325
5326         /* Delay 1 ms if AUX CH is in power down state. Based on spec
5327          * section 2.3.1.2, if AUX CH may be powered down due to
5328          * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
5329          * signal and may need up to 1 ms before being able to reply.
5330          */
5331         if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
5332                 udelay(1000);
5333
5334         dpcd_set_source_specific_data(link);
5335         /* Sink may need to configure internals based on vendor, so allow some
5336          * time before proceeding with possibly vendor specific transactions
5337          */
5338         msleep(post_oui_delay);
5339
5340         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5341                 status = core_link_read_dpcd(
5342                                 link,
5343                                 DP_DPCD_REV,
5344                                 dpcd_data,
5345                                 sizeof(dpcd_data));
5346                 if (status == DC_OK)
5347                         break;
5348         }
5349
5350         if (status != DC_OK) {
5351                 dm_error("%s: Read receiver caps dpcd data failed.\n", __func__);
5352                 return false;
5353         }
5354
5355         if (!is_lttpr_present)
5356                 dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
5357
5358         {
5359                 union training_aux_rd_interval aux_rd_interval;
5360
5361                 aux_rd_interval.raw =
5362                         dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
5363
5364                 link->dpcd_caps.ext_receiver_cap_field_present =
5365                                 aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1;
5366
5367                 if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
5368                         uint8_t ext_cap_data[16];
5369
5370                         memset(ext_cap_data, '\0', sizeof(ext_cap_data));
5371                         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5372                                 status = core_link_read_dpcd(
5373                                 link,
5374                                 DP_DP13_DPCD_REV,
5375                                 ext_cap_data,
5376                                 sizeof(ext_cap_data));
5377                                 if (status == DC_OK) {
5378                                         memcpy(dpcd_data, ext_cap_data, sizeof(dpcd_data));
5379                                         break;
5380                                 }
5381                         }
5382                         if (status != DC_OK)
5383                                 dm_error("%s: Read extend caps data failed, use cap from dpcd 0.\n", __func__);
5384                 }
5385         }
5386
5387         link->dpcd_caps.dpcd_rev.raw =
5388                         dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
5389
5390         if (link->dpcd_caps.ext_receiver_cap_field_present) {
5391                 for (i = 0; i < read_dpcd_retry_cnt; i++) {
5392                         status = core_link_read_dpcd(
5393                                         link,
5394                                         DP_DPRX_FEATURE_ENUMERATION_LIST,
5395                                         &dpcd_dprx_data,
5396                                         sizeof(dpcd_dprx_data));
5397                         if (status == DC_OK)
5398                                 break;
5399                 }
5400
5401                 link->dpcd_caps.dprx_feature.raw = dpcd_dprx_data;
5402
5403                 if (status != DC_OK)
5404                         dm_error("%s: Read DPRX caps data failed.\n", __func__);
5405         }
5406
5407         else {
5408                 link->dpcd_caps.dprx_feature.raw = 0;
5409         }
5410
5411
5412         /* Error condition checking...
5413          * It is impossible for Sink to report Max Lane Count = 0.
5414          * It is possible for Sink to report Max Link Rate = 0, if it is
5415          * an eDP device that is reporting specialized link rates in the
5416          * SUPPORTED_LINK_RATE table.
5417          */
5418         if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
5419                 return false;
5420
5421         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
5422                                  DP_DPCD_REV];
5423
5424         read_dp_device_vendor_id(link);
5425
5426         /* TODO - decouple raw mst capability from policy decision */
5427         link->dpcd_caps.is_mst_capable = is_mst_supported(link);
5428
5429         get_active_converter_info(ds_port.byte, link);
5430
5431         dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
5432
5433         down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
5434                                  DP_DPCD_REV];
5435
5436         link->dpcd_caps.allow_invalid_MSA_timing_param =
5437                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
5438
5439         link->dpcd_caps.max_ln_count.raw = dpcd_data[
5440                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
5441
5442         link->dpcd_caps.max_down_spread.raw = dpcd_data[
5443                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
5444
5445         link->reported_link_cap.lane_count =
5446                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
5447         link->reported_link_cap.link_rate = get_link_rate_from_max_link_bw(
5448                         dpcd_data[DP_MAX_LINK_RATE - DP_DPCD_REV]);
5449         link->reported_link_cap.link_spread =
5450                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
5451                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
5452
5453         edp_config_cap.raw = dpcd_data[
5454                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
5455         link->dpcd_caps.panel_mode_edp =
5456                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
5457         link->dpcd_caps.dpcd_display_control_capable =
5458                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
5459         link->dpcd_caps.channel_coding_cap.raw =
5460                         dpcd_data[DP_MAIN_LINK_CHANNEL_CODING - DP_DPCD_REV];
5461         link->test_pattern_enabled = false;
5462         link->compliance_test_state.raw = 0;
5463
5464         /* read sink count */
5465         core_link_read_dpcd(link,
5466                         DP_SINK_COUNT,
5467                         &link->dpcd_caps.sink_count.raw,
5468                         sizeof(link->dpcd_caps.sink_count.raw));
5469
5470         /* read sink ieee oui */
5471         core_link_read_dpcd(link,
5472                         DP_SINK_OUI,
5473                         (uint8_t *)(&sink_id),
5474                         sizeof(sink_id));
5475
5476         link->dpcd_caps.sink_dev_id =
5477                         (sink_id.ieee_oui[0] << 16) +
5478                         (sink_id.ieee_oui[1] << 8) +
5479                         (sink_id.ieee_oui[2]);
5480
5481         memmove(
5482                 link->dpcd_caps.sink_dev_id_str,
5483                 sink_id.ieee_device_id,
5484                 sizeof(sink_id.ieee_device_id));
5485
5486         /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */
5487         {
5488                 uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 };
5489
5490                 if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
5491                     !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017,
5492                             sizeof(str_mbp_2017))) {
5493                         link->reported_link_cap.link_rate = 0x0c;
5494                 }
5495         }
5496
5497         core_link_read_dpcd(
5498                 link,
5499                 DP_SINK_HW_REVISION_START,
5500                 (uint8_t *)&dp_hw_fw_revision,
5501                 sizeof(dp_hw_fw_revision));
5502
5503         link->dpcd_caps.sink_hw_revision =
5504                 dp_hw_fw_revision.ieee_hw_rev;
5505
5506         memmove(
5507                 link->dpcd_caps.sink_fw_revision,
5508                 dp_hw_fw_revision.ieee_fw_rev,
5509                 sizeof(dp_hw_fw_revision.ieee_fw_rev));
5510
5511         /* Quirk for Apple MBP 2018 15" Retina panels: wrong DP_MAX_LINK_RATE */
5512         {
5513                 uint8_t str_mbp_2018[] = { 101, 68, 21, 103, 98, 97 };
5514                 uint8_t fwrev_mbp_2018[] = { 7, 4 };
5515                 uint8_t fwrev_mbp_2018_vega[] = { 8, 4 };
5516
5517                 /* We also check for the firmware revision as 16,1 models have an
5518                  * identical device id and are incorrectly quirked otherwise.
5519                  */
5520                 if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
5521                     !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2018,
5522                              sizeof(str_mbp_2018)) &&
5523                     (!memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018,
5524                              sizeof(fwrev_mbp_2018)) ||
5525                     !memcmp(link->dpcd_caps.sink_fw_revision, fwrev_mbp_2018_vega,
5526                              sizeof(fwrev_mbp_2018_vega)))) {
5527                         link->reported_link_cap.link_rate = LINK_RATE_RBR2;
5528                 }
5529         }
5530
5531         memset(&link->dpcd_caps.dsc_caps, '\0',
5532                         sizeof(link->dpcd_caps.dsc_caps));
5533         memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
5534         /* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */
5535         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
5536                 status = core_link_read_dpcd(
5537                                 link,
5538                                 DP_FEC_CAPABILITY,
5539                                 &link->dpcd_caps.fec_cap.raw,
5540                                 sizeof(link->dpcd_caps.fec_cap.raw));
5541                 status = core_link_read_dpcd(
5542                                 link,
5543                                 DP_DSC_SUPPORT,
5544                                 link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
5545                                 sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
5546                 if (link->dpcd_caps.dongle_type != DISPLAY_DONGLE_NONE) {
5547                         status = core_link_read_dpcd(
5548                                         link,
5549                                         DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
5550                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
5551                                         sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw));
5552                         DC_LOG_DSC("DSC branch decoder capability is read at link %d", link->link_index);
5553                         DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_0 = 0x%02x",
5554                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_0);
5555                         DC_LOG_DSC("\tBRANCH_OVERALL_THROUGHPUT_1 = 0x%02x",
5556                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_OVERALL_THROUGHPUT_1);
5557                         DC_LOG_DSC("\tBRANCH_MAX_LINE_WIDTH 0x%02x",
5558                                         link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.fields.BRANCH_MAX_LINE_WIDTH);
5559                 }
5560
5561                 /* Apply work around to disable FEC and DSC for USB4 tunneling in TBT3 compatibility mode
5562                  * only if required.
5563                  */
5564                 if (link->ep_type == DISPLAY_ENDPOINT_USB4_DPIA &&
5565 #if defined(CONFIG_DRM_AMD_DC_DCN)
5566                                 !link->dc->debug.dpia_debug.bits.disable_force_tbt3_work_around &&
5567 #endif
5568                                 link->dpcd_caps.is_branch_dev &&
5569                                 link->dpcd_caps.branch_dev_id == DP_BRANCH_DEVICE_ID_90CC24 &&
5570                                 link->dpcd_caps.branch_hw_revision == DP_BRANCH_HW_REV_10 &&
5571                                 (link->dpcd_caps.fec_cap.bits.FEC_CAPABLE ||
5572                                 link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT)) {
5573                         /* A TBT3 device is expected to report no support for FEC or DSC to a USB4 DPIA.
5574                          * Clear FEC and DSC capabilities as a work around if that is not the case.
5575                          */
5576                         link->wa_flags.dpia_forced_tbt3_mode = true;
5577                         memset(&link->dpcd_caps.dsc_caps, '\0', sizeof(link->dpcd_caps.dsc_caps));
5578                         memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
5579                         DC_LOG_DSC("Clear DSC SUPPORT for USB4 link(%d) in TBT3 compatibility mode", link->link_index);
5580                 } else
5581                         link->wa_flags.dpia_forced_tbt3_mode = false;
5582         }
5583
5584         if (!dpcd_read_sink_ext_caps(link))
5585                 link->dpcd_sink_ext_caps.raw = 0;
5586
5587         if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED) {
5588                 DC_LOG_DP2("128b/132b encoding is supported at link %d", link->link_index);
5589
5590                 core_link_read_dpcd(link,
5591                                 DP_128b_132b_SUPPORTED_LINK_RATES,
5592                                 &link->dpcd_caps.dp_128b_132b_supported_link_rates.raw,
5593                                 sizeof(link->dpcd_caps.dp_128b_132b_supported_link_rates.raw));
5594                 if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR20)
5595                         link->reported_link_cap.link_rate = LINK_RATE_UHBR20;
5596                 else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR13_5)
5597                         link->reported_link_cap.link_rate = LINK_RATE_UHBR13_5;
5598                 else if (link->dpcd_caps.dp_128b_132b_supported_link_rates.bits.UHBR10)
5599                         link->reported_link_cap.link_rate = LINK_RATE_UHBR10;
5600                 else
5601                         dm_error("%s: Invalid RX 128b_132b_supported_link_rates\n", __func__);
5602                 DC_LOG_DP2("128b/132b supported link rates is read at link %d", link->link_index);
5603                 DC_LOG_DP2("\tmax 128b/132b link rate support is %d.%d GHz",
5604                                 link->reported_link_cap.link_rate / 100,
5605                                 link->reported_link_cap.link_rate % 100);
5606
5607                 core_link_read_dpcd(link,
5608                                 DP_SINK_VIDEO_FALLBACK_FORMATS,
5609                                 &link->dpcd_caps.fallback_formats.raw,
5610                                 sizeof(link->dpcd_caps.fallback_formats.raw));
5611                 DC_LOG_DP2("sink video fallback format is read at link %d", link->link_index);
5612                 if (link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support)
5613                         DC_LOG_DP2("\t1920x1080@60Hz 24bpp fallback format supported");
5614                 if (link->dpcd_caps.fallback_formats.bits.dp_1280x720_60Hz_24bpp_support)
5615                         DC_LOG_DP2("\t1280x720@60Hz 24bpp fallback format supported");
5616                 if (link->dpcd_caps.fallback_formats.bits.dp_1024x768_60Hz_24bpp_support)
5617                         DC_LOG_DP2("\t1024x768@60Hz 24bpp fallback format supported");
5618                 if (link->dpcd_caps.fallback_formats.raw == 0) {
5619                         DC_LOG_DP2("\tno supported fallback formats, assume 1920x1080@60Hz 24bpp is supported");
5620                         link->dpcd_caps.fallback_formats.bits.dp_1920x1080_60Hz_24bpp_support = 1;
5621                 }
5622
5623                 core_link_read_dpcd(link,
5624                                 DP_FEC_CAPABILITY_1,
5625                                 &link->dpcd_caps.fec_cap1.raw,
5626                                 sizeof(link->dpcd_caps.fec_cap1.raw));
5627                 DC_LOG_DP2("FEC CAPABILITY 1 is read at link %d", link->link_index);
5628                 if (link->dpcd_caps.fec_cap1.bits.AGGREGATED_ERROR_COUNTERS_CAPABLE)
5629                         DC_LOG_DP2("\tFEC aggregated error counters are supported");
5630         }
5631
5632         retrieve_cable_id(link);
5633         dpcd_write_cable_id_to_dprx(link);
5634
5635         /* Connectivity log: detection */
5636         CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
5637
5638         return true;
5639 }
5640
5641 bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
5642 {
5643         uint8_t dpcd_data[16];
5644         uint32_t read_dpcd_retry_cnt = 3;
5645         enum dc_status status = DC_ERROR_UNEXPECTED;
5646         union dp_downstream_port_present ds_port = { 0 };
5647         union down_stream_port_count down_strm_port_count;
5648         union edp_configuration_cap edp_config_cap;
5649
5650         int i;
5651
5652         for (i = 0; i < read_dpcd_retry_cnt; i++) {
5653                 status = core_link_read_dpcd(
5654                                 link,
5655                                 DP_DPCD_REV,
5656                                 dpcd_data,
5657                                 sizeof(dpcd_data));
5658                 if (status == DC_OK)
5659                         break;
5660         }
5661
5662         link->dpcd_caps.dpcd_rev.raw =
5663                 dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
5664
5665         if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
5666                 return false;
5667
5668         ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
5669                         DP_DPCD_REV];
5670
5671         get_active_converter_info(ds_port.byte, link);
5672
5673         down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
5674                         DP_DPCD_REV];
5675
5676         link->dpcd_caps.allow_invalid_MSA_timing_param =
5677                 down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
5678
5679         link->dpcd_caps.max_ln_count.raw = dpcd_data[
5680                 DP_MAX_LANE_COUNT - DP_DPCD_REV];
5681
5682         link->dpcd_caps.max_down_spread.raw = dpcd_data[
5683                 DP_MAX_DOWNSPREAD - DP_DPCD_REV];
5684
5685         link->reported_link_cap.lane_count =
5686                 link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
5687         link->reported_link_cap.link_rate = dpcd_data[
5688                 DP_MAX_LINK_RATE - DP_DPCD_REV];
5689         link->reported_link_cap.link_spread =
5690                 link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
5691                 LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
5692
5693         edp_config_cap.raw = dpcd_data[
5694                 DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
5695         link->dpcd_caps.panel_mode_edp =
5696                 edp_config_cap.bits.ALT_SCRAMBLER_RESET;
5697         link->dpcd_caps.dpcd_display_control_capable =
5698                 edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
5699
5700         return true;
5701 }
5702
5703 bool detect_dp_sink_caps(struct dc_link *link)
5704 {
5705         return retrieve_link_cap(link);
5706 }
5707
5708 static enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
5709 {
5710         enum dc_link_rate link_rate;
5711         // LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
5712         switch (link_rate_in_khz) {
5713         case 1620000:
5714                 link_rate = LINK_RATE_LOW;              // Rate_1 (RBR)         - 1.62 Gbps/Lane
5715                 break;
5716         case 2160000:
5717                 link_rate = LINK_RATE_RATE_2;   // Rate_2                       - 2.16 Gbps/Lane
5718                 break;
5719         case 2430000:
5720                 link_rate = LINK_RATE_RATE_3;   // Rate_3                       - 2.43 Gbps/Lane
5721                 break;
5722         case 2700000:
5723                 link_rate = LINK_RATE_HIGH;             // Rate_4 (HBR)         - 2.70 Gbps/Lane
5724                 break;
5725         case 3240000:
5726                 link_rate = LINK_RATE_RBR2;             // Rate_5 (RBR2)        - 3.24 Gbps/Lane
5727                 break;
5728         case 4320000:
5729                 link_rate = LINK_RATE_RATE_6;   // Rate_6                       - 4.32 Gbps/Lane
5730                 break;
5731         case 5400000:
5732                 link_rate = LINK_RATE_HIGH2;    // Rate_7 (HBR2)        - 5.40 Gbps/Lane
5733                 break;
5734         case 8100000:
5735                 link_rate = LINK_RATE_HIGH3;    // Rate_8 (HBR3)        - 8.10 Gbps/Lane
5736                 break;
5737         default:
5738                 link_rate = LINK_RATE_UNKNOWN;
5739                 break;
5740         }
5741         return link_rate;
5742 }
5743
5744 void detect_edp_sink_caps(struct dc_link *link)
5745 {
5746         uint8_t supported_link_rates[16];
5747         uint32_t entry;
5748         uint32_t link_rate_in_khz;
5749         enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
5750         uint8_t backlight_adj_cap;
5751
5752         retrieve_link_cap(link);
5753         link->dpcd_caps.edp_supported_link_rates_count = 0;
5754         memset(supported_link_rates, 0, sizeof(supported_link_rates));
5755
5756         /*
5757          * edp_supported_link_rates_count is only valid for eDP v1.4 or higher.
5758          * Per VESA eDP spec, "The DPCD revision for eDP v1.4 is 13h"
5759          */
5760         if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_13 &&
5761                         (link->dc->debug.optimize_edp_link_rate ||
5762                         link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
5763                 // Read DPCD 00010h - 0001Fh 16 bytes at one shot
5764                 core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
5765                                                         supported_link_rates, sizeof(supported_link_rates));
5766
5767                 for (entry = 0; entry < 16; entry += 2) {
5768                         // DPCD register reports per-lane link rate = 16-bit link rate capability
5769                         // value X 200 kHz. Need multiplier to find link rate in kHz.
5770                         link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
5771                                                                                 supported_link_rates[entry]) * 200;
5772
5773                         if (link_rate_in_khz != 0) {
5774                                 link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
5775                                 link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate;
5776                                 link->dpcd_caps.edp_supported_link_rates_count++;
5777
5778                                 if (link->reported_link_cap.link_rate < link_rate)
5779                                         link->reported_link_cap.link_rate = link_rate;
5780                         }
5781                 }
5782         }
5783         core_link_read_dpcd(link, DP_EDP_BACKLIGHT_ADJUSTMENT_CAP,
5784                                                 &backlight_adj_cap, sizeof(backlight_adj_cap));
5785
5786         link->dpcd_caps.dynamic_backlight_capable_edp =
5787                                 (backlight_adj_cap & DP_EDP_DYNAMIC_BACKLIGHT_CAP) ? true:false;
5788
5789         dc_link_set_default_brightness_aux(link);
5790
5791         core_link_read_dpcd(link, DP_EDP_DPCD_REV,
5792                 &link->dpcd_caps.edp_rev,
5793                 sizeof(link->dpcd_caps.edp_rev));
5794         /*
5795          * PSR is only valid for eDP v1.3 or higher.
5796          */
5797         if (link->dpcd_caps.edp_rev >= DP_EDP_13) {
5798                 core_link_read_dpcd(link, DP_PSR_SUPPORT,
5799                         &link->dpcd_caps.psr_info.psr_version,
5800                         sizeof(link->dpcd_caps.psr_info.psr_version));
5801                 core_link_read_dpcd(link, DP_PSR_CAPS,
5802                         &link->dpcd_caps.psr_info.psr_dpcd_caps.raw,
5803                         sizeof(link->dpcd_caps.psr_info.psr_dpcd_caps.raw));
5804                 if (link->dpcd_caps.psr_info.psr_dpcd_caps.bits.Y_COORDINATE_REQUIRED) {
5805                         core_link_read_dpcd(link, DP_PSR2_SU_Y_GRANULARITY,
5806                                 &link->dpcd_caps.psr_info.psr2_su_y_granularity_cap,
5807                                 sizeof(link->dpcd_caps.psr_info.psr2_su_y_granularity_cap));
5808                 }
5809         }
5810
5811         /*
5812          * ALPM is only valid for eDP v1.4 or higher.
5813          */
5814         if (link->dpcd_caps.dpcd_rev.raw >= DP_EDP_14)
5815                 core_link_read_dpcd(link, DP_RECEIVER_ALPM_CAP,
5816                         &link->dpcd_caps.alpm_caps.raw,
5817                         sizeof(link->dpcd_caps.alpm_caps.raw));
5818 }
5819
5820 void dc_link_dp_enable_hpd(const struct dc_link *link)
5821 {
5822         struct link_encoder *encoder = link->link_enc;
5823
5824         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
5825                 encoder->funcs->enable_hpd(encoder);
5826 }
5827
5828 void dc_link_dp_disable_hpd(const struct dc_link *link)
5829 {
5830         struct link_encoder *encoder = link->link_enc;
5831
5832         if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
5833                 encoder->funcs->disable_hpd(encoder);
5834 }
5835
5836 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
5837 {
5838         if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
5839                         test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
5840                         test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
5841                 return true;
5842         else
5843                 return false;
5844 }
5845
5846 static void set_crtc_test_pattern(struct dc_link *link,
5847                                 struct pipe_ctx *pipe_ctx,
5848                                 enum dp_test_pattern test_pattern,
5849                                 enum dp_test_pattern_color_space test_pattern_color_space)
5850 {
5851         enum controller_dp_test_pattern controller_test_pattern;
5852         enum dc_color_depth color_depth = pipe_ctx->
5853                 stream->timing.display_color_depth;
5854         struct bit_depth_reduction_params params;
5855         struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
5856         int width = pipe_ctx->stream->timing.h_addressable +
5857                 pipe_ctx->stream->timing.h_border_left +
5858                 pipe_ctx->stream->timing.h_border_right;
5859         int height = pipe_ctx->stream->timing.v_addressable +
5860                 pipe_ctx->stream->timing.v_border_bottom +
5861                 pipe_ctx->stream->timing.v_border_top;
5862
5863         memset(&params, 0, sizeof(params));
5864
5865         switch (test_pattern) {
5866         case DP_TEST_PATTERN_COLOR_SQUARES:
5867                 controller_test_pattern =
5868                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
5869         break;
5870         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
5871                 controller_test_pattern =
5872                                 CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
5873         break;
5874         case DP_TEST_PATTERN_VERTICAL_BARS:
5875                 controller_test_pattern =
5876                                 CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
5877         break;
5878         case DP_TEST_PATTERN_HORIZONTAL_BARS:
5879                 controller_test_pattern =
5880                                 CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
5881         break;
5882         case DP_TEST_PATTERN_COLOR_RAMP:
5883                 controller_test_pattern =
5884                                 CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
5885         break;
5886         default:
5887                 controller_test_pattern =
5888                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
5889         break;
5890         }
5891
5892         switch (test_pattern) {
5893         case DP_TEST_PATTERN_COLOR_SQUARES:
5894         case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
5895         case DP_TEST_PATTERN_VERTICAL_BARS:
5896         case DP_TEST_PATTERN_HORIZONTAL_BARS:
5897         case DP_TEST_PATTERN_COLOR_RAMP:
5898         {
5899                 /* disable bit depth reduction */
5900                 pipe_ctx->stream->bit_depth_params = params;
5901                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
5902                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
5903                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
5904                                 controller_test_pattern, color_depth);
5905                 else if (link->dc->hwss.set_disp_pattern_generator) {
5906                         struct pipe_ctx *odm_pipe;
5907                         enum controller_dp_color_space controller_color_space;
5908                         int opp_cnt = 1;
5909                         int offset = 0;
5910                         int dpg_width = width;
5911
5912                         switch (test_pattern_color_space) {
5913                         case DP_TEST_PATTERN_COLOR_SPACE_RGB:
5914                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
5915                                 break;
5916                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
5917                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
5918                                 break;
5919                         case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
5920                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
5921                                 break;
5922                         case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
5923                         default:
5924                                 controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
5925                                 DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
5926                                 ASSERT(0);
5927                                 break;
5928                         }
5929
5930                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
5931                                 opp_cnt++;
5932                         dpg_width = width / opp_cnt;
5933                         offset = dpg_width;
5934
5935                         link->dc->hwss.set_disp_pattern_generator(link->dc,
5936                                         pipe_ctx,
5937                                         controller_test_pattern,
5938                                         controller_color_space,
5939                                         color_depth,
5940                                         NULL,
5941                                         dpg_width,
5942                                         height,
5943                                         0);
5944
5945                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
5946                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
5947
5948                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
5949                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
5950                                                 odm_pipe,
5951                                                 controller_test_pattern,
5952                                                 controller_color_space,
5953                                                 color_depth,
5954                                                 NULL,
5955                                                 dpg_width,
5956                                                 height,
5957                                                 offset);
5958                                 offset += offset;
5959                         }
5960                 }
5961         }
5962         break;
5963         case DP_TEST_PATTERN_VIDEO_MODE:
5964         {
5965                 /* restore bitdepth reduction */
5966                 resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
5967                 pipe_ctx->stream->bit_depth_params = params;
5968                 opp->funcs->opp_program_bit_depth_reduction(opp, &params);
5969                 if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
5970                         pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
5971                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
5972                                 color_depth);
5973                 else if (link->dc->hwss.set_disp_pattern_generator) {
5974                         struct pipe_ctx *odm_pipe;
5975                         int opp_cnt = 1;
5976                         int dpg_width;
5977
5978                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
5979                                 opp_cnt++;
5980
5981                         dpg_width = width / opp_cnt;
5982                         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
5983                                 struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
5984
5985                                 odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
5986                                 link->dc->hwss.set_disp_pattern_generator(link->dc,
5987                                                 odm_pipe,
5988                                                 CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
5989                                                 CONTROLLER_DP_COLOR_SPACE_UDEFINED,
5990                                                 color_depth,
5991                                                 NULL,
5992                                                 dpg_width,
5993                                                 height,
5994                                                 0);
5995                         }
5996                         link->dc->hwss.set_disp_pattern_generator(link->dc,
5997                                         pipe_ctx,
5998                                         CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
5999                                         CONTROLLER_DP_COLOR_SPACE_UDEFINED,
6000                                         color_depth,
6001                                         NULL,
6002                                         dpg_width,
6003                                         height,
6004                                         0);
6005                 }
6006         }
6007         break;
6008
6009         default:
6010         break;
6011         }
6012 }
6013
6014 bool dc_link_dp_set_test_pattern(
6015         struct dc_link *link,
6016         enum dp_test_pattern test_pattern,
6017         enum dp_test_pattern_color_space test_pattern_color_space,
6018         const struct link_training_settings *p_link_settings,
6019         const unsigned char *p_custom_pattern,
6020         unsigned int cust_pattern_size)
6021 {
6022         struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
6023         struct pipe_ctx *pipe_ctx = NULL;
6024         unsigned int lane;
6025         unsigned int i;
6026         unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
6027         union dpcd_training_pattern training_pattern;
6028         enum dpcd_phy_test_patterns pattern;
6029
6030         memset(&training_pattern, 0, sizeof(training_pattern));
6031
6032         for (i = 0; i < MAX_PIPES; i++) {
6033                 if (pipes[i].stream == NULL)
6034                         continue;
6035
6036                 if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
6037                         pipe_ctx = &pipes[i];
6038                         break;
6039                 }
6040         }
6041
6042         if (pipe_ctx == NULL)
6043                 return false;
6044
6045         /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
6046         if (link->test_pattern_enabled && test_pattern ==
6047                         DP_TEST_PATTERN_VIDEO_MODE) {
6048                 /* Set CRTC Test Pattern */
6049                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
6050                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
6051                                 (uint8_t *)p_custom_pattern,
6052                                 (uint32_t)cust_pattern_size);
6053
6054                 /* Unblank Stream */
6055                 link->dc->hwss.unblank_stream(
6056                         pipe_ctx,
6057                         &link->verified_link_cap);
6058                 /* TODO:m_pHwss->MuteAudioEndpoint
6059                  * (pPathMode->pDisplayPath, false);
6060                  */
6061
6062                 /* Reset Test Pattern state */
6063                 link->test_pattern_enabled = false;
6064
6065                 return true;
6066         }
6067
6068         /* Check for PHY Test Patterns */
6069         if (is_dp_phy_pattern(test_pattern)) {
6070                 /* Set DPCD Lane Settings before running test pattern */
6071                 if (p_link_settings != NULL) {
6072                         if (link->dc->debug.apply_vendor_specific_lttpr_wa &&
6073                                         (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
6074                                         link->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
6075                                 dp_fixed_vs_pe_set_retimer_lane_settings(
6076                                                 link,
6077                                                 p_link_settings->dpcd_lane_settings,
6078                                                 p_link_settings->link_settings.lane_count);
6079                         } else {
6080                                 dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
6081                         }
6082                         dpcd_set_lane_settings(link, p_link_settings, DPRX);
6083                 }
6084
6085                 /* Blank stream if running test pattern */
6086                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
6087                         /*TODO:
6088                          * m_pHwss->
6089                          * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
6090                          */
6091                         /* Blank stream */
6092                         pipes->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc);
6093                 }
6094
6095                 dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
6096                                 (uint8_t *)p_custom_pattern,
6097                                 (uint32_t)cust_pattern_size);
6098
6099                 if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
6100                         /* Set Test Pattern state */
6101                         link->test_pattern_enabled = true;
6102                         if (p_link_settings != NULL)
6103                                 dpcd_set_link_settings(link,
6104                                                 p_link_settings);
6105                 }
6106
6107                 switch (test_pattern) {
6108                 case DP_TEST_PATTERN_VIDEO_MODE:
6109                         pattern = PHY_TEST_PATTERN_NONE;
6110                         break;
6111                 case DP_TEST_PATTERN_D102:
6112                         pattern = PHY_TEST_PATTERN_D10_2;
6113                         break;
6114                 case DP_TEST_PATTERN_SYMBOL_ERROR:
6115                         pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
6116                         break;
6117                 case DP_TEST_PATTERN_PRBS7:
6118                         pattern = PHY_TEST_PATTERN_PRBS7;
6119                         break;
6120                 case DP_TEST_PATTERN_80BIT_CUSTOM:
6121                         pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
6122                         break;
6123                 case DP_TEST_PATTERN_CP2520_1:
6124                         pattern = PHY_TEST_PATTERN_CP2520_1;
6125                         break;
6126                 case DP_TEST_PATTERN_CP2520_2:
6127                         pattern = PHY_TEST_PATTERN_CP2520_2;
6128                         break;
6129                 case DP_TEST_PATTERN_CP2520_3:
6130                         pattern = PHY_TEST_PATTERN_CP2520_3;
6131                         break;
6132                 case DP_TEST_PATTERN_128b_132b_TPS1:
6133                         pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
6134                         break;
6135                 case DP_TEST_PATTERN_128b_132b_TPS2:
6136                         pattern = PHY_TEST_PATTERN_128b_132b_TPS2;
6137                         break;
6138                 case DP_TEST_PATTERN_PRBS9:
6139                         pattern = PHY_TEST_PATTERN_PRBS9;
6140                         break;
6141                 case DP_TEST_PATTERN_PRBS11:
6142                         pattern = PHY_TEST_PATTERN_PRBS11;
6143                         break;
6144                 case DP_TEST_PATTERN_PRBS15:
6145                         pattern = PHY_TEST_PATTERN_PRBS15;
6146                         break;
6147                 case DP_TEST_PATTERN_PRBS23:
6148                         pattern = PHY_TEST_PATTERN_PRBS23;
6149                         break;
6150                 case DP_TEST_PATTERN_PRBS31:
6151                         pattern = PHY_TEST_PATTERN_PRBS31;
6152                         break;
6153                 case DP_TEST_PATTERN_264BIT_CUSTOM:
6154                         pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
6155                         break;
6156                 case DP_TEST_PATTERN_SQUARE_PULSE:
6157                         pattern = PHY_TEST_PATTERN_SQUARE_PULSE;
6158                         break;
6159                 default:
6160                         return false;
6161                 }
6162
6163                 if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
6164                 /*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
6165                         return false;
6166
6167                 if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
6168 #if defined(CONFIG_DRM_AMD_DC_DCN)
6169                         if (test_pattern == DP_TEST_PATTERN_SQUARE_PULSE)
6170                                 core_link_write_dpcd(link,
6171                                                 DP_LINK_SQUARE_PATTERN,
6172                                                 p_custom_pattern,
6173                                                 1);
6174
6175 #endif
6176                         /* tell receiver that we are sending qualification
6177                          * pattern DP 1.2 or later - DP receiver's link quality
6178                          * pattern is set using DPCD LINK_QUAL_LANEx_SET
6179                          * register (0x10B~0x10E)\
6180                          */
6181                         for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
6182                                 link_qual_pattern[lane] =
6183                                                 (unsigned char)(pattern);
6184
6185                         core_link_write_dpcd(link,
6186                                         DP_LINK_QUAL_LANE0_SET,
6187                                         link_qual_pattern,
6188                                         sizeof(link_qual_pattern));
6189                 } else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
6190                            link->dpcd_caps.dpcd_rev.raw == 0) {
6191                         /* tell receiver that we are sending qualification
6192                          * pattern DP 1.1a or earlier - DP receiver's link
6193                          * quality pattern is set using
6194                          * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
6195                          * register (0x102). We will use v_1.3 when we are
6196                          * setting test pattern for DP 1.1.
6197                          */
6198                         core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
6199                                             &training_pattern.raw,
6200                                             sizeof(training_pattern));
6201                         training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
6202                         core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
6203                                              &training_pattern.raw,
6204                                              sizeof(training_pattern));
6205                 }
6206         } else {
6207                 enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
6208
6209                 switch (test_pattern_color_space) {
6210                 case DP_TEST_PATTERN_COLOR_SPACE_RGB:
6211                         color_space = COLOR_SPACE_SRGB;
6212                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6213                                 color_space = COLOR_SPACE_SRGB_LIMITED;
6214                         break;
6215
6216                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
6217                         color_space = COLOR_SPACE_YCBCR601;
6218                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6219                                 color_space = COLOR_SPACE_YCBCR601_LIMITED;
6220                         break;
6221                 case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
6222                         color_space = COLOR_SPACE_YCBCR709;
6223                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6224                                 color_space = COLOR_SPACE_YCBCR709_LIMITED;
6225                         break;
6226                 default:
6227                         break;
6228                 }
6229
6230                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
6231                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
6232                                 union dmub_hw_lock_flags hw_locks = { 0 };
6233                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
6234
6235                                 hw_locks.bits.lock_dig = 1;
6236                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
6237
6238                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
6239                                                         true,
6240                                                         &hw_locks,
6241                                                         &inst_flags);
6242                         } else
6243                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
6244                                                 pipe_ctx->stream_res.tg);
6245                 }
6246
6247                 pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
6248                 /* update MSA to requested color space */
6249                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
6250                                 &pipe_ctx->stream->timing,
6251                                 color_space,
6252                                 pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
6253                                 link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
6254
6255                 if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
6256                         if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
6257                                 pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
6258                         else
6259                                 pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
6260                         resource_build_info_frame(pipe_ctx);
6261                         link->dc->hwss.update_info_frame(pipe_ctx);
6262                 }
6263
6264                 /* CRTC Patterns */
6265                 set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
6266                 pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
6267                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6268                                 CRTC_STATE_VACTIVE);
6269                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6270                                 CRTC_STATE_VBLANK);
6271                 pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
6272                                 CRTC_STATE_VACTIVE);
6273
6274                 if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
6275                         if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
6276                                 union dmub_hw_lock_flags hw_locks = { 0 };
6277                                 struct dmub_hw_lock_inst_flags inst_flags = { 0 };
6278
6279                                 hw_locks.bits.lock_dig = 1;
6280                                 inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
6281
6282                                 dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
6283                                                         false,
6284                                                         &hw_locks,
6285                                                         &inst_flags);
6286                         } else
6287                                 pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
6288                                                 pipe_ctx->stream_res.tg);
6289                 }
6290
6291                 /* Set Test Pattern state */
6292                 link->test_pattern_enabled = true;
6293         }
6294
6295         return true;
6296 }
6297
6298 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
6299 {
6300         unsigned char mstmCntl;
6301
6302         core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
6303         if (enable)
6304                 mstmCntl |= DP_MST_EN;
6305         else
6306                 mstmCntl &= (~DP_MST_EN);
6307
6308         core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
6309 }
6310
6311 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
6312 {
6313         union dpcd_edp_config edp_config_set;
6314         bool panel_mode_edp = false;
6315
6316         memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
6317
6318         if (panel_mode != DP_PANEL_MODE_DEFAULT) {
6319
6320                 switch (panel_mode) {
6321                 case DP_PANEL_MODE_EDP:
6322                 case DP_PANEL_MODE_SPECIAL:
6323                         panel_mode_edp = true;
6324                         break;
6325
6326                 default:
6327                                 break;
6328                 }
6329
6330                 /*set edp panel mode in receiver*/
6331                 core_link_read_dpcd(
6332                         link,
6333                         DP_EDP_CONFIGURATION_SET,
6334                         &edp_config_set.raw,
6335                         sizeof(edp_config_set.raw));
6336
6337                 if (edp_config_set.bits.PANEL_MODE_EDP
6338                         != panel_mode_edp) {
6339                         enum dc_status result;
6340
6341                         edp_config_set.bits.PANEL_MODE_EDP =
6342                         panel_mode_edp;
6343                         result = core_link_write_dpcd(
6344                                 link,
6345                                 DP_EDP_CONFIGURATION_SET,
6346                                 &edp_config_set.raw,
6347                                 sizeof(edp_config_set.raw));
6348
6349                         ASSERT(result == DC_OK);
6350                 }
6351         }
6352         DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
6353                  "eDP panel mode enabled: %d \n",
6354                  link->link_index,
6355                  link->dpcd_caps.panel_mode_edp,
6356                  panel_mode_edp);
6357 }
6358
6359 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
6360 {
6361         /* We need to explicitly check that connector
6362          * is not DP. Some Travis_VGA get reported
6363          * by video bios as DP.
6364          */
6365         if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
6366
6367                 switch (link->dpcd_caps.branch_dev_id) {
6368                 case DP_BRANCH_DEVICE_ID_0022B9:
6369                         /* alternate scrambler reset is required for Travis
6370                          * for the case when external chip does not
6371                          * provide sink device id, alternate scrambler
6372                          * scheme will  be overriden later by querying
6373                          * Encoder features
6374                          */
6375                         if (strncmp(
6376                                 link->dpcd_caps.branch_dev_name,
6377                                 DP_VGA_LVDS_CONVERTER_ID_2,
6378                                 sizeof(
6379                                 link->dpcd_caps.
6380                                 branch_dev_name)) == 0) {
6381                                         return DP_PANEL_MODE_SPECIAL;
6382                         }
6383                         break;
6384                 case DP_BRANCH_DEVICE_ID_00001A:
6385                         /* alternate scrambler reset is required for Travis
6386                          * for the case when external chip does not provide
6387                          * sink device id, alternate scrambler scheme will
6388                          * be overriden later by querying Encoder feature
6389                          */
6390                         if (strncmp(link->dpcd_caps.branch_dev_name,
6391                                 DP_VGA_LVDS_CONVERTER_ID_3,
6392                                 sizeof(
6393                                 link->dpcd_caps.
6394                                 branch_dev_name)) == 0) {
6395                                         return DP_PANEL_MODE_SPECIAL;
6396                         }
6397                         break;
6398                 default:
6399                         break;
6400                 }
6401         }
6402
6403         if (link->dpcd_caps.panel_mode_edp &&
6404                 (link->connector_signal == SIGNAL_TYPE_EDP ||
6405                  (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
6406                   link->is_internal_display))) {
6407                 return DP_PANEL_MODE_EDP;
6408         }
6409
6410         return DP_PANEL_MODE_DEFAULT;
6411 }
6412
6413 enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready)
6414 {
6415         /* FEC has to be "set ready" before the link training.
6416          * The policy is to always train with FEC
6417          * if the sink supports it and leave it enabled on link.
6418          * If FEC is not supported, disable it.
6419          */
6420         struct link_encoder *link_enc = NULL;
6421         enum dc_status status = DC_OK;
6422         uint8_t fec_config = 0;
6423
6424         link_enc = link_enc_cfg_get_link_enc(link);
6425         ASSERT(link_enc);
6426
6427         if (!dc_link_should_enable_fec(link))
6428                 return status;
6429
6430         if (link_enc->funcs->fec_set_ready &&
6431                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
6432                 if (ready) {
6433                         fec_config = 1;
6434                         status = core_link_write_dpcd(link,
6435                                         DP_FEC_CONFIGURATION,
6436                                         &fec_config,
6437                                         sizeof(fec_config));
6438                         if (status == DC_OK) {
6439                                 link_enc->funcs->fec_set_ready(link_enc, true);
6440                                 link->fec_state = dc_link_fec_ready;
6441                         } else {
6442                                 link_enc->funcs->fec_set_ready(link_enc, false);
6443                                 link->fec_state = dc_link_fec_not_ready;
6444                                 dm_error("dpcd write failed to set fec_ready");
6445                         }
6446                 } else if (link->fec_state == dc_link_fec_ready) {
6447                         fec_config = 0;
6448                         status = core_link_write_dpcd(link,
6449                                         DP_FEC_CONFIGURATION,
6450                                         &fec_config,
6451                                         sizeof(fec_config));
6452                         link_enc->funcs->fec_set_ready(link_enc, false);
6453                         link->fec_state = dc_link_fec_not_ready;
6454                 }
6455         }
6456
6457         return status;
6458 }
6459
6460 void dp_set_fec_enable(struct dc_link *link, bool enable)
6461 {
6462         struct link_encoder *link_enc = NULL;
6463
6464         link_enc = link_enc_cfg_get_link_enc(link);
6465         ASSERT(link_enc);
6466
6467         if (!dc_link_should_enable_fec(link))
6468                 return;
6469
6470         if (link_enc->funcs->fec_set_enable &&
6471                         link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
6472                 if (link->fec_state == dc_link_fec_ready && enable) {
6473                         /* Accord to DP spec, FEC enable sequence can first
6474                          * be transmitted anytime after 1000 LL codes have
6475                          * been transmitted on the link after link training
6476                          * completion. Using 1 lane RBR should have the maximum
6477                          * time for transmitting 1000 LL codes which is 6.173 us.
6478                          * So use 7 microseconds delay instead.
6479                          */
6480                         udelay(7);
6481                         link_enc->funcs->fec_set_enable(link_enc, true);
6482                         link->fec_state = dc_link_fec_enabled;
6483                 } else if (link->fec_state == dc_link_fec_enabled && !enable) {
6484                         link_enc->funcs->fec_set_enable(link_enc, false);
6485                         link->fec_state = dc_link_fec_ready;
6486                 }
6487         }
6488 }
6489
6490 void dpcd_set_source_specific_data(struct dc_link *link)
6491 {
6492         if (!link->dc->vendor_signature.is_valid) {
6493                 enum dc_status __maybe_unused result_write_min_hblank = DC_NOT_SUPPORTED;
6494                 struct dpcd_amd_signature amd_signature = {0};
6495                 struct dpcd_amd_device_id amd_device_id = {0};
6496
6497                 amd_device_id.device_id_byte1 =
6498                                 (uint8_t)(link->ctx->asic_id.chip_id);
6499                 amd_device_id.device_id_byte2 =
6500                                 (uint8_t)(link->ctx->asic_id.chip_id >> 8);
6501                 amd_device_id.dce_version =
6502                                 (uint8_t)(link->ctx->dce_version);
6503                 amd_device_id.dal_version_byte1 = 0x0; // needed? where to get?
6504                 amd_device_id.dal_version_byte2 = 0x0; // needed? where to get?
6505
6506                 core_link_read_dpcd(link, DP_SOURCE_OUI,
6507                                 (uint8_t *)(&amd_signature),
6508                                 sizeof(amd_signature));
6509
6510                 if (!((amd_signature.AMD_IEEE_TxSignature_byte1 == 0x0) &&
6511                         (amd_signature.AMD_IEEE_TxSignature_byte2 == 0x0) &&
6512                         (amd_signature.AMD_IEEE_TxSignature_byte3 == 0x1A))) {
6513
6514                         amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0;
6515                         amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0;
6516                         amd_signature.AMD_IEEE_TxSignature_byte3 = 0x1A;
6517
6518                         core_link_write_dpcd(link, DP_SOURCE_OUI,
6519                                 (uint8_t *)(&amd_signature),
6520                                 sizeof(amd_signature));
6521                 }
6522
6523                 core_link_write_dpcd(link, DP_SOURCE_OUI+0x03,
6524                                 (uint8_t *)(&amd_device_id),
6525                                 sizeof(amd_device_id));
6526
6527                 if (link->ctx->dce_version >= DCN_VERSION_2_0 &&
6528                         link->dc->caps.min_horizontal_blanking_period != 0) {
6529
6530                         uint8_t hblank_size = (uint8_t)link->dc->caps.min_horizontal_blanking_period;
6531
6532                         if (link->preferred_link_setting.dpcd_source_device_specific_field_support) {
6533                                 result_write_min_hblank = core_link_write_dpcd(link,
6534                                         DP_SOURCE_MINIMUM_HBLANK_SUPPORTED, (uint8_t *)(&hblank_size),
6535                                         sizeof(hblank_size));
6536
6537                                 if (result_write_min_hblank == DC_ERROR_UNEXPECTED)
6538                                         link->preferred_link_setting.dpcd_source_device_specific_field_support = false;
6539                         } else {
6540                                 DC_LOG_DC("Sink device does not support 00340h DPCD write. Skipping on purpose.\n");
6541                         }
6542                 }
6543
6544                 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION,
6545                                                         WPP_BIT_FLAG_DC_DETECTION_DP_CAPS,
6546                                                         "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'",
6547                                                         result_write_min_hblank,
6548                                                         link->link_index,
6549                                                         link->ctx->dce_version,
6550                                                         DP_SOURCE_MINIMUM_HBLANK_SUPPORTED,
6551                                                         link->dc->caps.min_horizontal_blanking_period,
6552                                                         link->dpcd_caps.branch_dev_id,
6553                                                         link->dpcd_caps.branch_dev_name[0],
6554                                                         link->dpcd_caps.branch_dev_name[1],
6555                                                         link->dpcd_caps.branch_dev_name[2],
6556                                                         link->dpcd_caps.branch_dev_name[3],
6557                                                         link->dpcd_caps.branch_dev_name[4],
6558                                                         link->dpcd_caps.branch_dev_name[5]);
6559         } else {
6560                 core_link_write_dpcd(link, DP_SOURCE_OUI,
6561                                 link->dc->vendor_signature.data.raw,
6562                                 sizeof(link->dc->vendor_signature.data.raw));
6563         }
6564 }
6565
6566 void dpcd_write_cable_id_to_dprx(struct dc_link *link)
6567 {
6568         if (!link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED ||
6569                         link->dpcd_caps.cable_id.raw == 0 ||
6570                         link->dprx_states.cable_id_written)
6571                 return;
6572
6573         core_link_write_dpcd(link, DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX,
6574                         &link->dpcd_caps.cable_id.raw,
6575                         sizeof(link->dpcd_caps.cable_id.raw));
6576
6577         link->dprx_states.cable_id_written = 1;
6578 }
6579
6580 bool dc_link_set_backlight_level_nits(struct dc_link *link,
6581                 bool isHDR,
6582                 uint32_t backlight_millinits,
6583                 uint32_t transition_time_in_ms)
6584 {
6585         struct dpcd_source_backlight_set dpcd_backlight_set;
6586         uint8_t backlight_control = isHDR ? 1 : 0;
6587
6588         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6589                         link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6590                 return false;
6591
6592         // OLEDs have no PWM, they can only use AUX
6593         if (link->dpcd_sink_ext_caps.bits.oled == 1)
6594                 backlight_control = 1;
6595
6596         *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits;
6597         *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms;
6598
6599
6600         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
6601                         (uint8_t *)(&dpcd_backlight_set),
6602                         sizeof(dpcd_backlight_set)) != DC_OK)
6603                 return false;
6604
6605         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
6606                         &backlight_control, 1) != DC_OK)
6607                 return false;
6608
6609         return true;
6610 }
6611
6612 bool dc_link_get_backlight_level_nits(struct dc_link *link,
6613                 uint32_t *backlight_millinits_avg,
6614                 uint32_t *backlight_millinits_peak)
6615 {
6616         union dpcd_source_backlight_get dpcd_backlight_get;
6617
6618         memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get));
6619
6620         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6621                         link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6622                 return false;
6623
6624         if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
6625                         dpcd_backlight_get.raw,
6626                         sizeof(union dpcd_source_backlight_get)) != DC_OK)
6627                 return false;
6628
6629         *backlight_millinits_avg =
6630                 dpcd_backlight_get.bytes.backlight_millinits_avg;
6631         *backlight_millinits_peak =
6632                 dpcd_backlight_get.bytes.backlight_millinits_peak;
6633
6634         /* On non-supported panels dpcd_read usually succeeds with 0 returned */
6635         if (*backlight_millinits_avg == 0 ||
6636                         *backlight_millinits_avg > *backlight_millinits_peak)
6637                 return false;
6638
6639         return true;
6640 }
6641
6642 bool dc_link_backlight_enable_aux(struct dc_link *link, bool enable)
6643 {
6644         uint8_t backlight_enable = enable ? 1 : 0;
6645
6646         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6647                 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6648                 return false;
6649
6650         if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
6651                 &backlight_enable, 1) != DC_OK)
6652                 return false;
6653
6654         return true;
6655 }
6656
6657 // we read default from 0x320 because we expect BIOS wrote it there
6658 // regular get_backlight_nit reads from panel set at 0x326
6659 bool dc_link_read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits)
6660 {
6661         if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
6662                 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
6663                 return false;
6664
6665         if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
6666                 (uint8_t *) backlight_millinits,
6667                 sizeof(uint32_t)) != DC_OK)
6668                 return false;
6669
6670         return true;
6671 }
6672
6673 bool dc_link_set_default_brightness_aux(struct dc_link *link)
6674 {
6675         uint32_t default_backlight;
6676
6677         if (link && link->dpcd_sink_ext_caps.bits.oled == 1) {
6678                 if (!dc_link_read_default_bl_aux(link, &default_backlight))
6679                         default_backlight = 150000;
6680                 // if < 5 nits or > 5000, it might be wrong readback
6681                 if (default_backlight < 5000 || default_backlight > 5000000)
6682                         default_backlight = 150000; //
6683
6684                 return dc_link_set_backlight_level_nits(link, true,
6685                                 default_backlight, 0);
6686         }
6687         return false;
6688 }
6689
6690 bool is_edp_ilr_optimization_required(struct dc_link *link, struct dc_crtc_timing *crtc_timing)
6691 {
6692         struct dc_link_settings link_setting;
6693         uint8_t link_bw_set;
6694         uint8_t link_rate_set;
6695         uint32_t req_bw;
6696         union lane_count_set lane_count_set = {0};
6697
6698         ASSERT(link || crtc_timing); // invalid input
6699
6700         if (link->dpcd_caps.edp_supported_link_rates_count == 0 ||
6701                         !link->dc->debug.optimize_edp_link_rate)
6702                 return false;
6703
6704
6705         // Read DPCD 00100h to find if standard link rates are set
6706         core_link_read_dpcd(link, DP_LINK_BW_SET,
6707                                 &link_bw_set, sizeof(link_bw_set));
6708
6709         if (link_bw_set) {
6710                 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS used link_bw_set\n");
6711                 return true;
6712         }
6713
6714         // Read DPCD 00115h to find the edp link rate set used
6715         core_link_read_dpcd(link, DP_LINK_RATE_SET,
6716                             &link_rate_set, sizeof(link_rate_set));
6717
6718         // Read DPCD 00101h to find out the number of lanes currently set
6719         core_link_read_dpcd(link, DP_LANE_COUNT_SET,
6720                                 &lane_count_set.raw, sizeof(lane_count_set));
6721
6722         req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing);
6723
6724         if (!crtc_timing->flags.DSC)
6725                 decide_edp_link_settings(link, &link_setting, req_bw);
6726         else
6727                 decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN);
6728
6729         if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate ||
6730                         lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) {
6731                 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS link_rate_set not optimal\n");
6732                 return true;
6733         }
6734
6735         DC_LOG_EVENT_LINK_TRAINING("eDP ILR: No optimization required, VBIOS set optimal link_rate_set\n");
6736         return false;
6737 }
6738
6739 enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings)
6740 {
6741         if ((link_settings->link_rate >= LINK_RATE_LOW) &&
6742                         (link_settings->link_rate <= LINK_RATE_HIGH3))
6743                 return DP_8b_10b_ENCODING;
6744         else if ((link_settings->link_rate >= LINK_RATE_UHBR10) &&
6745                         (link_settings->link_rate <= LINK_RATE_UHBR20))
6746                 return DP_128b_132b_ENCODING;
6747         return DP_UNKNOWN_ENCODING;
6748 }
6749
6750 enum dp_link_encoding dc_link_dp_mst_decide_link_encoding_format(const struct dc_link *link)
6751 {
6752         struct dc_link_settings link_settings = {0};
6753
6754         if (!dc_is_dp_signal(link->connector_signal))
6755                 return DP_UNKNOWN_ENCODING;
6756
6757         if (link->preferred_link_setting.lane_count !=
6758                         LANE_COUNT_UNKNOWN &&
6759                         link->preferred_link_setting.link_rate !=
6760                                         LINK_RATE_UNKNOWN) {
6761                 link_settings = link->preferred_link_setting;
6762         } else {
6763                 decide_mst_link_settings(link, &link_settings);
6764         }
6765
6766         return dp_get_link_encoding_format(&link_settings);
6767 }
6768
6769 // TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
6770 static void get_lane_status(
6771         struct dc_link *link,
6772         uint32_t lane_count,
6773         union lane_status *status,
6774         union lane_align_status_updated *status_updated)
6775 {
6776         unsigned int lane;
6777         uint8_t dpcd_buf[3] = {0};
6778
6779         if (status == NULL || status_updated == NULL) {
6780                 return;
6781         }
6782
6783         core_link_read_dpcd(
6784                         link,
6785                         DP_LANE0_1_STATUS,
6786                         dpcd_buf,
6787                         sizeof(dpcd_buf));
6788
6789         for (lane = 0; lane < lane_count; lane++) {
6790                 status[lane].raw = get_nibble_at_index(&dpcd_buf[0], lane);
6791         }
6792
6793         status_updated->raw = dpcd_buf[2];
6794 }
6795
6796 bool dpcd_write_128b_132b_sst_payload_allocation_table(
6797                 const struct dc_stream_state *stream,
6798                 struct dc_link *link,
6799                 struct link_mst_stream_allocation_table *proposed_table,
6800                 bool allocate)
6801 {
6802         const uint8_t vc_id = 1; /// VC ID always 1 for SST
6803         const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST
6804         bool result = false;
6805         uint8_t req_slot_count = 0;
6806         struct fixed31_32 avg_time_slots_per_mtp = { 0 };
6807         union payload_table_update_status update_status = { 0 };
6808         const uint32_t max_retries = 30;
6809         uint32_t retries = 0;
6810
6811         if (allocate)   {
6812                 avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
6813                 req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
6814         } else {
6815                 /// Leave req_slot_count = 0 if allocate is false.
6816         }
6817
6818         /// Write DPCD 2C0 = 1 to start updating
6819         update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1;
6820         core_link_write_dpcd(
6821                         link,
6822                         DP_PAYLOAD_TABLE_UPDATE_STATUS,
6823                         &update_status.raw,
6824                         1);
6825
6826         /// Program the changes in DPCD 1C0 - 1C2
6827         ASSERT(vc_id == 1);
6828         core_link_write_dpcd(
6829                         link,
6830                         DP_PAYLOAD_ALLOCATE_SET,
6831                         &vc_id,
6832                         1);
6833
6834         ASSERT(start_time_slot == 0);
6835         core_link_write_dpcd(
6836                         link,
6837                         DP_PAYLOAD_ALLOCATE_START_TIME_SLOT,
6838                         &start_time_slot,
6839                         1);
6840
6841         ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT); /// Validation should filter out modes that exceed link BW
6842         core_link_write_dpcd(
6843                         link,
6844                         DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
6845                         &req_slot_count,
6846                         1);
6847
6848         /// Poll till DPCD 2C0 read 1
6849         /// Try for at least 150ms (30 retries, with 5ms delay after each attempt)
6850
6851         while (retries < max_retries) {
6852                 if (core_link_read_dpcd(
6853                                 link,
6854                                 DP_PAYLOAD_TABLE_UPDATE_STATUS,
6855                                 &update_status.raw,
6856                                 1) == DC_OK) {
6857                         if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) {
6858                                 DC_LOG_DP2("SST Update Payload: downstream payload table updated.");
6859                                 result = true;
6860                                 break;
6861                         }
6862                 } else {
6863                         union dpcd_rev dpcdRev;
6864
6865                         if (core_link_read_dpcd(
6866                                         link,
6867                                         DP_DPCD_REV,
6868                                         &dpcdRev.raw,
6869                                         1) != DC_OK) {
6870                                 DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision "
6871                                                 "of sink while polling payload table "
6872                                                 "updated status bit.");
6873                                 break;
6874                         }
6875                 }
6876                 retries++;
6877                 msleep(5);
6878         }
6879
6880         if (!result && retries == max_retries) {
6881                 DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, "
6882                                 "continue on. Something is wrong with the branch.");
6883                 // TODO - DP2.0 Payload: Read and log the payload table from downstream branch
6884         }
6885
6886         proposed_table->stream_count = 1; /// Always 1 stream for SST
6887         proposed_table->stream_allocations[0].slot_count = req_slot_count;
6888         proposed_table->stream_allocations[0].vcp_id = vc_id;
6889
6890         return result;
6891 }
6892
6893 bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link)
6894 {
6895         /*
6896          * wait for ACT handled
6897          */
6898         int i;
6899         const int act_retries = 30;
6900         enum act_return_status result = ACT_FAILED;
6901         union payload_table_update_status update_status = {0};
6902         union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
6903         union lane_align_status_updated lane_status_updated;
6904
6905         for (i = 0; i < act_retries; i++) {
6906                 get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated);
6907
6908                 if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
6909                                 !dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
6910                                 !dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) ||
6911                                 !dp_is_interlane_aligned(lane_status_updated)) {
6912                         DC_LOG_ERROR("SST Update Payload: Link loss occurred while "
6913                                         "polling for ACT handled.");
6914                         result = ACT_LINK_LOST;
6915                         break;
6916                 }
6917                 core_link_read_dpcd(
6918                                 link,
6919                                 DP_PAYLOAD_TABLE_UPDATE_STATUS,
6920                                 &update_status.raw,
6921                                 1);
6922
6923                 if (update_status.bits.ACT_HANDLED == 1) {
6924                         DC_LOG_DP2("SST Update Payload: ACT handled by downstream.");
6925                         result = ACT_SUCCESS;
6926                         break;
6927                 }
6928
6929                 msleep(5);
6930         }
6931
6932         if (result == ACT_FAILED) {
6933                 DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, "
6934                                 "continue on. Something is wrong with the branch.");
6935         }
6936
6937         return (result == ACT_SUCCESS);
6938 }
6939
6940 struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
6941                 const struct dc_stream_state *stream,
6942                 const struct dc_link *link)
6943 {
6944         struct fixed31_32 link_bw_effective =
6945                         dc_fixpt_from_int(
6946                                         dc_link_bandwidth_kbps(link, &link->cur_link_settings));
6947         struct fixed31_32 timeslot_bw_effective =
6948                         dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
6949         struct fixed31_32 timing_bw =
6950                         dc_fixpt_from_int(
6951                                         dc_bandwidth_in_kbps_from_timing(&stream->timing));
6952         struct fixed31_32 avg_time_slots_per_mtp =
6953                         dc_fixpt_div(timing_bw, timeslot_bw_effective);
6954
6955         return avg_time_slots_per_mtp;
6956 }
6957
6958 bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx)
6959 {
6960         /* If this assert is hit then we have a link encoder dynamic management issue */
6961         ASSERT(pipe_ctx->stream_res.hpo_dp_stream_enc ? pipe_ctx->link_res.hpo_dp_link_enc != NULL : true);
6962         return (pipe_ctx->stream_res.hpo_dp_stream_enc &&
6963                         pipe_ctx->link_res.hpo_dp_link_enc &&
6964                         dc_is_dp_signal(pipe_ctx->stream->signal));
6965 }
6966
6967 void edp_panel_backlight_power_on(struct dc_link *link)
6968 {
6969         if (link->connector_signal != SIGNAL_TYPE_EDP)
6970                 return;
6971
6972         link->dc->hwss.edp_power_control(link, true);
6973         link->dc->hwss.edp_wait_for_hpd_ready(link, true);
6974         if (link->dc->hwss.edp_backlight_control)
6975                 link->dc->hwss.edp_backlight_control(link, true);
6976 }
6977
6978 void dc_link_clear_dprx_states(struct dc_link *link)
6979 {
6980         memset(&link->dprx_states, 0, sizeof(link->dprx_states));
6981 }
6982
6983 void dp_receiver_power_ctrl(struct dc_link *link, bool on)
6984 {
6985         uint8_t state;
6986
6987         state = on ? DP_POWER_STATE_D0 : DP_POWER_STATE_D3;
6988
6989         if (link->sync_lt_in_progress)
6990                 return;
6991
6992         core_link_write_dpcd(link, DP_SET_POWER, &state,
6993                                                  sizeof(state));
6994
6995 }
6996
6997 void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
6998 {
6999         if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
7000                 core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
7001                                         &dp_test_mode, sizeof(dp_test_mode));
7002 }
7003
7004
7005 static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
7006 {
7007         switch (lttpr_repeater_count) {
7008         case 0x80: // 1 lttpr repeater
7009                 return 1;
7010         case 0x40: // 2 lttpr repeaters
7011                 return 2;
7012         case 0x20: // 3 lttpr repeaters
7013                 return 3;
7014         case 0x10: // 4 lttpr repeaters
7015                 return 4;
7016         case 0x08: // 5 lttpr repeaters
7017                 return 5;
7018         case 0x04: // 6 lttpr repeaters
7019                 return 6;
7020         case 0x02: // 7 lttpr repeaters
7021                 return 7;
7022         case 0x01: // 8 lttpr repeaters
7023                 return 8;
7024         default:
7025                 break;
7026         }
7027         return 0; // invalid value
7028 }
7029
7030 static inline bool is_immediate_downstream(struct dc_link *link, uint32_t offset)
7031 {
7032         return (convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == offset);
7033 }
7034
7035 void dp_enable_link_phy(
7036         struct dc_link *link,
7037         const struct link_resource *link_res,
7038         enum signal_type signal,
7039         enum clock_source_id clock_source,
7040         const struct dc_link_settings *link_settings)
7041 {
7042         struct dc  *dc = link->ctx->dc;
7043         struct dmcu *dmcu = dc->res_pool->dmcu;
7044         struct pipe_ctx *pipes =
7045                         link->dc->current_state->res_ctx.pipe_ctx;
7046         struct clock_source *dp_cs =
7047                         link->dc->res_pool->dp_clock_source;
7048         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7049         unsigned int i;
7050
7051         if (link->connector_signal == SIGNAL_TYPE_EDP) {
7052                 link->dc->hwss.edp_power_control(link, true);
7053                 link->dc->hwss.edp_wait_for_hpd_ready(link, true);
7054         }
7055
7056         /* If the current pixel clock source is not DTO(happens after
7057          * switching from HDMI passive dongle to DP on the same connector),
7058          * switch the pixel clock source to DTO.
7059          */
7060         for (i = 0; i < MAX_PIPES; i++) {
7061                 if (pipes[i].stream != NULL &&
7062                         pipes[i].stream->link == link) {
7063                         if (pipes[i].clock_source != NULL &&
7064                                         pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) {
7065                                 pipes[i].clock_source = dp_cs;
7066                                 pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz =
7067                                                 pipes[i].stream->timing.pix_clk_100hz;
7068                                 pipes[i].clock_source->funcs->program_pix_clk(
7069                                                         pipes[i].clock_source,
7070                                                         &pipes[i].stream_res.pix_clk_params,
7071                                                         &pipes[i].pll_settings);
7072                         }
7073                 }
7074         }
7075
7076         link->cur_link_settings = *link_settings;
7077
7078         if (dp_get_link_encoding_format(link_settings) == DP_8b_10b_ENCODING) {
7079                 if (dc->clk_mgr->funcs->notify_link_rate_change)
7080                         dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
7081         }
7082
7083         if (dmcu != NULL && dmcu->funcs->lock_phy)
7084                 dmcu->funcs->lock_phy(dmcu);
7085
7086         if (link_hwss->ext.enable_dp_link_output)
7087                 link_hwss->ext.enable_dp_link_output(link, link_res, signal,
7088                                 clock_source, link_settings);
7089
7090         if (dmcu != NULL && dmcu->funcs->unlock_phy)
7091                 dmcu->funcs->unlock_phy(dmcu);
7092
7093         dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
7094         dp_receiver_power_ctrl(link, true);
7095 }
7096
7097 void edp_add_delay_for_T9(struct dc_link *link)
7098 {
7099         if (link->local_sink &&
7100                         link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off > 0)
7101                 udelay(link->local_sink->edid_caps.panel_patch.extra_delay_backlight_off * 1000);
7102 }
7103
7104 bool edp_receiver_ready_T9(struct dc_link *link)
7105 {
7106         unsigned int tries = 0;
7107         unsigned char sinkstatus = 0;
7108         unsigned char edpRev = 0;
7109         enum dc_status result = DC_OK;
7110
7111         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
7112
7113         /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
7114         if (result == DC_OK && edpRev >= DP_EDP_12) {
7115                 do {
7116                         sinkstatus = 1;
7117                         result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
7118                         if (sinkstatus == 0)
7119                                 break;
7120                         if (result != DC_OK)
7121                                 break;
7122                         udelay(100); //MAx T9
7123                 } while (++tries < 50);
7124         }
7125
7126         return result;
7127 }
7128 bool edp_receiver_ready_T7(struct dc_link *link)
7129 {
7130         unsigned char sinkstatus = 0;
7131         unsigned char edpRev = 0;
7132         enum dc_status result = DC_OK;
7133
7134         /* use absolute time stamp to constrain max T7*/
7135         unsigned long long enter_timestamp = 0;
7136         unsigned long long finish_timestamp = 0;
7137         unsigned long long time_taken_in_ns = 0;
7138
7139         result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev));
7140
7141         if (result == DC_OK && edpRev >= DP_EDP_12) {
7142                 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/
7143                 enter_timestamp = dm_get_timestamp(link->ctx);
7144                 do {
7145                         sinkstatus = 0;
7146                         result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus));
7147                         if (sinkstatus == 1)
7148                                 break;
7149                         if (result != DC_OK)
7150                                 break;
7151                         udelay(25);
7152                         finish_timestamp = dm_get_timestamp(link->ctx);
7153                         time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp);
7154                 } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms
7155         }
7156
7157         if (link->local_sink &&
7158                         link->local_sink->edid_caps.panel_patch.extra_t7_ms > 0)
7159                 udelay(link->local_sink->edid_caps.panel_patch.extra_t7_ms * 1000);
7160
7161         return result;
7162 }
7163
7164 void dp_disable_link_phy(struct dc_link *link, const struct link_resource *link_res,
7165                 enum signal_type signal)
7166 {
7167         struct dc  *dc = link->ctx->dc;
7168         struct dmcu *dmcu = dc->res_pool->dmcu;
7169         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7170
7171         if (!link->wa_flags.dp_keep_receiver_powered)
7172                 dp_receiver_power_ctrl(link, false);
7173
7174         if (signal == SIGNAL_TYPE_EDP) {
7175                 if (link->dc->hwss.edp_backlight_control)
7176                         link->dc->hwss.edp_backlight_control(link, false);
7177                 if (link_hwss->ext.disable_dp_link_output)
7178                         link_hwss->ext.disable_dp_link_output(link, link_res, signal);
7179                 link->dc->hwss.edp_power_control(link, false);
7180         } else {
7181                 if (dmcu != NULL && dmcu->funcs->lock_phy)
7182                         dmcu->funcs->lock_phy(dmcu);
7183                 if (link_hwss->ext.disable_dp_link_output)
7184                         link_hwss->ext.disable_dp_link_output(link, link_res, signal);
7185                 if (dmcu != NULL && dmcu->funcs->unlock_phy)
7186                         dmcu->funcs->unlock_phy(dmcu);
7187         }
7188
7189         dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
7190
7191         /* Clear current link setting.*/
7192         memset(&link->cur_link_settings, 0,
7193                         sizeof(link->cur_link_settings));
7194
7195         if (dc->clk_mgr->funcs->notify_link_rate_change)
7196                 dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link);
7197 }
7198
7199 void dp_disable_link_phy_mst(struct dc_link *link, const struct link_resource *link_res,
7200                 enum signal_type signal)
7201 {
7202         /* MST disable link only when no stream use the link */
7203         if (link->mst_stream_alloc_table.stream_count > 0)
7204                 return;
7205
7206         dp_disable_link_phy(link, link_res, signal);
7207
7208         /* set the sink to SST mode after disabling the link */
7209         dp_enable_mst_on_sink(link, false);
7210 }
7211
7212 bool dp_set_hw_training_pattern(
7213         struct dc_link *link,
7214         const struct link_resource *link_res,
7215         enum dc_dp_training_pattern pattern,
7216         uint32_t offset)
7217 {
7218         enum dp_test_pattern test_pattern = DP_TEST_PATTERN_UNSUPPORTED;
7219
7220         switch (pattern) {
7221         case DP_TRAINING_PATTERN_SEQUENCE_1:
7222                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN1;
7223                 break;
7224         case DP_TRAINING_PATTERN_SEQUENCE_2:
7225                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN2;
7226                 break;
7227         case DP_TRAINING_PATTERN_SEQUENCE_3:
7228                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN3;
7229                 break;
7230         case DP_TRAINING_PATTERN_SEQUENCE_4:
7231                 test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
7232                 break;
7233         case DP_128b_132b_TPS1:
7234                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE;
7235                 break;
7236         case DP_128b_132b_TPS2:
7237                 test_pattern = DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE;
7238                 break;
7239         default:
7240                 break;
7241         }
7242
7243         dp_set_hw_test_pattern(link, link_res, test_pattern, NULL, 0);
7244
7245         return true;
7246 }
7247
7248 void dp_set_hw_lane_settings(
7249         struct dc_link *link,
7250         const struct link_resource *link_res,
7251         const struct link_training_settings *link_settings,
7252         uint32_t offset)
7253 {
7254         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7255
7256         if ((link->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && !is_immediate_downstream(link, offset))
7257                 return;
7258
7259         if (link_hwss->ext.set_dp_lane_settings)
7260                 link_hwss->ext.set_dp_lane_settings(link, link_res,
7261                                 &link_settings->link_settings,
7262                                 link_settings->hw_lane_settings);
7263
7264         memmove(link->cur_lane_setting,
7265                         link_settings->hw_lane_settings,
7266                         sizeof(link->cur_lane_setting));
7267 }
7268
7269 void dp_set_hw_test_pattern(
7270         struct dc_link *link,
7271         const struct link_resource *link_res,
7272         enum dp_test_pattern test_pattern,
7273         uint8_t *custom_pattern,
7274         uint32_t custom_pattern_size)
7275 {
7276         const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
7277         struct encoder_set_dp_phy_pattern_param pattern_param = {0};
7278
7279         pattern_param.dp_phy_pattern = test_pattern;
7280         pattern_param.custom_pattern = custom_pattern;
7281         pattern_param.custom_pattern_size = custom_pattern_size;
7282         pattern_param.dp_panel_mode = dp_get_panel_mode(link);
7283
7284         if (link_hwss->ext.set_dp_link_test_pattern)
7285                 link_hwss->ext.set_dp_link_test_pattern(link, link_res, &pattern_param);
7286 }
7287
7288 void dp_retrain_link_dp_test(struct dc_link *link,
7289                         struct dc_link_settings *link_setting,
7290                         bool skip_video_pattern)
7291 {
7292         struct pipe_ctx *pipes =
7293                         &link->dc->current_state->res_ctx.pipe_ctx[0];
7294         unsigned int i;
7295
7296
7297         for (i = 0; i < MAX_PIPES; i++) {
7298                 if (pipes[i].stream != NULL &&
7299                         !pipes[i].top_pipe && !pipes[i].prev_odm_pipe &&
7300                         pipes[i].stream->link != NULL &&
7301                         pipes[i].stream_res.stream_enc != NULL &&
7302                         pipes[i].stream->link == link) {
7303                         udelay(100);
7304
7305                         pipes[i].stream_res.stream_enc->funcs->dp_blank(link,
7306                                         pipes[i].stream_res.stream_enc);
7307
7308                         /* disable any test pattern that might be active */
7309                         dp_set_hw_test_pattern(link, &pipes[i].link_res,
7310                                         DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
7311
7312                         dp_receiver_power_ctrl(link, false);
7313
7314                         link->dc->hwss.disable_stream(&pipes[i]);
7315                         if ((&pipes[i])->stream_res.audio && !link->dc->debug.az_endpoint_mute_only)
7316                                 (&pipes[i])->stream_res.audio->funcs->az_disable((&pipes[i])->stream_res.audio);
7317
7318                         if (link->link_enc)
7319                                 link->link_enc->funcs->disable_output(
7320                                                 link->link_enc,
7321                                                 SIGNAL_TYPE_DISPLAY_PORT);
7322
7323                         /* Clear current link setting. */
7324                         memset(&link->cur_link_settings, 0,
7325                                 sizeof(link->cur_link_settings));
7326
7327                         perform_link_training_with_retries(
7328                                         link_setting,
7329                                         skip_video_pattern,
7330                                         LINK_TRAINING_ATTEMPTS,
7331                                         &pipes[i],
7332                                         SIGNAL_TYPE_DISPLAY_PORT,
7333                                         false);
7334
7335                         link->dc->hwss.enable_stream(&pipes[i]);
7336
7337                         link->dc->hwss.unblank_stream(&pipes[i],
7338                                         link_setting);
7339
7340                         if (pipes[i].stream_res.audio) {
7341                                 /* notify audio driver for
7342                                  * audio modes of monitor */
7343                                 pipes[i].stream_res.audio->funcs->az_enable(
7344                                                 pipes[i].stream_res.audio);
7345
7346                                 /* un-mute audio */
7347                                 /* TODO: audio should be per stream rather than
7348                                  * per link */
7349                                 pipes[i].stream_res.stream_enc->funcs->
7350                                 audio_mute_control(
7351                                         pipes[i].stream_res.stream_enc, false);
7352                         }
7353                 }
7354         }
7355 }
7356
7357 #undef DC_LOGGER
7358 #define DC_LOGGER \
7359         dsc->ctx->logger
7360 static void dsc_optc_config_log(struct display_stream_compressor *dsc,
7361                 struct dsc_optc_config *config)
7362 {
7363         uint32_t precision = 1 << 28;
7364         uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
7365         uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
7366         uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
7367
7368         /* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
7369          * bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
7370          * 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
7371          */
7372         ll_bytes_per_pix_fraq *= 10000000;
7373         ll_bytes_per_pix_fraq /= precision;
7374
7375         DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
7376                         config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
7377         DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
7378         DC_LOG_DSC("\tslice_width %d", config->slice_width);
7379 }
7380
7381 bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
7382 {
7383         struct dc *dc = pipe_ctx->stream->ctx->dc;
7384         struct dc_stream_state *stream = pipe_ctx->stream;
7385         bool result = false;
7386
7387         if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
7388                 result = true;
7389         else
7390                 result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
7391         return result;
7392 }
7393
7394 /* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
7395  * i.e. after dp_enable_dsc_on_rx() had been called
7396  */
7397 void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
7398 {
7399         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7400         struct dc *dc = pipe_ctx->stream->ctx->dc;
7401         struct dc_stream_state *stream = pipe_ctx->stream;
7402         struct pipe_ctx *odm_pipe;
7403         int opp_cnt = 1;
7404
7405         for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
7406                 opp_cnt++;
7407
7408         if (enable) {
7409                 struct dsc_config dsc_cfg;
7410                 struct dsc_optc_config dsc_optc_cfg;
7411                 enum optc_dsc_mode optc_dsc_mode;
7412
7413                 /* Enable DSC hw block */
7414                 dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
7415                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
7416                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
7417                 dsc_cfg.color_depth = stream->timing.display_color_depth;
7418                 dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
7419                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
7420                 ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
7421                 dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
7422
7423                 dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
7424                 dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
7425                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
7426                         struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
7427
7428                         odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
7429                         odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
7430                 }
7431                 dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
7432                 dsc_cfg.pic_width *= opp_cnt;
7433
7434                 optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
7435
7436                 /* Enable DSC in encoder */
7437                 if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
7438                                 && !is_dp_128b_132b_signal(pipe_ctx)) {
7439                         DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
7440                         dsc_optc_config_log(dsc, &dsc_optc_cfg);
7441                         pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
7442                                                                         optc_dsc_mode,
7443                                                                         dsc_optc_cfg.bytes_per_pixel,
7444                                                                         dsc_optc_cfg.slice_width);
7445
7446                         /* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
7447                 }
7448
7449                 /* Enable DSC in OPTC */
7450                 DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
7451                 dsc_optc_config_log(dsc, &dsc_optc_cfg);
7452                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
7453                                                         optc_dsc_mode,
7454                                                         dsc_optc_cfg.bytes_per_pixel,
7455                                                         dsc_optc_cfg.slice_width);
7456         } else {
7457                 /* disable DSC in OPTC */
7458                 pipe_ctx->stream_res.tg->funcs->set_dsc_config(
7459                                 pipe_ctx->stream_res.tg,
7460                                 OPTC_DSC_DISABLED, 0, 0);
7461
7462                 /* disable DSC in stream encoder */
7463                 if (dc_is_dp_signal(stream->signal)) {
7464                         if (is_dp_128b_132b_signal(pipe_ctx))
7465                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7466                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7467                                                                                 false,
7468                                                                                 NULL,
7469                                                                                 true);
7470                         else if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
7471                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
7472                                                 pipe_ctx->stream_res.stream_enc,
7473                                                 OPTC_DSC_DISABLED, 0, 0);
7474                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7475                                                         pipe_ctx->stream_res.stream_enc, false, NULL, true);
7476                         }
7477                 }
7478
7479                 /* disable DSC block */
7480                 pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
7481                 for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
7482                         odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
7483         }
7484 }
7485
7486 bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
7487 {
7488         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7489         bool result = false;
7490
7491         if (!pipe_ctx->stream->timing.flags.DSC)
7492                 goto out;
7493         if (!dsc)
7494                 goto out;
7495
7496         if (enable) {
7497                 {
7498                         dp_set_dsc_on_stream(pipe_ctx, true);
7499                         result = true;
7500                 }
7501         } else {
7502                 dp_set_dsc_on_rx(pipe_ctx, false);
7503                 dp_set_dsc_on_stream(pipe_ctx, false);
7504                 result = true;
7505         }
7506 out:
7507         return result;
7508 }
7509
7510 /*
7511  * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
7512  * hence PPS info packet update need to use frame update instead of immediate update.
7513  * Added parameter immediate_update for this purpose.
7514  * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
7515  * which is the only place where a "false" would be passed in for param immediate_update.
7516  *
7517  * immediate_update is only applicable when DSC is enabled.
7518  */
7519 bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
7520 {
7521         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7522         struct dc_stream_state *stream = pipe_ctx->stream;
7523
7524         if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
7525                 return false;
7526
7527         if (enable) {
7528                 struct dsc_config dsc_cfg;
7529                 uint8_t dsc_packed_pps[128];
7530
7531                 memset(&dsc_cfg, 0, sizeof(dsc_cfg));
7532                 memset(dsc_packed_pps, 0, 128);
7533
7534                 /* Enable DSC hw block */
7535                 dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
7536                 dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
7537                 dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
7538                 dsc_cfg.color_depth = stream->timing.display_color_depth;
7539                 dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
7540                 dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
7541
7542                 DC_LOG_DSC(" ");
7543                 dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
7544                 if (dc_is_dp_signal(stream->signal)) {
7545                         DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
7546                         if (is_dp_128b_132b_signal(pipe_ctx))
7547                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7548                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7549                                                                                 true,
7550                                                                                 &dsc_packed_pps[0],
7551                                                                                 immediate_update);
7552                         else
7553                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7554                                                 pipe_ctx->stream_res.stream_enc,
7555                                                 true,
7556                                                 &dsc_packed_pps[0],
7557                                                 immediate_update);
7558                 }
7559         } else {
7560                 /* disable DSC PPS in stream encoder */
7561                 if (dc_is_dp_signal(stream->signal)) {
7562                         if (is_dp_128b_132b_signal(pipe_ctx))
7563                                 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
7564                                                                                 pipe_ctx->stream_res.hpo_dp_stream_enc,
7565                                                                                 false,
7566                                                                                 NULL,
7567                                                                                 true);
7568                         else
7569                                 pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
7570                                                 pipe_ctx->stream_res.stream_enc, false, NULL, true);
7571                 }
7572         }
7573
7574         return true;
7575 }
7576
7577
7578 bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
7579 {
7580         struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
7581
7582         if (!pipe_ctx->stream->timing.flags.DSC)
7583                 return false;
7584         if (!dsc)
7585                 return false;
7586
7587         dp_set_dsc_on_stream(pipe_ctx, true);
7588         dp_set_dsc_pps_sdp(pipe_ctx, true, false);
7589         return true;
7590 }
7591
7592 #undef DC_LOGGER
7593 #define DC_LOGGER \
7594         link->ctx->logger