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