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