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