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