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