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