1 /*	$NetBSD: amdgpu_dc_link_dp.c,v 1.5 2021/12/19 11:22:40 riastradh Exp $	*/
2 
3 /* Copyright 2015 Advanced Micro Devices, Inc. */
4 #include <sys/cdefs.h>
5 __KERNEL_RCSID(0, "$NetBSD: amdgpu_dc_link_dp.c,v 1.5 2021/12/19 11:22:40 riastradh Exp $");
6 
7 #include "dm_services.h"
8 #include "dc.h"
9 #include "dc_link_dp.h"
10 #include "dm_helpers.h"
11 #include "opp.h"
12 #include "dsc.h"
13 #include "resource.h"
14 
15 #include "inc/core_types.h"
16 #include "link_hwss.h"
17 #include "dc_link_ddc.h"
18 #include "core_status.h"
19 #include "dpcd_defs.h"
20 
21 #include "resource.h"
22 #define DC_LOGGER \
23 	link->ctx->logger
24 
25 
26 #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE   0x50
27 
28 /* maximum pre emphasis level allowed for each voltage swing level*/
29 static const enum dc_pre_emphasis voltage_swing_to_pre_emphasis[] = {
30 		PRE_EMPHASIS_LEVEL3,
31 		PRE_EMPHASIS_LEVEL2,
32 		PRE_EMPHASIS_LEVEL1,
33 		PRE_EMPHASIS_DISABLED };
34 
35 enum {
36 	POST_LT_ADJ_REQ_LIMIT = 6,
37 	POST_LT_ADJ_REQ_TIMEOUT = 200
38 };
39 
40 enum {
41 	LINK_TRAINING_MAX_RETRY_COUNT = 5,
42 	/* to avoid infinite loop where-in the receiver
43 	 * switches between different VS
44 	 */
45 	LINK_TRAINING_MAX_CR_RETRY = 100
46 };
47 
48 static bool decide_fallback_link_setting(
49 		struct dc_link_settings initial_link_settings,
50 		struct dc_link_settings *current_link_setting,
51 		enum link_training_result training_result);
52 static struct dc_link_settings get_common_supported_link_settings(
53 		struct dc_link_settings link_setting_a,
54 		struct dc_link_settings link_setting_b);
55 
get_training_aux_rd_interval(struct dc_link * link,uint32_t default_wait_in_micro_secs)56 static uint32_t get_training_aux_rd_interval(
57 	struct dc_link *link,
58 	uint32_t default_wait_in_micro_secs)
59 {
60 	union training_aux_rd_interval training_rd_interval;
61 
62 	memset(&training_rd_interval, 0, sizeof(training_rd_interval));
63 
64 	/* overwrite the delay if rev > 1.1*/
65 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
66 		/* DP 1.2 or later - retrieve delay through
67 		 * "DPCD_ADDR_TRAINING_AUX_RD_INTERVAL" register */
68 		core_link_read_dpcd(
69 			link,
70 			DP_TRAINING_AUX_RD_INTERVAL,
71 			(uint8_t *)&training_rd_interval,
72 			sizeof(training_rd_interval));
73 
74 		if (training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL)
75 			default_wait_in_micro_secs = training_rd_interval.bits.TRAINIG_AUX_RD_INTERVAL * 4000;
76 	}
77 
78 	return default_wait_in_micro_secs;
79 }
80 
wait_for_training_aux_rd_interval(struct dc_link * link,uint32_t wait_in_micro_secs)81 static void wait_for_training_aux_rd_interval(
82 	struct dc_link *link,
83 	uint32_t wait_in_micro_secs)
84 {
85 	udelay(wait_in_micro_secs);
86 
87 	DC_LOG_HW_LINK_TRAINING("%s:\n wait = %d\n",
88 		__func__,
89 		wait_in_micro_secs);
90 }
91 
dpcd_set_training_pattern(struct dc_link * link,union dpcd_training_pattern dpcd_pattern)92 static void dpcd_set_training_pattern(
93 	struct dc_link *link,
94 	union dpcd_training_pattern dpcd_pattern)
95 {
96 	core_link_write_dpcd(
97 		link,
98 		DP_TRAINING_PATTERN_SET,
99 		&dpcd_pattern.raw,
100 		1);
101 
102 	DC_LOG_HW_LINK_TRAINING("%s\n %x pattern = %x\n",
103 		__func__,
104 		DP_TRAINING_PATTERN_SET,
105 		dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
106 }
107 
get_supported_tp(struct dc_link * link)108 static enum dc_dp_training_pattern get_supported_tp(struct dc_link *link)
109 {
110 	enum dc_dp_training_pattern highest_tp = DP_TRAINING_PATTERN_SEQUENCE_2;
111 	struct encoder_feature_support *features = &link->link_enc->features;
112 	struct dpcd_caps *dpcd_caps = &link->dpcd_caps;
113 
114 	if (features->flags.bits.IS_TPS3_CAPABLE)
115 		highest_tp = DP_TRAINING_PATTERN_SEQUENCE_3;
116 
117 	if (features->flags.bits.IS_TPS4_CAPABLE)
118 		highest_tp = DP_TRAINING_PATTERN_SEQUENCE_4;
119 
120 	if (dpcd_caps->max_down_spread.bits.TPS4_SUPPORTED &&
121 		highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_4)
122 		return DP_TRAINING_PATTERN_SEQUENCE_4;
123 
124 	if (dpcd_caps->max_ln_count.bits.TPS3_SUPPORTED &&
125 		highest_tp >= DP_TRAINING_PATTERN_SEQUENCE_3)
126 		return DP_TRAINING_PATTERN_SEQUENCE_3;
127 
128 	return DP_TRAINING_PATTERN_SEQUENCE_2;
129 }
130 
dpcd_set_link_settings(struct dc_link * link,const struct link_training_settings * lt_settings)131 static void dpcd_set_link_settings(
132 	struct dc_link *link,
133 	const struct link_training_settings *lt_settings)
134 {
135 	uint8_t rate;
136 
137 	union down_spread_ctrl downspread = { {0} };
138 	union lane_count_set lane_count_set = { {0} };
139 	enum dc_dp_training_pattern dp_tr_pattern;
140 
141 	downspread.raw = (uint8_t)
142 	(lt_settings->link_settings.link_spread);
143 
144 	lane_count_set.bits.LANE_COUNT_SET =
145 	lt_settings->link_settings.lane_count;
146 
147 	lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
148 	lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
149 
150 	dp_tr_pattern = get_supported_tp(link);
151 
152 	if (dp_tr_pattern != DP_TRAINING_PATTERN_SEQUENCE_4) {
153 		lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
154 				link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
155 	}
156 
157 	core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
158 		&downspread.raw, sizeof(downspread));
159 
160 	core_link_write_dpcd(link, DP_LANE_COUNT_SET,
161 		&lane_count_set.raw, 1);
162 
163 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
164 			lt_settings->link_settings.use_link_rate_set == true) {
165 		rate = 0;
166 		core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
167 		core_link_write_dpcd(link, DP_LINK_RATE_SET,
168 				&lt_settings->link_settings.link_rate_set, 1);
169 	} else {
170 		rate = (uint8_t) (lt_settings->link_settings.link_rate);
171 		core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
172 	}
173 
174 	if (rate) {
175 		DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
176 			__func__,
177 			DP_LINK_BW_SET,
178 			lt_settings->link_settings.link_rate,
179 			DP_LANE_COUNT_SET,
180 			lt_settings->link_settings.lane_count,
181 			lt_settings->enhanced_framing,
182 			DP_DOWNSPREAD_CTRL,
183 			lt_settings->link_settings.link_spread);
184 	} else {
185 		DC_LOG_HW_LINK_TRAINING("%s\n %x rate set = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
186 			__func__,
187 			DP_LINK_RATE_SET,
188 			lt_settings->link_settings.link_rate_set,
189 			DP_LANE_COUNT_SET,
190 			lt_settings->link_settings.lane_count,
191 			lt_settings->enhanced_framing,
192 			DP_DOWNSPREAD_CTRL,
193 			lt_settings->link_settings.link_spread);
194 	}
195 }
196 
197 static enum dpcd_training_patterns
dc_dp_training_pattern_to_dpcd_training_pattern(struct dc_link * link,enum dc_dp_training_pattern pattern)198 	dc_dp_training_pattern_to_dpcd_training_pattern(
199 	struct dc_link *link,
200 	enum dc_dp_training_pattern pattern)
201 {
202 	enum dpcd_training_patterns dpcd_tr_pattern =
203 	DPCD_TRAINING_PATTERN_VIDEOIDLE;
204 
205 	switch (pattern) {
206 	case DP_TRAINING_PATTERN_SEQUENCE_1:
207 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_1;
208 		break;
209 	case DP_TRAINING_PATTERN_SEQUENCE_2:
210 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_2;
211 		break;
212 	case DP_TRAINING_PATTERN_SEQUENCE_3:
213 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_3;
214 		break;
215 	case DP_TRAINING_PATTERN_SEQUENCE_4:
216 		dpcd_tr_pattern = DPCD_TRAINING_PATTERN_4;
217 		break;
218 	default:
219 		ASSERT(0);
220 		DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
221 			__func__, pattern);
222 		break;
223 	}
224 
225 	return dpcd_tr_pattern;
226 }
227 
is_repeater(struct dc_link * link,uint32_t offset)228 static inline bool is_repeater(struct dc_link *link, uint32_t offset)
229 {
230 	return (!link->is_lttpr_mode_transparent && offset != 0);
231 }
232 
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)233 static void dpcd_set_lt_pattern_and_lane_settings(
234 	struct dc_link *link,
235 	const struct link_training_settings *lt_settings,
236 	enum dc_dp_training_pattern pattern,
237 	uint32_t offset)
238 {
239 	union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = { { {0} } };
240 
241 	uint32_t dpcd_base_lt_offset;
242 
243 	uint8_t dpcd_lt_buffer[5] = {0};
244 	union dpcd_training_pattern dpcd_pattern = { {0} };
245 	uint32_t lane;
246 	uint32_t size_in_bytes;
247 	bool edp_workaround = false; /* TODO link_prop.INTERNAL */
248 	dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET;
249 
250 	if (is_repeater(link, offset))
251 		dpcd_base_lt_offset = DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
252 			((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
253 
254 	/*****************************************************************
255 	* DpcdAddress_TrainingPatternSet
256 	*****************************************************************/
257 	dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
258 		dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
259 
260 	dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
261 		= dpcd_pattern.raw;
262 
263 	if (is_repeater(link, offset)) {
264 		DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n 0x%X pattern = %x\n",
265 			__func__,
266 			offset,
267 			dpcd_base_lt_offset,
268 			dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
269 	} else {
270 		DC_LOG_HW_LINK_TRAINING("%s\n 0x%X pattern = %x\n",
271 			__func__,
272 			dpcd_base_lt_offset,
273 			dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
274 	}
275 	/*****************************************************************
276 	* DpcdAddress_Lane0Set -> DpcdAddress_Lane3Set
277 	*****************************************************************/
278 	for (lane = 0; lane <
279 		(uint32_t)(lt_settings->link_settings.lane_count); lane++) {
280 
281 		dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
282 		(uint8_t)(lt_settings->lane_settings[lane].VOLTAGE_SWING);
283 		dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
284 		(uint8_t)(lt_settings->lane_settings[lane].PRE_EMPHASIS);
285 
286 		dpcd_lane[lane].bits.MAX_SWING_REACHED =
287 		(lt_settings->lane_settings[lane].VOLTAGE_SWING ==
288 		VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
289 		dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
290 		(lt_settings->lane_settings[lane].PRE_EMPHASIS ==
291 		PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
292 	}
293 
294 	/* concatenate everything into one buffer*/
295 
296 	size_in_bytes = lt_settings->link_settings.lane_count * sizeof(dpcd_lane[0]);
297 
298 	 // 0x00103 - 0x00102
299 	memmove(
300 		&dpcd_lt_buffer[DP_TRAINING_LANE0_SET - DP_TRAINING_PATTERN_SET],
301 		dpcd_lane,
302 		size_in_bytes);
303 
304 	if (is_repeater(link, offset)) {
305 		DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
306 				" 0x%X VS set = %x PE set = %x max VS Reached = %x  max PE Reached = %x\n",
307 			__func__,
308 			offset,
309 			dpcd_base_lt_offset,
310 			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
311 			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
312 			dpcd_lane[0].bits.MAX_SWING_REACHED,
313 			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
314 	} else {
315 		DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
316 			__func__,
317 			dpcd_base_lt_offset,
318 			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
319 			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
320 			dpcd_lane[0].bits.MAX_SWING_REACHED,
321 			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
322 	}
323 	if (edp_workaround) {
324 		/* for eDP write in 2 parts because the 5-byte burst is
325 		* causing issues on some eDP panels (EPR#366724)
326 		*/
327 		core_link_write_dpcd(
328 			link,
329 			DP_TRAINING_PATTERN_SET,
330 			&dpcd_pattern.raw,
331 			sizeof(dpcd_pattern.raw));
332 
333 		core_link_write_dpcd(
334 			link,
335 			DP_TRAINING_LANE0_SET,
336 			(uint8_t *)(dpcd_lane),
337 			size_in_bytes);
338 
339 		} else
340 		/* write it all in (1 + number-of-lanes)-byte burst*/
341 			core_link_write_dpcd(
342 				link,
343 				dpcd_base_lt_offset,
344 				dpcd_lt_buffer,
345 				size_in_bytes + sizeof(dpcd_pattern.raw));
346 
347 	link->cur_lane_setting = lt_settings->lane_settings[0];
348 }
349 
is_cr_done(enum dc_lane_count ln_count,union lane_status * dpcd_lane_status)350 static bool is_cr_done(enum dc_lane_count ln_count,
351 	union lane_status *dpcd_lane_status)
352 {
353 	bool done = true;
354 	uint32_t lane;
355 	/*LANEx_CR_DONE bits All 1's?*/
356 	for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
357 		if (!dpcd_lane_status[lane].bits.CR_DONE_0)
358 			done = false;
359 	}
360 	return done;
361 
362 }
363 
is_ch_eq_done(enum dc_lane_count ln_count,union lane_status * dpcd_lane_status,union lane_align_status_updated * lane_status_updated)364 static bool is_ch_eq_done(enum dc_lane_count ln_count,
365 	union lane_status *dpcd_lane_status,
366 	union lane_align_status_updated *lane_status_updated)
367 {
368 	bool done = true;
369 	uint32_t lane;
370 	if (!lane_status_updated->bits.INTERLANE_ALIGN_DONE)
371 		done = false;
372 	else {
373 		for (lane = 0; lane < (uint32_t)(ln_count); lane++) {
374 			if (!dpcd_lane_status[lane].bits.SYMBOL_LOCKED_0 ||
375 				!dpcd_lane_status[lane].bits.CHANNEL_EQ_DONE_0)
376 				done = false;
377 		}
378 	}
379 	return done;
380 
381 }
382 
update_drive_settings(struct link_training_settings * dest,struct link_training_settings src)383 static void update_drive_settings(
384 		struct link_training_settings *dest,
385 		struct link_training_settings src)
386 {
387 	uint32_t lane;
388 	for (lane = 0; lane < src.link_settings.lane_count; lane++) {
389 		if (dest->voltage_swing == NULL)
390 			dest->lane_settings[lane].VOLTAGE_SWING = src.lane_settings[lane].VOLTAGE_SWING;
391 		else
392 			dest->lane_settings[lane].VOLTAGE_SWING = *dest->voltage_swing;
393 
394 		if (dest->pre_emphasis == NULL)
395 			dest->lane_settings[lane].PRE_EMPHASIS = src.lane_settings[lane].PRE_EMPHASIS;
396 		else
397 			dest->lane_settings[lane].PRE_EMPHASIS = *dest->pre_emphasis;
398 
399 		if (dest->post_cursor2 == NULL)
400 			dest->lane_settings[lane].POST_CURSOR2 = src.lane_settings[lane].POST_CURSOR2;
401 		else
402 			dest->lane_settings[lane].POST_CURSOR2 = *dest->post_cursor2;
403 	}
404 }
405 
get_nibble_at_index(const uint8_t * buf,uint32_t index)406 static uint8_t get_nibble_at_index(const uint8_t *buf,
407 	uint32_t index)
408 {
409 	uint8_t nibble;
410 	nibble = buf[index / 2];
411 
412 	if (index % 2)
413 		nibble >>= 4;
414 	else
415 		nibble &= 0x0F;
416 
417 	return nibble;
418 }
419 
get_max_pre_emphasis_for_voltage_swing(enum dc_voltage_swing voltage)420 static enum dc_pre_emphasis get_max_pre_emphasis_for_voltage_swing(
421 	enum dc_voltage_swing voltage)
422 {
423 	enum dc_pre_emphasis pre_emphasis;
424 	pre_emphasis = PRE_EMPHASIS_MAX_LEVEL;
425 
426 	if (voltage <= VOLTAGE_SWING_MAX_LEVEL)
427 		pre_emphasis = voltage_swing_to_pre_emphasis[voltage];
428 
429 	return pre_emphasis;
430 
431 }
432 
find_max_drive_settings(const struct link_training_settings * link_training_setting,struct link_training_settings * max_lt_setting)433 static void find_max_drive_settings(
434 	const struct link_training_settings *link_training_setting,
435 	struct link_training_settings *max_lt_setting)
436 {
437 	uint32_t lane;
438 	struct dc_lane_settings max_requested;
439 
440 	max_requested.VOLTAGE_SWING =
441 		link_training_setting->
442 		lane_settings[0].VOLTAGE_SWING;
443 	max_requested.PRE_EMPHASIS =
444 		link_training_setting->
445 		lane_settings[0].PRE_EMPHASIS;
446 	/*max_requested.postCursor2 =
447 	 * link_training_setting->laneSettings[0].postCursor2;*/
448 
449 	/* Determine what the maximum of the requested settings are*/
450 	for (lane = 1; lane < link_training_setting->link_settings.lane_count;
451 			lane++) {
452 		if (link_training_setting->lane_settings[lane].VOLTAGE_SWING >
453 			max_requested.VOLTAGE_SWING)
454 
455 			max_requested.VOLTAGE_SWING =
456 			link_training_setting->
457 			lane_settings[lane].VOLTAGE_SWING;
458 
459 		if (link_training_setting->lane_settings[lane].PRE_EMPHASIS >
460 				max_requested.PRE_EMPHASIS)
461 			max_requested.PRE_EMPHASIS =
462 			link_training_setting->
463 			lane_settings[lane].PRE_EMPHASIS;
464 
465 		/*
466 		if (link_training_setting->laneSettings[lane].postCursor2 >
467 		 max_requested.postCursor2)
468 		{
469 		max_requested.postCursor2 =
470 		link_training_setting->laneSettings[lane].postCursor2;
471 		}
472 		*/
473 	}
474 
475 	/* make sure the requested settings are
476 	 * not higher than maximum settings*/
477 	if (max_requested.VOLTAGE_SWING > VOLTAGE_SWING_MAX_LEVEL)
478 		max_requested.VOLTAGE_SWING = VOLTAGE_SWING_MAX_LEVEL;
479 
480 	if (max_requested.PRE_EMPHASIS > PRE_EMPHASIS_MAX_LEVEL)
481 		max_requested.PRE_EMPHASIS = PRE_EMPHASIS_MAX_LEVEL;
482 	/*
483 	if (max_requested.postCursor2 > PostCursor2_MaxLevel)
484 	max_requested.postCursor2 = PostCursor2_MaxLevel;
485 	*/
486 
487 	/* make sure the pre-emphasis matches the voltage swing*/
488 	if (max_requested.PRE_EMPHASIS >
489 		get_max_pre_emphasis_for_voltage_swing(
490 			max_requested.VOLTAGE_SWING))
491 		max_requested.PRE_EMPHASIS =
492 		get_max_pre_emphasis_for_voltage_swing(
493 			max_requested.VOLTAGE_SWING);
494 
495 	/*
496 	 * Post Cursor2 levels are completely independent from
497 	 * pre-emphasis (Post Cursor1) levels. But Post Cursor2 levels
498 	 * can only be applied to each allowable combination of voltage
499 	 * swing and pre-emphasis levels */
500 	 /* if ( max_requested.postCursor2 >
501 	  *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing))
502 	  *  max_requested.postCursor2 =
503 	  *  getMaxPostCursor2ForVoltageSwing(max_requested.voltageSwing);
504 	  */
505 
506 	max_lt_setting->link_settings.link_rate =
507 		link_training_setting->link_settings.link_rate;
508 	max_lt_setting->link_settings.lane_count =
509 	link_training_setting->link_settings.lane_count;
510 	max_lt_setting->link_settings.link_spread =
511 		link_training_setting->link_settings.link_spread;
512 
513 	for (lane = 0; lane <
514 		link_training_setting->link_settings.lane_count;
515 		lane++) {
516 		max_lt_setting->lane_settings[lane].VOLTAGE_SWING =
517 			max_requested.VOLTAGE_SWING;
518 		max_lt_setting->lane_settings[lane].PRE_EMPHASIS =
519 			max_requested.PRE_EMPHASIS;
520 		/*max_lt_setting->laneSettings[lane].postCursor2 =
521 		 * max_requested.postCursor2;
522 		 */
523 	}
524 
525 }
526 
get_lane_status_and_drive_settings(struct dc_link * link,const struct link_training_settings * link_training_setting,union lane_status * ln_status,union lane_align_status_updated * ln_status_updated,struct link_training_settings * req_settings,uint32_t offset)527 static void get_lane_status_and_drive_settings(
528 	struct dc_link *link,
529 	const struct link_training_settings *link_training_setting,
530 	union lane_status *ln_status,
531 	union lane_align_status_updated *ln_status_updated,
532 	struct link_training_settings *req_settings,
533 	uint32_t offset)
534 {
535 	unsigned int lane01_status_address = DP_LANE0_1_STATUS;
536 	uint8_t lane_adjust_offset = 4;
537 	unsigned int lane01_adjust_address;
538 	uint8_t dpcd_buf[6] = {0};
539 	union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = { { {0} } };
540 	struct link_training_settings request_settings = { {0} };
541 	uint32_t lane;
542 
543 	memset(req_settings, '\0', sizeof(struct link_training_settings));
544 
545 	if (is_repeater(link, offset)) {
546 		lane01_status_address =
547 				DP_LANE0_1_STATUS_PHY_REPEATER1 +
548 				((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
549 		lane_adjust_offset = 3;
550 	}
551 
552 	core_link_read_dpcd(
553 		link,
554 		lane01_status_address,
555 		(uint8_t *)(dpcd_buf),
556 		sizeof(dpcd_buf));
557 
558 	for (lane = 0; lane <
559 		(uint32_t)(link_training_setting->link_settings.lane_count);
560 		lane++) {
561 
562 		ln_status[lane].raw =
563 			get_nibble_at_index(&dpcd_buf[0], lane);
564 		dpcd_lane_adjust[lane].raw =
565 			get_nibble_at_index(&dpcd_buf[lane_adjust_offset], lane);
566 	}
567 
568 	ln_status_updated->raw = dpcd_buf[2];
569 
570 	if (is_repeater(link, offset)) {
571 		DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
572 				" 0x%X Lane01Status = %x\n 0x%X Lane23Status = %x\n ",
573 			__func__,
574 			offset,
575 			lane01_status_address, dpcd_buf[0],
576 			lane01_status_address + 1, dpcd_buf[1]);
577 	} else {
578 		DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X Lane01Status = %x\n 0x%X Lane23Status = %x\n ",
579 			__func__,
580 			lane01_status_address, dpcd_buf[0],
581 			lane01_status_address + 1, dpcd_buf[1]);
582 	}
583 	lane01_adjust_address = DP_ADJUST_REQUEST_LANE0_1;
584 
585 	if (is_repeater(link, offset))
586 		lane01_adjust_address = DP_ADJUST_REQUEST_LANE0_1_PHY_REPEATER1 +
587 				((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
588 
589 	if (is_repeater(link, offset)) {
590 		DC_LOG_HW_LINK_TRAINING("%s:\n LTTPR Repeater ID: %d\n"
591 				" 0x%X Lane01AdjustRequest = %x\n 0x%X Lane23AdjustRequest = %x\n",
592 					__func__,
593 					offset,
594 					lane01_adjust_address,
595 					dpcd_buf[lane_adjust_offset],
596 					lane01_adjust_address + 1,
597 					dpcd_buf[lane_adjust_offset + 1]);
598 	} else {
599 		DC_LOG_HW_LINK_TRAINING("%s:\n 0x%X Lane01AdjustRequest = %x\n 0x%X Lane23AdjustRequest = %x\n",
600 			__func__,
601 			lane01_adjust_address,
602 			dpcd_buf[lane_adjust_offset],
603 			lane01_adjust_address + 1,
604 			dpcd_buf[lane_adjust_offset + 1]);
605 	}
606 
607 	/*copy to req_settings*/
608 	request_settings.link_settings.lane_count =
609 		link_training_setting->link_settings.lane_count;
610 	request_settings.link_settings.link_rate =
611 		link_training_setting->link_settings.link_rate;
612 	request_settings.link_settings.link_spread =
613 		link_training_setting->link_settings.link_spread;
614 
615 	for (lane = 0; lane <
616 		(uint32_t)(link_training_setting->link_settings.lane_count);
617 		lane++) {
618 
619 		request_settings.lane_settings[lane].VOLTAGE_SWING =
620 			(enum dc_voltage_swing)(dpcd_lane_adjust[lane].bits.
621 				VOLTAGE_SWING_LANE);
622 		request_settings.lane_settings[lane].PRE_EMPHASIS =
623 			(enum dc_pre_emphasis)(dpcd_lane_adjust[lane].bits.
624 				PRE_EMPHASIS_LANE);
625 	}
626 
627 	/*Note: for postcursor2, read adjusted
628 	 * postcursor2 settings from*/
629 	/*DpcdAddress_AdjustRequestPostCursor2 =
630 	 *0x020C (not implemented yet)*/
631 
632 	/* we find the maximum of the requested settings across all lanes*/
633 	/* and set this maximum for all lanes*/
634 	find_max_drive_settings(&request_settings, req_settings);
635 
636 	/* if post cursor 2 is needed in the future,
637 	 * read DpcdAddress_AdjustRequestPostCursor2 = 0x020C
638 	 */
639 
640 }
641 
dpcd_set_lane_settings(struct dc_link * link,const struct link_training_settings * link_training_setting,uint32_t offset)642 static void dpcd_set_lane_settings(
643 	struct dc_link *link,
644 	const struct link_training_settings *link_training_setting,
645 	uint32_t offset)
646 {
647 	union dpcd_training_lane dpcd_lane[LANE_COUNT_DP_MAX] = {{{0}}};
648 	uint32_t lane;
649 	unsigned int lane0_set_address;
650 
651 	lane0_set_address = DP_TRAINING_LANE0_SET;
652 
653 	if (is_repeater(link, offset))
654 		lane0_set_address = DP_TRAINING_LANE0_SET_PHY_REPEATER1 +
655 		((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
656 
657 	for (lane = 0; lane <
658 		(uint32_t)(link_training_setting->
659 		link_settings.lane_count);
660 		lane++) {
661 		dpcd_lane[lane].bits.VOLTAGE_SWING_SET =
662 			(uint8_t)(link_training_setting->
663 			lane_settings[lane].VOLTAGE_SWING);
664 		dpcd_lane[lane].bits.PRE_EMPHASIS_SET =
665 			(uint8_t)(link_training_setting->
666 			lane_settings[lane].PRE_EMPHASIS);
667 		dpcd_lane[lane].bits.MAX_SWING_REACHED =
668 			(link_training_setting->
669 			lane_settings[lane].VOLTAGE_SWING ==
670 			VOLTAGE_SWING_MAX_LEVEL ? 1 : 0);
671 		dpcd_lane[lane].bits.MAX_PRE_EMPHASIS_REACHED =
672 			(link_training_setting->
673 			lane_settings[lane].PRE_EMPHASIS ==
674 			PRE_EMPHASIS_MAX_LEVEL ? 1 : 0);
675 	}
676 
677 	core_link_write_dpcd(link,
678 		lane0_set_address,
679 		(uint8_t *)(dpcd_lane),
680 		link_training_setting->link_settings.lane_count);
681 
682 	/*
683 	if (LTSettings.link.rate == LinkRate_High2)
684 	{
685 		DpcdTrainingLaneSet2 dpcd_lane2[lane_count_DPMax] = {0};
686 		for ( uint32_t lane = 0;
687 		lane < lane_count_DPMax; lane++)
688 		{
689 			dpcd_lane2[lane].bits.post_cursor2_set =
690 			static_cast<unsigned char>(
691 			LTSettings.laneSettings[lane].postCursor2);
692 			dpcd_lane2[lane].bits.max_post_cursor2_reached = 0;
693 		}
694 		m_pDpcdAccessSrv->WriteDpcdData(
695 		DpcdAddress_Lane0Set2,
696 		reinterpret_cast<unsigned char*>(dpcd_lane2),
697 		LTSettings.link.lanes);
698 	}
699 	*/
700 
701 	if (is_repeater(link, offset)) {
702 		DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Repeater ID: %d\n"
703 				" 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
704 			__func__,
705 			offset,
706 			lane0_set_address,
707 			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
708 			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
709 			dpcd_lane[0].bits.MAX_SWING_REACHED,
710 			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
711 
712 	} else {
713 		DC_LOG_HW_LINK_TRAINING("%s\n 0x%X VS set = %x  PE set = %x max VS Reached = %x  max PE Reached = %x\n",
714 			__func__,
715 			lane0_set_address,
716 			dpcd_lane[0].bits.VOLTAGE_SWING_SET,
717 			dpcd_lane[0].bits.PRE_EMPHASIS_SET,
718 			dpcd_lane[0].bits.MAX_SWING_REACHED,
719 			dpcd_lane[0].bits.MAX_PRE_EMPHASIS_REACHED);
720 	}
721 	link->cur_lane_setting = link_training_setting->lane_settings[0];
722 
723 }
724 
is_max_vs_reached(const struct link_training_settings * lt_settings)725 static bool is_max_vs_reached(
726 	const struct link_training_settings *lt_settings)
727 {
728 	uint32_t lane;
729 	for (lane = 0; lane <
730 		(uint32_t)(lt_settings->link_settings.lane_count);
731 		lane++) {
732 		if (lt_settings->lane_settings[lane].VOLTAGE_SWING
733 			== VOLTAGE_SWING_MAX_LEVEL)
734 			return true;
735 	}
736 	return false;
737 
738 }
739 
perform_post_lt_adj_req_sequence(struct dc_link * link,struct link_training_settings * lt_settings)740 static bool perform_post_lt_adj_req_sequence(
741 	struct dc_link *link,
742 	struct link_training_settings *lt_settings)
743 {
744 	enum dc_lane_count lane_count =
745 	lt_settings->link_settings.lane_count;
746 
747 	uint32_t adj_req_count;
748 	uint32_t adj_req_timer;
749 	bool req_drv_setting_changed;
750 	uint32_t lane;
751 
752 	req_drv_setting_changed = false;
753 	for (adj_req_count = 0; adj_req_count < POST_LT_ADJ_REQ_LIMIT;
754 	adj_req_count++) {
755 
756 		req_drv_setting_changed = false;
757 
758 		for (adj_req_timer = 0;
759 			adj_req_timer < POST_LT_ADJ_REQ_TIMEOUT;
760 			adj_req_timer++) {
761 
762 			struct link_training_settings req_settings;
763 			union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
764 			union lane_align_status_updated
765 				dpcd_lane_status_updated;
766 
767 			get_lane_status_and_drive_settings(
768 			link,
769 			lt_settings,
770 			dpcd_lane_status,
771 			&dpcd_lane_status_updated,
772 			&req_settings,
773 			DPRX);
774 
775 			if (dpcd_lane_status_updated.bits.
776 					POST_LT_ADJ_REQ_IN_PROGRESS == 0)
777 				return true;
778 
779 			if (!is_cr_done(lane_count, dpcd_lane_status))
780 				return false;
781 
782 			if (!is_ch_eq_done(
783 				lane_count,
784 				dpcd_lane_status,
785 				&dpcd_lane_status_updated))
786 				return false;
787 
788 			for (lane = 0; lane < (uint32_t)(lane_count); lane++) {
789 
790 				if (lt_settings->
791 				lane_settings[lane].VOLTAGE_SWING !=
792 				req_settings.lane_settings[lane].
793 				VOLTAGE_SWING ||
794 				lt_settings->lane_settings[lane].PRE_EMPHASIS !=
795 				req_settings.lane_settings[lane].PRE_EMPHASIS) {
796 
797 					req_drv_setting_changed = true;
798 					break;
799 				}
800 			}
801 
802 			if (req_drv_setting_changed) {
803 				update_drive_settings(
804 					lt_settings, req_settings);
805 
806 				dc_link_dp_set_drive_settings(link,
807 						lt_settings);
808 				break;
809 			}
810 
811 			msleep(1);
812 		}
813 
814 		if (!req_drv_setting_changed) {
815 			DC_LOG_WARNING("%s: Post Link Training Adjust Request Timed out\n",
816 				__func__);
817 
818 			ASSERT(0);
819 			return true;
820 		}
821 	}
822 	DC_LOG_WARNING("%s: Post Link Training Adjust Request limit reached\n",
823 		__func__);
824 
825 	ASSERT(0);
826 	return true;
827 
828 }
829 
830 /* Only used for channel equalization */
translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval)831 static uint32_t translate_training_aux_read_interval(uint32_t dpcd_aux_read_interval)
832 {
833 	unsigned int aux_rd_interval_us = 400;
834 
835 	switch (dpcd_aux_read_interval) {
836 	case 0x01:
837 		aux_rd_interval_us = 400;
838 		break;
839 	case 0x02:
840 		aux_rd_interval_us = 4000;
841 		break;
842 	case 0x03:
843 		aux_rd_interval_us = 8000;
844 		break;
845 	case 0x04:
846 		aux_rd_interval_us = 16000;
847 		break;
848 	default:
849 		break;
850 	}
851 
852 	return aux_rd_interval_us;
853 }
854 
get_cr_failure(enum dc_lane_count ln_count,union lane_status * dpcd_lane_status)855 static enum link_training_result get_cr_failure(enum dc_lane_count ln_count,
856 					union lane_status *dpcd_lane_status)
857 {
858 	enum link_training_result result = LINK_TRAINING_SUCCESS;
859 
860 	if (ln_count >= LANE_COUNT_ONE && !dpcd_lane_status[0].bits.CR_DONE_0)
861 		result = LINK_TRAINING_CR_FAIL_LANE0;
862 	else if (ln_count >= LANE_COUNT_TWO && !dpcd_lane_status[1].bits.CR_DONE_0)
863 		result = LINK_TRAINING_CR_FAIL_LANE1;
864 	else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[2].bits.CR_DONE_0)
865 		result = LINK_TRAINING_CR_FAIL_LANE23;
866 	else if (ln_count >= LANE_COUNT_FOUR && !dpcd_lane_status[3].bits.CR_DONE_0)
867 		result = LINK_TRAINING_CR_FAIL_LANE23;
868 	return result;
869 }
870 
perform_channel_equalization_sequence(struct dc_link * link,struct link_training_settings * lt_settings,uint32_t offset)871 static enum link_training_result perform_channel_equalization_sequence(
872 	struct dc_link *link,
873 	struct link_training_settings *lt_settings,
874 	uint32_t offset)
875 {
876 	struct link_training_settings req_settings;
877 	enum dc_dp_training_pattern tr_pattern;
878 	uint32_t retries_ch_eq;
879 	uint32_t wait_time_microsec;
880 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
881 	union lane_align_status_updated dpcd_lane_status_updated = { {0} };
882 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = { { {0} } };
883 
884 	/* Note: also check that TPS4 is a supported feature*/
885 
886 	tr_pattern = lt_settings->pattern_for_eq;
887 
888 	if (is_repeater(link, offset))
889 		tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_4;
890 
891 	dp_set_hw_training_pattern(link, tr_pattern, offset);
892 
893 	for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
894 		retries_ch_eq++) {
895 
896 		dp_set_hw_lane_settings(link, lt_settings, offset);
897 
898 		/* 2. update DPCD*/
899 		if (!retries_ch_eq)
900 			/* EPR #361076 - write as a 5-byte burst,
901 			 * but only for the 1-st iteration
902 			 */
903 
904 			dpcd_set_lt_pattern_and_lane_settings(
905 				link,
906 				lt_settings,
907 				tr_pattern, offset);
908 		else
909 			dpcd_set_lane_settings(link, lt_settings, offset);
910 
911 		/* 3. wait for receiver to lock-on*/
912 		wait_time_microsec = lt_settings->eq_pattern_time;
913 
914 		if (is_repeater(link, offset))
915 			wait_time_microsec =
916 					translate_training_aux_read_interval(
917 						link->dpcd_caps.lttpr_caps.aux_rd_interval[offset - 1]);
918 
919 		wait_for_training_aux_rd_interval(
920 				link,
921 				wait_time_microsec);
922 
923 		/* 4. Read lane status and requested
924 		 * drive settings as set by the sink*/
925 
926 		get_lane_status_and_drive_settings(
927 			link,
928 			lt_settings,
929 			dpcd_lane_status,
930 			&dpcd_lane_status_updated,
931 			&req_settings,
932 			offset);
933 
934 		/* 5. check CR done*/
935 		if (!is_cr_done(lane_count, dpcd_lane_status))
936 			return LINK_TRAINING_EQ_FAIL_CR;
937 
938 		/* 6. check CHEQ done*/
939 		if (is_ch_eq_done(lane_count,
940 			dpcd_lane_status,
941 			&dpcd_lane_status_updated))
942 			return LINK_TRAINING_SUCCESS;
943 
944 		/* 7. update VS/PE/PC2 in lt_settings*/
945 		update_drive_settings(lt_settings, req_settings);
946 	}
947 
948 	return LINK_TRAINING_EQ_FAIL_EQ;
949 
950 }
951 #define TRAINING_AUX_RD_INTERVAL 100 //us
952 
perform_clock_recovery_sequence(struct dc_link * link,struct link_training_settings * lt_settings,uint32_t offset)953 static enum link_training_result perform_clock_recovery_sequence(
954 	struct dc_link *link,
955 	struct link_training_settings *lt_settings,
956 	uint32_t offset)
957 {
958 	uint32_t retries_cr;
959 	uint32_t retry_count;
960 	uint32_t wait_time_microsec;
961 	struct link_training_settings req_settings;
962 	enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
963 	enum dc_dp_training_pattern tr_pattern = DP_TRAINING_PATTERN_SEQUENCE_1;
964 	union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
965 	union lane_align_status_updated dpcd_lane_status_updated;
966 
967 	retries_cr = 0;
968 	retry_count = 0;
969 
970 	dp_set_hw_training_pattern(link, tr_pattern, offset);
971 
972 	/* najeeb - The synaptics MST hub can put the LT in
973 	* infinite loop by switching the VS
974 	*/
975 	/* between level 0 and level 1 continuously, here
976 	* we try for CR lock for LinkTrainingMaxCRRetry count*/
977 	while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
978 		(retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
979 
980 		memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
981 		memset(&dpcd_lane_status_updated, '\0',
982 		sizeof(dpcd_lane_status_updated));
983 
984 		/* 1. call HWSS to set lane settings*/
985 		dp_set_hw_lane_settings(
986 				link,
987 				lt_settings,
988 				offset);
989 
990 		/* 2. update DPCD of the receiver*/
991 		if (!retry_count)
992 			/* EPR #361076 - write as a 5-byte burst,
993 			 * but only for the 1-st iteration.*/
994 			dpcd_set_lt_pattern_and_lane_settings(
995 					link,
996 					lt_settings,
997 					tr_pattern,
998 					offset);
999 		else
1000 			dpcd_set_lane_settings(
1001 					link,
1002 					lt_settings,
1003 					offset);
1004 
1005 		/* 3. wait receiver to lock-on*/
1006 		wait_time_microsec = lt_settings->cr_pattern_time;
1007 
1008 		if (!link->is_lttpr_mode_transparent)
1009 			wait_time_microsec = TRAINING_AUX_RD_INTERVAL;
1010 
1011 		wait_for_training_aux_rd_interval(
1012 				link,
1013 				wait_time_microsec);
1014 
1015 		/* 4. Read lane status and requested drive
1016 		* settings as set by the sink
1017 		*/
1018 		get_lane_status_and_drive_settings(
1019 				link,
1020 				lt_settings,
1021 				dpcd_lane_status,
1022 				&dpcd_lane_status_updated,
1023 				&req_settings,
1024 				offset);
1025 
1026 		/* 5. check CR done*/
1027 		if (is_cr_done(lane_count, dpcd_lane_status))
1028 			return LINK_TRAINING_SUCCESS;
1029 
1030 		/* 6. max VS reached*/
1031 		if (is_max_vs_reached(lt_settings))
1032 			break;
1033 
1034 		/* 7. same voltage*/
1035 		/* Note: VS same for all lanes,
1036 		* so comparing first lane is sufficient*/
1037 		if (lt_settings->lane_settings[0].VOLTAGE_SWING ==
1038 			req_settings.lane_settings[0].VOLTAGE_SWING)
1039 			retries_cr++;
1040 		else
1041 			retries_cr = 0;
1042 
1043 		/* 8. update VS/PE/PC2 in lt_settings*/
1044 		update_drive_settings(lt_settings, req_settings);
1045 
1046 		retry_count++;
1047 	}
1048 
1049 	if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
1050 		ASSERT(0);
1051 		DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
1052 			__func__,
1053 			LINK_TRAINING_MAX_CR_RETRY);
1054 
1055 	}
1056 
1057 	return get_cr_failure(lane_count, dpcd_lane_status);
1058 }
1059 
perform_link_training_int(struct dc_link * link,struct link_training_settings * lt_settings,enum link_training_result status)1060 static inline enum link_training_result perform_link_training_int(
1061 	struct dc_link *link,
1062 	struct link_training_settings *lt_settings,
1063 	enum link_training_result status)
1064 {
1065 	union lane_count_set lane_count_set = { {0} };
1066 	union dpcd_training_pattern dpcd_pattern = { {0} };
1067 
1068 	/* 3. set training not in progress*/
1069 	dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
1070 	dpcd_set_training_pattern(link, dpcd_pattern);
1071 
1072 	/* 4. mainlink output idle pattern*/
1073 	dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
1074 
1075 	/*
1076 	 * 5. post training adjust if required
1077 	 * If the upstream DPTX and downstream DPRX both support TPS4,
1078 	 * TPS4 must be used instead of POST_LT_ADJ_REQ.
1079 	 */
1080 	if (link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED != 1 ||
1081 			get_supported_tp(link) == DP_TRAINING_PATTERN_SEQUENCE_4)
1082 		return status;
1083 
1084 	if (status == LINK_TRAINING_SUCCESS &&
1085 		perform_post_lt_adj_req_sequence(link, lt_settings) == false)
1086 		status = LINK_TRAINING_LQA_FAIL;
1087 
1088 	lane_count_set.bits.LANE_COUNT_SET = lt_settings->link_settings.lane_count;
1089 	lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
1090 	lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
1091 
1092 	core_link_write_dpcd(
1093 		link,
1094 		DP_LANE_COUNT_SET,
1095 		&lane_count_set.raw,
1096 		sizeof(lane_count_set));
1097 
1098 	return status;
1099 }
1100 
initialize_training_settings(struct dc_link * link,const struct dc_link_settings * link_setting,const struct dc_link_training_overrides * overrides,struct link_training_settings * lt_settings)1101 static void initialize_training_settings(
1102 	 struct dc_link *link,
1103 	const struct dc_link_settings *link_setting,
1104 	const struct dc_link_training_overrides *overrides,
1105 	struct link_training_settings *lt_settings)
1106 {
1107 	uint32_t lane;
1108 
1109 	memset(lt_settings, '\0', sizeof(struct link_training_settings));
1110 
1111 	/* Initialize link settings */
1112 	lt_settings->link_settings.use_link_rate_set = link_setting->use_link_rate_set;
1113 	lt_settings->link_settings.link_rate_set = link_setting->link_rate_set;
1114 
1115 	if (link->preferred_link_setting.link_rate != LINK_RATE_UNKNOWN)
1116 		lt_settings->link_settings.link_rate = link->preferred_link_setting.link_rate;
1117 	else
1118 		lt_settings->link_settings.link_rate = link_setting->link_rate;
1119 
1120 	if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN)
1121 		lt_settings->link_settings.lane_count = link->preferred_link_setting.lane_count;
1122 	else
1123 		lt_settings->link_settings.lane_count = link_setting->lane_count;
1124 
1125 	/*@todo[vdevulap] move SS to LS, should not be handled by displaypath*/
1126 
1127 	/* TODO hard coded to SS for now
1128 	 * lt_settings.link_settings.link_spread =
1129 	 * dal_display_path_is_ss_supported(
1130 	 * path_mode->display_path) ?
1131 	 * LINK_SPREAD_05_DOWNSPREAD_30KHZ :
1132 	 * LINK_SPREAD_DISABLED;
1133 	 */
1134 	/* Initialize link spread */
1135 	if (link->dp_ss_off)
1136 		lt_settings->link_settings.link_spread = LINK_SPREAD_DISABLED;
1137 	else if (overrides->downspread != NULL)
1138 		lt_settings->link_settings.link_spread
1139 			= *overrides->downspread
1140 			? LINK_SPREAD_05_DOWNSPREAD_30KHZ
1141 			: LINK_SPREAD_DISABLED;
1142 	else
1143 		lt_settings->link_settings.link_spread = LINK_SPREAD_05_DOWNSPREAD_30KHZ;
1144 
1145 	/* Initialize lane settings overrides */
1146 	if (overrides->voltage_swing != NULL)
1147 		lt_settings->voltage_swing = overrides->voltage_swing;
1148 
1149 	if (overrides->pre_emphasis != NULL)
1150 		lt_settings->pre_emphasis = overrides->pre_emphasis;
1151 
1152 	if (overrides->post_cursor2 != NULL)
1153 		lt_settings->post_cursor2 = overrides->post_cursor2;
1154 
1155 	/* Initialize lane settings (VS/PE/PC2) */
1156 	for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
1157 		lt_settings->lane_settings[lane].VOLTAGE_SWING =
1158 			lt_settings->voltage_swing != NULL ?
1159 			*lt_settings->voltage_swing :
1160 			VOLTAGE_SWING_LEVEL0;
1161 		lt_settings->lane_settings[lane].PRE_EMPHASIS =
1162 			lt_settings->pre_emphasis != NULL ?
1163 			*lt_settings->pre_emphasis
1164 			: PRE_EMPHASIS_DISABLED;
1165 		lt_settings->lane_settings[lane].POST_CURSOR2 =
1166 			lt_settings->post_cursor2 != NULL ?
1167 			*lt_settings->post_cursor2
1168 			: POST_CURSOR2_DISABLED;
1169 	}
1170 
1171 	/* Initialize training timings */
1172 	if (overrides->cr_pattern_time != NULL)
1173 		lt_settings->cr_pattern_time = *overrides->cr_pattern_time;
1174 	else
1175 		lt_settings->cr_pattern_time = get_training_aux_rd_interval(link, 100);
1176 
1177 	if (overrides->eq_pattern_time != NULL)
1178 		lt_settings->eq_pattern_time = *overrides->eq_pattern_time;
1179 	else
1180 		lt_settings->eq_pattern_time = get_training_aux_rd_interval(link, 400);
1181 
1182 	if (overrides->pattern_for_eq != NULL)
1183 		lt_settings->pattern_for_eq = *overrides->pattern_for_eq;
1184 	else
1185 		lt_settings->pattern_for_eq = get_supported_tp(link);
1186 
1187 	if (overrides->enhanced_framing != NULL)
1188 		lt_settings->enhanced_framing = *overrides->enhanced_framing;
1189 	else
1190 		lt_settings->enhanced_framing = 1;
1191 }
1192 
convert_to_count(uint8_t lttpr_repeater_count)1193 static uint8_t convert_to_count(uint8_t lttpr_repeater_count)
1194 {
1195 	switch (lttpr_repeater_count) {
1196 	case 0x80: // 1 lttpr repeater
1197 		return 1;
1198 	case 0x40: // 2 lttpr repeaters
1199 		return 2;
1200 	case 0x20: // 3 lttpr repeaters
1201 		return 3;
1202 	case 0x10: // 4 lttpr repeaters
1203 		return 4;
1204 	case 0x08: // 5 lttpr repeaters
1205 		return 5;
1206 	case 0x04: // 6 lttpr repeaters
1207 		return 6;
1208 	case 0x02: // 7 lttpr repeaters
1209 		return 7;
1210 	case 0x01: // 8 lttpr repeaters
1211 		return 8;
1212 	default:
1213 		break;
1214 	}
1215 	return 0; // invalid value
1216 }
1217 
configure_lttpr_mode(struct dc_link * link)1218 static void configure_lttpr_mode(struct dc_link *link)
1219 {
1220 	/* aux timeout is already set to extended */
1221 	/* RESET/SET lttpr mode to enable non transparent mode */
1222 	uint8_t repeater_cnt;
1223 	uint32_t aux_interval_address;
1224 	uint8_t repeater_id;
1225 	enum dc_status result = DC_ERROR_UNEXPECTED;
1226 	uint8_t repeater_mode = DP_PHY_REPEATER_MODE_TRANSPARENT;
1227 
1228 	DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Transparent Mode\n", __func__);
1229 	result = core_link_write_dpcd(link,
1230 			DP_PHY_REPEATER_MODE,
1231 			(uint8_t *)&repeater_mode,
1232 			sizeof(repeater_mode));
1233 
1234 	if (result == DC_OK) {
1235 		link->dpcd_caps.lttpr_caps.mode = repeater_mode;
1236 	}
1237 
1238 	if (!link->is_lttpr_mode_transparent) {
1239 
1240 		DC_LOG_HW_LINK_TRAINING("%s\n Set LTTPR to Non Transparent Mode\n", __func__);
1241 
1242 		repeater_mode = DP_PHY_REPEATER_MODE_NON_TRANSPARENT;
1243 		result = core_link_write_dpcd(link,
1244 				DP_PHY_REPEATER_MODE,
1245 				(uint8_t *)&repeater_mode,
1246 				sizeof(repeater_mode));
1247 
1248 		if (result == DC_OK) {
1249 			link->dpcd_caps.lttpr_caps.mode = repeater_mode;
1250 		}
1251 
1252 		repeater_cnt = convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
1253 		for (repeater_id = repeater_cnt; repeater_id > 0; repeater_id--) {
1254 			aux_interval_address = DP_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 +
1255 						((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
1256 			core_link_read_dpcd(
1257 				link,
1258 				aux_interval_address,
1259 				(uint8_t *)&link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1],
1260 				sizeof(link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1]));
1261 			link->dpcd_caps.lttpr_caps.aux_rd_interval[repeater_id - 1] &= 0x7F;
1262 		}
1263 	}
1264 }
1265 
repeater_training_done(struct dc_link * link,uint32_t offset)1266 static void repeater_training_done(struct dc_link *link, uint32_t offset)
1267 {
1268 	union dpcd_training_pattern dpcd_pattern = { {0} };
1269 
1270 	const uint32_t dpcd_base_lt_offset =
1271 			DP_TRAINING_PATTERN_SET_PHY_REPEATER1 +
1272 				((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
1273 	/* Set training not in progress*/
1274 	dpcd_pattern.v1_4.TRAINING_PATTERN_SET = DPCD_TRAINING_PATTERN_VIDEOIDLE;
1275 
1276 	core_link_write_dpcd(
1277 		link,
1278 		dpcd_base_lt_offset,
1279 		&dpcd_pattern.raw,
1280 		1);
1281 
1282 	DC_LOG_HW_LINK_TRAINING("%s\n LTTPR Id: %d 0x%X pattern = %x\n",
1283 		__func__,
1284 		offset,
1285 		dpcd_base_lt_offset,
1286 		dpcd_pattern.v1_4.TRAINING_PATTERN_SET);
1287 }
1288 
print_status_message(struct dc_link * link,const struct link_training_settings * lt_settings,enum link_training_result status)1289 static void print_status_message(
1290 	struct dc_link *link,
1291 	const struct link_training_settings *lt_settings,
1292 	enum link_training_result status)
1293 {
1294 	const char *link_rate = "Unknown";
1295 	const char *lt_result = "Unknown";
1296 	const char *lt_spread = "Disabled";
1297 
1298 	switch (lt_settings->link_settings.link_rate) {
1299 	case LINK_RATE_LOW:
1300 		link_rate = "RBR";
1301 		break;
1302 	case LINK_RATE_HIGH:
1303 		link_rate = "HBR";
1304 		break;
1305 	case LINK_RATE_HIGH2:
1306 		link_rate = "HBR2";
1307 		break;
1308 	case LINK_RATE_RBR2:
1309 		link_rate = "RBR2";
1310 		break;
1311 	case LINK_RATE_HIGH3:
1312 		link_rate = "HBR3";
1313 		break;
1314 	default:
1315 		break;
1316 	}
1317 
1318 	switch (status) {
1319 	case LINK_TRAINING_SUCCESS:
1320 		lt_result = "pass";
1321 		break;
1322 	case LINK_TRAINING_CR_FAIL_LANE0:
1323 		lt_result = "CR failed lane0";
1324 		break;
1325 	case LINK_TRAINING_CR_FAIL_LANE1:
1326 		lt_result = "CR failed lane1";
1327 		break;
1328 	case LINK_TRAINING_CR_FAIL_LANE23:
1329 		lt_result = "CR failed lane23";
1330 		break;
1331 	case LINK_TRAINING_EQ_FAIL_CR:
1332 		lt_result = "CR failed in EQ";
1333 		break;
1334 	case LINK_TRAINING_EQ_FAIL_EQ:
1335 		lt_result = "EQ failed";
1336 		break;
1337 	case LINK_TRAINING_LQA_FAIL:
1338 		lt_result = "LQA failed";
1339 		break;
1340 	default:
1341 		break;
1342 	}
1343 
1344 	switch (lt_settings->link_settings.link_spread) {
1345 	case LINK_SPREAD_DISABLED:
1346 		lt_spread = "Disabled";
1347 		break;
1348 	case LINK_SPREAD_05_DOWNSPREAD_30KHZ:
1349 		lt_spread = "0.5% 30KHz";
1350 		break;
1351 	case LINK_SPREAD_05_DOWNSPREAD_33KHZ:
1352 		lt_spread = "0.5% 33KHz";
1353 		break;
1354 	default:
1355 		break;
1356 	}
1357 
1358 	/* Connectivity log: link training */
1359 	CONN_MSG_LT(link, "%sx%d %s VS=%d, PE=%d, DS=%s",
1360 				link_rate,
1361 				lt_settings->link_settings.lane_count,
1362 				lt_result,
1363 				lt_settings->lane_settings[0].VOLTAGE_SWING,
1364 				lt_settings->lane_settings[0].PRE_EMPHASIS,
1365 				lt_spread);
1366 }
1367 
dc_link_dp_set_drive_settings(struct dc_link * link,struct link_training_settings * lt_settings)1368 void dc_link_dp_set_drive_settings(
1369 	struct dc_link *link,
1370 	struct link_training_settings *lt_settings)
1371 {
1372 	/* program ASIC PHY settings*/
1373 	dp_set_hw_lane_settings(link, lt_settings, DPRX);
1374 
1375 	/* Notify DP sink the PHY settings from source */
1376 	dpcd_set_lane_settings(link, lt_settings, DPRX);
1377 }
1378 
dc_link_dp_perform_link_training_skip_aux(struct dc_link * link,const struct dc_link_settings * link_setting)1379 bool dc_link_dp_perform_link_training_skip_aux(
1380 	struct dc_link *link,
1381 	const struct dc_link_settings *link_setting)
1382 {
1383 	struct link_training_settings lt_settings;
1384 	enum dc_dp_training_pattern pattern_for_cr = DP_TRAINING_PATTERN_SEQUENCE_1;
1385 
1386 	initialize_training_settings(
1387 			link,
1388 			link_setting,
1389 			&link->preferred_training_settings,
1390 			&lt_settings);
1391 
1392 	/* 1. Perform_clock_recovery_sequence. */
1393 
1394 	/* transmit training pattern for clock recovery */
1395 	dp_set_hw_training_pattern(link, pattern_for_cr, DPRX);
1396 
1397 	/* call HWSS to set lane settings*/
1398 	dp_set_hw_lane_settings(link, &lt_settings, DPRX);
1399 
1400 	/* wait receiver to lock-on*/
1401 	wait_for_training_aux_rd_interval(link, lt_settings.cr_pattern_time);
1402 
1403 	/* 2. Perform_channel_equalization_sequence. */
1404 
1405 	/* transmit training pattern for channel equalization. */
1406 	dp_set_hw_training_pattern(link, lt_settings.pattern_for_eq, DPRX);
1407 
1408 	/* call HWSS to set lane settings*/
1409 	dp_set_hw_lane_settings(link, &lt_settings, DPRX);
1410 
1411 	/* wait receiver to lock-on. */
1412 	wait_for_training_aux_rd_interval(link, lt_settings.eq_pattern_time);
1413 
1414 	/* 3. Perform_link_training_int. */
1415 
1416 	/* Mainlink output idle pattern. */
1417 	dp_set_hw_test_pattern(link, DP_TEST_PATTERN_VIDEO_MODE, NULL, 0);
1418 
1419 	print_status_message(link, &lt_settings, LINK_TRAINING_SUCCESS);
1420 
1421 	return true;
1422 }
1423 
dc_link_dp_perform_link_training(struct dc_link * link,const struct dc_link_settings * link_setting,bool skip_video_pattern)1424 enum link_training_result dc_link_dp_perform_link_training(
1425 	struct dc_link *link,
1426 	const struct dc_link_settings *link_setting,
1427 	bool skip_video_pattern)
1428 {
1429 	enum link_training_result status = LINK_TRAINING_SUCCESS;
1430 	struct link_training_settings lt_settings;
1431 
1432 	bool fec_enable;
1433 	uint8_t repeater_cnt;
1434 	uint8_t repeater_id;
1435 
1436 	initialize_training_settings(
1437 			link,
1438 			link_setting,
1439 			&link->preferred_training_settings,
1440 			&lt_settings);
1441 
1442 	/* 1. set link rate, lane count and spread. */
1443 	dpcd_set_link_settings(link, &lt_settings);
1444 
1445 	if (link->preferred_training_settings.fec_enable != NULL)
1446 		fec_enable = *link->preferred_training_settings.fec_enable;
1447 	else
1448 		fec_enable = true;
1449 
1450 	dp_set_fec_ready(link, fec_enable);
1451 
1452 	if (!link->is_lttpr_mode_transparent) {
1453 		/* Configure lttpr mode */
1454 		configure_lttpr_mode(link);
1455 
1456 		/* 2. perform link training (set link training done
1457 		 *  to false is done as well)
1458 		 */
1459 		repeater_cnt = convert_to_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
1460 
1461 		for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
1462 				repeater_id--) {
1463 			status = perform_clock_recovery_sequence(link, &lt_settings, repeater_id);
1464 
1465 			if (status != LINK_TRAINING_SUCCESS)
1466 				break;
1467 
1468 			status = perform_channel_equalization_sequence(link,
1469 					&lt_settings,
1470 					repeater_id);
1471 
1472 			if (status != LINK_TRAINING_SUCCESS)
1473 				break;
1474 
1475 			repeater_training_done(link, repeater_id);
1476 		}
1477 	}
1478 
1479 	if (status == LINK_TRAINING_SUCCESS) {
1480 		status = perform_clock_recovery_sequence(link, &lt_settings, DPRX);
1481 	if (status == LINK_TRAINING_SUCCESS) {
1482 		status = perform_channel_equalization_sequence(link,
1483 					&lt_settings,
1484 					DPRX);
1485 		}
1486 	}
1487 
1488 	if ((status == LINK_TRAINING_SUCCESS) || !skip_video_pattern) {
1489 		status = perform_link_training_int(link,
1490 				&lt_settings,
1491 				status);
1492 	}
1493 
1494 	/* 6. print status message*/
1495 	print_status_message(link, &lt_settings, status);
1496 
1497 	if (status != LINK_TRAINING_SUCCESS)
1498 		link->ctx->dc->debug_data.ltFailCount++;
1499 
1500 	return status;
1501 }
1502 
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)1503 bool perform_link_training_with_retries(
1504 	const struct dc_link_settings *link_setting,
1505 	bool skip_video_pattern,
1506 	int attempts,
1507 	struct pipe_ctx *pipe_ctx,
1508 	enum signal_type signal)
1509 {
1510 	uint8_t j;
1511 	uint8_t delay_between_attempts = LINK_TRAINING_RETRY_DELAY;
1512 	struct dc_stream_state *stream = pipe_ctx->stream;
1513 	struct dc_link *link = stream->link;
1514 	enum dp_panel_mode panel_mode = dp_get_panel_mode(link);
1515 
1516 	for (j = 0; j < attempts; ++j) {
1517 
1518 		dp_enable_link_phy(
1519 			link,
1520 			signal,
1521 			pipe_ctx->clock_source->id,
1522 			link_setting);
1523 
1524 		if (stream->sink_patches.dppowerup_delay > 0) {
1525 			int delay_dp_power_up_in_ms = stream->sink_patches.dppowerup_delay;
1526 
1527 			msleep(delay_dp_power_up_in_ms);
1528 		}
1529 
1530 		dp_set_panel_mode(link, panel_mode);
1531 
1532 		/* We need to do this before the link training to ensure the idle pattern in SST
1533 		 * mode will be sent right after the link training
1534 		 */
1535 		link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
1536 								pipe_ctx->stream_res.stream_enc->id, true);
1537 
1538 		if (link->aux_access_disabled) {
1539 			dc_link_dp_perform_link_training_skip_aux(link, link_setting);
1540 			return true;
1541 		} else if (dc_link_dp_perform_link_training(
1542 				link,
1543 				link_setting,
1544 				skip_video_pattern) == LINK_TRAINING_SUCCESS)
1545 			return true;
1546 
1547 		/* latest link training still fail, skip delay and keep PHY on
1548 		 */
1549 		if (j == (attempts - 1))
1550 			break;
1551 
1552 		dp_disable_link_phy(link, signal);
1553 
1554 		msleep(delay_between_attempts);
1555 
1556 		delay_between_attempts += LINK_TRAINING_RETRY_DELAY;
1557 	}
1558 
1559 	return false;
1560 }
1561 
get_clock_source_id(struct dc_link * link)1562 static enum clock_source_id get_clock_source_id(struct dc_link *link)
1563 {
1564 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_UNDEFINED;
1565 	struct clock_source *dp_cs = link->dc->res_pool->dp_clock_source;
1566 
1567 	if (dp_cs != NULL) {
1568 		dp_cs_id = dp_cs->id;
1569 	} else {
1570 		/*
1571 		 * dp clock source is not initialized for some reason.
1572 		 * Should not happen, CLOCK_SOURCE_ID_EXTERNAL will be used
1573 		 */
1574 		ASSERT(dp_cs);
1575 	}
1576 
1577 	return dp_cs_id;
1578 }
1579 
set_dp_mst_mode(struct dc_link * link,bool mst_enable)1580 static void set_dp_mst_mode(struct dc_link *link, bool mst_enable)
1581 {
1582 	if (mst_enable == false &&
1583 		link->type == dc_connection_mst_branch) {
1584 		/* Disable MST on link. Use only local sink. */
1585 		dp_disable_link_phy_mst(link, link->connector_signal);
1586 
1587 		link->type = dc_connection_single;
1588 		link->local_sink = link->remote_sinks[0];
1589 		link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
1590 	} else if (mst_enable == true &&
1591 			link->type == dc_connection_single &&
1592 			link->remote_sinks[0] != NULL) {
1593 		/* Re-enable MST on link. */
1594 		dp_disable_link_phy(link, link->connector_signal);
1595 		dp_enable_mst_on_sink(link, true);
1596 
1597 		link->type = dc_connection_mst_branch;
1598 		link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1599 	}
1600 }
1601 
dc_link_dp_sync_lt_begin(struct dc_link * link)1602 bool dc_link_dp_sync_lt_begin(struct dc_link *link)
1603 {
1604 	/* Begin Sync LT. During this time,
1605 	 * DPCD:600h must not be powered down.
1606 	 */
1607 	link->sync_lt_in_progress = true;
1608 
1609 	/*Clear any existing preferred settings.*/
1610 	memset(&link->preferred_training_settings, 0,
1611 		sizeof(struct dc_link_training_overrides));
1612 	memset(&link->preferred_link_setting, 0,
1613 		sizeof(struct dc_link_settings));
1614 
1615 	return true;
1616 }
1617 
dc_link_dp_sync_lt_attempt(struct dc_link * link,struct dc_link_settings * link_settings,struct dc_link_training_overrides * lt_overrides)1618 enum link_training_result dc_link_dp_sync_lt_attempt(
1619     struct dc_link *link,
1620     struct dc_link_settings *link_settings,
1621     struct dc_link_training_overrides *lt_overrides)
1622 {
1623 	struct link_training_settings lt_settings;
1624 	enum link_training_result lt_status = LINK_TRAINING_SUCCESS;
1625 	enum dp_panel_mode panel_mode = DP_PANEL_MODE_DEFAULT;
1626 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1627 	bool fec_enable = false;
1628 
1629 	initialize_training_settings(
1630 		link,
1631 		link_settings,
1632 		lt_overrides,
1633 		&lt_settings);
1634 
1635 	/* Setup MST Mode */
1636 	if (lt_overrides->mst_enable)
1637 		set_dp_mst_mode(link, *lt_overrides->mst_enable);
1638 
1639 	/* Disable link */
1640 	dp_disable_link_phy(link, link->connector_signal);
1641 
1642 	/* Enable link */
1643 	dp_cs_id = get_clock_source_id(link);
1644 	dp_enable_link_phy(link, link->connector_signal,
1645 		dp_cs_id, link_settings);
1646 
1647 	/* Set FEC enable */
1648 	fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
1649 	dp_set_fec_ready(link, fec_enable);
1650 
1651 	if (lt_overrides->alternate_scrambler_reset) {
1652 		if (*lt_overrides->alternate_scrambler_reset)
1653 			panel_mode = DP_PANEL_MODE_EDP;
1654 		else
1655 			panel_mode = DP_PANEL_MODE_DEFAULT;
1656 	} else
1657 		panel_mode = dp_get_panel_mode(link);
1658 
1659 	dp_set_panel_mode(link, panel_mode);
1660 
1661 	/* Attempt to train with given link training settings */
1662 
1663 	/* Set link rate, lane count and spread. */
1664 	dpcd_set_link_settings(link, &lt_settings);
1665 
1666 	/* 2. perform link training (set link training done
1667 	 *  to false is done as well)
1668 	 */
1669 	lt_status = perform_clock_recovery_sequence(link, &lt_settings, DPRX);
1670 	if (lt_status == LINK_TRAINING_SUCCESS) {
1671 		lt_status = perform_channel_equalization_sequence(link,
1672 						&lt_settings,
1673 						DPRX);
1674 	}
1675 
1676 	/* 3. Sync LT must skip TRAINING_PATTERN_SET:0 (video pattern)*/
1677 	/* 4. print status message*/
1678 	print_status_message(link, &lt_settings, lt_status);
1679 
1680 	return lt_status;
1681 }
1682 
dc_link_dp_sync_lt_end(struct dc_link * link,bool link_down)1683 bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
1684 {
1685 	/* If input parameter is set, shut down phy.
1686 	 * Still shouldn't turn off dp_receiver (DPCD:600h)
1687 	 */
1688 	if (link_down == true) {
1689 		dp_disable_link_phy(link, link->connector_signal);
1690 		dp_set_fec_ready(link, false);
1691 	}
1692 
1693 	link->sync_lt_in_progress = false;
1694 	return true;
1695 }
1696 
get_max_link_cap(struct dc_link * link)1697 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
1698 {
1699 	/* Set Default link settings */
1700 	struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH,
1701 			LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0};
1702 
1703 	/* Higher link settings based on feature supported */
1704 	if (link->link_enc->features.flags.bits.IS_HBR2_CAPABLE)
1705 		max_link_cap.link_rate = LINK_RATE_HIGH2;
1706 
1707 	if (link->link_enc->features.flags.bits.IS_HBR3_CAPABLE)
1708 		max_link_cap.link_rate = LINK_RATE_HIGH3;
1709 
1710 	if (link->link_enc->funcs->get_max_link_cap)
1711 		link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
1712 
1713 	/* Lower link settings based on sink's link cap */
1714 	if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
1715 		max_link_cap.lane_count =
1716 				link->reported_link_cap.lane_count;
1717 	if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
1718 		max_link_cap.link_rate =
1719 				link->reported_link_cap.link_rate;
1720 	if (link->reported_link_cap.link_spread <
1721 			max_link_cap.link_spread)
1722 		max_link_cap.link_spread =
1723 				link->reported_link_cap.link_spread;
1724 	/*
1725 	 * account for lttpr repeaters cap
1726 	 * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
1727 	 */
1728 	if (!link->is_lttpr_mode_transparent) {
1729 		if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
1730 			max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
1731 
1732 		if (link->dpcd_caps.lttpr_caps.max_link_rate < max_link_cap.link_rate)
1733 			max_link_cap.link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
1734 
1735 		DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane count %d max_link rate %d \n",
1736 						__func__,
1737 						max_link_cap.lane_count,
1738 						max_link_cap.link_rate);
1739 	}
1740 	return max_link_cap;
1741 }
1742 
read_hpd_rx_irq_data(struct dc_link * link,union hpd_irq_data * irq_data)1743 static enum dc_status read_hpd_rx_irq_data(
1744 	struct dc_link *link,
1745 	union hpd_irq_data *irq_data)
1746 {
1747 	static enum dc_status retval;
1748 
1749 	/* The HW reads 16 bytes from 200h on HPD,
1750 	 * but if we get an AUX_DEFER, the HW cannot retry
1751 	 * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
1752 	 * fail, so we now explicitly read 6 bytes which is
1753 	 * the req from the above mentioned test cases.
1754 	 *
1755 	 * For DP 1.4 we need to read those from 2002h range.
1756 	 */
1757 	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
1758 		retval = core_link_read_dpcd(
1759 			link,
1760 			DP_SINK_COUNT,
1761 			irq_data->raw,
1762 			sizeof(union hpd_irq_data));
1763 	else {
1764 		/* Read 14 bytes in a single read and then copy only the required fields.
1765 		 * This is more efficient than doing it in two separate AUX reads. */
1766 
1767 		uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
1768 
1769 		retval = core_link_read_dpcd(
1770 			link,
1771 			DP_SINK_COUNT_ESI,
1772 			tmp,
1773 			sizeof(tmp));
1774 
1775 		if (retval != DC_OK)
1776 			return retval;
1777 
1778 		irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
1779 		irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
1780 		irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
1781 		irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
1782 		irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
1783 		irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
1784 	}
1785 
1786 	return retval;
1787 }
1788 
hpd_rx_irq_check_link_loss_status(struct dc_link * link,union hpd_irq_data * hpd_irq_dpcd_data)1789 static bool hpd_rx_irq_check_link_loss_status(
1790 	struct dc_link *link,
1791 	union hpd_irq_data *hpd_irq_dpcd_data)
1792 {
1793 	uint8_t irq_reg_rx_power_state = 0;
1794 	enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
1795 	union lane_status lane_status;
1796 	uint32_t lane;
1797 	bool sink_status_changed;
1798 	bool return_code;
1799 
1800 	sink_status_changed = false;
1801 	return_code = false;
1802 
1803 	if (link->cur_link_settings.lane_count == 0)
1804 		return return_code;
1805 
1806 	/*1. Check that Link Status changed, before re-training.*/
1807 
1808 	/*parse lane status*/
1809 	for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
1810 		/* check status of lanes 0,1
1811 		 * changed DpcdAddress_Lane01Status (0x202)
1812 		 */
1813 		lane_status.raw = get_nibble_at_index(
1814 			&hpd_irq_dpcd_data->bytes.lane01_status.raw,
1815 			lane);
1816 
1817 		if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1818 			!lane_status.bits.CR_DONE_0 ||
1819 			!lane_status.bits.SYMBOL_LOCKED_0) {
1820 			/* if one of the channel equalization, clock
1821 			 * recovery or symbol lock is dropped
1822 			 * consider it as (link has been
1823 			 * dropped) dp sink status has changed
1824 			 */
1825 			sink_status_changed = true;
1826 			break;
1827 		}
1828 	}
1829 
1830 	/* Check interlane align.*/
1831 	if (sink_status_changed ||
1832 		!hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
1833 
1834 		DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
1835 
1836 		return_code = true;
1837 
1838 		/*2. Check that we can handle interrupt: Not in FS DOS,
1839 		 *  Not in "Display Timeout" state, Link is trained.
1840 		 */
1841 		dpcd_result = core_link_read_dpcd(link,
1842 			DP_SET_POWER,
1843 			&irq_reg_rx_power_state,
1844 			sizeof(irq_reg_rx_power_state));
1845 
1846 		if (dpcd_result != DC_OK) {
1847 			DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
1848 				__func__);
1849 		} else {
1850 			if (irq_reg_rx_power_state != DP_SET_POWER_D0)
1851 				return_code = false;
1852 		}
1853 	}
1854 
1855 	return return_code;
1856 }
1857 
dp_verify_link_cap(struct dc_link * link,struct dc_link_settings * known_limit_link_setting,int * fail_count)1858 bool dp_verify_link_cap(
1859 	struct dc_link *link,
1860 	struct dc_link_settings *known_limit_link_setting,
1861 	int *fail_count)
1862 {
1863 	struct dc_link_settings max_link_cap = {0};
1864 	struct dc_link_settings cur_link_setting = {0};
1865 	struct dc_link_settings *cur = &cur_link_setting;
1866 	struct dc_link_settings initial_link_settings = {0};
1867 	bool success;
1868 	bool skip_link_training;
1869 	bool skip_video_pattern;
1870 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1871 	enum link_training_result status;
1872 	union hpd_irq_data irq_data;
1873 
1874 	if (link->dc->debug.skip_detection_link_training) {
1875 		link->verified_link_cap = *known_limit_link_setting;
1876 		return true;
1877 	}
1878 
1879 	memset(&irq_data, 0, sizeof(irq_data));
1880 	success = false;
1881 	skip_link_training = false;
1882 
1883 	max_link_cap = get_max_link_cap(link);
1884 
1885 	/* Grant extended timeout request */
1886 	if (!link->is_lttpr_mode_transparent && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) {
1887 		uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80;
1888 
1889 		core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
1890 	}
1891 
1892 	/* TODO implement override and monitor patch later */
1893 
1894 	/* try to train the link from high to low to
1895 	 * find the physical link capability
1896 	 */
1897 	/* disable PHY done possible by BIOS, will be done by driver itself */
1898 	dp_disable_link_phy(link, link->connector_signal);
1899 
1900 	/* Temporary Renoir-specific workaround for SWDEV-215184;
1901 	 * PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle,
1902 	 * so add extra cycle of enabling and disabling the PHY before first link training.
1903 	 */
1904 	if (link->link_enc->features.flags.bits.DP_IS_USB_C &&
1905 			link->dc->debug.usbc_combo_phy_reset_wa) {
1906 		dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur);
1907 		dp_disable_link_phy(link, link->connector_signal);
1908 	}
1909 
1910 	dp_cs_id = get_clock_source_id(link);
1911 
1912 	/* link training starts with the maximum common settings
1913 	 * supported by both sink and ASIC.
1914 	 */
1915 	initial_link_settings = get_common_supported_link_settings(
1916 			*known_limit_link_setting,
1917 			max_link_cap);
1918 	cur_link_setting = initial_link_settings;
1919 	do {
1920 		skip_video_pattern = true;
1921 
1922 		if (cur->link_rate == LINK_RATE_LOW)
1923 			skip_video_pattern = false;
1924 
1925 		dp_enable_link_phy(
1926 				link,
1927 				link->connector_signal,
1928 				dp_cs_id,
1929 				cur);
1930 
1931 
1932 		if (skip_link_training)
1933 			success = true;
1934 		else {
1935 			status = dc_link_dp_perform_link_training(
1936 							link,
1937 							cur,
1938 							skip_video_pattern);
1939 			if (status == LINK_TRAINING_SUCCESS)
1940 				success = true;
1941 			else
1942 				(*fail_count)++;
1943 		}
1944 
1945 		if (success) {
1946 			link->verified_link_cap = *cur;
1947 			udelay(1000);
1948 			if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK)
1949 				if (hpd_rx_irq_check_link_loss_status(
1950 						link,
1951 						&irq_data))
1952 					(*fail_count)++;
1953 		}
1954 		/* always disable the link before trying another
1955 		 * setting or before returning we'll enable it later
1956 		 * based on the actual mode we're driving
1957 		 */
1958 		dp_disable_link_phy(link, link->connector_signal);
1959 	} while (!success && decide_fallback_link_setting(
1960 			initial_link_settings, cur, status));
1961 
1962 	/* Link Training failed for all Link Settings
1963 	 *  (Lane Count is still unknown)
1964 	 */
1965 	if (!success) {
1966 		/* If all LT fails for all settings,
1967 		 * set verified = failed safe (1 lane low)
1968 		 */
1969 		link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1970 		link->verified_link_cap.link_rate = LINK_RATE_LOW;
1971 
1972 		link->verified_link_cap.link_spread =
1973 		LINK_SPREAD_DISABLED;
1974 	}
1975 
1976 
1977 	return success;
1978 }
1979 
dp_verify_link_cap_with_retries(struct dc_link * link,struct dc_link_settings * known_limit_link_setting,int attempts)1980 bool dp_verify_link_cap_with_retries(
1981 	struct dc_link *link,
1982 	struct dc_link_settings *known_limit_link_setting,
1983 	int attempts)
1984 {
1985 	uint8_t i = 0;
1986 	bool success = false;
1987 
1988 	for (i = 0; i < attempts; i++) {
1989 		int fail_count = 0;
1990 		enum dc_connection_type type = dc_connection_none;
1991 
1992 		memset(&link->verified_link_cap, 0,
1993 				sizeof(struct dc_link_settings));
1994 		if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
1995 			link->verified_link_cap.lane_count = LANE_COUNT_ONE;
1996 			link->verified_link_cap.link_rate = LINK_RATE_LOW;
1997 			link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED;
1998 			break;
1999 		} else if (dp_verify_link_cap(link,
2000 				&link->reported_link_cap,
2001 				&fail_count) && fail_count == 0) {
2002 			success = true;
2003 			break;
2004 		}
2005 		msleep(10);
2006 	}
2007 	return success;
2008 }
2009 
dp_verify_mst_link_cap(struct dc_link * link)2010 bool dp_verify_mst_link_cap(
2011 	struct dc_link *link)
2012 {
2013 	struct dc_link_settings max_link_cap = {0};
2014 
2015 	max_link_cap = get_max_link_cap(link);
2016 	link->verified_link_cap = get_common_supported_link_settings(
2017 		link->reported_link_cap,
2018 		max_link_cap);
2019 
2020 	return true;
2021 }
2022 
get_common_supported_link_settings(struct dc_link_settings link_setting_a,struct dc_link_settings link_setting_b)2023 static struct dc_link_settings get_common_supported_link_settings(
2024 		struct dc_link_settings link_setting_a,
2025 		struct dc_link_settings link_setting_b)
2026 {
2027 	struct dc_link_settings link_settings = {0};
2028 
2029 	link_settings.lane_count =
2030 		(link_setting_a.lane_count <=
2031 			link_setting_b.lane_count) ?
2032 			link_setting_a.lane_count :
2033 			link_setting_b.lane_count;
2034 	link_settings.link_rate =
2035 		(link_setting_a.link_rate <=
2036 			link_setting_b.link_rate) ?
2037 			link_setting_a.link_rate :
2038 			link_setting_b.link_rate;
2039 	link_settings.link_spread = LINK_SPREAD_DISABLED;
2040 
2041 	/* in DP compliance test, DPR-120 may have
2042 	 * a random value in its MAX_LINK_BW dpcd field.
2043 	 * We map it to the maximum supported link rate that
2044 	 * is smaller than MAX_LINK_BW in this case.
2045 	 */
2046 	if (link_settings.link_rate > LINK_RATE_HIGH3) {
2047 		link_settings.link_rate = LINK_RATE_HIGH3;
2048 	} else if (link_settings.link_rate < LINK_RATE_HIGH3
2049 			&& link_settings.link_rate > LINK_RATE_HIGH2) {
2050 		link_settings.link_rate = LINK_RATE_HIGH2;
2051 	} else if (link_settings.link_rate < LINK_RATE_HIGH2
2052 			&& link_settings.link_rate > LINK_RATE_HIGH) {
2053 		link_settings.link_rate = LINK_RATE_HIGH;
2054 	} else if (link_settings.link_rate < LINK_RATE_HIGH
2055 			&& link_settings.link_rate > LINK_RATE_LOW) {
2056 		link_settings.link_rate = LINK_RATE_LOW;
2057 	} else if (link_settings.link_rate < LINK_RATE_LOW) {
2058 		link_settings.link_rate = LINK_RATE_UNKNOWN;
2059 	}
2060 
2061 	return link_settings;
2062 }
2063 
reached_minimum_lane_count(enum dc_lane_count lane_count)2064 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
2065 {
2066 	return lane_count <= LANE_COUNT_ONE;
2067 }
2068 
reached_minimum_link_rate(enum dc_link_rate link_rate)2069 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
2070 {
2071 	return link_rate <= LINK_RATE_LOW;
2072 }
2073 
reduce_lane_count(enum dc_lane_count lane_count)2074 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
2075 {
2076 	switch (lane_count) {
2077 	case LANE_COUNT_FOUR:
2078 		return LANE_COUNT_TWO;
2079 	case LANE_COUNT_TWO:
2080 		return LANE_COUNT_ONE;
2081 	case LANE_COUNT_ONE:
2082 		return LANE_COUNT_UNKNOWN;
2083 	default:
2084 		return LANE_COUNT_UNKNOWN;
2085 	}
2086 }
2087 
reduce_link_rate(enum dc_link_rate link_rate)2088 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
2089 {
2090 	switch (link_rate) {
2091 	case LINK_RATE_HIGH3:
2092 		return LINK_RATE_HIGH2;
2093 	case LINK_RATE_HIGH2:
2094 		return LINK_RATE_HIGH;
2095 	case LINK_RATE_HIGH:
2096 		return LINK_RATE_LOW;
2097 	case LINK_RATE_LOW:
2098 		return LINK_RATE_UNKNOWN;
2099 	default:
2100 		return LINK_RATE_UNKNOWN;
2101 	}
2102 }
2103 
increase_lane_count(enum dc_lane_count lane_count)2104 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
2105 {
2106 	switch (lane_count) {
2107 	case LANE_COUNT_ONE:
2108 		return LANE_COUNT_TWO;
2109 	case LANE_COUNT_TWO:
2110 		return LANE_COUNT_FOUR;
2111 	default:
2112 		return LANE_COUNT_UNKNOWN;
2113 	}
2114 }
2115 
increase_link_rate(enum dc_link_rate link_rate)2116 static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
2117 {
2118 	switch (link_rate) {
2119 	case LINK_RATE_LOW:
2120 		return LINK_RATE_HIGH;
2121 	case LINK_RATE_HIGH:
2122 		return LINK_RATE_HIGH2;
2123 	case LINK_RATE_HIGH2:
2124 		return LINK_RATE_HIGH3;
2125 	default:
2126 		return LINK_RATE_UNKNOWN;
2127 	}
2128 }
2129 
2130 /*
2131  * function: set link rate and lane count fallback based
2132  * on current link setting and last link training result
2133  * return value:
2134  *			true - link setting could be set
2135  *			false - has reached minimum setting
2136  *					and no further fallback could be done
2137  */
decide_fallback_link_setting(struct dc_link_settings initial_link_settings,struct dc_link_settings * current_link_setting,enum link_training_result training_result)2138 static bool decide_fallback_link_setting(
2139 		struct dc_link_settings initial_link_settings,
2140 		struct dc_link_settings *current_link_setting,
2141 		enum link_training_result training_result)
2142 {
2143 	if (!current_link_setting)
2144 		return false;
2145 
2146 	switch (training_result) {
2147 	case LINK_TRAINING_CR_FAIL_LANE0:
2148 	case LINK_TRAINING_CR_FAIL_LANE1:
2149 	case LINK_TRAINING_CR_FAIL_LANE23:
2150 	case LINK_TRAINING_LQA_FAIL:
2151 	{
2152 		if (!reached_minimum_link_rate
2153 				(current_link_setting->link_rate)) {
2154 			current_link_setting->link_rate =
2155 				reduce_link_rate(
2156 					current_link_setting->link_rate);
2157 		} else if (!reached_minimum_lane_count
2158 				(current_link_setting->lane_count)) {
2159 			current_link_setting->link_rate =
2160 				initial_link_settings.link_rate;
2161 			if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
2162 				return false;
2163 			else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
2164 				current_link_setting->lane_count =
2165 						LANE_COUNT_ONE;
2166 			else if (training_result ==
2167 					LINK_TRAINING_CR_FAIL_LANE23)
2168 				current_link_setting->lane_count =
2169 						LANE_COUNT_TWO;
2170 			else
2171 				current_link_setting->lane_count =
2172 					reduce_lane_count(
2173 					current_link_setting->lane_count);
2174 		} else {
2175 			return false;
2176 		}
2177 		break;
2178 	}
2179 	case LINK_TRAINING_EQ_FAIL_EQ:
2180 	{
2181 		if (!reached_minimum_lane_count
2182 				(current_link_setting->lane_count)) {
2183 			current_link_setting->lane_count =
2184 				reduce_lane_count(
2185 					current_link_setting->lane_count);
2186 		} else if (!reached_minimum_link_rate
2187 				(current_link_setting->link_rate)) {
2188 			current_link_setting->link_rate =
2189 				reduce_link_rate(
2190 					current_link_setting->link_rate);
2191 		} else {
2192 			return false;
2193 		}
2194 		break;
2195 	}
2196 	case LINK_TRAINING_EQ_FAIL_CR:
2197 	{
2198 		if (!reached_minimum_link_rate
2199 				(current_link_setting->link_rate)) {
2200 			current_link_setting->link_rate =
2201 				reduce_link_rate(
2202 					current_link_setting->link_rate);
2203 		} else {
2204 			return false;
2205 		}
2206 		break;
2207 	}
2208 	default:
2209 		return false;
2210 	}
2211 	return true;
2212 }
2213 
dp_validate_mode_timing(struct dc_link * link,const struct dc_crtc_timing * timing)2214 bool dp_validate_mode_timing(
2215 	struct dc_link *link,
2216 	const struct dc_crtc_timing *timing)
2217 {
2218 	uint32_t req_bw;
2219 	uint32_t max_bw;
2220 
2221 	const struct dc_link_settings *link_setting;
2222 
2223 	/*always DP fail safe mode*/
2224 	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
2225 		timing->h_addressable == (uint32_t) 640 &&
2226 		timing->v_addressable == (uint32_t) 480)
2227 		return true;
2228 
2229 	link_setting = dc_link_get_link_cap(link);
2230 
2231 	/* TODO: DYNAMIC_VALIDATION needs to be implemented */
2232 	/*if (flags.DYNAMIC_VALIDATION == 1 &&
2233 		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
2234 		link_setting = &link->verified_link_cap;
2235 	*/
2236 
2237 	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
2238 	max_bw = dc_link_bandwidth_kbps(link, link_setting);
2239 
2240 	if (req_bw <= max_bw) {
2241 		/* remember the biggest mode here, during
2242 		 * initial link training (to get
2243 		 * verified_link_cap), LS sends event about
2244 		 * cannot train at reported cap to upper
2245 		 * layer and upper layer will re-enumerate modes.
2246 		 * this is not necessary if the lower
2247 		 * verified_link_cap is enough to drive
2248 		 * all the modes */
2249 
2250 		/* TODO: DYNAMIC_VALIDATION needs to be implemented */
2251 		/* if (flags.DYNAMIC_VALIDATION == 1)
2252 			dpsst->max_req_bw_for_verified_linkcap = dal_max(
2253 				dpsst->max_req_bw_for_verified_linkcap, req_bw); */
2254 		return true;
2255 	} else
2256 		return false;
2257 }
2258 
decide_dp_link_settings(struct dc_link * link,struct dc_link_settings * link_setting,uint32_t req_bw)2259 static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
2260 {
2261 	struct dc_link_settings initial_link_setting = {
2262 		LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
2263 	struct dc_link_settings current_link_setting =
2264 			initial_link_setting;
2265 	uint32_t link_bw;
2266 
2267 	/* search for the minimum link setting that:
2268 	 * 1. is supported according to the link training result
2269 	 * 2. could support the b/w requested by the timing
2270 	 */
2271 	while (current_link_setting.link_rate <=
2272 			link->verified_link_cap.link_rate) {
2273 		link_bw = dc_link_bandwidth_kbps(
2274 				link,
2275 				&current_link_setting);
2276 		if (req_bw <= link_bw) {
2277 			*link_setting = current_link_setting;
2278 			return true;
2279 		}
2280 
2281 		if (current_link_setting.lane_count <
2282 				link->verified_link_cap.lane_count) {
2283 			current_link_setting.lane_count =
2284 					increase_lane_count(
2285 							current_link_setting.lane_count);
2286 		} else {
2287 			current_link_setting.link_rate =
2288 					increase_link_rate(
2289 							current_link_setting.link_rate);
2290 			current_link_setting.lane_count =
2291 					initial_link_setting.lane_count;
2292 		}
2293 	}
2294 
2295 	return false;
2296 }
2297 
decide_edp_link_settings(struct dc_link * link,struct dc_link_settings * link_setting,uint32_t req_bw)2298 static bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
2299 {
2300 	struct dc_link_settings initial_link_setting;
2301 	struct dc_link_settings current_link_setting;
2302 	uint32_t link_bw;
2303 
2304 	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14 ||
2305 			link->dpcd_caps.edp_supported_link_rates_count == 0) {
2306 		*link_setting = link->verified_link_cap;
2307 		return true;
2308 	}
2309 
2310 	memset(&initial_link_setting, 0, sizeof(initial_link_setting));
2311 	initial_link_setting.lane_count = LANE_COUNT_ONE;
2312 	initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
2313 	initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
2314 	initial_link_setting.use_link_rate_set = true;
2315 	initial_link_setting.link_rate_set = 0;
2316 	current_link_setting = initial_link_setting;
2317 
2318 	/* search for the minimum link setting that:
2319 	 * 1. is supported according to the link training result
2320 	 * 2. could support the b/w requested by the timing
2321 	 */
2322 	while (current_link_setting.link_rate <=
2323 			link->verified_link_cap.link_rate) {
2324 		link_bw = dc_link_bandwidth_kbps(
2325 				link,
2326 				&current_link_setting);
2327 		if (req_bw <= link_bw) {
2328 			*link_setting = current_link_setting;
2329 			return true;
2330 		}
2331 
2332 		if (current_link_setting.lane_count <
2333 				link->verified_link_cap.lane_count) {
2334 			current_link_setting.lane_count =
2335 					increase_lane_count(
2336 							current_link_setting.lane_count);
2337 		} else {
2338 			if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
2339 				current_link_setting.link_rate_set++;
2340 				current_link_setting.link_rate =
2341 					link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
2342 				current_link_setting.lane_count =
2343 									initial_link_setting.lane_count;
2344 			} else
2345 				break;
2346 		}
2347 	}
2348 	return false;
2349 }
2350 
decide_link_settings(struct dc_stream_state * stream,struct dc_link_settings * link_setting)2351 void decide_link_settings(struct dc_stream_state *stream,
2352 	struct dc_link_settings *link_setting)
2353 {
2354 	struct dc_link *link;
2355 	uint32_t req_bw;
2356 
2357 	req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
2358 
2359 	link = stream->link;
2360 
2361 	/* if preferred is specified through AMDDP, use it, if it's enough
2362 	 * to drive the mode
2363 	 */
2364 	if (link->preferred_link_setting.lane_count !=
2365 			LANE_COUNT_UNKNOWN &&
2366 			link->preferred_link_setting.link_rate !=
2367 					LINK_RATE_UNKNOWN) {
2368 		*link_setting =  link->preferred_link_setting;
2369 		return;
2370 	}
2371 
2372 	/* MST doesn't perform link training for now
2373 	 * TODO: add MST specific link training routine
2374 	 */
2375 	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2376 		*link_setting = link->verified_link_cap;
2377 		return;
2378 	}
2379 
2380 	if (link->connector_signal == SIGNAL_TYPE_EDP) {
2381 		if (decide_edp_link_settings(link, link_setting, req_bw))
2382 			return;
2383 	} else if (decide_dp_link_settings(link, link_setting, req_bw))
2384 		return;
2385 
2386 	BREAK_TO_DEBUGGER();
2387 	ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
2388 
2389 	*link_setting = link->verified_link_cap;
2390 }
2391 
2392 /*************************Short Pulse IRQ***************************/
allow_hpd_rx_irq(const struct dc_link * link)2393 static bool allow_hpd_rx_irq(const struct dc_link *link)
2394 {
2395 	/*
2396 	 * Don't handle RX IRQ unless one of following is met:
2397 	 * 1) The link is established (cur_link_settings != unknown)
2398 	 * 2) We kicked off MST detection
2399 	 * 3) We know we're dealing with an active dongle
2400 	 */
2401 
2402 	if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
2403 		(link->type == dc_connection_mst_branch) ||
2404 		is_dp_active_dongle(link))
2405 		return true;
2406 
2407 	return false;
2408 }
2409 
handle_hpd_irq_psr_sink(struct dc_link * link)2410 static bool handle_hpd_irq_psr_sink(struct dc_link *link)
2411 {
2412 	union dpcd_psr_configuration psr_configuration;
2413 
2414 	if (!link->psr_feature_enabled)
2415 		return false;
2416 
2417 	dm_helpers_dp_read_dpcd(
2418 		link->ctx,
2419 		link,
2420 		368,/*DpcdAddress_PSR_Enable_Cfg*/
2421 		&psr_configuration.raw,
2422 		sizeof(psr_configuration.raw));
2423 
2424 
2425 	if (psr_configuration.bits.ENABLE) {
2426 		unsigned char dpcdbuf[3] = {0};
2427 		union psr_error_status psr_error_status;
2428 		union psr_sink_psr_status psr_sink_psr_status;
2429 
2430 		dm_helpers_dp_read_dpcd(
2431 			link->ctx,
2432 			link,
2433 			0x2006, /*DpcdAddress_PSR_Error_Status*/
2434 			(unsigned char *) dpcdbuf,
2435 			sizeof(dpcdbuf));
2436 
2437 		/*DPCD 2006h   ERROR STATUS*/
2438 		psr_error_status.raw = dpcdbuf[0];
2439 		/*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
2440 		psr_sink_psr_status.raw = dpcdbuf[2];
2441 
2442 		if (psr_error_status.bits.LINK_CRC_ERROR ||
2443 				psr_error_status.bits.RFB_STORAGE_ERROR) {
2444 			/* Acknowledge and clear error bits */
2445 			dm_helpers_dp_write_dpcd(
2446 				link->ctx,
2447 				link,
2448 				8198,/*DpcdAddress_PSR_Error_Status*/
2449 				&psr_error_status.raw,
2450 				sizeof(psr_error_status.raw));
2451 
2452 			/* PSR error, disable and re-enable PSR */
2453 			dc_link_set_psr_allow_active(link, false, true);
2454 			dc_link_set_psr_allow_active(link, true, true);
2455 
2456 			return true;
2457 		} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
2458 				PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
2459 			/* No error is detect, PSR is active.
2460 			 * We should return with IRQ_HPD handled without
2461 			 * checking for loss of sync since PSR would have
2462 			 * powered down main link.
2463 			 */
2464 			return true;
2465 		}
2466 	}
2467 	return false;
2468 }
2469 
dp_test_send_link_training(struct dc_link * link)2470 static void dp_test_send_link_training(struct dc_link *link)
2471 {
2472 	struct dc_link_settings link_settings = {0};
2473 
2474 	core_link_read_dpcd(
2475 			link,
2476 			DP_TEST_LANE_COUNT,
2477 			(unsigned char *)(&link_settings.lane_count),
2478 			1);
2479 	core_link_read_dpcd(
2480 			link,
2481 			DP_TEST_LINK_RATE,
2482 			(unsigned char *)(&link_settings.link_rate),
2483 			1);
2484 
2485 	/* Set preferred link settings */
2486 	link->verified_link_cap.lane_count = link_settings.lane_count;
2487 	link->verified_link_cap.link_rate = link_settings.link_rate;
2488 
2489 	dp_retrain_link_dp_test(link, &link_settings, false);
2490 }
2491 
2492 /* TODO Raven hbr2 compliance eye output is unstable
2493  * (toggling on and off) with debugger break
2494  * This caueses intermittent PHY automation failure
2495  * Need to look into the root cause */
dp_test_send_phy_test_pattern(struct dc_link * link)2496 static void dp_test_send_phy_test_pattern(struct dc_link *link)
2497 {
2498 	union phy_test_pattern dpcd_test_pattern;
2499 	union lane_adjust dpcd_lane_adjustment[2];
2500 	unsigned char dpcd_post_cursor_2_adjustment = 0;
2501 	unsigned char test_80_bit_pattern[
2502 			(DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2503 			DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
2504 	enum dp_test_pattern test_pattern;
2505 	struct dc_link_training_settings link_settings;
2506 	union lane_adjust dpcd_lane_adjust;
2507 	unsigned int lane;
2508 	struct link_training_settings link_training_settings;
2509 	int i = 0;
2510 
2511 	dpcd_test_pattern.raw = 0;
2512 	memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
2513 	memset(&link_settings, 0, sizeof(link_settings));
2514 
2515 	/* get phy test pattern and pattern parameters from DP receiver */
2516 	core_link_read_dpcd(
2517 			link,
2518 			DP_TEST_PHY_PATTERN,
2519 			&dpcd_test_pattern.raw,
2520 			sizeof(dpcd_test_pattern));
2521 	core_link_read_dpcd(
2522 			link,
2523 			DP_ADJUST_REQUEST_LANE0_1,
2524 			&dpcd_lane_adjustment[0].raw,
2525 			sizeof(dpcd_lane_adjustment));
2526 
2527 	/*get post cursor 2 parameters
2528 	 * For DP 1.1a or eariler, this DPCD register's value is 0
2529 	 * For DP 1.2 or later:
2530 	 * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
2531 	 * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
2532 	 */
2533 	core_link_read_dpcd(
2534 			link,
2535 			DP_ADJUST_REQUEST_POST_CURSOR2,
2536 			&dpcd_post_cursor_2_adjustment,
2537 			sizeof(dpcd_post_cursor_2_adjustment));
2538 
2539 	/* translate request */
2540 	switch (dpcd_test_pattern.bits.PATTERN) {
2541 	case PHY_TEST_PATTERN_D10_2:
2542 		test_pattern = DP_TEST_PATTERN_D102;
2543 		break;
2544 	case PHY_TEST_PATTERN_SYMBOL_ERROR:
2545 		test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
2546 		break;
2547 	case PHY_TEST_PATTERN_PRBS7:
2548 		test_pattern = DP_TEST_PATTERN_PRBS7;
2549 		break;
2550 	case PHY_TEST_PATTERN_80BIT_CUSTOM:
2551 		test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
2552 		break;
2553 	case PHY_TEST_PATTERN_CP2520_1:
2554 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
2555 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2556 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
2557 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2558 		break;
2559 	case PHY_TEST_PATTERN_CP2520_2:
2560 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
2561 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2562 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
2563 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2564 		break;
2565 	case PHY_TEST_PATTERN_CP2520_3:
2566 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
2567 		break;
2568 	default:
2569 		test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2570 	break;
2571 	}
2572 
2573 	if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM)
2574 		core_link_read_dpcd(
2575 				link,
2576 				DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
2577 				test_80_bit_pattern,
2578 				sizeof(test_80_bit_pattern));
2579 
2580 	/* prepare link training settings */
2581 	link_settings.link = link->cur_link_settings;
2582 
2583 	for (lane = 0; lane <
2584 		(unsigned int)(link->cur_link_settings.lane_count);
2585 		lane++) {
2586 		dpcd_lane_adjust.raw =
2587 			get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
2588 		link_settings.lane_settings[lane].VOLTAGE_SWING =
2589 			(enum dc_voltage_swing)
2590 			(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
2591 		link_settings.lane_settings[lane].PRE_EMPHASIS =
2592 			(enum dc_pre_emphasis)
2593 			(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
2594 		link_settings.lane_settings[lane].POST_CURSOR2 =
2595 			(enum dc_post_cursor2)
2596 			((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
2597 	}
2598 
2599 	for (i = 0; i < 4; i++)
2600 		link_training_settings.lane_settings[i] =
2601 				link_settings.lane_settings[i];
2602 	link_training_settings.link_settings = link_settings.link;
2603 	link_training_settings.allow_invalid_msa_timing_param = false;
2604 	/*Usage: Measure DP physical lane signal
2605 	 * by DP SI test equipment automatically.
2606 	 * PHY test pattern request is generated by equipment via HPD interrupt.
2607 	 * HPD needs to be active all the time. HPD should be active
2608 	 * all the time. Do not touch it.
2609 	 * forward request to DS
2610 	 */
2611 	dc_link_dp_set_test_pattern(
2612 		link,
2613 		test_pattern,
2614 		DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
2615 		&link_training_settings,
2616 		test_80_bit_pattern,
2617 		(DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2618 		DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1);
2619 }
2620 
dp_test_send_link_test_pattern(struct dc_link * link)2621 static void dp_test_send_link_test_pattern(struct dc_link *link)
2622 {
2623 	union link_test_pattern dpcd_test_pattern;
2624 	union test_misc dpcd_test_params;
2625 	enum dp_test_pattern test_pattern;
2626 	enum dp_test_pattern_color_space test_pattern_color_space =
2627 			DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED;
2628 
2629 	memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
2630 	memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
2631 
2632 	/* get link test pattern and pattern parameters */
2633 	core_link_read_dpcd(
2634 			link,
2635 			DP_TEST_PATTERN,
2636 			&dpcd_test_pattern.raw,
2637 			sizeof(dpcd_test_pattern));
2638 	core_link_read_dpcd(
2639 			link,
2640 			DP_TEST_MISC0,
2641 			&dpcd_test_params.raw,
2642 			sizeof(dpcd_test_params));
2643 
2644 	switch (dpcd_test_pattern.bits.PATTERN) {
2645 	case LINK_TEST_PATTERN_COLOR_RAMP:
2646 		test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
2647 	break;
2648 	case LINK_TEST_PATTERN_VERTICAL_BARS:
2649 		test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
2650 	break; /* black and white */
2651 	case LINK_TEST_PATTERN_COLOR_SQUARES:
2652 		test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
2653 				TEST_DYN_RANGE_VESA ?
2654 				DP_TEST_PATTERN_COLOR_SQUARES :
2655 				DP_TEST_PATTERN_COLOR_SQUARES_CEA);
2656 	break;
2657 	default:
2658 		test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2659 	break;
2660 	}
2661 
2662 	test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ?
2663 			DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 :
2664 			DP_TEST_PATTERN_COLOR_SPACE_YCBCR601;
2665 
2666 	dc_link_dp_set_test_pattern(
2667 			link,
2668 			test_pattern,
2669 			test_pattern_color_space,
2670 			NULL,
2671 			NULL,
2672 			0);
2673 }
2674 
dp_test_get_audio_test_data(struct dc_link * link,bool disable_video)2675 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
2676 {
2677 	union audio_test_mode            dpcd_test_mode = {0};
2678 	struct audio_test_pattern_type   dpcd_pattern_type = {0};
2679 	union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
2680 	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
2681 
2682 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
2683 	struct pipe_ctx *pipe_ctx = &pipes[0];
2684 	unsigned int channel_count;
2685 	unsigned int channel = 0;
2686 	unsigned int modes = 0;
2687 	unsigned int sampling_rate_in_hz = 0;
2688 
2689 	// get audio test mode and test pattern parameters
2690 	core_link_read_dpcd(
2691 		link,
2692 		DP_TEST_AUDIO_MODE,
2693 		&dpcd_test_mode.raw,
2694 		sizeof(dpcd_test_mode));
2695 
2696 	core_link_read_dpcd(
2697 		link,
2698 		DP_TEST_AUDIO_PATTERN_TYPE,
2699 		&dpcd_pattern_type.value,
2700 		sizeof(dpcd_pattern_type));
2701 
2702 	channel_count = dpcd_test_mode.bits.channel_count + 1;
2703 
2704 	// read pattern periods for requested channels when sawTooth pattern is requested
2705 	if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
2706 			dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
2707 
2708 		test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
2709 				DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
2710 		// read period for each channel
2711 		for (channel = 0; channel < channel_count; channel++) {
2712 			core_link_read_dpcd(
2713 							link,
2714 							DP_TEST_AUDIO_PERIOD_CH1 + channel,
2715 							&dpcd_pattern_period[channel].raw,
2716 							sizeof(dpcd_pattern_period[channel]));
2717 		}
2718 	}
2719 
2720 	// translate sampling rate
2721 	switch (dpcd_test_mode.bits.sampling_rate) {
2722 	case AUDIO_SAMPLING_RATE_32KHZ:
2723 		sampling_rate_in_hz = 32000;
2724 		break;
2725 	case AUDIO_SAMPLING_RATE_44_1KHZ:
2726 		sampling_rate_in_hz = 44100;
2727 		break;
2728 	case AUDIO_SAMPLING_RATE_48KHZ:
2729 		sampling_rate_in_hz = 48000;
2730 		break;
2731 	case AUDIO_SAMPLING_RATE_88_2KHZ:
2732 		sampling_rate_in_hz = 88200;
2733 		break;
2734 	case AUDIO_SAMPLING_RATE_96KHZ:
2735 		sampling_rate_in_hz = 96000;
2736 		break;
2737 	case AUDIO_SAMPLING_RATE_176_4KHZ:
2738 		sampling_rate_in_hz = 176400;
2739 		break;
2740 	case AUDIO_SAMPLING_RATE_192KHZ:
2741 		sampling_rate_in_hz = 192000;
2742 		break;
2743 	default:
2744 		sampling_rate_in_hz = 0;
2745 		break;
2746 	}
2747 
2748 	link->audio_test_data.flags.test_requested = 1;
2749 	link->audio_test_data.flags.disable_video = disable_video;
2750 	link->audio_test_data.sampling_rate = sampling_rate_in_hz;
2751 	link->audio_test_data.channel_count = channel_count;
2752 	link->audio_test_data.pattern_type = test_pattern;
2753 
2754 	if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
2755 		for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
2756 			link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
2757 		}
2758 	}
2759 }
2760 
handle_automated_test(struct dc_link * link)2761 static void handle_automated_test(struct dc_link *link)
2762 {
2763 	union test_request test_request;
2764 	union test_response test_response;
2765 
2766 	memset(&test_request, 0, sizeof(test_request));
2767 	memset(&test_response, 0, sizeof(test_response));
2768 
2769 	core_link_read_dpcd(
2770 		link,
2771 		DP_TEST_REQUEST,
2772 		&test_request.raw,
2773 		sizeof(union test_request));
2774 	if (test_request.bits.LINK_TRAINING) {
2775 		/* ACK first to let DP RX test box monitor LT sequence */
2776 		test_response.bits.ACK = 1;
2777 		core_link_write_dpcd(
2778 			link,
2779 			DP_TEST_RESPONSE,
2780 			&test_response.raw,
2781 			sizeof(test_response));
2782 		dp_test_send_link_training(link);
2783 		/* no acknowledge request is needed again */
2784 		test_response.bits.ACK = 0;
2785 	}
2786 	if (test_request.bits.LINK_TEST_PATTRN) {
2787 		dp_test_send_link_test_pattern(link);
2788 		test_response.bits.ACK = 1;
2789 	}
2790 
2791 	if (test_request.bits.AUDIO_TEST_PATTERN) {
2792 		dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
2793 		test_response.bits.ACK = 1;
2794 	}
2795 
2796 	if (test_request.bits.PHY_TEST_PATTERN) {
2797 		dp_test_send_phy_test_pattern(link);
2798 		test_response.bits.ACK = 1;
2799 	}
2800 
2801 	/* send request acknowledgment */
2802 	if (test_response.bits.ACK)
2803 		core_link_write_dpcd(
2804 			link,
2805 			DP_TEST_RESPONSE,
2806 			&test_response.raw,
2807 			sizeof(test_response));
2808 }
2809 
dc_link_handle_hpd_rx_irq(struct dc_link * link,union hpd_irq_data * out_hpd_irq_dpcd_data,bool * out_link_loss)2810 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss)
2811 {
2812 	union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } };
2813 	union device_service_irq device_service_clear = { { 0 } };
2814 	enum dc_status result;
2815 	bool status = false;
2816 	struct pipe_ctx *pipe_ctx;
2817 	struct dc_link_settings previous_link_settings;
2818 	int i;
2819 
2820 	if (out_link_loss)
2821 		*out_link_loss = false;
2822 	/* For use cases related to down stream connection status change,
2823 	 * PSR and device auto test, refer to function handle_sst_hpd_irq
2824 	 * in DAL2.1*/
2825 
2826 	DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
2827 		__func__, link->link_index);
2828 
2829 
2830 	 /* All the "handle_hpd_irq_xxx()" methods
2831 		 * should be called only after
2832 		 * dal_dpsst_ls_read_hpd_irq_data
2833 		 * Order of calls is important too
2834 		 */
2835 	result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
2836 	if (out_hpd_irq_dpcd_data)
2837 		*out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
2838 
2839 	if (result != DC_OK) {
2840 		DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
2841 			__func__);
2842 		return false;
2843 	}
2844 
2845 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
2846 		device_service_clear.bits.AUTOMATED_TEST = 1;
2847 		core_link_write_dpcd(
2848 			link,
2849 			DP_DEVICE_SERVICE_IRQ_VECTOR,
2850 			&device_service_clear.raw,
2851 			sizeof(device_service_clear.raw));
2852 		device_service_clear.raw = 0;
2853 		handle_automated_test(link);
2854 		return false;
2855 	}
2856 
2857 	if (!allow_hpd_rx_irq(link)) {
2858 		DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
2859 			__func__, link->link_index);
2860 		return false;
2861 	}
2862 
2863 	if (handle_hpd_irq_psr_sink(link))
2864 		/* PSR-related error was detected and handled */
2865 		return true;
2866 
2867 	/* If PSR-related error handled, Main link may be off,
2868 	 * so do not handle as a normal sink status change interrupt.
2869 	 */
2870 
2871 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
2872 		return true;
2873 
2874 	/* check if we have MST msg and return since we poll for it */
2875 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
2876 		return false;
2877 
2878 	/* For now we only handle 'Downstream port status' case.
2879 	 * If we got sink count changed it means
2880 	 * Downstream port status changed,
2881 	 * then DM should call DC to do the detection.
2882 	 * NOTE: Do not handle link loss on eDP since it is internal link*/
2883 	if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
2884 		hpd_rx_irq_check_link_loss_status(
2885 			link,
2886 			&hpd_irq_dpcd_data)) {
2887 		/* Connectivity log: link loss */
2888 		CONN_DATA_LINK_LOSS(link,
2889 					hpd_irq_dpcd_data.raw,
2890 					sizeof(hpd_irq_dpcd_data),
2891 					"Status: ");
2892 
2893 		for (i = 0; i < MAX_PIPES; i++) {
2894 			pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
2895 			if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
2896 				break;
2897 		}
2898 
2899 		if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
2900 			return false;
2901 
2902 		previous_link_settings = link->cur_link_settings;
2903 
2904 		perform_link_training_with_retries(&previous_link_settings,
2905 			true, LINK_TRAINING_ATTEMPTS,
2906 			pipe_ctx,
2907 			pipe_ctx->stream->signal);
2908 
2909 		if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
2910 			dc_link_reallocate_mst_payload(link);
2911 
2912 		status = false;
2913 		if (out_link_loss)
2914 			*out_link_loss = true;
2915 	}
2916 
2917 	if (link->type == dc_connection_active_dongle &&
2918 		hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
2919 			!= link->dpcd_sink_count)
2920 		status = true;
2921 
2922 	/* reasons for HPD RX:
2923 	 * 1. Link Loss - ie Re-train the Link
2924 	 * 2. MST sideband message
2925 	 * 3. Automated Test - ie. Internal Commit
2926 	 * 4. CP (copy protection) - (not interesting for DM???)
2927 	 * 5. DRR
2928 	 * 6. Downstream Port status changed
2929 	 * -ie. Detect - this the only one
2930 	 * which is interesting for DM because
2931 	 * it must call dc_link_detect.
2932 	 */
2933 	return status;
2934 }
2935 
2936 /*query dpcd for version and mst cap addresses*/
is_mst_supported(struct dc_link * link)2937 bool is_mst_supported(struct dc_link *link)
2938 {
2939 	bool mst          = false;
2940 	enum dc_status st = DC_OK;
2941 	union dpcd_rev rev;
2942 	union mstm_cap cap;
2943 
2944 	if (link->preferred_training_settings.mst_enable &&
2945 		*link->preferred_training_settings.mst_enable == false) {
2946 		return false;
2947 	}
2948 
2949 	rev.raw  = 0;
2950 	cap.raw  = 0;
2951 
2952 	st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
2953 			sizeof(rev));
2954 
2955 	if (st == DC_OK && rev.raw >= DPCD_REV_12) {
2956 
2957 		st = core_link_read_dpcd(link, DP_MSTM_CAP,
2958 				&cap.raw, sizeof(cap));
2959 		if (st == DC_OK && cap.bits.MST_CAP == 1)
2960 			mst = true;
2961 	}
2962 	return mst;
2963 
2964 }
2965 
is_dp_active_dongle(const struct dc_link * link)2966 bool is_dp_active_dongle(const struct dc_link *link)
2967 {
2968 	return link->dpcd_caps.is_branch_dev;
2969 }
2970 
translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)2971 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
2972 {
2973 	switch (bpc) {
2974 	case DOWN_STREAM_MAX_8BPC:
2975 		return 8;
2976 	case DOWN_STREAM_MAX_10BPC:
2977 		return 10;
2978 	case DOWN_STREAM_MAX_12BPC:
2979 		return 12;
2980 	case DOWN_STREAM_MAX_16BPC:
2981 		return 16;
2982 	default:
2983 		break;
2984 	}
2985 
2986 	return -1;
2987 }
2988 
read_dp_device_vendor_id(struct dc_link * link)2989 static void read_dp_device_vendor_id(struct dc_link *link)
2990 {
2991 	struct dp_device_vendor_id dp_id;
2992 
2993 	/* read IEEE branch device id */
2994 	core_link_read_dpcd(
2995 		link,
2996 		DP_BRANCH_OUI,
2997 		(uint8_t *)&dp_id,
2998 		sizeof(dp_id));
2999 
3000 	link->dpcd_caps.branch_dev_id =
3001 		(dp_id.ieee_oui[0] << 16) +
3002 		(dp_id.ieee_oui[1] << 8) +
3003 		dp_id.ieee_oui[2];
3004 
3005 	memmove(
3006 		link->dpcd_caps.branch_dev_name,
3007 		dp_id.ieee_device_id,
3008 		sizeof(dp_id.ieee_device_id));
3009 }
3010 
3011 
3012 
get_active_converter_info(uint8_t data,struct dc_link * link)3013 static void get_active_converter_info(
3014 	uint8_t data, struct dc_link *link)
3015 {
3016 	union dp_downstream_port_present ds_port = { .byte = data };
3017 	memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
3018 
3019 	/* decode converter info*/
3020 	if (!ds_port.fields.PORT_PRESENT) {
3021 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3022 		ddc_service_set_dongle_type(link->ddc,
3023 				link->dpcd_caps.dongle_type);
3024 		link->dpcd_caps.is_branch_dev = false;
3025 		return;
3026 	}
3027 
3028 	/* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
3029 	if (ds_port.fields.PORT_TYPE == DOWNSTREAM_DP) {
3030 		link->dpcd_caps.is_branch_dev = false;
3031 	}
3032 
3033 	else {
3034 		link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
3035 	}
3036 
3037 	switch (ds_port.fields.PORT_TYPE) {
3038 	case DOWNSTREAM_VGA:
3039 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
3040 		break;
3041 	case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
3042 		/* At this point we don't know is it DVI or HDMI or DP++,
3043 		 * assume DVI.*/
3044 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
3045 		break;
3046 	default:
3047 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3048 		break;
3049 	}
3050 
3051 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
3052 		uint8_t det_caps[16]; /* CTS 4.2.2.7 expects source to read Detailed Capabilities Info : 00080h-0008F.*/
3053 		union dwnstream_port_caps_byte0 *port_caps =
3054 			(union dwnstream_port_caps_byte0 *)det_caps;
3055 		core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
3056 				det_caps, sizeof(det_caps));
3057 
3058 		switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
3059 		/*Handle DP case as DONGLE_NONE*/
3060 		case DOWN_STREAM_DETAILED_DP:
3061 			link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3062 			break;
3063 		case DOWN_STREAM_DETAILED_VGA:
3064 			link->dpcd_caps.dongle_type =
3065 				DISPLAY_DONGLE_DP_VGA_CONVERTER;
3066 			break;
3067 		case DOWN_STREAM_DETAILED_DVI:
3068 			link->dpcd_caps.dongle_type =
3069 				DISPLAY_DONGLE_DP_DVI_CONVERTER;
3070 			break;
3071 		case DOWN_STREAM_DETAILED_HDMI:
3072 		case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
3073 			/*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
3074 			link->dpcd_caps.dongle_type =
3075 				DISPLAY_DONGLE_DP_HDMI_CONVERTER;
3076 
3077 			link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
3078 			if (ds_port.fields.DETAILED_CAPS) {
3079 
3080 				union dwnstream_port_caps_byte3_hdmi
3081 					hdmi_caps = {.raw = det_caps[3] };
3082 				union dwnstream_port_caps_byte2
3083 					hdmi_color_caps = {.raw = det_caps[2] };
3084 				link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz =
3085 					det_caps[1] * 2500;
3086 
3087 				link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
3088 					hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
3089 				/*YCBCR capability only for HDMI case*/
3090 				if (port_caps->bits.DWN_STRM_PORTX_TYPE
3091 						== DOWN_STREAM_DETAILED_HDMI) {
3092 					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
3093 							hdmi_caps.bits.YCrCr422_PASS_THROUGH;
3094 					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
3095 							hdmi_caps.bits.YCrCr420_PASS_THROUGH;
3096 					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
3097 							hdmi_caps.bits.YCrCr422_CONVERSION;
3098 					link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
3099 							hdmi_caps.bits.YCrCr420_CONVERSION;
3100 				}
3101 
3102 				link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
3103 					translate_dpcd_max_bpc(
3104 						hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
3105 
3106 				if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
3107 					link->dpcd_caps.dongle_caps.extendedCapValid = true;
3108 			}
3109 
3110 			break;
3111 		}
3112 	}
3113 
3114 	ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
3115 
3116 	{
3117 		struct dp_sink_hw_fw_revision dp_hw_fw_revision;
3118 
3119 		core_link_read_dpcd(
3120 			link,
3121 			DP_BRANCH_REVISION_START,
3122 			(uint8_t *)&dp_hw_fw_revision,
3123 			sizeof(dp_hw_fw_revision));
3124 
3125 		link->dpcd_caps.branch_hw_revision =
3126 			dp_hw_fw_revision.ieee_hw_rev;
3127 
3128 		memmove(
3129 			link->dpcd_caps.branch_fw_revision,
3130 			dp_hw_fw_revision.ieee_fw_rev,
3131 			sizeof(dp_hw_fw_revision.ieee_fw_rev));
3132 	}
3133 }
3134 
dp_wa_power_up_0010FA(struct dc_link * link,uint8_t * dpcd_data,int length)3135 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
3136 		int length)
3137 {
3138 	int retry = 0;
3139 
3140 	if (!link->dpcd_caps.dpcd_rev.raw) {
3141 		do {
3142 			dp_receiver_power_ctrl(link, true);
3143 			core_link_read_dpcd(link, DP_DPCD_REV,
3144 							dpcd_data, length);
3145 			link->dpcd_caps.dpcd_rev.raw = dpcd_data[
3146 				DP_DPCD_REV -
3147 				DP_DPCD_REV];
3148 		} while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
3149 	}
3150 
3151 	if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
3152 		switch (link->dpcd_caps.branch_dev_id) {
3153 		/* 0010FA active dongles (DP-VGA, DP-DLDVI converters) power down
3154 		 * all internal circuits including AUX communication preventing
3155 		 * reading DPCD table and EDID (spec violation).
3156 		 * Encoder will skip DP RX power down on disable_output to
3157 		 * keep receiver powered all the time.*/
3158 		case DP_BRANCH_DEVICE_ID_0010FA:
3159 		case DP_BRANCH_DEVICE_ID_0080E1:
3160 		case DP_BRANCH_DEVICE_ID_00E04C:
3161 			link->wa_flags.dp_keep_receiver_powered = true;
3162 			break;
3163 
3164 		/* TODO: May need work around for other dongles. */
3165 		default:
3166 			link->wa_flags.dp_keep_receiver_powered = false;
3167 			break;
3168 		}
3169 	} else
3170 		link->wa_flags.dp_keep_receiver_powered = false;
3171 }
3172 
retrieve_link_cap(struct dc_link * link)3173 static bool retrieve_link_cap(struct dc_link *link)
3174 {
3175 	/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
3176 	 * which means size 16 will be good for both of those DPCD register block reads
3177 	 */
3178 	uint8_t dpcd_data[16];
3179 	uint8_t lttpr_dpcd_data[6];
3180 
3181 	/*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
3182 	 */
3183 	uint8_t dpcd_dprx_data = '\0';
3184 	uint8_t dpcd_power_state = '\0';
3185 
3186 	struct dp_device_vendor_id sink_id;
3187 	union down_stream_port_count down_strm_port_count;
3188 	union edp_configuration_cap edp_config_cap;
3189 	union dp_downstream_port_present ds_port = { 0 };
3190 	enum dc_status status = DC_ERROR_UNEXPECTED;
3191 	uint32_t read_dpcd_retry_cnt = 3;
3192 	int i;
3193 	struct dp_sink_hw_fw_revision dp_hw_fw_revision;
3194 
3195 	/* Set default timeout to 3.2ms and read LTTPR capabilities */
3196 	bool ext_timeout_support = link->dc->caps.extended_aux_timeout_support &&
3197 			!link->dc->config.disable_extended_timeout_support;
3198 
3199 	link->is_lttpr_mode_transparent = true;
3200 
3201 	if (ext_timeout_support) {
3202 		dc_link_aux_configure_timeout(link->ddc,
3203 					LINK_AUX_DEFAULT_EXTENDED_TIMEOUT_PERIOD);
3204 	}
3205 
3206 	memset(dpcd_data, '\0', sizeof(dpcd_data));
3207 	memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
3208 	memset(&down_strm_port_count,
3209 		'\0', sizeof(union down_stream_port_count));
3210 	memset(&edp_config_cap, '\0',
3211 		sizeof(union edp_configuration_cap));
3212 
3213 	status = core_link_read_dpcd(link, DP_SET_POWER,
3214 				&dpcd_power_state, sizeof(dpcd_power_state));
3215 
3216 	/* Delay 1 ms if AUX CH is in power down state. Based on spec
3217 	 * section 2.3.1.2, if AUX CH may be powered down due to
3218 	 * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
3219 	 * signal and may need up to 1 ms before being able to reply.
3220 	 */
3221 	if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
3222 		udelay(1000);
3223 
3224 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
3225 		status = core_link_read_dpcd(
3226 				link,
3227 				DP_DPCD_REV,
3228 				dpcd_data,
3229 				sizeof(dpcd_data));
3230 		if (status == DC_OK)
3231 			break;
3232 	}
3233 
3234 	if (status != DC_OK) {
3235 		dm_error("%s: Read dpcd data failed.\n", __func__);
3236 		return false;
3237 	}
3238 
3239 	if (ext_timeout_support) {
3240 
3241 		status = core_link_read_dpcd(
3242 				link,
3243 				DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
3244 				lttpr_dpcd_data,
3245 				sizeof(lttpr_dpcd_data));
3246 
3247 		link->dpcd_caps.lttpr_caps.revision.raw =
3248 				lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV -
3249 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3250 
3251 		link->dpcd_caps.lttpr_caps.max_link_rate =
3252 				lttpr_dpcd_data[DP_MAX_LINK_RATE_PHY_REPEATER -
3253 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3254 
3255 		link->dpcd_caps.lttpr_caps.phy_repeater_cnt =
3256 				lttpr_dpcd_data[DP_PHY_REPEATER_CNT -
3257 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3258 
3259 		link->dpcd_caps.lttpr_caps.max_lane_count =
3260 				lttpr_dpcd_data[DP_MAX_LANE_COUNT_PHY_REPEATER -
3261 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3262 
3263 		link->dpcd_caps.lttpr_caps.mode =
3264 				lttpr_dpcd_data[DP_PHY_REPEATER_MODE -
3265 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3266 
3267 		link->dpcd_caps.lttpr_caps.max_ext_timeout =
3268 				lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
3269 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3270 
3271 		if (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 &&
3272 				link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
3273 				link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
3274 				link->dpcd_caps.lttpr_caps.revision.raw >= 0x14) {
3275 			link->is_lttpr_mode_transparent = false;
3276 		} else {
3277 			/*No lttpr reset timeout to its default value*/
3278 			link->is_lttpr_mode_transparent = true;
3279 			dc_link_aux_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
3280 		}
3281 
3282 		CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
3283 	}
3284 
3285 	{
3286 		union training_aux_rd_interval aux_rd_interval;
3287 
3288 		aux_rd_interval.raw =
3289 			dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
3290 
3291 		link->dpcd_caps.ext_receiver_cap_field_present =
3292 				aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1;
3293 
3294 		if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
3295 			uint8_t ext_cap_data[16];
3296 
3297 			memset(ext_cap_data, '\0', sizeof(ext_cap_data));
3298 			for (i = 0; i < read_dpcd_retry_cnt; i++) {
3299 				status = core_link_read_dpcd(
3300 				link,
3301 				DP_DP13_DPCD_REV,
3302 				ext_cap_data,
3303 				sizeof(ext_cap_data));
3304 				if (status == DC_OK) {
3305 					memcpy(dpcd_data, ext_cap_data, sizeof(dpcd_data));
3306 					break;
3307 				}
3308 			}
3309 			if (status != DC_OK)
3310 				dm_error("%s: Read extend caps data failed, use cap from dpcd 0.\n", __func__);
3311 		}
3312 	}
3313 
3314 	link->dpcd_caps.dpcd_rev.raw =
3315 			dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
3316 
3317 	if (link->dpcd_caps.dpcd_rev.raw >= 0x14) {
3318 		for (i = 0; i < read_dpcd_retry_cnt; i++) {
3319 			status = core_link_read_dpcd(
3320 					link,
3321 					DP_DPRX_FEATURE_ENUMERATION_LIST,
3322 					&dpcd_dprx_data,
3323 					sizeof(dpcd_dprx_data));
3324 			if (status == DC_OK)
3325 				break;
3326 		}
3327 
3328 		link->dpcd_caps.dprx_feature.raw = dpcd_dprx_data;
3329 
3330 		if (status != DC_OK)
3331 			dm_error("%s: Read DPRX caps data failed.\n", __func__);
3332 	}
3333 
3334 	else {
3335 		link->dpcd_caps.dprx_feature.raw = 0;
3336 	}
3337 
3338 
3339 	/* Error condition checking...
3340 	 * It is impossible for Sink to report Max Lane Count = 0.
3341 	 * It is possible for Sink to report Max Link Rate = 0, if it is
3342 	 * an eDP device that is reporting specialized link rates in the
3343 	 * SUPPORTED_LINK_RATE table.
3344 	 */
3345 	if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
3346 		return false;
3347 
3348 	ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
3349 				 DP_DPCD_REV];
3350 
3351 	read_dp_device_vendor_id(link);
3352 
3353 	get_active_converter_info(ds_port.byte, link);
3354 
3355 	dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
3356 
3357 	down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
3358 				 DP_DPCD_REV];
3359 
3360 	link->dpcd_caps.allow_invalid_MSA_timing_param =
3361 		down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
3362 
3363 	link->dpcd_caps.max_ln_count.raw = dpcd_data[
3364 		DP_MAX_LANE_COUNT - DP_DPCD_REV];
3365 
3366 	link->dpcd_caps.max_down_spread.raw = dpcd_data[
3367 		DP_MAX_DOWNSPREAD - DP_DPCD_REV];
3368 
3369 	link->reported_link_cap.lane_count =
3370 		link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
3371 	link->reported_link_cap.link_rate = dpcd_data[
3372 		DP_MAX_LINK_RATE - DP_DPCD_REV];
3373 	link->reported_link_cap.link_spread =
3374 		link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
3375 		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
3376 
3377 	edp_config_cap.raw = dpcd_data[
3378 		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
3379 	link->dpcd_caps.panel_mode_edp =
3380 		edp_config_cap.bits.ALT_SCRAMBLER_RESET;
3381 	link->dpcd_caps.dpcd_display_control_capable =
3382 		edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
3383 
3384 	link->test_pattern_enabled = false;
3385 	link->compliance_test_state.raw = 0;
3386 
3387 	/* read sink count */
3388 	core_link_read_dpcd(link,
3389 			DP_SINK_COUNT,
3390 			&link->dpcd_caps.sink_count.raw,
3391 			sizeof(link->dpcd_caps.sink_count.raw));
3392 
3393 	/* read sink ieee oui */
3394 	core_link_read_dpcd(link,
3395 			DP_SINK_OUI,
3396 			(uint8_t *)(&sink_id),
3397 			sizeof(sink_id));
3398 
3399 	link->dpcd_caps.sink_dev_id =
3400 			(sink_id.ieee_oui[0] << 16) +
3401 			(sink_id.ieee_oui[1] << 8) +
3402 			(sink_id.ieee_oui[2]);
3403 
3404 	memmove(
3405 		link->dpcd_caps.sink_dev_id_str,
3406 		sink_id.ieee_device_id,
3407 		sizeof(sink_id.ieee_device_id));
3408 
3409 	core_link_read_dpcd(
3410 		link,
3411 		DP_SINK_HW_REVISION_START,
3412 		(uint8_t *)&dp_hw_fw_revision,
3413 		sizeof(dp_hw_fw_revision));
3414 
3415 	link->dpcd_caps.sink_hw_revision =
3416 		dp_hw_fw_revision.ieee_hw_rev;
3417 
3418 	memmove(
3419 		link->dpcd_caps.sink_fw_revision,
3420 		dp_hw_fw_revision.ieee_fw_rev,
3421 		sizeof(dp_hw_fw_revision.ieee_fw_rev));
3422 
3423 	memset(&link->dpcd_caps.dsc_caps, '\0',
3424 			sizeof(link->dpcd_caps.dsc_caps));
3425 	memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
3426 	/* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */
3427 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
3428 		status = core_link_read_dpcd(
3429 				link,
3430 				DP_FEC_CAPABILITY,
3431 				&link->dpcd_caps.fec_cap.raw,
3432 				sizeof(link->dpcd_caps.fec_cap.raw));
3433 		status = core_link_read_dpcd(
3434 				link,
3435 				DP_DSC_SUPPORT,
3436 				link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
3437 				sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
3438 		status = core_link_read_dpcd(
3439 				link,
3440 				DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
3441 				link->dpcd_caps.dsc_caps.dsc_ext_caps.raw,
3442 				sizeof(link->dpcd_caps.dsc_caps.dsc_ext_caps.raw));
3443 	}
3444 
3445 	/* Connectivity log: detection */
3446 	CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
3447 
3448 	return true;
3449 }
3450 
dp_overwrite_extended_receiver_cap(struct dc_link * link)3451 bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
3452 {
3453 	uint8_t dpcd_data[16];
3454 	uint32_t read_dpcd_retry_cnt = 3;
3455 	enum dc_status status = DC_ERROR_UNEXPECTED;
3456 	union dp_downstream_port_present ds_port = { 0 };
3457 	union down_stream_port_count down_strm_port_count;
3458 	union edp_configuration_cap edp_config_cap;
3459 
3460 	int i;
3461 
3462 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
3463 		status = core_link_read_dpcd(
3464 				link,
3465 				DP_DPCD_REV,
3466 				dpcd_data,
3467 				sizeof(dpcd_data));
3468 		if (status == DC_OK)
3469 			break;
3470 	}
3471 
3472 	link->dpcd_caps.dpcd_rev.raw =
3473 		dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
3474 
3475 	if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
3476 		return false;
3477 
3478 	ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
3479 			DP_DPCD_REV];
3480 
3481 	get_active_converter_info(ds_port.byte, link);
3482 
3483 	down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
3484 			DP_DPCD_REV];
3485 
3486 	link->dpcd_caps.allow_invalid_MSA_timing_param =
3487 		down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
3488 
3489 	link->dpcd_caps.max_ln_count.raw = dpcd_data[
3490 		DP_MAX_LANE_COUNT - DP_DPCD_REV];
3491 
3492 	link->dpcd_caps.max_down_spread.raw = dpcd_data[
3493 		DP_MAX_DOWNSPREAD - DP_DPCD_REV];
3494 
3495 	link->reported_link_cap.lane_count =
3496 		link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
3497 	link->reported_link_cap.link_rate = dpcd_data[
3498 		DP_MAX_LINK_RATE - DP_DPCD_REV];
3499 	link->reported_link_cap.link_spread =
3500 		link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
3501 		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
3502 
3503 	edp_config_cap.raw = dpcd_data[
3504 		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
3505 	link->dpcd_caps.panel_mode_edp =
3506 		edp_config_cap.bits.ALT_SCRAMBLER_RESET;
3507 	link->dpcd_caps.dpcd_display_control_capable =
3508 		edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
3509 
3510 	return true;
3511 }
3512 
detect_dp_sink_caps(struct dc_link * link)3513 bool detect_dp_sink_caps(struct dc_link *link)
3514 {
3515 	return retrieve_link_cap(link);
3516 
3517 	/* dc init_hw has power encoder using default
3518 	 * signal for connector. For native DP, no
3519 	 * need to power up encoder again. If not native
3520 	 * DP, hw_init may need check signal or power up
3521 	 * encoder here.
3522 	 */
3523 	/* TODO save sink caps in link->sink */
3524 }
3525 
linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)3526 enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
3527 {
3528 	enum dc_link_rate link_rate;
3529 	// LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
3530 	switch (link_rate_in_khz) {
3531 	case 1620000:
3532 		link_rate = LINK_RATE_LOW;		// Rate_1 (RBR)		- 1.62 Gbps/Lane
3533 		break;
3534 	case 2160000:
3535 		link_rate = LINK_RATE_RATE_2;	// Rate_2			- 2.16 Gbps/Lane
3536 		break;
3537 	case 2430000:
3538 		link_rate = LINK_RATE_RATE_3;	// Rate_3			- 2.43 Gbps/Lane
3539 		break;
3540 	case 2700000:
3541 		link_rate = LINK_RATE_HIGH;		// Rate_4 (HBR)		- 2.70 Gbps/Lane
3542 		break;
3543 	case 3240000:
3544 		link_rate = LINK_RATE_RBR2;		// Rate_5 (RBR2)	- 3.24 Gbps/Lane
3545 		break;
3546 	case 4320000:
3547 		link_rate = LINK_RATE_RATE_6;	// Rate_6			- 4.32 Gbps/Lane
3548 		break;
3549 	case 5400000:
3550 		link_rate = LINK_RATE_HIGH2;	// Rate_7 (HBR2)	- 5.40 Gbps/Lane
3551 		break;
3552 	case 8100000:
3553 		link_rate = LINK_RATE_HIGH3;	// Rate_8 (HBR3)	- 8.10 Gbps/Lane
3554 		break;
3555 	default:
3556 		link_rate = LINK_RATE_UNKNOWN;
3557 		break;
3558 	}
3559 	return link_rate;
3560 }
3561 
detect_edp_sink_caps(struct dc_link * link)3562 void detect_edp_sink_caps(struct dc_link *link)
3563 {
3564 	uint8_t supported_link_rates[16];
3565 	uint32_t entry;
3566 	uint32_t link_rate_in_khz;
3567 	enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
3568 
3569 	retrieve_link_cap(link);
3570 	link->dpcd_caps.edp_supported_link_rates_count = 0;
3571 	memset(supported_link_rates, 0, sizeof(supported_link_rates));
3572 
3573 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
3574 			(link->dc->config.optimize_edp_link_rate ||
3575 			link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
3576 		// Read DPCD 00010h - 0001Fh 16 bytes at one shot
3577 		core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
3578 							supported_link_rates, sizeof(supported_link_rates));
3579 
3580 		for (entry = 0; entry < 16; entry += 2) {
3581 			// DPCD register reports per-lane link rate = 16-bit link rate capability
3582 			// value X 200 kHz. Need multiplier to find link rate in kHz.
3583 			link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
3584 										supported_link_rates[entry]) * 200;
3585 
3586 			if (link_rate_in_khz != 0) {
3587 				link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
3588 				link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate;
3589 				link->dpcd_caps.edp_supported_link_rates_count++;
3590 
3591 				if (link->reported_link_cap.link_rate < link_rate)
3592 					link->reported_link_cap.link_rate = link_rate;
3593 			}
3594 		}
3595 	}
3596 	link->verified_link_cap = link->reported_link_cap;
3597 }
3598 
dc_link_dp_enable_hpd(const struct dc_link * link)3599 void dc_link_dp_enable_hpd(const struct dc_link *link)
3600 {
3601 	struct link_encoder *encoder = link->link_enc;
3602 
3603 	if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3604 		encoder->funcs->enable_hpd(encoder);
3605 }
3606 
dc_link_dp_disable_hpd(const struct dc_link * link)3607 void dc_link_dp_disable_hpd(const struct dc_link *link)
3608 {
3609 	struct link_encoder *encoder = link->link_enc;
3610 
3611 	if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3612 		encoder->funcs->disable_hpd(encoder);
3613 }
3614 
is_dp_phy_pattern(enum dp_test_pattern test_pattern)3615 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
3616 {
3617 	if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
3618 			test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
3619 			test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
3620 		return true;
3621 	else
3622 		return false;
3623 }
3624 
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)3625 static void set_crtc_test_pattern(struct dc_link *link,
3626 				struct pipe_ctx *pipe_ctx,
3627 				enum dp_test_pattern test_pattern,
3628 				enum dp_test_pattern_color_space test_pattern_color_space)
3629 {
3630 	enum controller_dp_test_pattern controller_test_pattern;
3631 	enum dc_color_depth color_depth = pipe_ctx->
3632 		stream->timing.display_color_depth;
3633 	struct bit_depth_reduction_params params;
3634 	struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
3635 	int width = pipe_ctx->stream->timing.h_addressable +
3636 		pipe_ctx->stream->timing.h_border_left +
3637 		pipe_ctx->stream->timing.h_border_right;
3638 	int height = pipe_ctx->stream->timing.v_addressable +
3639 		pipe_ctx->stream->timing.v_border_bottom +
3640 		pipe_ctx->stream->timing.v_border_top;
3641 
3642 	memset(&params, 0, sizeof(params));
3643 
3644 	switch (test_pattern) {
3645 	case DP_TEST_PATTERN_COLOR_SQUARES:
3646 		controller_test_pattern =
3647 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
3648 	break;
3649 	case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3650 		controller_test_pattern =
3651 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
3652 	break;
3653 	case DP_TEST_PATTERN_VERTICAL_BARS:
3654 		controller_test_pattern =
3655 				CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
3656 	break;
3657 	case DP_TEST_PATTERN_HORIZONTAL_BARS:
3658 		controller_test_pattern =
3659 				CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
3660 	break;
3661 	case DP_TEST_PATTERN_COLOR_RAMP:
3662 		controller_test_pattern =
3663 				CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
3664 	break;
3665 	default:
3666 		controller_test_pattern =
3667 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
3668 	break;
3669 	}
3670 
3671 	switch (test_pattern) {
3672 	case DP_TEST_PATTERN_COLOR_SQUARES:
3673 	case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3674 	case DP_TEST_PATTERN_VERTICAL_BARS:
3675 	case DP_TEST_PATTERN_HORIZONTAL_BARS:
3676 	case DP_TEST_PATTERN_COLOR_RAMP:
3677 	{
3678 		/* disable bit depth reduction */
3679 		pipe_ctx->stream->bit_depth_params = params;
3680 		opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3681 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3682 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3683 				controller_test_pattern, color_depth);
3684 		else if (opp->funcs->opp_set_disp_pattern_generator) {
3685 			struct pipe_ctx *odm_pipe;
3686 			enum controller_dp_color_space controller_color_space;
3687 			int opp_cnt = 1;
3688 			int count;
3689 
3690 			switch (test_pattern_color_space) {
3691 			case DP_TEST_PATTERN_COLOR_SPACE_RGB:
3692 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
3693 				break;
3694 			case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
3695 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
3696 				break;
3697 			case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
3698 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
3699 				break;
3700 			case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
3701 			default:
3702 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
3703 				DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
3704 				ASSERT(0);
3705 				break;
3706 			}
3707 
3708 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3709 				opp_cnt++;
3710 
3711 			width /= opp_cnt;
3712 
3713 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3714 				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3715 
3716 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3717 				odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3718 					controller_test_pattern,
3719 					controller_color_space,
3720 					color_depth,
3721 					NULL,
3722 					width,
3723 					height);
3724 			}
3725 			opp->funcs->opp_set_disp_pattern_generator(opp,
3726 				controller_test_pattern,
3727 				controller_color_space,
3728 				color_depth,
3729 				NULL,
3730 				width,
3731 				height);
3732 			/* wait for dpg to blank pixel data with test pattern */
3733 			for (count = 0; count < 1000; count++) {
3734 				if (opp->funcs->dpg_is_blanked(opp))
3735 					break;
3736 				udelay(100);
3737 			}
3738 		}
3739 	}
3740 	break;
3741 	case DP_TEST_PATTERN_VIDEO_MODE:
3742 	{
3743 		/* restore bitdepth reduction */
3744 		resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
3745 		pipe_ctx->stream->bit_depth_params = params;
3746 		opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3747 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3748 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3749 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3750 				color_depth);
3751 		else if (opp->funcs->opp_set_disp_pattern_generator) {
3752 			struct pipe_ctx *odm_pipe;
3753 			int opp_cnt = 1;
3754 
3755 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3756 				opp_cnt++;
3757 
3758 			width /= opp_cnt;
3759 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3760 				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3761 
3762 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3763 				odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3764 					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3765 					CONTROLLER_DP_COLOR_SPACE_UDEFINED,
3766 					color_depth,
3767 					NULL,
3768 					width,
3769 					height);
3770 			}
3771 			opp->funcs->opp_set_disp_pattern_generator(opp,
3772 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3773 				CONTROLLER_DP_COLOR_SPACE_UDEFINED,
3774 				color_depth,
3775 				NULL,
3776 				width,
3777 				height);
3778 		}
3779 	}
3780 	break;
3781 
3782 	default:
3783 	break;
3784 	}
3785 }
3786 
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)3787 bool dc_link_dp_set_test_pattern(
3788 	struct dc_link *link,
3789 	enum dp_test_pattern test_pattern,
3790 	enum dp_test_pattern_color_space test_pattern_color_space,
3791 	const struct link_training_settings *p_link_settings,
3792 	const unsigned char *p_custom_pattern,
3793 	unsigned int cust_pattern_size)
3794 {
3795 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
3796 	struct pipe_ctx *pipe_ctx = &pipes[0];
3797 	unsigned int lane;
3798 	unsigned int i;
3799 	unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
3800 	union dpcd_training_pattern training_pattern;
3801 	enum dpcd_phy_test_patterns pattern;
3802 
3803 	memset(&training_pattern, 0, sizeof(training_pattern));
3804 
3805 	for (i = 0; i < MAX_PIPES; i++) {
3806 		if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
3807 			pipe_ctx = &pipes[i];
3808 			break;
3809 		}
3810 	}
3811 
3812 	/* Reset CRTC Test Pattern if it is currently running and request
3813 	 * is VideoMode Reset DP Phy Test Pattern if it is currently running
3814 	 * and request is VideoMode
3815 	 */
3816 	if (link->test_pattern_enabled && test_pattern ==
3817 			DP_TEST_PATTERN_VIDEO_MODE) {
3818 		/* Set CRTC Test Pattern */
3819 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
3820 		dp_set_hw_test_pattern(link, test_pattern,
3821 				(const uint8_t *)p_custom_pattern,
3822 				(uint32_t)cust_pattern_size);
3823 
3824 		/* Unblank Stream */
3825 		link->dc->hwss.unblank_stream(
3826 			pipe_ctx,
3827 			&link->verified_link_cap);
3828 		/* TODO:m_pHwss->MuteAudioEndpoint
3829 		 * (pPathMode->pDisplayPath, false);
3830 		 */
3831 
3832 		/* Reset Test Pattern state */
3833 		link->test_pattern_enabled = false;
3834 
3835 		return true;
3836 	}
3837 
3838 	/* Check for PHY Test Patterns */
3839 	if (is_dp_phy_pattern(test_pattern)) {
3840 		/* Set DPCD Lane Settings before running test pattern */
3841 		if (p_link_settings != NULL) {
3842 			dp_set_hw_lane_settings(link, p_link_settings, DPRX);
3843 			dpcd_set_lane_settings(link, p_link_settings, DPRX);
3844 		}
3845 
3846 		/* Blank stream if running test pattern */
3847 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
3848 			/*TODO:
3849 			 * m_pHwss->
3850 			 * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
3851 			 */
3852 			/* Blank stream */
3853 			pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
3854 		}
3855 
3856 		dp_set_hw_test_pattern(link, test_pattern,
3857 				(const uint8_t *)p_custom_pattern,
3858 				(uint32_t)cust_pattern_size);
3859 
3860 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
3861 			/* Set Test Pattern state */
3862 			link->test_pattern_enabled = true;
3863 			if (p_link_settings != NULL)
3864 				dpcd_set_link_settings(link,
3865 						p_link_settings);
3866 		}
3867 
3868 		switch (test_pattern) {
3869 		case DP_TEST_PATTERN_VIDEO_MODE:
3870 			pattern = PHY_TEST_PATTERN_NONE;
3871 			break;
3872 		case DP_TEST_PATTERN_D102:
3873 			pattern = PHY_TEST_PATTERN_D10_2;
3874 			break;
3875 		case DP_TEST_PATTERN_SYMBOL_ERROR:
3876 			pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
3877 			break;
3878 		case DP_TEST_PATTERN_PRBS7:
3879 			pattern = PHY_TEST_PATTERN_PRBS7;
3880 			break;
3881 		case DP_TEST_PATTERN_80BIT_CUSTOM:
3882 			pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
3883 			break;
3884 		case DP_TEST_PATTERN_CP2520_1:
3885 			pattern = PHY_TEST_PATTERN_CP2520_1;
3886 			break;
3887 		case DP_TEST_PATTERN_CP2520_2:
3888 			pattern = PHY_TEST_PATTERN_CP2520_2;
3889 			break;
3890 		case DP_TEST_PATTERN_CP2520_3:
3891 			pattern = PHY_TEST_PATTERN_CP2520_3;
3892 			break;
3893 		default:
3894 			return false;
3895 		}
3896 
3897 		if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
3898 		/*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
3899 			return false;
3900 
3901 		if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
3902 			/* tell receiver that we are sending qualification
3903 			 * pattern DP 1.2 or later - DP receiver's link quality
3904 			 * pattern is set using DPCD LINK_QUAL_LANEx_SET
3905 			 * register (0x10B~0x10E)\
3906 			 */
3907 			for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
3908 				link_qual_pattern[lane] =
3909 						(unsigned char)(pattern);
3910 
3911 			core_link_write_dpcd(link,
3912 					DP_LINK_QUAL_LANE0_SET,
3913 					link_qual_pattern,
3914 					sizeof(link_qual_pattern));
3915 		} else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
3916 			   link->dpcd_caps.dpcd_rev.raw == 0) {
3917 			/* tell receiver that we are sending qualification
3918 			 * pattern DP 1.1a or earlier - DP receiver's link
3919 			 * quality pattern is set using
3920 			 * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
3921 			 * register (0x102). We will use v_1.3 when we are
3922 			 * setting test pattern for DP 1.1.
3923 			 */
3924 			core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
3925 					    &training_pattern.raw,
3926 					    sizeof(training_pattern));
3927 			training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
3928 			core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
3929 					     &training_pattern.raw,
3930 					     sizeof(training_pattern));
3931 		}
3932 	} else {
3933 		enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
3934 
3935 		switch (test_pattern_color_space) {
3936 		case DP_TEST_PATTERN_COLOR_SPACE_RGB:
3937 			color_space = COLOR_SPACE_SRGB;
3938 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
3939 				color_space = COLOR_SPACE_SRGB_LIMITED;
3940 			break;
3941 
3942 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
3943 			color_space = COLOR_SPACE_YCBCR601;
3944 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
3945 				color_space = COLOR_SPACE_YCBCR601_LIMITED;
3946 			break;
3947 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
3948 			color_space = COLOR_SPACE_YCBCR709;
3949 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
3950 				color_space = COLOR_SPACE_YCBCR709_LIMITED;
3951 			break;
3952 		default:
3953 			break;
3954 		}
3955 		/* update MSA to requested color space */
3956 		pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
3957 				&pipe_ctx->stream->timing,
3958 				color_space,
3959 				pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
3960 				link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
3961 
3962 		/* CRTC Patterns */
3963 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
3964 
3965 		/* Set Test Pattern state */
3966 		link->test_pattern_enabled = true;
3967 	}
3968 
3969 	return true;
3970 }
3971 
dp_enable_mst_on_sink(struct dc_link * link,bool enable)3972 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
3973 {
3974 	unsigned char mstmCntl;
3975 
3976 	core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
3977 	if (enable)
3978 		mstmCntl |= DP_MST_EN;
3979 	else
3980 		mstmCntl &= (~DP_MST_EN);
3981 
3982 	core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
3983 }
3984 
dp_set_panel_mode(struct dc_link * link,enum dp_panel_mode panel_mode)3985 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
3986 {
3987 	union dpcd_edp_config edp_config_set;
3988 	bool panel_mode_edp = false;
3989 
3990 	memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
3991 
3992 	if (panel_mode != DP_PANEL_MODE_DEFAULT) {
3993 
3994 		switch (panel_mode) {
3995 		case DP_PANEL_MODE_EDP:
3996 		case DP_PANEL_MODE_SPECIAL:
3997 			panel_mode_edp = true;
3998 			break;
3999 
4000 		default:
4001 				break;
4002 		}
4003 
4004 		/*set edp panel mode in receiver*/
4005 		core_link_read_dpcd(
4006 			link,
4007 			DP_EDP_CONFIGURATION_SET,
4008 			&edp_config_set.raw,
4009 			sizeof(edp_config_set.raw));
4010 
4011 		if (edp_config_set.bits.PANEL_MODE_EDP
4012 			!= panel_mode_edp) {
4013 			enum dc_status result = DC_ERROR_UNEXPECTED;
4014 
4015 			edp_config_set.bits.PANEL_MODE_EDP =
4016 			panel_mode_edp;
4017 			result = core_link_write_dpcd(
4018 				link,
4019 				DP_EDP_CONFIGURATION_SET,
4020 				&edp_config_set.raw,
4021 				sizeof(edp_config_set.raw));
4022 
4023 			ASSERT(result == DC_OK);
4024 		}
4025 	}
4026 	DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
4027 		 "eDP panel mode enabled: %d \n",
4028 		 link->link_index,
4029 		 link->dpcd_caps.panel_mode_edp,
4030 		 panel_mode_edp);
4031 }
4032 
dp_get_panel_mode(struct dc_link * link)4033 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
4034 {
4035 	/* We need to explicitly check that connector
4036 	 * is not DP. Some Travis_VGA get reported
4037 	 * by video bios as DP.
4038 	 */
4039 	if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
4040 
4041 		switch (link->dpcd_caps.branch_dev_id) {
4042 		case DP_BRANCH_DEVICE_ID_0022B9:
4043 			/* alternate scrambler reset is required for Travis
4044 			 * for the case when external chip does not
4045 			 * provide sink device id, alternate scrambler
4046 			 * scheme will  be overriden later by querying
4047 			 * Encoder features
4048 			 */
4049 			if (strncmp(
4050 				link->dpcd_caps.branch_dev_name,
4051 				DP_VGA_LVDS_CONVERTER_ID_2,
4052 				sizeof(
4053 				link->dpcd_caps.
4054 				branch_dev_name)) == 0) {
4055 					return DP_PANEL_MODE_SPECIAL;
4056 			}
4057 			break;
4058 		case DP_BRANCH_DEVICE_ID_00001A:
4059 			/* alternate scrambler reset is required for Travis
4060 			 * for the case when external chip does not provide
4061 			 * sink device id, alternate scrambler scheme will
4062 			 * be overriden later by querying Encoder feature
4063 			 */
4064 			if (strncmp(link->dpcd_caps.branch_dev_name,
4065 				DP_VGA_LVDS_CONVERTER_ID_3,
4066 				sizeof(
4067 				link->dpcd_caps.
4068 				branch_dev_name)) == 0) {
4069 					return DP_PANEL_MODE_SPECIAL;
4070 			}
4071 			break;
4072 		default:
4073 			break;
4074 		}
4075 	}
4076 
4077 	if (link->dpcd_caps.panel_mode_edp) {
4078 		return DP_PANEL_MODE_EDP;
4079 	}
4080 
4081 	return DP_PANEL_MODE_DEFAULT;
4082 }
4083 
dp_set_fec_ready(struct dc_link * link,bool ready)4084 void dp_set_fec_ready(struct dc_link *link, bool ready)
4085 {
4086 	/* FEC has to be "set ready" before the link training.
4087 	 * The policy is to always train with FEC
4088 	 * if the sink supports it and leave it enabled on link.
4089 	 * If FEC is not supported, disable it.
4090 	 */
4091 	struct link_encoder *link_enc = link->link_enc;
4092 	uint8_t fec_config = 0;
4093 
4094 	if (link->dc->debug.disable_fec ||
4095 			IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment))
4096 		return;
4097 
4098 	if (link_enc->funcs->fec_set_ready &&
4099 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
4100 		if (ready) {
4101 			fec_config = 1;
4102 			if (core_link_write_dpcd(link,
4103 					DP_FEC_CONFIGURATION,
4104 					&fec_config,
4105 					sizeof(fec_config)) == DC_OK) {
4106 				link_enc->funcs->fec_set_ready(link_enc, true);
4107 				link->fec_state = dc_link_fec_ready;
4108 			} else {
4109 				link->link_enc->funcs->fec_set_ready(link->link_enc, false);
4110 				link->fec_state = dc_link_fec_not_ready;
4111 				dm_error("dpcd write failed to set fec_ready");
4112 			}
4113 		} else if (link->fec_state == dc_link_fec_ready) {
4114 			fec_config = 0;
4115 			core_link_write_dpcd(link,
4116 					DP_FEC_CONFIGURATION,
4117 					&fec_config,
4118 					sizeof(fec_config));
4119 			link->link_enc->funcs->fec_set_ready(
4120 					link->link_enc, false);
4121 			link->fec_state = dc_link_fec_not_ready;
4122 		}
4123 	}
4124 }
4125 
dp_set_fec_enable(struct dc_link * link,bool enable)4126 void dp_set_fec_enable(struct dc_link *link, bool enable)
4127 {
4128 	struct link_encoder *link_enc = link->link_enc;
4129 
4130 	if (link->dc->debug.disable_fec ||
4131 			IS_FPGA_MAXIMUS_DC(link->ctx->dce_environment))
4132 		return;
4133 
4134 	if (link_enc->funcs->fec_set_enable &&
4135 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
4136 		if (link->fec_state == dc_link_fec_ready && enable) {
4137 			/* Accord to DP spec, FEC enable sequence can first
4138 			 * be transmitted anytime after 1000 LL codes have
4139 			 * been transmitted on the link after link training
4140 			 * completion. Using 1 lane RBR should have the maximum
4141 			 * time for transmitting 1000 LL codes which is 6.173 us.
4142 			 * So use 7 microseconds delay instead.
4143 			 */
4144 			udelay(7);
4145 			link_enc->funcs->fec_set_enable(link_enc, true);
4146 			link->fec_state = dc_link_fec_enabled;
4147 		} else if (link->fec_state == dc_link_fec_enabled && !enable) {
4148 			link_enc->funcs->fec_set_enable(link_enc, false);
4149 			link->fec_state = dc_link_fec_ready;
4150 		}
4151 	}
4152 }
4153 
4154