• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = 4000;
881 		break;
882 	case 0x02:
883 		aux_rd_interval_us = 8000;
884 		break;
885 	case 0x03:
886 		aux_rd_interval_us = 12000;
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 		dc_sink_retain(link->local_sink);
1708 		dm_helpers_dp_mst_stop_top_mgr(link->ctx, link);
1709 	} else if (mst_enable == true &&
1710 			link->type == dc_connection_single &&
1711 			link->remote_sinks[0] != NULL) {
1712 		/* Re-enable MST on link. */
1713 		dp_disable_link_phy(link, link->connector_signal);
1714 		dp_enable_mst_on_sink(link, true);
1715 
1716 		link->type = dc_connection_mst_branch;
1717 		link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST;
1718 	}
1719 }
1720 
dc_link_dp_sync_lt_begin(struct dc_link * link)1721 bool dc_link_dp_sync_lt_begin(struct dc_link *link)
1722 {
1723 	/* Begin Sync LT. During this time,
1724 	 * DPCD:600h must not be powered down.
1725 	 */
1726 	link->sync_lt_in_progress = true;
1727 
1728 	/*Clear any existing preferred settings.*/
1729 	memset(&link->preferred_training_settings, 0,
1730 		sizeof(struct dc_link_training_overrides));
1731 	memset(&link->preferred_link_setting, 0,
1732 		sizeof(struct dc_link_settings));
1733 
1734 	return true;
1735 }
1736 
dc_link_dp_sync_lt_attempt(struct dc_link * link,struct dc_link_settings * link_settings,struct dc_link_training_overrides * lt_overrides)1737 enum link_training_result dc_link_dp_sync_lt_attempt(
1738     struct dc_link *link,
1739     struct dc_link_settings *link_settings,
1740     struct dc_link_training_overrides *lt_overrides)
1741 {
1742 	struct link_training_settings lt_settings;
1743 	enum link_training_result lt_status = LINK_TRAINING_SUCCESS;
1744 	enum dp_panel_mode panel_mode = DP_PANEL_MODE_DEFAULT;
1745 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1746 	bool fec_enable = false;
1747 
1748 	initialize_training_settings(
1749 		link,
1750 		link_settings,
1751 		lt_overrides,
1752 		&lt_settings);
1753 
1754 	/* Setup MST Mode */
1755 	if (lt_overrides->mst_enable)
1756 		set_dp_mst_mode(link, *lt_overrides->mst_enable);
1757 
1758 	/* Disable link */
1759 	dp_disable_link_phy(link, link->connector_signal);
1760 
1761 	/* Enable link */
1762 	dp_cs_id = get_clock_source_id(link);
1763 	dp_enable_link_phy(link, link->connector_signal,
1764 		dp_cs_id, link_settings);
1765 
1766 	/* Set FEC enable */
1767 	fec_enable = lt_overrides->fec_enable && *lt_overrides->fec_enable;
1768 	dp_set_fec_ready(link, fec_enable);
1769 
1770 	if (lt_overrides->alternate_scrambler_reset) {
1771 		if (*lt_overrides->alternate_scrambler_reset)
1772 			panel_mode = DP_PANEL_MODE_EDP;
1773 		else
1774 			panel_mode = DP_PANEL_MODE_DEFAULT;
1775 	} else
1776 		panel_mode = dp_get_panel_mode(link);
1777 
1778 	dp_set_panel_mode(link, panel_mode);
1779 
1780 	/* Attempt to train with given link training settings */
1781 	if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
1782 		start_clock_recovery_pattern_early(link, &lt_settings, DPRX);
1783 
1784 	/* Set link rate, lane count and spread. */
1785 	dpcd_set_link_settings(link, &lt_settings);
1786 
1787 	/* 2. perform link training (set link training done
1788 	 *  to false is done as well)
1789 	 */
1790 	lt_status = perform_clock_recovery_sequence(link, &lt_settings, DPRX);
1791 	if (lt_status == LINK_TRAINING_SUCCESS) {
1792 		lt_status = perform_channel_equalization_sequence(link,
1793 						&lt_settings,
1794 						DPRX);
1795 	}
1796 
1797 	/* 3. Sync LT must skip TRAINING_PATTERN_SET:0 (video pattern)*/
1798 	/* 4. print status message*/
1799 	print_status_message(link, &lt_settings, lt_status);
1800 
1801 	return lt_status;
1802 }
1803 
dc_link_dp_sync_lt_end(struct dc_link * link,bool link_down)1804 bool dc_link_dp_sync_lt_end(struct dc_link *link, bool link_down)
1805 {
1806 	/* If input parameter is set, shut down phy.
1807 	 * Still shouldn't turn off dp_receiver (DPCD:600h)
1808 	 */
1809 	if (link_down == true) {
1810 		dp_disable_link_phy(link, link->connector_signal);
1811 		dp_set_fec_ready(link, false);
1812 	}
1813 
1814 	link->sync_lt_in_progress = false;
1815 	return true;
1816 }
1817 
get_max_link_cap(struct dc_link * link)1818 static struct dc_link_settings get_max_link_cap(struct dc_link *link)
1819 {
1820 	struct dc_link_settings max_link_cap = {0};
1821 
1822 	/* get max link encoder capability */
1823 	link->link_enc->funcs->get_max_link_cap(link->link_enc, &max_link_cap);
1824 
1825 	/* Lower link settings based on sink's link cap */
1826 	if (link->reported_link_cap.lane_count < max_link_cap.lane_count)
1827 		max_link_cap.lane_count =
1828 				link->reported_link_cap.lane_count;
1829 	if (link->reported_link_cap.link_rate < max_link_cap.link_rate)
1830 		max_link_cap.link_rate =
1831 				link->reported_link_cap.link_rate;
1832 	if (link->reported_link_cap.link_spread <
1833 			max_link_cap.link_spread)
1834 		max_link_cap.link_spread =
1835 				link->reported_link_cap.link_spread;
1836 	/*
1837 	 * account for lttpr repeaters cap
1838 	 * notes: repeaters do not snoop in the DPRX Capabilities addresses (3.6.3).
1839 	 */
1840 	if (link->lttpr_non_transparent_mode) {
1841 		if (link->dpcd_caps.lttpr_caps.max_lane_count < max_link_cap.lane_count)
1842 			max_link_cap.lane_count = link->dpcd_caps.lttpr_caps.max_lane_count;
1843 
1844 		if (link->dpcd_caps.lttpr_caps.max_link_rate < max_link_cap.link_rate)
1845 			max_link_cap.link_rate = link->dpcd_caps.lttpr_caps.max_link_rate;
1846 
1847 		DC_LOG_HW_LINK_TRAINING("%s\n Training with LTTPR,  max_lane count %d max_link rate %d \n",
1848 						__func__,
1849 						max_link_cap.lane_count,
1850 						max_link_cap.link_rate);
1851 	}
1852 	return max_link_cap;
1853 }
1854 
read_hpd_rx_irq_data(struct dc_link * link,union hpd_irq_data * irq_data)1855 static enum dc_status read_hpd_rx_irq_data(
1856 	struct dc_link *link,
1857 	union hpd_irq_data *irq_data)
1858 {
1859 	static enum dc_status retval;
1860 
1861 	/* The HW reads 16 bytes from 200h on HPD,
1862 	 * but if we get an AUX_DEFER, the HW cannot retry
1863 	 * and this causes the CTS tests 4.3.2.1 - 3.2.4 to
1864 	 * fail, so we now explicitly read 6 bytes which is
1865 	 * the req from the above mentioned test cases.
1866 	 *
1867 	 * For DP 1.4 we need to read those from 2002h range.
1868 	 */
1869 	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14)
1870 		retval = core_link_read_dpcd(
1871 			link,
1872 			DP_SINK_COUNT,
1873 			irq_data->raw,
1874 			sizeof(union hpd_irq_data));
1875 	else {
1876 		/* Read 14 bytes in a single read and then copy only the required fields.
1877 		 * This is more efficient than doing it in two separate AUX reads. */
1878 
1879 		uint8_t tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI + 1];
1880 
1881 		retval = core_link_read_dpcd(
1882 			link,
1883 			DP_SINK_COUNT_ESI,
1884 			tmp,
1885 			sizeof(tmp));
1886 
1887 		if (retval != DC_OK)
1888 			return retval;
1889 
1890 		irq_data->bytes.sink_cnt.raw = tmp[DP_SINK_COUNT_ESI - DP_SINK_COUNT_ESI];
1891 		irq_data->bytes.device_service_irq.raw = tmp[DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 - DP_SINK_COUNT_ESI];
1892 		irq_data->bytes.lane01_status.raw = tmp[DP_LANE0_1_STATUS_ESI - DP_SINK_COUNT_ESI];
1893 		irq_data->bytes.lane23_status.raw = tmp[DP_LANE2_3_STATUS_ESI - DP_SINK_COUNT_ESI];
1894 		irq_data->bytes.lane_status_updated.raw = tmp[DP_LANE_ALIGN_STATUS_UPDATED_ESI - DP_SINK_COUNT_ESI];
1895 		irq_data->bytes.sink_status.raw = tmp[DP_SINK_STATUS_ESI - DP_SINK_COUNT_ESI];
1896 	}
1897 
1898 	return retval;
1899 }
1900 
hpd_rx_irq_check_link_loss_status(struct dc_link * link,union hpd_irq_data * hpd_irq_dpcd_data)1901 static bool hpd_rx_irq_check_link_loss_status(
1902 	struct dc_link *link,
1903 	union hpd_irq_data *hpd_irq_dpcd_data)
1904 {
1905 	uint8_t irq_reg_rx_power_state = 0;
1906 	enum dc_status dpcd_result = DC_ERROR_UNEXPECTED;
1907 	union lane_status lane_status;
1908 	uint32_t lane;
1909 	bool sink_status_changed;
1910 	bool return_code;
1911 
1912 	sink_status_changed = false;
1913 	return_code = false;
1914 
1915 	if (link->cur_link_settings.lane_count == 0)
1916 		return return_code;
1917 
1918 	/*1. Check that Link Status changed, before re-training.*/
1919 
1920 	/*parse lane status*/
1921 	for (lane = 0; lane < link->cur_link_settings.lane_count; lane++) {
1922 		/* check status of lanes 0,1
1923 		 * changed DpcdAddress_Lane01Status (0x202)
1924 		 */
1925 		lane_status.raw = get_nibble_at_index(
1926 			&hpd_irq_dpcd_data->bytes.lane01_status.raw,
1927 			lane);
1928 
1929 		if (!lane_status.bits.CHANNEL_EQ_DONE_0 ||
1930 			!lane_status.bits.CR_DONE_0 ||
1931 			!lane_status.bits.SYMBOL_LOCKED_0) {
1932 			/* if one of the channel equalization, clock
1933 			 * recovery or symbol lock is dropped
1934 			 * consider it as (link has been
1935 			 * dropped) dp sink status has changed
1936 			 */
1937 			sink_status_changed = true;
1938 			break;
1939 		}
1940 	}
1941 
1942 	/* Check interlane align.*/
1943 	if (sink_status_changed ||
1944 		!hpd_irq_dpcd_data->bytes.lane_status_updated.bits.INTERLANE_ALIGN_DONE) {
1945 
1946 		DC_LOG_HW_HPD_IRQ("%s: Link Status changed.\n", __func__);
1947 
1948 		return_code = true;
1949 
1950 		/*2. Check that we can handle interrupt: Not in FS DOS,
1951 		 *  Not in "Display Timeout" state, Link is trained.
1952 		 */
1953 		dpcd_result = core_link_read_dpcd(link,
1954 			DP_SET_POWER,
1955 			&irq_reg_rx_power_state,
1956 			sizeof(irq_reg_rx_power_state));
1957 
1958 		if (dpcd_result != DC_OK) {
1959 			DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain power state.\n",
1960 				__func__);
1961 		} else {
1962 			if (irq_reg_rx_power_state != DP_SET_POWER_D0)
1963 				return_code = false;
1964 		}
1965 	}
1966 
1967 	return return_code;
1968 }
1969 
dp_verify_link_cap(struct dc_link * link,struct dc_link_settings * known_limit_link_setting,int * fail_count)1970 bool dp_verify_link_cap(
1971 	struct dc_link *link,
1972 	struct dc_link_settings *known_limit_link_setting,
1973 	int *fail_count)
1974 {
1975 	struct dc_link_settings max_link_cap = {0};
1976 	struct dc_link_settings cur_link_setting = {0};
1977 	struct dc_link_settings *cur = &cur_link_setting;
1978 	struct dc_link_settings initial_link_settings = {0};
1979 	bool success;
1980 	bool skip_link_training;
1981 	bool skip_video_pattern;
1982 	enum clock_source_id dp_cs_id = CLOCK_SOURCE_ID_EXTERNAL;
1983 	enum link_training_result status;
1984 	union hpd_irq_data irq_data;
1985 
1986 	if (link->dc->debug.skip_detection_link_training) {
1987 		link->verified_link_cap = *known_limit_link_setting;
1988 		return true;
1989 	}
1990 
1991 	memset(&irq_data, 0, sizeof(irq_data));
1992 	success = false;
1993 	skip_link_training = false;
1994 
1995 	max_link_cap = get_max_link_cap(link);
1996 
1997 	/* Grant extended timeout request */
1998 	if (link->lttpr_non_transparent_mode && link->dpcd_caps.lttpr_caps.max_ext_timeout > 0) {
1999 		uint8_t grant = link->dpcd_caps.lttpr_caps.max_ext_timeout & 0x80;
2000 
2001 		core_link_write_dpcd(link, DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT, &grant, sizeof(grant));
2002 	}
2003 
2004 	/* TODO implement override and monitor patch later */
2005 
2006 	/* try to train the link from high to low to
2007 	 * find the physical link capability
2008 	 */
2009 	/* disable PHY done possible by BIOS, will be done by driver itself */
2010 	dp_disable_link_phy(link, link->connector_signal);
2011 
2012 	dp_cs_id = get_clock_source_id(link);
2013 
2014 	/* link training starts with the maximum common settings
2015 	 * supported by both sink and ASIC.
2016 	 */
2017 	initial_link_settings = get_common_supported_link_settings(
2018 			*known_limit_link_setting,
2019 			max_link_cap);
2020 	cur_link_setting = initial_link_settings;
2021 
2022 	/* Temporary Renoir-specific workaround for SWDEV-215184;
2023 	 * PHY will sometimes be in bad state on hotplugging display from certain USB-C dongle,
2024 	 * so add extra cycle of enabling and disabling the PHY before first link training.
2025 	 */
2026 	if (link->link_enc->features.flags.bits.DP_IS_USB_C &&
2027 			link->dc->debug.usbc_combo_phy_reset_wa) {
2028 		dp_enable_link_phy(link, link->connector_signal, dp_cs_id, cur);
2029 		dp_disable_link_phy(link, link->connector_signal);
2030 	}
2031 
2032 	do {
2033 		skip_video_pattern = true;
2034 
2035 		if (cur->link_rate == LINK_RATE_LOW)
2036 			skip_video_pattern = false;
2037 
2038 		dp_enable_link_phy(
2039 				link,
2040 				link->connector_signal,
2041 				dp_cs_id,
2042 				cur);
2043 
2044 
2045 		if (skip_link_training)
2046 			success = true;
2047 		else {
2048 			status = dc_link_dp_perform_link_training(
2049 							link,
2050 							cur,
2051 							skip_video_pattern);
2052 			if (status == LINK_TRAINING_SUCCESS)
2053 				success = true;
2054 			else
2055 				(*fail_count)++;
2056 		}
2057 
2058 		if (success) {
2059 			link->verified_link_cap = *cur;
2060 			udelay(1000);
2061 			if (read_hpd_rx_irq_data(link, &irq_data) == DC_OK)
2062 				if (hpd_rx_irq_check_link_loss_status(
2063 						link,
2064 						&irq_data))
2065 					(*fail_count)++;
2066 		}
2067 		/* always disable the link before trying another
2068 		 * setting or before returning we'll enable it later
2069 		 * based on the actual mode we're driving
2070 		 */
2071 		dp_disable_link_phy(link, link->connector_signal);
2072 	} while (!success && decide_fallback_link_setting(
2073 			initial_link_settings, cur, status));
2074 
2075 	/* Link Training failed for all Link Settings
2076 	 *  (Lane Count is still unknown)
2077 	 */
2078 	if (!success) {
2079 		/* If all LT fails for all settings,
2080 		 * set verified = failed safe (1 lane low)
2081 		 */
2082 		link->verified_link_cap.lane_count = LANE_COUNT_ONE;
2083 		link->verified_link_cap.link_rate = LINK_RATE_LOW;
2084 
2085 		link->verified_link_cap.link_spread =
2086 		LINK_SPREAD_DISABLED;
2087 	}
2088 
2089 
2090 	return success;
2091 }
2092 
dp_verify_link_cap_with_retries(struct dc_link * link,struct dc_link_settings * known_limit_link_setting,int attempts)2093 bool dp_verify_link_cap_with_retries(
2094 	struct dc_link *link,
2095 	struct dc_link_settings *known_limit_link_setting,
2096 	int attempts)
2097 {
2098 	uint8_t i = 0;
2099 	bool success = false;
2100 
2101 	for (i = 0; i < attempts; i++) {
2102 		int fail_count = 0;
2103 		enum dc_connection_type type = dc_connection_none;
2104 
2105 		memset(&link->verified_link_cap, 0,
2106 				sizeof(struct dc_link_settings));
2107 		if (!dc_link_detect_sink(link, &type) || type == dc_connection_none) {
2108 			link->verified_link_cap.lane_count = LANE_COUNT_ONE;
2109 			link->verified_link_cap.link_rate = LINK_RATE_LOW;
2110 			link->verified_link_cap.link_spread = LINK_SPREAD_DISABLED;
2111 			break;
2112 		} else if (dp_verify_link_cap(link,
2113 				&link->reported_link_cap,
2114 				&fail_count) && fail_count == 0) {
2115 			success = true;
2116 			break;
2117 		}
2118 		msleep(10);
2119 	}
2120 	return success;
2121 }
2122 
dp_verify_mst_link_cap(struct dc_link * link)2123 bool dp_verify_mst_link_cap(
2124 	struct dc_link *link)
2125 {
2126 	struct dc_link_settings max_link_cap = {0};
2127 
2128 	max_link_cap = get_max_link_cap(link);
2129 	link->verified_link_cap = get_common_supported_link_settings(
2130 		link->reported_link_cap,
2131 		max_link_cap);
2132 
2133 	return true;
2134 }
2135 
get_common_supported_link_settings(struct dc_link_settings link_setting_a,struct dc_link_settings link_setting_b)2136 static struct dc_link_settings get_common_supported_link_settings(
2137 		struct dc_link_settings link_setting_a,
2138 		struct dc_link_settings link_setting_b)
2139 {
2140 	struct dc_link_settings link_settings = {0};
2141 
2142 	link_settings.lane_count =
2143 		(link_setting_a.lane_count <=
2144 			link_setting_b.lane_count) ?
2145 			link_setting_a.lane_count :
2146 			link_setting_b.lane_count;
2147 	link_settings.link_rate =
2148 		(link_setting_a.link_rate <=
2149 			link_setting_b.link_rate) ?
2150 			link_setting_a.link_rate :
2151 			link_setting_b.link_rate;
2152 	link_settings.link_spread = LINK_SPREAD_DISABLED;
2153 
2154 	/* in DP compliance test, DPR-120 may have
2155 	 * a random value in its MAX_LINK_BW dpcd field.
2156 	 * We map it to the maximum supported link rate that
2157 	 * is smaller than MAX_LINK_BW in this case.
2158 	 */
2159 	if (link_settings.link_rate > LINK_RATE_HIGH3) {
2160 		link_settings.link_rate = LINK_RATE_HIGH3;
2161 	} else if (link_settings.link_rate < LINK_RATE_HIGH3
2162 			&& link_settings.link_rate > LINK_RATE_HIGH2) {
2163 		link_settings.link_rate = LINK_RATE_HIGH2;
2164 	} else if (link_settings.link_rate < LINK_RATE_HIGH2
2165 			&& link_settings.link_rate > LINK_RATE_HIGH) {
2166 		link_settings.link_rate = LINK_RATE_HIGH;
2167 	} else if (link_settings.link_rate < LINK_RATE_HIGH
2168 			&& link_settings.link_rate > LINK_RATE_LOW) {
2169 		link_settings.link_rate = LINK_RATE_LOW;
2170 	} else if (link_settings.link_rate < LINK_RATE_LOW) {
2171 		link_settings.link_rate = LINK_RATE_UNKNOWN;
2172 	}
2173 
2174 	return link_settings;
2175 }
2176 
reached_minimum_lane_count(enum dc_lane_count lane_count)2177 static inline bool reached_minimum_lane_count(enum dc_lane_count lane_count)
2178 {
2179 	return lane_count <= LANE_COUNT_ONE;
2180 }
2181 
reached_minimum_link_rate(enum dc_link_rate link_rate)2182 static inline bool reached_minimum_link_rate(enum dc_link_rate link_rate)
2183 {
2184 	return link_rate <= LINK_RATE_LOW;
2185 }
2186 
reduce_lane_count(enum dc_lane_count lane_count)2187 static enum dc_lane_count reduce_lane_count(enum dc_lane_count lane_count)
2188 {
2189 	switch (lane_count) {
2190 	case LANE_COUNT_FOUR:
2191 		return LANE_COUNT_TWO;
2192 	case LANE_COUNT_TWO:
2193 		return LANE_COUNT_ONE;
2194 	case LANE_COUNT_ONE:
2195 		return LANE_COUNT_UNKNOWN;
2196 	default:
2197 		return LANE_COUNT_UNKNOWN;
2198 	}
2199 }
2200 
reduce_link_rate(enum dc_link_rate link_rate)2201 static enum dc_link_rate reduce_link_rate(enum dc_link_rate link_rate)
2202 {
2203 	switch (link_rate) {
2204 	case LINK_RATE_HIGH3:
2205 		return LINK_RATE_HIGH2;
2206 	case LINK_RATE_HIGH2:
2207 		return LINK_RATE_HIGH;
2208 	case LINK_RATE_HIGH:
2209 		return LINK_RATE_LOW;
2210 	case LINK_RATE_LOW:
2211 		return LINK_RATE_UNKNOWN;
2212 	default:
2213 		return LINK_RATE_UNKNOWN;
2214 	}
2215 }
2216 
increase_lane_count(enum dc_lane_count lane_count)2217 static enum dc_lane_count increase_lane_count(enum dc_lane_count lane_count)
2218 {
2219 	switch (lane_count) {
2220 	case LANE_COUNT_ONE:
2221 		return LANE_COUNT_TWO;
2222 	case LANE_COUNT_TWO:
2223 		return LANE_COUNT_FOUR;
2224 	default:
2225 		return LANE_COUNT_UNKNOWN;
2226 	}
2227 }
2228 
increase_link_rate(enum dc_link_rate link_rate)2229 static enum dc_link_rate increase_link_rate(enum dc_link_rate link_rate)
2230 {
2231 	switch (link_rate) {
2232 	case LINK_RATE_LOW:
2233 		return LINK_RATE_HIGH;
2234 	case LINK_RATE_HIGH:
2235 		return LINK_RATE_HIGH2;
2236 	case LINK_RATE_HIGH2:
2237 		return LINK_RATE_HIGH3;
2238 	default:
2239 		return LINK_RATE_UNKNOWN;
2240 	}
2241 }
2242 
2243 /*
2244  * function: set link rate and lane count fallback based
2245  * on current link setting and last link training result
2246  * return value:
2247  *			true - link setting could be set
2248  *			false - has reached minimum setting
2249  *					and no further fallback could be done
2250  */
decide_fallback_link_setting(struct dc_link_settings initial_link_settings,struct dc_link_settings * current_link_setting,enum link_training_result training_result)2251 static bool decide_fallback_link_setting(
2252 		struct dc_link_settings initial_link_settings,
2253 		struct dc_link_settings *current_link_setting,
2254 		enum link_training_result training_result)
2255 {
2256 	if (!current_link_setting)
2257 		return false;
2258 
2259 	switch (training_result) {
2260 	case LINK_TRAINING_CR_FAIL_LANE0:
2261 	case LINK_TRAINING_CR_FAIL_LANE1:
2262 	case LINK_TRAINING_CR_FAIL_LANE23:
2263 	case LINK_TRAINING_LQA_FAIL:
2264 	{
2265 		if (!reached_minimum_link_rate
2266 				(current_link_setting->link_rate)) {
2267 			current_link_setting->link_rate =
2268 				reduce_link_rate(
2269 					current_link_setting->link_rate);
2270 		} else if (!reached_minimum_lane_count
2271 				(current_link_setting->lane_count)) {
2272 			current_link_setting->link_rate =
2273 				initial_link_settings.link_rate;
2274 			if (training_result == LINK_TRAINING_CR_FAIL_LANE0)
2275 				return false;
2276 			else if (training_result == LINK_TRAINING_CR_FAIL_LANE1)
2277 				current_link_setting->lane_count =
2278 						LANE_COUNT_ONE;
2279 			else if (training_result ==
2280 					LINK_TRAINING_CR_FAIL_LANE23)
2281 				current_link_setting->lane_count =
2282 						LANE_COUNT_TWO;
2283 			else
2284 				current_link_setting->lane_count =
2285 					reduce_lane_count(
2286 					current_link_setting->lane_count);
2287 		} else {
2288 			return false;
2289 		}
2290 		break;
2291 	}
2292 	case LINK_TRAINING_EQ_FAIL_EQ:
2293 	{
2294 		if (!reached_minimum_lane_count
2295 				(current_link_setting->lane_count)) {
2296 			current_link_setting->lane_count =
2297 				reduce_lane_count(
2298 					current_link_setting->lane_count);
2299 		} else if (!reached_minimum_link_rate
2300 				(current_link_setting->link_rate)) {
2301 			current_link_setting->link_rate =
2302 				reduce_link_rate(
2303 					current_link_setting->link_rate);
2304 		} else {
2305 			return false;
2306 		}
2307 		break;
2308 	}
2309 	case LINK_TRAINING_EQ_FAIL_CR:
2310 	{
2311 		if (!reached_minimum_link_rate
2312 				(current_link_setting->link_rate)) {
2313 			current_link_setting->link_rate =
2314 				reduce_link_rate(
2315 					current_link_setting->link_rate);
2316 		} else {
2317 			return false;
2318 		}
2319 		break;
2320 	}
2321 	default:
2322 		return false;
2323 	}
2324 	return true;
2325 }
2326 
dp_validate_mode_timing(struct dc_link * link,const struct dc_crtc_timing * timing)2327 bool dp_validate_mode_timing(
2328 	struct dc_link *link,
2329 	const struct dc_crtc_timing *timing)
2330 {
2331 	uint32_t req_bw;
2332 	uint32_t max_bw;
2333 
2334 	const struct dc_link_settings *link_setting;
2335 
2336 	/*always DP fail safe mode*/
2337 	if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
2338 		timing->h_addressable == (uint32_t) 640 &&
2339 		timing->v_addressable == (uint32_t) 480)
2340 		return true;
2341 
2342 	link_setting = dc_link_get_link_cap(link);
2343 
2344 	/* TODO: DYNAMIC_VALIDATION needs to be implemented */
2345 	/*if (flags.DYNAMIC_VALIDATION == 1 &&
2346 		link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
2347 		link_setting = &link->verified_link_cap;
2348 	*/
2349 
2350 	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
2351 	max_bw = dc_link_bandwidth_kbps(link, link_setting);
2352 
2353 	if (req_bw <= max_bw) {
2354 		/* remember the biggest mode here, during
2355 		 * initial link training (to get
2356 		 * verified_link_cap), LS sends event about
2357 		 * cannot train at reported cap to upper
2358 		 * layer and upper layer will re-enumerate modes.
2359 		 * this is not necessary if the lower
2360 		 * verified_link_cap is enough to drive
2361 		 * all the modes */
2362 
2363 		/* TODO: DYNAMIC_VALIDATION needs to be implemented */
2364 		/* if (flags.DYNAMIC_VALIDATION == 1)
2365 			dpsst->max_req_bw_for_verified_linkcap = dal_max(
2366 				dpsst->max_req_bw_for_verified_linkcap, req_bw); */
2367 		return true;
2368 	} else
2369 		return false;
2370 }
2371 
decide_dp_link_settings(struct dc_link * link,struct dc_link_settings * link_setting,uint32_t req_bw)2372 static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
2373 {
2374 	struct dc_link_settings initial_link_setting = {
2375 		LANE_COUNT_ONE, LINK_RATE_LOW, LINK_SPREAD_DISABLED, false, 0};
2376 	struct dc_link_settings current_link_setting =
2377 			initial_link_setting;
2378 	uint32_t link_bw;
2379 
2380 	if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
2381 		return false;
2382 
2383 	/* search for the minimum link setting that:
2384 	 * 1. is supported according to the link training result
2385 	 * 2. could support the b/w requested by the timing
2386 	 */
2387 	while (current_link_setting.link_rate <=
2388 			link->verified_link_cap.link_rate) {
2389 		link_bw = dc_link_bandwidth_kbps(
2390 				link,
2391 				&current_link_setting);
2392 		if (req_bw <= link_bw) {
2393 			*link_setting = current_link_setting;
2394 			return true;
2395 		}
2396 
2397 		if (current_link_setting.lane_count <
2398 				link->verified_link_cap.lane_count) {
2399 			current_link_setting.lane_count =
2400 					increase_lane_count(
2401 							current_link_setting.lane_count);
2402 		} else {
2403 			current_link_setting.link_rate =
2404 					increase_link_rate(
2405 							current_link_setting.link_rate);
2406 			current_link_setting.lane_count =
2407 					initial_link_setting.lane_count;
2408 		}
2409 	}
2410 
2411 	return false;
2412 }
2413 
decide_edp_link_settings(struct dc_link * link,struct dc_link_settings * link_setting,uint32_t req_bw)2414 static bool decide_edp_link_settings(struct dc_link *link, struct dc_link_settings *link_setting, uint32_t req_bw)
2415 {
2416 	struct dc_link_settings initial_link_setting;
2417 	struct dc_link_settings current_link_setting;
2418 	uint32_t link_bw;
2419 
2420 	if (link->dpcd_caps.dpcd_rev.raw < DPCD_REV_14 ||
2421 			link->dpcd_caps.edp_supported_link_rates_count == 0) {
2422 		*link_setting = link->verified_link_cap;
2423 		return true;
2424 	}
2425 
2426 	memset(&initial_link_setting, 0, sizeof(initial_link_setting));
2427 	initial_link_setting.lane_count = LANE_COUNT_ONE;
2428 	initial_link_setting.link_rate = link->dpcd_caps.edp_supported_link_rates[0];
2429 	initial_link_setting.link_spread = LINK_SPREAD_DISABLED;
2430 	initial_link_setting.use_link_rate_set = true;
2431 	initial_link_setting.link_rate_set = 0;
2432 	current_link_setting = initial_link_setting;
2433 
2434 	/* search for the minimum link setting that:
2435 	 * 1. is supported according to the link training result
2436 	 * 2. could support the b/w requested by the timing
2437 	 */
2438 	while (current_link_setting.link_rate <=
2439 			link->verified_link_cap.link_rate) {
2440 		link_bw = dc_link_bandwidth_kbps(
2441 				link,
2442 				&current_link_setting);
2443 		if (req_bw <= link_bw) {
2444 			*link_setting = current_link_setting;
2445 			return true;
2446 		}
2447 
2448 		if (current_link_setting.lane_count <
2449 				link->verified_link_cap.lane_count) {
2450 			current_link_setting.lane_count =
2451 					increase_lane_count(
2452 							current_link_setting.lane_count);
2453 		} else {
2454 			if (current_link_setting.link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
2455 				current_link_setting.link_rate_set++;
2456 				current_link_setting.link_rate =
2457 					link->dpcd_caps.edp_supported_link_rates[current_link_setting.link_rate_set];
2458 				current_link_setting.lane_count =
2459 									initial_link_setting.lane_count;
2460 			} else
2461 				break;
2462 		}
2463 	}
2464 	return false;
2465 }
2466 
decide_mst_link_settings(const struct dc_link * link,struct dc_link_settings * link_setting)2467 static bool decide_mst_link_settings(const struct dc_link *link, struct dc_link_settings *link_setting)
2468 {
2469 	*link_setting = link->verified_link_cap;
2470 	return true;
2471 }
2472 
decide_link_settings(struct dc_stream_state * stream,struct dc_link_settings * link_setting)2473 void decide_link_settings(struct dc_stream_state *stream,
2474 	struct dc_link_settings *link_setting)
2475 {
2476 	struct dc_link *link;
2477 	uint32_t req_bw;
2478 
2479 	req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);
2480 
2481 	link = stream->link;
2482 
2483 	/* if preferred is specified through AMDDP, use it, if it's enough
2484 	 * to drive the mode
2485 	 */
2486 	if (link->preferred_link_setting.lane_count !=
2487 			LANE_COUNT_UNKNOWN &&
2488 			link->preferred_link_setting.link_rate !=
2489 					LINK_RATE_UNKNOWN) {
2490 		*link_setting =  link->preferred_link_setting;
2491 		return;
2492 	}
2493 
2494 	/* MST doesn't perform link training for now
2495 	 * TODO: add MST specific link training routine
2496 	 */
2497 	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
2498 		if (decide_mst_link_settings(link, link_setting))
2499 			return;
2500 	} else if (link->connector_signal == SIGNAL_TYPE_EDP) {
2501 		if (decide_edp_link_settings(link, link_setting, req_bw))
2502 			return;
2503 	} else if (decide_dp_link_settings(link, link_setting, req_bw))
2504 		return;
2505 
2506 	BREAK_TO_DEBUGGER();
2507 	ASSERT(link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN);
2508 
2509 	*link_setting = link->verified_link_cap;
2510 }
2511 
2512 /*************************Short Pulse IRQ***************************/
allow_hpd_rx_irq(const struct dc_link * link)2513 static bool allow_hpd_rx_irq(const struct dc_link *link)
2514 {
2515 	/*
2516 	 * Don't handle RX IRQ unless one of following is met:
2517 	 * 1) The link is established (cur_link_settings != unknown)
2518 	 * 2) We kicked off MST detection
2519 	 * 3) We know we're dealing with an active dongle
2520 	 */
2521 
2522 	if ((link->cur_link_settings.lane_count != LANE_COUNT_UNKNOWN) ||
2523 		(link->type == dc_connection_mst_branch) ||
2524 		is_dp_active_dongle(link))
2525 		return true;
2526 
2527 	return false;
2528 }
2529 
handle_hpd_irq_psr_sink(struct dc_link * link)2530 static bool handle_hpd_irq_psr_sink(struct dc_link *link)
2531 {
2532 	union dpcd_psr_configuration psr_configuration;
2533 
2534 	if (!link->psr_settings.psr_feature_enabled)
2535 		return false;
2536 
2537 	dm_helpers_dp_read_dpcd(
2538 		link->ctx,
2539 		link,
2540 		368,/*DpcdAddress_PSR_Enable_Cfg*/
2541 		&psr_configuration.raw,
2542 		sizeof(psr_configuration.raw));
2543 
2544 
2545 	if (psr_configuration.bits.ENABLE) {
2546 		unsigned char dpcdbuf[3] = {0};
2547 		union psr_error_status psr_error_status;
2548 		union psr_sink_psr_status psr_sink_psr_status;
2549 
2550 		dm_helpers_dp_read_dpcd(
2551 			link->ctx,
2552 			link,
2553 			0x2006, /*DpcdAddress_PSR_Error_Status*/
2554 			(unsigned char *) dpcdbuf,
2555 			sizeof(dpcdbuf));
2556 
2557 		/*DPCD 2006h   ERROR STATUS*/
2558 		psr_error_status.raw = dpcdbuf[0];
2559 		/*DPCD 2008h   SINK PANEL SELF REFRESH STATUS*/
2560 		psr_sink_psr_status.raw = dpcdbuf[2];
2561 
2562 		if (psr_error_status.bits.LINK_CRC_ERROR ||
2563 				psr_error_status.bits.RFB_STORAGE_ERROR) {
2564 			/* Acknowledge and clear error bits */
2565 			dm_helpers_dp_write_dpcd(
2566 				link->ctx,
2567 				link,
2568 				8198,/*DpcdAddress_PSR_Error_Status*/
2569 				&psr_error_status.raw,
2570 				sizeof(psr_error_status.raw));
2571 
2572 			/* PSR error, disable and re-enable PSR */
2573 			dc_link_set_psr_allow_active(link, false, true);
2574 			dc_link_set_psr_allow_active(link, true, true);
2575 
2576 			return true;
2577 		} else if (psr_sink_psr_status.bits.SINK_SELF_REFRESH_STATUS ==
2578 				PSR_SINK_STATE_ACTIVE_DISPLAY_FROM_SINK_RFB){
2579 			/* No error is detect, PSR is active.
2580 			 * We should return with IRQ_HPD handled without
2581 			 * checking for loss of sync since PSR would have
2582 			 * powered down main link.
2583 			 */
2584 			return true;
2585 		}
2586 	}
2587 	return false;
2588 }
2589 
dp_test_send_link_training(struct dc_link * link)2590 static void dp_test_send_link_training(struct dc_link *link)
2591 {
2592 	struct dc_link_settings link_settings = {0};
2593 
2594 	core_link_read_dpcd(
2595 			link,
2596 			DP_TEST_LANE_COUNT,
2597 			(unsigned char *)(&link_settings.lane_count),
2598 			1);
2599 	core_link_read_dpcd(
2600 			link,
2601 			DP_TEST_LINK_RATE,
2602 			(unsigned char *)(&link_settings.link_rate),
2603 			1);
2604 
2605 	/* Set preferred link settings */
2606 	link->verified_link_cap.lane_count = link_settings.lane_count;
2607 	link->verified_link_cap.link_rate = link_settings.link_rate;
2608 
2609 	dp_retrain_link_dp_test(link, &link_settings, false);
2610 }
2611 
2612 /* TODO Raven hbr2 compliance eye output is unstable
2613  * (toggling on and off) with debugger break
2614  * This caueses intermittent PHY automation failure
2615  * Need to look into the root cause */
dp_test_send_phy_test_pattern(struct dc_link * link)2616 static void dp_test_send_phy_test_pattern(struct dc_link *link)
2617 {
2618 	union phy_test_pattern dpcd_test_pattern;
2619 	union lane_adjust dpcd_lane_adjustment[2];
2620 	unsigned char dpcd_post_cursor_2_adjustment = 0;
2621 	unsigned char test_80_bit_pattern[
2622 			(DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2623 			DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1] = {0};
2624 	enum dp_test_pattern test_pattern;
2625 	struct dc_link_training_settings link_settings;
2626 	union lane_adjust dpcd_lane_adjust;
2627 	unsigned int lane;
2628 	struct link_training_settings link_training_settings;
2629 	int i = 0;
2630 
2631 	dpcd_test_pattern.raw = 0;
2632 	memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
2633 	memset(&link_settings, 0, sizeof(link_settings));
2634 
2635 	/* get phy test pattern and pattern parameters from DP receiver */
2636 	core_link_read_dpcd(
2637 			link,
2638 			DP_PHY_TEST_PATTERN,
2639 			&dpcd_test_pattern.raw,
2640 			sizeof(dpcd_test_pattern));
2641 	core_link_read_dpcd(
2642 			link,
2643 			DP_ADJUST_REQUEST_LANE0_1,
2644 			&dpcd_lane_adjustment[0].raw,
2645 			sizeof(dpcd_lane_adjustment));
2646 
2647 	/*get post cursor 2 parameters
2648 	 * For DP 1.1a or eariler, this DPCD register's value is 0
2649 	 * For DP 1.2 or later:
2650 	 * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
2651 	 * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
2652 	 */
2653 	core_link_read_dpcd(
2654 			link,
2655 			DP_ADJUST_REQUEST_POST_CURSOR2,
2656 			&dpcd_post_cursor_2_adjustment,
2657 			sizeof(dpcd_post_cursor_2_adjustment));
2658 
2659 	/* translate request */
2660 	switch (dpcd_test_pattern.bits.PATTERN) {
2661 	case PHY_TEST_PATTERN_D10_2:
2662 		test_pattern = DP_TEST_PATTERN_D102;
2663 		break;
2664 	case PHY_TEST_PATTERN_SYMBOL_ERROR:
2665 		test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
2666 		break;
2667 	case PHY_TEST_PATTERN_PRBS7:
2668 		test_pattern = DP_TEST_PATTERN_PRBS7;
2669 		break;
2670 	case PHY_TEST_PATTERN_80BIT_CUSTOM:
2671 		test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
2672 		break;
2673 	case PHY_TEST_PATTERN_CP2520_1:
2674 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
2675 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2676 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
2677 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2678 		break;
2679 	case PHY_TEST_PATTERN_CP2520_2:
2680 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
2681 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
2682 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
2683 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
2684 		break;
2685 	case PHY_TEST_PATTERN_CP2520_3:
2686 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
2687 		break;
2688 	default:
2689 		test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2690 	break;
2691 	}
2692 
2693 	if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM)
2694 		core_link_read_dpcd(
2695 				link,
2696 				DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
2697 				test_80_bit_pattern,
2698 				sizeof(test_80_bit_pattern));
2699 
2700 	/* prepare link training settings */
2701 	link_settings.link = link->cur_link_settings;
2702 
2703 	for (lane = 0; lane <
2704 		(unsigned int)(link->cur_link_settings.lane_count);
2705 		lane++) {
2706 		dpcd_lane_adjust.raw =
2707 			get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
2708 		link_settings.lane_settings[lane].VOLTAGE_SWING =
2709 			(enum dc_voltage_swing)
2710 			(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
2711 		link_settings.lane_settings[lane].PRE_EMPHASIS =
2712 			(enum dc_pre_emphasis)
2713 			(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
2714 		link_settings.lane_settings[lane].POST_CURSOR2 =
2715 			(enum dc_post_cursor2)
2716 			((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
2717 	}
2718 
2719 	for (i = 0; i < 4; i++)
2720 		link_training_settings.lane_settings[i] =
2721 				link_settings.lane_settings[i];
2722 	link_training_settings.link_settings = link_settings.link;
2723 	link_training_settings.allow_invalid_msa_timing_param = false;
2724 	/*Usage: Measure DP physical lane signal
2725 	 * by DP SI test equipment automatically.
2726 	 * PHY test pattern request is generated by equipment via HPD interrupt.
2727 	 * HPD needs to be active all the time. HPD should be active
2728 	 * all the time. Do not touch it.
2729 	 * forward request to DS
2730 	 */
2731 	dc_link_dp_set_test_pattern(
2732 		link,
2733 		test_pattern,
2734 		DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
2735 		&link_training_settings,
2736 		test_80_bit_pattern,
2737 		(DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
2738 		DP_TEST_80BIT_CUSTOM_PATTERN_7_0)+1);
2739 }
2740 
dp_test_send_link_test_pattern(struct dc_link * link)2741 static void dp_test_send_link_test_pattern(struct dc_link *link)
2742 {
2743 	union link_test_pattern dpcd_test_pattern;
2744 	union test_misc dpcd_test_params;
2745 	enum dp_test_pattern test_pattern;
2746 	enum dp_test_pattern_color_space test_pattern_color_space =
2747 			DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED;
2748 
2749 	memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
2750 	memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
2751 
2752 	/* get link test pattern and pattern parameters */
2753 	core_link_read_dpcd(
2754 			link,
2755 			DP_TEST_PATTERN,
2756 			&dpcd_test_pattern.raw,
2757 			sizeof(dpcd_test_pattern));
2758 	core_link_read_dpcd(
2759 			link,
2760 			DP_TEST_MISC0,
2761 			&dpcd_test_params.raw,
2762 			sizeof(dpcd_test_params));
2763 
2764 	switch (dpcd_test_pattern.bits.PATTERN) {
2765 	case LINK_TEST_PATTERN_COLOR_RAMP:
2766 		test_pattern = DP_TEST_PATTERN_COLOR_RAMP;
2767 	break;
2768 	case LINK_TEST_PATTERN_VERTICAL_BARS:
2769 		test_pattern = DP_TEST_PATTERN_VERTICAL_BARS;
2770 	break; /* black and white */
2771 	case LINK_TEST_PATTERN_COLOR_SQUARES:
2772 		test_pattern = (dpcd_test_params.bits.DYN_RANGE ==
2773 				TEST_DYN_RANGE_VESA ?
2774 				DP_TEST_PATTERN_COLOR_SQUARES :
2775 				DP_TEST_PATTERN_COLOR_SQUARES_CEA);
2776 	break;
2777 	default:
2778 		test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
2779 	break;
2780 	}
2781 
2782 	if (dpcd_test_params.bits.CLR_FORMAT == 0)
2783 		test_pattern_color_space = DP_TEST_PATTERN_COLOR_SPACE_RGB;
2784 	else
2785 		test_pattern_color_space = dpcd_test_params.bits.YCBCR_COEFS ?
2786 				DP_TEST_PATTERN_COLOR_SPACE_YCBCR709 :
2787 				DP_TEST_PATTERN_COLOR_SPACE_YCBCR601;
2788 
2789 	dc_link_dp_set_test_pattern(
2790 			link,
2791 			test_pattern,
2792 			test_pattern_color_space,
2793 			NULL,
2794 			NULL,
2795 			0);
2796 }
2797 
dp_test_get_audio_test_data(struct dc_link * link,bool disable_video)2798 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
2799 {
2800 	union audio_test_mode            dpcd_test_mode = {0};
2801 	struct audio_test_pattern_type   dpcd_pattern_type = {0};
2802 	union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
2803 	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
2804 
2805 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
2806 	struct pipe_ctx *pipe_ctx = &pipes[0];
2807 	unsigned int channel_count;
2808 	unsigned int channel = 0;
2809 	unsigned int modes = 0;
2810 	unsigned int sampling_rate_in_hz = 0;
2811 
2812 	// get audio test mode and test pattern parameters
2813 	core_link_read_dpcd(
2814 		link,
2815 		DP_TEST_AUDIO_MODE,
2816 		&dpcd_test_mode.raw,
2817 		sizeof(dpcd_test_mode));
2818 
2819 	core_link_read_dpcd(
2820 		link,
2821 		DP_TEST_AUDIO_PATTERN_TYPE,
2822 		&dpcd_pattern_type.value,
2823 		sizeof(dpcd_pattern_type));
2824 
2825 	channel_count = dpcd_test_mode.bits.channel_count + 1;
2826 
2827 	// read pattern periods for requested channels when sawTooth pattern is requested
2828 	if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
2829 			dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
2830 
2831 		test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
2832 				DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
2833 		// read period for each channel
2834 		for (channel = 0; channel < channel_count; channel++) {
2835 			core_link_read_dpcd(
2836 							link,
2837 							DP_TEST_AUDIO_PERIOD_CH1 + channel,
2838 							&dpcd_pattern_period[channel].raw,
2839 							sizeof(dpcd_pattern_period[channel]));
2840 		}
2841 	}
2842 
2843 	// translate sampling rate
2844 	switch (dpcd_test_mode.bits.sampling_rate) {
2845 	case AUDIO_SAMPLING_RATE_32KHZ:
2846 		sampling_rate_in_hz = 32000;
2847 		break;
2848 	case AUDIO_SAMPLING_RATE_44_1KHZ:
2849 		sampling_rate_in_hz = 44100;
2850 		break;
2851 	case AUDIO_SAMPLING_RATE_48KHZ:
2852 		sampling_rate_in_hz = 48000;
2853 		break;
2854 	case AUDIO_SAMPLING_RATE_88_2KHZ:
2855 		sampling_rate_in_hz = 88200;
2856 		break;
2857 	case AUDIO_SAMPLING_RATE_96KHZ:
2858 		sampling_rate_in_hz = 96000;
2859 		break;
2860 	case AUDIO_SAMPLING_RATE_176_4KHZ:
2861 		sampling_rate_in_hz = 176400;
2862 		break;
2863 	case AUDIO_SAMPLING_RATE_192KHZ:
2864 		sampling_rate_in_hz = 192000;
2865 		break;
2866 	default:
2867 		sampling_rate_in_hz = 0;
2868 		break;
2869 	}
2870 
2871 	link->audio_test_data.flags.test_requested = 1;
2872 	link->audio_test_data.flags.disable_video = disable_video;
2873 	link->audio_test_data.sampling_rate = sampling_rate_in_hz;
2874 	link->audio_test_data.channel_count = channel_count;
2875 	link->audio_test_data.pattern_type = test_pattern;
2876 
2877 	if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
2878 		for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
2879 			link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
2880 		}
2881 	}
2882 }
2883 
handle_automated_test(struct dc_link * link)2884 static void handle_automated_test(struct dc_link *link)
2885 {
2886 	union test_request test_request;
2887 	union test_response test_response;
2888 
2889 	memset(&test_request, 0, sizeof(test_request));
2890 	memset(&test_response, 0, sizeof(test_response));
2891 
2892 	core_link_read_dpcd(
2893 		link,
2894 		DP_TEST_REQUEST,
2895 		&test_request.raw,
2896 		sizeof(union test_request));
2897 	if (test_request.bits.LINK_TRAINING) {
2898 		/* ACK first to let DP RX test box monitor LT sequence */
2899 		test_response.bits.ACK = 1;
2900 		core_link_write_dpcd(
2901 			link,
2902 			DP_TEST_RESPONSE,
2903 			&test_response.raw,
2904 			sizeof(test_response));
2905 		dp_test_send_link_training(link);
2906 		/* no acknowledge request is needed again */
2907 		test_response.bits.ACK = 0;
2908 	}
2909 	if (test_request.bits.LINK_TEST_PATTRN) {
2910 		dp_test_send_link_test_pattern(link);
2911 		test_response.bits.ACK = 1;
2912 	}
2913 
2914 	if (test_request.bits.AUDIO_TEST_PATTERN) {
2915 		dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
2916 		test_response.bits.ACK = 1;
2917 	}
2918 
2919 	if (test_request.bits.PHY_TEST_PATTERN) {
2920 		dp_test_send_phy_test_pattern(link);
2921 		test_response.bits.ACK = 1;
2922 	}
2923 
2924 	/* send request acknowledgment */
2925 	if (test_response.bits.ACK)
2926 		core_link_write_dpcd(
2927 			link,
2928 			DP_TEST_RESPONSE,
2929 			&test_response.raw,
2930 			sizeof(test_response));
2931 }
2932 
dc_link_handle_hpd_rx_irq(struct dc_link * link,union hpd_irq_data * out_hpd_irq_dpcd_data,bool * out_link_loss)2933 bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd_irq_dpcd_data, bool *out_link_loss)
2934 {
2935 	union hpd_irq_data hpd_irq_dpcd_data = { { { {0} } } };
2936 	union device_service_irq device_service_clear = { { 0 } };
2937 	enum dc_status result;
2938 	bool status = false;
2939 	struct pipe_ctx *pipe_ctx;
2940 	int i;
2941 
2942 	if (out_link_loss)
2943 		*out_link_loss = false;
2944 	/* For use cases related to down stream connection status change,
2945 	 * PSR and device auto test, refer to function handle_sst_hpd_irq
2946 	 * in DAL2.1*/
2947 
2948 	DC_LOG_HW_HPD_IRQ("%s: Got short pulse HPD on link %d\n",
2949 		__func__, link->link_index);
2950 
2951 
2952 	 /* All the "handle_hpd_irq_xxx()" methods
2953 		 * should be called only after
2954 		 * dal_dpsst_ls_read_hpd_irq_data
2955 		 * Order of calls is important too
2956 		 */
2957 	result = read_hpd_rx_irq_data(link, &hpd_irq_dpcd_data);
2958 	if (out_hpd_irq_dpcd_data)
2959 		*out_hpd_irq_dpcd_data = hpd_irq_dpcd_data;
2960 
2961 	if (result != DC_OK) {
2962 		DC_LOG_HW_HPD_IRQ("%s: DPCD read failed to obtain irq data\n",
2963 			__func__);
2964 		return false;
2965 	}
2966 
2967 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.AUTOMATED_TEST) {
2968 		device_service_clear.bits.AUTOMATED_TEST = 1;
2969 		core_link_write_dpcd(
2970 			link,
2971 			DP_DEVICE_SERVICE_IRQ_VECTOR,
2972 			&device_service_clear.raw,
2973 			sizeof(device_service_clear.raw));
2974 		device_service_clear.raw = 0;
2975 		handle_automated_test(link);
2976 		return false;
2977 	}
2978 
2979 	if (!allow_hpd_rx_irq(link)) {
2980 		DC_LOG_HW_HPD_IRQ("%s: skipping HPD handling on %d\n",
2981 			__func__, link->link_index);
2982 		return false;
2983 	}
2984 
2985 	if (handle_hpd_irq_psr_sink(link))
2986 		/* PSR-related error was detected and handled */
2987 		return true;
2988 
2989 	/* If PSR-related error handled, Main link may be off,
2990 	 * so do not handle as a normal sink status change interrupt.
2991 	 */
2992 
2993 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.UP_REQ_MSG_RDY)
2994 		return true;
2995 
2996 	/* check if we have MST msg and return since we poll for it */
2997 	if (hpd_irq_dpcd_data.bytes.device_service_irq.bits.DOWN_REP_MSG_RDY)
2998 		return false;
2999 
3000 	/* For now we only handle 'Downstream port status' case.
3001 	 * If we got sink count changed it means
3002 	 * Downstream port status changed,
3003 	 * then DM should call DC to do the detection.
3004 	 * NOTE: Do not handle link loss on eDP since it is internal link*/
3005 	if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
3006 		hpd_rx_irq_check_link_loss_status(
3007 			link,
3008 			&hpd_irq_dpcd_data)) {
3009 		/* Connectivity log: link loss */
3010 		CONN_DATA_LINK_LOSS(link,
3011 					hpd_irq_dpcd_data.raw,
3012 					sizeof(hpd_irq_dpcd_data),
3013 					"Status: ");
3014 
3015 		for (i = 0; i < MAX_PIPES; i++) {
3016 			pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
3017 			if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
3018 				break;
3019 		}
3020 
3021 		if (pipe_ctx == NULL || pipe_ctx->stream == NULL)
3022 			return false;
3023 
3024 
3025 		for (i = 0; i < MAX_PIPES; i++) {
3026 			pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
3027 			if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
3028 					pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
3029 				core_link_disable_stream(pipe_ctx);
3030 		}
3031 
3032 		for (i = 0; i < MAX_PIPES; i++) {
3033 			pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
3034 			if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
3035 					pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
3036 				core_link_enable_stream(link->dc->current_state, pipe_ctx);
3037 		}
3038 
3039 		status = false;
3040 		if (out_link_loss)
3041 			*out_link_loss = true;
3042 	}
3043 
3044 	if (link->type == dc_connection_active_dongle &&
3045 		hpd_irq_dpcd_data.bytes.sink_cnt.bits.SINK_COUNT
3046 			!= link->dpcd_sink_count)
3047 		status = true;
3048 
3049 	/* reasons for HPD RX:
3050 	 * 1. Link Loss - ie Re-train the Link
3051 	 * 2. MST sideband message
3052 	 * 3. Automated Test - ie. Internal Commit
3053 	 * 4. CP (copy protection) - (not interesting for DM???)
3054 	 * 5. DRR
3055 	 * 6. Downstream Port status changed
3056 	 * -ie. Detect - this the only one
3057 	 * which is interesting for DM because
3058 	 * it must call dc_link_detect.
3059 	 */
3060 	return status;
3061 }
3062 
3063 /*query dpcd for version and mst cap addresses*/
is_mst_supported(struct dc_link * link)3064 bool is_mst_supported(struct dc_link *link)
3065 {
3066 	bool mst          = false;
3067 	enum dc_status st = DC_OK;
3068 	union dpcd_rev rev;
3069 	union mstm_cap cap;
3070 
3071 	if (link->preferred_training_settings.mst_enable &&
3072 		*link->preferred_training_settings.mst_enable == false) {
3073 		return false;
3074 	}
3075 
3076 	rev.raw  = 0;
3077 	cap.raw  = 0;
3078 
3079 	st = core_link_read_dpcd(link, DP_DPCD_REV, &rev.raw,
3080 			sizeof(rev));
3081 
3082 	if (st == DC_OK && rev.raw >= DPCD_REV_12) {
3083 
3084 		st = core_link_read_dpcd(link, DP_MSTM_CAP,
3085 				&cap.raw, sizeof(cap));
3086 		if (st == DC_OK && cap.bits.MST_CAP == 1)
3087 			mst = true;
3088 	}
3089 	return mst;
3090 
3091 }
3092 
is_dp_active_dongle(const struct dc_link * link)3093 bool is_dp_active_dongle(const struct dc_link *link)
3094 {
3095 	return link->dpcd_caps.is_branch_dev;
3096 }
3097 
translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)3098 static int translate_dpcd_max_bpc(enum dpcd_downstream_port_max_bpc bpc)
3099 {
3100 	switch (bpc) {
3101 	case DOWN_STREAM_MAX_8BPC:
3102 		return 8;
3103 	case DOWN_STREAM_MAX_10BPC:
3104 		return 10;
3105 	case DOWN_STREAM_MAX_12BPC:
3106 		return 12;
3107 	case DOWN_STREAM_MAX_16BPC:
3108 		return 16;
3109 	default:
3110 		break;
3111 	}
3112 
3113 	return -1;
3114 }
3115 
read_dp_device_vendor_id(struct dc_link * link)3116 static void read_dp_device_vendor_id(struct dc_link *link)
3117 {
3118 	struct dp_device_vendor_id dp_id;
3119 
3120 	/* read IEEE branch device id */
3121 	core_link_read_dpcd(
3122 		link,
3123 		DP_BRANCH_OUI,
3124 		(uint8_t *)&dp_id,
3125 		sizeof(dp_id));
3126 
3127 	link->dpcd_caps.branch_dev_id =
3128 		(dp_id.ieee_oui[0] << 16) +
3129 		(dp_id.ieee_oui[1] << 8) +
3130 		dp_id.ieee_oui[2];
3131 
3132 	memmove(
3133 		link->dpcd_caps.branch_dev_name,
3134 		dp_id.ieee_device_id,
3135 		sizeof(dp_id.ieee_device_id));
3136 }
3137 
3138 
3139 
get_active_converter_info(uint8_t data,struct dc_link * link)3140 static void get_active_converter_info(
3141 	uint8_t data, struct dc_link *link)
3142 {
3143 	union dp_downstream_port_present ds_port = { .byte = data };
3144 	memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps));
3145 
3146 	/* decode converter info*/
3147 	if (!ds_port.fields.PORT_PRESENT) {
3148 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3149 		ddc_service_set_dongle_type(link->ddc,
3150 				link->dpcd_caps.dongle_type);
3151 		link->dpcd_caps.is_branch_dev = false;
3152 		return;
3153 	}
3154 
3155 	/* DPCD 0x5 bit 0 = 1, it indicate it's branch device */
3156 	if (ds_port.fields.PORT_TYPE == DOWNSTREAM_DP) {
3157 		link->dpcd_caps.is_branch_dev = false;
3158 	}
3159 
3160 	else {
3161 		link->dpcd_caps.is_branch_dev = ds_port.fields.PORT_PRESENT;
3162 	}
3163 
3164 	switch (ds_port.fields.PORT_TYPE) {
3165 	case DOWNSTREAM_VGA:
3166 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_VGA_CONVERTER;
3167 		break;
3168 	case DOWNSTREAM_DVI_HDMI_DP_PLUS_PLUS:
3169 		/* At this point we don't know is it DVI or HDMI or DP++,
3170 		 * assume DVI.*/
3171 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_DP_DVI_CONVERTER;
3172 		break;
3173 	default:
3174 		link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3175 		break;
3176 	}
3177 
3178 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_11) {
3179 		uint8_t det_caps[16]; /* CTS 4.2.2.7 expects source to read Detailed Capabilities Info : 00080h-0008F.*/
3180 		union dwnstream_port_caps_byte0 *port_caps =
3181 			(union dwnstream_port_caps_byte0 *)det_caps;
3182 		if (core_link_read_dpcd(link, DP_DOWNSTREAM_PORT_0,
3183 				det_caps, sizeof(det_caps)) == DC_OK) {
3184 
3185 			switch (port_caps->bits.DWN_STRM_PORTX_TYPE) {
3186 			/*Handle DP case as DONGLE_NONE*/
3187 			case DOWN_STREAM_DETAILED_DP:
3188 				link->dpcd_caps.dongle_type = DISPLAY_DONGLE_NONE;
3189 				break;
3190 			case DOWN_STREAM_DETAILED_VGA:
3191 				link->dpcd_caps.dongle_type =
3192 					DISPLAY_DONGLE_DP_VGA_CONVERTER;
3193 				break;
3194 			case DOWN_STREAM_DETAILED_DVI:
3195 				link->dpcd_caps.dongle_type =
3196 					DISPLAY_DONGLE_DP_DVI_CONVERTER;
3197 				break;
3198 			case DOWN_STREAM_DETAILED_HDMI:
3199 			case DOWN_STREAM_DETAILED_DP_PLUS_PLUS:
3200 				/*Handle DP++ active converter case, process DP++ case as HDMI case according DP1.4 spec*/
3201 				link->dpcd_caps.dongle_type =
3202 					DISPLAY_DONGLE_DP_HDMI_CONVERTER;
3203 
3204 				link->dpcd_caps.dongle_caps.dongle_type = link->dpcd_caps.dongle_type;
3205 				if (ds_port.fields.DETAILED_CAPS) {
3206 
3207 					union dwnstream_port_caps_byte3_hdmi
3208 						hdmi_caps = {.raw = det_caps[3] };
3209 					union dwnstream_port_caps_byte2
3210 						hdmi_color_caps = {.raw = det_caps[2] };
3211 					link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz =
3212 						det_caps[1] * 2500;
3213 
3214 					link->dpcd_caps.dongle_caps.is_dp_hdmi_s3d_converter =
3215 						hdmi_caps.bits.FRAME_SEQ_TO_FRAME_PACK;
3216 					/*YCBCR capability only for HDMI case*/
3217 					if (port_caps->bits.DWN_STRM_PORTX_TYPE
3218 							== DOWN_STREAM_DETAILED_HDMI) {
3219 						link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_pass_through =
3220 								hdmi_caps.bits.YCrCr422_PASS_THROUGH;
3221 						link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_pass_through =
3222 								hdmi_caps.bits.YCrCr420_PASS_THROUGH;
3223 						link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr422_converter =
3224 								hdmi_caps.bits.YCrCr422_CONVERSION;
3225 						link->dpcd_caps.dongle_caps.is_dp_hdmi_ycbcr420_converter =
3226 								hdmi_caps.bits.YCrCr420_CONVERSION;
3227 					}
3228 
3229 					link->dpcd_caps.dongle_caps.dp_hdmi_max_bpc =
3230 						translate_dpcd_max_bpc(
3231 							hdmi_color_caps.bits.MAX_BITS_PER_COLOR_COMPONENT);
3232 
3233 					if (link->dpcd_caps.dongle_caps.dp_hdmi_max_pixel_clk_in_khz != 0)
3234 						link->dpcd_caps.dongle_caps.extendedCapValid = true;
3235 				}
3236 
3237 				break;
3238 			}
3239 		}
3240 	}
3241 
3242 	ddc_service_set_dongle_type(link->ddc, link->dpcd_caps.dongle_type);
3243 
3244 	{
3245 		struct dp_sink_hw_fw_revision dp_hw_fw_revision;
3246 
3247 		core_link_read_dpcd(
3248 			link,
3249 			DP_BRANCH_REVISION_START,
3250 			(uint8_t *)&dp_hw_fw_revision,
3251 			sizeof(dp_hw_fw_revision));
3252 
3253 		link->dpcd_caps.branch_hw_revision =
3254 			dp_hw_fw_revision.ieee_hw_rev;
3255 
3256 		memmove(
3257 			link->dpcd_caps.branch_fw_revision,
3258 			dp_hw_fw_revision.ieee_fw_rev,
3259 			sizeof(dp_hw_fw_revision.ieee_fw_rev));
3260 	}
3261 }
3262 
dp_wa_power_up_0010FA(struct dc_link * link,uint8_t * dpcd_data,int length)3263 static void dp_wa_power_up_0010FA(struct dc_link *link, uint8_t *dpcd_data,
3264 		int length)
3265 {
3266 	int retry = 0;
3267 
3268 	if (!link->dpcd_caps.dpcd_rev.raw) {
3269 		do {
3270 			dp_receiver_power_ctrl(link, true);
3271 			core_link_read_dpcd(link, DP_DPCD_REV,
3272 							dpcd_data, length);
3273 			link->dpcd_caps.dpcd_rev.raw = dpcd_data[
3274 				DP_DPCD_REV -
3275 				DP_DPCD_REV];
3276 		} while (retry++ < 4 && !link->dpcd_caps.dpcd_rev.raw);
3277 	}
3278 
3279 	if (link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_VGA_CONVERTER) {
3280 		switch (link->dpcd_caps.branch_dev_id) {
3281 		/* 0010FA active dongles (DP-VGA, DP-DLDVI converters) power down
3282 		 * all internal circuits including AUX communication preventing
3283 		 * reading DPCD table and EDID (spec violation).
3284 		 * Encoder will skip DP RX power down on disable_output to
3285 		 * keep receiver powered all the time.*/
3286 		case DP_BRANCH_DEVICE_ID_0010FA:
3287 		case DP_BRANCH_DEVICE_ID_0080E1:
3288 		case DP_BRANCH_DEVICE_ID_00E04C:
3289 			link->wa_flags.dp_keep_receiver_powered = true;
3290 			break;
3291 
3292 		/* TODO: May need work around for other dongles. */
3293 		default:
3294 			link->wa_flags.dp_keep_receiver_powered = false;
3295 			break;
3296 		}
3297 	} else
3298 		link->wa_flags.dp_keep_receiver_powered = false;
3299 }
3300 
3301 /* Read additional sink caps defined in source specific DPCD area
3302  * This function currently only reads from SinkCapability address (DP_SOURCE_SINK_CAP)
3303  */
dpcd_read_sink_ext_caps(struct dc_link * link)3304 static bool dpcd_read_sink_ext_caps(struct dc_link *link)
3305 {
3306 	uint8_t dpcd_data;
3307 
3308 	if (!link)
3309 		return false;
3310 
3311 	if (core_link_read_dpcd(link, DP_SOURCE_SINK_CAP, &dpcd_data, 1) != DC_OK)
3312 		return false;
3313 
3314 	link->dpcd_sink_ext_caps.raw = dpcd_data;
3315 	return true;
3316 }
3317 
retrieve_link_cap(struct dc_link * link)3318 static bool retrieve_link_cap(struct dc_link *link)
3319 {
3320 	/* DP_ADAPTER_CAP - DP_DPCD_REV + 1 == 16 and also DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT + 1 == 16,
3321 	 * which means size 16 will be good for both of those DPCD register block reads
3322 	 */
3323 	uint8_t dpcd_data[16];
3324 	uint8_t lttpr_dpcd_data[6];
3325 
3326 	/*Only need to read 1 byte starting from DP_DPRX_FEATURE_ENUMERATION_LIST.
3327 	 */
3328 	uint8_t dpcd_dprx_data = '\0';
3329 	uint8_t dpcd_power_state = '\0';
3330 
3331 	struct dp_device_vendor_id sink_id;
3332 	union down_stream_port_count down_strm_port_count;
3333 	union edp_configuration_cap edp_config_cap;
3334 	union dp_downstream_port_present ds_port = { 0 };
3335 	enum dc_status status = DC_ERROR_UNEXPECTED;
3336 	uint32_t read_dpcd_retry_cnt = 3;
3337 	int i;
3338 	struct dp_sink_hw_fw_revision dp_hw_fw_revision;
3339 	bool is_lttpr_present = false;
3340 	const uint32_t post_oui_delay = 30; // 30ms
3341 
3342 	memset(dpcd_data, '\0', sizeof(dpcd_data));
3343 	memset(lttpr_dpcd_data, '\0', sizeof(lttpr_dpcd_data));
3344 	memset(&down_strm_port_count,
3345 		'\0', sizeof(union down_stream_port_count));
3346 	memset(&edp_config_cap, '\0',
3347 		sizeof(union edp_configuration_cap));
3348 
3349 	/* if extended timeout is supported in hardware,
3350 	 * default to LTTPR timeout (3.2ms) first as a W/A for DP link layer
3351 	 * CTS 4.2.1.1 regression introduced by CTS specs requirement update.
3352 	 */
3353 	dc_link_aux_try_to_configure_timeout(link->ddc,
3354 			LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD);
3355 
3356 	status = core_link_read_dpcd(link, DP_SET_POWER,
3357 				&dpcd_power_state, sizeof(dpcd_power_state));
3358 
3359 	/* Delay 1 ms if AUX CH is in power down state. Based on spec
3360 	 * section 2.3.1.2, if AUX CH may be powered down due to
3361 	 * write to DPCD 600h = 2. Sink AUX CH is monitoring differential
3362 	 * signal and may need up to 1 ms before being able to reply.
3363 	 */
3364 	if (status != DC_OK || dpcd_power_state == DP_SET_POWER_D3)
3365 		udelay(1000);
3366 
3367 	dpcd_set_source_specific_data(link);
3368 	/* Sink may need to configure internals based on vendor, so allow some
3369 	 * time before proceeding with possibly vendor specific transactions
3370 	 */
3371 	msleep(post_oui_delay);
3372 
3373 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
3374 		status = core_link_read_dpcd(
3375 				link,
3376 				DP_DPCD_REV,
3377 				dpcd_data,
3378 				sizeof(dpcd_data));
3379 		if (status == DC_OK)
3380 			break;
3381 	}
3382 
3383 	if (status != DC_OK) {
3384 		dm_error("%s: Read dpcd data failed.\n", __func__);
3385 		return false;
3386 	}
3387 
3388 	if (link->dc->caps.extended_aux_timeout_support &&
3389 			link->dc->config.allow_lttpr_non_transparent_mode) {
3390 		/* By reading LTTPR capability, RX assumes that we will enable
3391 		 * LTTPR non transparent if LTTPR is present.
3392 		 * Therefore, only query LTTPR capability when both LTTPR
3393 		 * extended aux timeout and
3394 		 * non transparent mode is supported by hardware
3395 		 */
3396 		status = core_link_read_dpcd(
3397 				link,
3398 				DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV,
3399 				lttpr_dpcd_data,
3400 				sizeof(lttpr_dpcd_data));
3401 
3402 		link->dpcd_caps.lttpr_caps.revision.raw =
3403 				lttpr_dpcd_data[DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV -
3404 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3405 
3406 		link->dpcd_caps.lttpr_caps.max_link_rate =
3407 				lttpr_dpcd_data[DP_MAX_LINK_RATE_PHY_REPEATER -
3408 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3409 
3410 		link->dpcd_caps.lttpr_caps.phy_repeater_cnt =
3411 				lttpr_dpcd_data[DP_PHY_REPEATER_CNT -
3412 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3413 
3414 		link->dpcd_caps.lttpr_caps.max_lane_count =
3415 				lttpr_dpcd_data[DP_MAX_LANE_COUNT_PHY_REPEATER -
3416 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3417 
3418 		link->dpcd_caps.lttpr_caps.mode =
3419 				lttpr_dpcd_data[DP_PHY_REPEATER_MODE -
3420 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3421 
3422 		link->dpcd_caps.lttpr_caps.max_ext_timeout =
3423 				lttpr_dpcd_data[DP_PHY_REPEATER_EXTENDED_WAIT_TIMEOUT -
3424 								DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
3425 
3426 		is_lttpr_present = (link->dpcd_caps.lttpr_caps.phy_repeater_cnt > 0 &&
3427 				link->dpcd_caps.lttpr_caps.max_lane_count > 0 &&
3428 				link->dpcd_caps.lttpr_caps.max_lane_count <= 4 &&
3429 				link->dpcd_caps.lttpr_caps.revision.raw >= 0x14);
3430 		if (is_lttpr_present)
3431 			CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
3432 	}
3433 
3434 	/* decide lttpr non transparent mode */
3435 	link->lttpr_non_transparent_mode = is_lttpr_present;
3436 
3437 	if (!is_lttpr_present)
3438 		dc_link_aux_try_to_configure_timeout(link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD);
3439 
3440 
3441 	{
3442 		union training_aux_rd_interval aux_rd_interval;
3443 
3444 		aux_rd_interval.raw =
3445 			dpcd_data[DP_TRAINING_AUX_RD_INTERVAL];
3446 
3447 		link->dpcd_caps.ext_receiver_cap_field_present =
3448 				aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1;
3449 
3450 		if (aux_rd_interval.bits.EXT_RECEIVER_CAP_FIELD_PRESENT == 1) {
3451 			uint8_t ext_cap_data[16];
3452 
3453 			memset(ext_cap_data, '\0', sizeof(ext_cap_data));
3454 			for (i = 0; i < read_dpcd_retry_cnt; i++) {
3455 				status = core_link_read_dpcd(
3456 				link,
3457 				DP_DP13_DPCD_REV,
3458 				ext_cap_data,
3459 				sizeof(ext_cap_data));
3460 				if (status == DC_OK) {
3461 					memcpy(dpcd_data, ext_cap_data, sizeof(dpcd_data));
3462 					break;
3463 				}
3464 			}
3465 			if (status != DC_OK)
3466 				dm_error("%s: Read extend caps data failed, use cap from dpcd 0.\n", __func__);
3467 		}
3468 	}
3469 
3470 	link->dpcd_caps.dpcd_rev.raw =
3471 			dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
3472 
3473 	if (link->dpcd_caps.ext_receiver_cap_field_present) {
3474 		for (i = 0; i < read_dpcd_retry_cnt; i++) {
3475 			status = core_link_read_dpcd(
3476 					link,
3477 					DP_DPRX_FEATURE_ENUMERATION_LIST,
3478 					&dpcd_dprx_data,
3479 					sizeof(dpcd_dprx_data));
3480 			if (status == DC_OK)
3481 				break;
3482 		}
3483 
3484 		link->dpcd_caps.dprx_feature.raw = dpcd_dprx_data;
3485 
3486 		if (status != DC_OK)
3487 			dm_error("%s: Read DPRX caps data failed.\n", __func__);
3488 	}
3489 
3490 	else {
3491 		link->dpcd_caps.dprx_feature.raw = 0;
3492 	}
3493 
3494 
3495 	/* Error condition checking...
3496 	 * It is impossible for Sink to report Max Lane Count = 0.
3497 	 * It is possible for Sink to report Max Link Rate = 0, if it is
3498 	 * an eDP device that is reporting specialized link rates in the
3499 	 * SUPPORTED_LINK_RATE table.
3500 	 */
3501 	if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
3502 		return false;
3503 
3504 	ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
3505 				 DP_DPCD_REV];
3506 
3507 	read_dp_device_vendor_id(link);
3508 
3509 	get_active_converter_info(ds_port.byte, link);
3510 
3511 	dp_wa_power_up_0010FA(link, dpcd_data, sizeof(dpcd_data));
3512 
3513 	down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
3514 				 DP_DPCD_REV];
3515 
3516 	link->dpcd_caps.allow_invalid_MSA_timing_param =
3517 		down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
3518 
3519 	link->dpcd_caps.max_ln_count.raw = dpcd_data[
3520 		DP_MAX_LANE_COUNT - DP_DPCD_REV];
3521 
3522 	link->dpcd_caps.max_down_spread.raw = dpcd_data[
3523 		DP_MAX_DOWNSPREAD - DP_DPCD_REV];
3524 
3525 	link->reported_link_cap.lane_count =
3526 		link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
3527 	link->reported_link_cap.link_rate = dpcd_data[
3528 		DP_MAX_LINK_RATE - DP_DPCD_REV];
3529 	link->reported_link_cap.link_spread =
3530 		link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
3531 		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
3532 
3533 	edp_config_cap.raw = dpcd_data[
3534 		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
3535 	link->dpcd_caps.panel_mode_edp =
3536 		edp_config_cap.bits.ALT_SCRAMBLER_RESET;
3537 	link->dpcd_caps.dpcd_display_control_capable =
3538 		edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
3539 
3540 	link->test_pattern_enabled = false;
3541 	link->compliance_test_state.raw = 0;
3542 
3543 	/* read sink count */
3544 	core_link_read_dpcd(link,
3545 			DP_SINK_COUNT,
3546 			&link->dpcd_caps.sink_count.raw,
3547 			sizeof(link->dpcd_caps.sink_count.raw));
3548 
3549 	/* read sink ieee oui */
3550 	core_link_read_dpcd(link,
3551 			DP_SINK_OUI,
3552 			(uint8_t *)(&sink_id),
3553 			sizeof(sink_id));
3554 
3555 	link->dpcd_caps.sink_dev_id =
3556 			(sink_id.ieee_oui[0] << 16) +
3557 			(sink_id.ieee_oui[1] << 8) +
3558 			(sink_id.ieee_oui[2]);
3559 
3560 	memmove(
3561 		link->dpcd_caps.sink_dev_id_str,
3562 		sink_id.ieee_device_id,
3563 		sizeof(sink_id.ieee_device_id));
3564 
3565 	/* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */
3566 	{
3567 		uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 };
3568 
3569 		if ((link->dpcd_caps.sink_dev_id == 0x0010fa) &&
3570 		    !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017,
3571 			    sizeof(str_mbp_2017))) {
3572 			link->reported_link_cap.link_rate = 0x0c;
3573 		}
3574 	}
3575 
3576 	core_link_read_dpcd(
3577 		link,
3578 		DP_SINK_HW_REVISION_START,
3579 		(uint8_t *)&dp_hw_fw_revision,
3580 		sizeof(dp_hw_fw_revision));
3581 
3582 	link->dpcd_caps.sink_hw_revision =
3583 		dp_hw_fw_revision.ieee_hw_rev;
3584 
3585 	memmove(
3586 		link->dpcd_caps.sink_fw_revision,
3587 		dp_hw_fw_revision.ieee_fw_rev,
3588 		sizeof(dp_hw_fw_revision.ieee_fw_rev));
3589 
3590 	memset(&link->dpcd_caps.dsc_caps, '\0',
3591 			sizeof(link->dpcd_caps.dsc_caps));
3592 	memset(&link->dpcd_caps.fec_cap, '\0', sizeof(link->dpcd_caps.fec_cap));
3593 	/* Read DSC and FEC sink capabilities if DP revision is 1.4 and up */
3594 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14) {
3595 		status = core_link_read_dpcd(
3596 				link,
3597 				DP_FEC_CAPABILITY,
3598 				&link->dpcd_caps.fec_cap.raw,
3599 				sizeof(link->dpcd_caps.fec_cap.raw));
3600 		status = core_link_read_dpcd(
3601 				link,
3602 				DP_DSC_SUPPORT,
3603 				link->dpcd_caps.dsc_caps.dsc_basic_caps.raw,
3604 				sizeof(link->dpcd_caps.dsc_caps.dsc_basic_caps.raw));
3605 		status = core_link_read_dpcd(
3606 				link,
3607 				DP_DSC_BRANCH_OVERALL_THROUGHPUT_0,
3608 				link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw,
3609 				sizeof(link->dpcd_caps.dsc_caps.dsc_branch_decoder_caps.raw));
3610 	}
3611 
3612 	if (!dpcd_read_sink_ext_caps(link))
3613 		link->dpcd_sink_ext_caps.raw = 0;
3614 
3615 	/* Connectivity log: detection */
3616 	CONN_DATA_DETECT(link, dpcd_data, sizeof(dpcd_data), "Rx Caps: ");
3617 
3618 	return true;
3619 }
3620 
dp_overwrite_extended_receiver_cap(struct dc_link * link)3621 bool dp_overwrite_extended_receiver_cap(struct dc_link *link)
3622 {
3623 	uint8_t dpcd_data[16];
3624 	uint32_t read_dpcd_retry_cnt = 3;
3625 	enum dc_status status = DC_ERROR_UNEXPECTED;
3626 	union dp_downstream_port_present ds_port = { 0 };
3627 	union down_stream_port_count down_strm_port_count;
3628 	union edp_configuration_cap edp_config_cap;
3629 
3630 	int i;
3631 
3632 	for (i = 0; i < read_dpcd_retry_cnt; i++) {
3633 		status = core_link_read_dpcd(
3634 				link,
3635 				DP_DPCD_REV,
3636 				dpcd_data,
3637 				sizeof(dpcd_data));
3638 		if (status == DC_OK)
3639 			break;
3640 	}
3641 
3642 	link->dpcd_caps.dpcd_rev.raw =
3643 		dpcd_data[DP_DPCD_REV - DP_DPCD_REV];
3644 
3645 	if (dpcd_data[DP_MAX_LANE_COUNT - DP_DPCD_REV] == 0)
3646 		return false;
3647 
3648 	ds_port.byte = dpcd_data[DP_DOWNSTREAMPORT_PRESENT -
3649 			DP_DPCD_REV];
3650 
3651 	get_active_converter_info(ds_port.byte, link);
3652 
3653 	down_strm_port_count.raw = dpcd_data[DP_DOWN_STREAM_PORT_COUNT -
3654 			DP_DPCD_REV];
3655 
3656 	link->dpcd_caps.allow_invalid_MSA_timing_param =
3657 		down_strm_port_count.bits.IGNORE_MSA_TIMING_PARAM;
3658 
3659 	link->dpcd_caps.max_ln_count.raw = dpcd_data[
3660 		DP_MAX_LANE_COUNT - DP_DPCD_REV];
3661 
3662 	link->dpcd_caps.max_down_spread.raw = dpcd_data[
3663 		DP_MAX_DOWNSPREAD - DP_DPCD_REV];
3664 
3665 	link->reported_link_cap.lane_count =
3666 		link->dpcd_caps.max_ln_count.bits.MAX_LANE_COUNT;
3667 	link->reported_link_cap.link_rate = dpcd_data[
3668 		DP_MAX_LINK_RATE - DP_DPCD_REV];
3669 	link->reported_link_cap.link_spread =
3670 		link->dpcd_caps.max_down_spread.bits.MAX_DOWN_SPREAD ?
3671 		LINK_SPREAD_05_DOWNSPREAD_30KHZ : LINK_SPREAD_DISABLED;
3672 
3673 	edp_config_cap.raw = dpcd_data[
3674 		DP_EDP_CONFIGURATION_CAP - DP_DPCD_REV];
3675 	link->dpcd_caps.panel_mode_edp =
3676 		edp_config_cap.bits.ALT_SCRAMBLER_RESET;
3677 	link->dpcd_caps.dpcd_display_control_capable =
3678 		edp_config_cap.bits.DPCD_DISPLAY_CONTROL_CAPABLE;
3679 
3680 	return true;
3681 }
3682 
detect_dp_sink_caps(struct dc_link * link)3683 bool detect_dp_sink_caps(struct dc_link *link)
3684 {
3685 	return retrieve_link_cap(link);
3686 
3687 	/* dc init_hw has power encoder using default
3688 	 * signal for connector. For native DP, no
3689 	 * need to power up encoder again. If not native
3690 	 * DP, hw_init may need check signal or power up
3691 	 * encoder here.
3692 	 */
3693 	/* TODO save sink caps in link->sink */
3694 }
3695 
linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)3696 enum dc_link_rate linkRateInKHzToLinkRateMultiplier(uint32_t link_rate_in_khz)
3697 {
3698 	enum dc_link_rate link_rate;
3699 	// LinkRate is normally stored as a multiplier of 0.27 Gbps per lane. Do the translation.
3700 	switch (link_rate_in_khz) {
3701 	case 1620000:
3702 		link_rate = LINK_RATE_LOW;		// Rate_1 (RBR)		- 1.62 Gbps/Lane
3703 		break;
3704 	case 2160000:
3705 		link_rate = LINK_RATE_RATE_2;	// Rate_2			- 2.16 Gbps/Lane
3706 		break;
3707 	case 2430000:
3708 		link_rate = LINK_RATE_RATE_3;	// Rate_3			- 2.43 Gbps/Lane
3709 		break;
3710 	case 2700000:
3711 		link_rate = LINK_RATE_HIGH;		// Rate_4 (HBR)		- 2.70 Gbps/Lane
3712 		break;
3713 	case 3240000:
3714 		link_rate = LINK_RATE_RBR2;		// Rate_5 (RBR2)	- 3.24 Gbps/Lane
3715 		break;
3716 	case 4320000:
3717 		link_rate = LINK_RATE_RATE_6;	// Rate_6			- 4.32 Gbps/Lane
3718 		break;
3719 	case 5400000:
3720 		link_rate = LINK_RATE_HIGH2;	// Rate_7 (HBR2)	- 5.40 Gbps/Lane
3721 		break;
3722 	case 8100000:
3723 		link_rate = LINK_RATE_HIGH3;	// Rate_8 (HBR3)	- 8.10 Gbps/Lane
3724 		break;
3725 	default:
3726 		link_rate = LINK_RATE_UNKNOWN;
3727 		break;
3728 	}
3729 	return link_rate;
3730 }
3731 
detect_edp_sink_caps(struct dc_link * link)3732 void detect_edp_sink_caps(struct dc_link *link)
3733 {
3734 	uint8_t supported_link_rates[16];
3735 	uint32_t entry;
3736 	uint32_t link_rate_in_khz;
3737 	enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
3738 
3739 	retrieve_link_cap(link);
3740 	link->dpcd_caps.edp_supported_link_rates_count = 0;
3741 	memset(supported_link_rates, 0, sizeof(supported_link_rates));
3742 
3743 	if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_14 &&
3744 			(link->dc->config.optimize_edp_link_rate ||
3745 			link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN)) {
3746 		// Read DPCD 00010h - 0001Fh 16 bytes at one shot
3747 		core_link_read_dpcd(link, DP_SUPPORTED_LINK_RATES,
3748 							supported_link_rates, sizeof(supported_link_rates));
3749 
3750 		for (entry = 0; entry < 16; entry += 2) {
3751 			// DPCD register reports per-lane link rate = 16-bit link rate capability
3752 			// value X 200 kHz. Need multiplier to find link rate in kHz.
3753 			link_rate_in_khz = (supported_link_rates[entry+1] * 0x100 +
3754 										supported_link_rates[entry]) * 200;
3755 
3756 			if (link_rate_in_khz != 0) {
3757 				link_rate = linkRateInKHzToLinkRateMultiplier(link_rate_in_khz);
3758 				link->dpcd_caps.edp_supported_link_rates[link->dpcd_caps.edp_supported_link_rates_count] = link_rate;
3759 				link->dpcd_caps.edp_supported_link_rates_count++;
3760 
3761 				if (link->reported_link_cap.link_rate < link_rate)
3762 					link->reported_link_cap.link_rate = link_rate;
3763 			}
3764 		}
3765 	}
3766 	link->verified_link_cap = link->reported_link_cap;
3767 
3768 	dc_link_set_default_brightness_aux(link);
3769 }
3770 
dc_link_dp_enable_hpd(const struct dc_link * link)3771 void dc_link_dp_enable_hpd(const struct dc_link *link)
3772 {
3773 	struct link_encoder *encoder = link->link_enc;
3774 
3775 	if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3776 		encoder->funcs->enable_hpd(encoder);
3777 }
3778 
dc_link_dp_disable_hpd(const struct dc_link * link)3779 void dc_link_dp_disable_hpd(const struct dc_link *link)
3780 {
3781 	struct link_encoder *encoder = link->link_enc;
3782 
3783 	if (encoder != NULL && encoder->funcs->enable_hpd != NULL)
3784 		encoder->funcs->disable_hpd(encoder);
3785 }
3786 
is_dp_phy_pattern(enum dp_test_pattern test_pattern)3787 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
3788 {
3789 	if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
3790 			test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
3791 			test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
3792 		return true;
3793 	else
3794 		return false;
3795 }
3796 
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)3797 static void set_crtc_test_pattern(struct dc_link *link,
3798 				struct pipe_ctx *pipe_ctx,
3799 				enum dp_test_pattern test_pattern,
3800 				enum dp_test_pattern_color_space test_pattern_color_space)
3801 {
3802 	enum controller_dp_test_pattern controller_test_pattern;
3803 	enum dc_color_depth color_depth = pipe_ctx->
3804 		stream->timing.display_color_depth;
3805 	struct bit_depth_reduction_params params;
3806 	struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
3807 	int width = pipe_ctx->stream->timing.h_addressable +
3808 		pipe_ctx->stream->timing.h_border_left +
3809 		pipe_ctx->stream->timing.h_border_right;
3810 	int height = pipe_ctx->stream->timing.v_addressable +
3811 		pipe_ctx->stream->timing.v_border_bottom +
3812 		pipe_ctx->stream->timing.v_border_top;
3813 
3814 	memset(&params, 0, sizeof(params));
3815 
3816 	switch (test_pattern) {
3817 	case DP_TEST_PATTERN_COLOR_SQUARES:
3818 		controller_test_pattern =
3819 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES;
3820 	break;
3821 	case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3822 		controller_test_pattern =
3823 				CONTROLLER_DP_TEST_PATTERN_COLORSQUARES_CEA;
3824 	break;
3825 	case DP_TEST_PATTERN_VERTICAL_BARS:
3826 		controller_test_pattern =
3827 				CONTROLLER_DP_TEST_PATTERN_VERTICALBARS;
3828 	break;
3829 	case DP_TEST_PATTERN_HORIZONTAL_BARS:
3830 		controller_test_pattern =
3831 				CONTROLLER_DP_TEST_PATTERN_HORIZONTALBARS;
3832 	break;
3833 	case DP_TEST_PATTERN_COLOR_RAMP:
3834 		controller_test_pattern =
3835 				CONTROLLER_DP_TEST_PATTERN_COLORRAMP;
3836 	break;
3837 	default:
3838 		controller_test_pattern =
3839 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
3840 	break;
3841 	}
3842 
3843 	switch (test_pattern) {
3844 	case DP_TEST_PATTERN_COLOR_SQUARES:
3845 	case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
3846 	case DP_TEST_PATTERN_VERTICAL_BARS:
3847 	case DP_TEST_PATTERN_HORIZONTAL_BARS:
3848 	case DP_TEST_PATTERN_COLOR_RAMP:
3849 	{
3850 		/* disable bit depth reduction */
3851 		pipe_ctx->stream->bit_depth_params = params;
3852 		opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3853 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3854 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3855 				controller_test_pattern, color_depth);
3856 		else if (opp->funcs->opp_set_disp_pattern_generator) {
3857 			struct pipe_ctx *odm_pipe;
3858 			enum controller_dp_color_space controller_color_space;
3859 			int opp_cnt = 1;
3860 			int offset = 0;
3861 			int dpg_width = width;
3862 
3863 			switch (test_pattern_color_space) {
3864 			case DP_TEST_PATTERN_COLOR_SPACE_RGB:
3865 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_RGB;
3866 				break;
3867 			case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
3868 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR601;
3869 				break;
3870 			case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
3871 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_YCBCR709;
3872 				break;
3873 			case DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED:
3874 			default:
3875 				controller_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
3876 				DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
3877 				ASSERT(0);
3878 				break;
3879 			}
3880 
3881 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3882 				opp_cnt++;
3883 			dpg_width = width / opp_cnt;
3884 			offset = dpg_width;
3885 
3886 			opp->funcs->opp_set_disp_pattern_generator(opp,
3887 				controller_test_pattern,
3888 				controller_color_space,
3889 				color_depth,
3890 				NULL,
3891 				dpg_width,
3892 				height,
3893 				0);
3894 
3895 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3896 				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3897 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3898 				odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3899 					controller_test_pattern,
3900 					controller_color_space,
3901 					color_depth,
3902 					NULL,
3903 					dpg_width,
3904 					height,
3905 					offset);
3906 				offset += offset;
3907 			}
3908 		}
3909 	}
3910 	break;
3911 	case DP_TEST_PATTERN_VIDEO_MODE:
3912 	{
3913 		/* restore bitdepth reduction */
3914 		resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
3915 		pipe_ctx->stream->bit_depth_params = params;
3916 		opp->funcs->opp_program_bit_depth_reduction(opp, &params);
3917 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
3918 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
3919 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3920 				color_depth);
3921 		else if (opp->funcs->opp_set_disp_pattern_generator) {
3922 			struct pipe_ctx *odm_pipe;
3923 			int opp_cnt = 1;
3924 			int dpg_width = width;
3925 
3926 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
3927 				opp_cnt++;
3928 
3929 			dpg_width = width / opp_cnt;
3930 			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
3931 				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
3932 
3933 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
3934 				odm_opp->funcs->opp_set_disp_pattern_generator(odm_opp,
3935 					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3936 					CONTROLLER_DP_COLOR_SPACE_UDEFINED,
3937 					color_depth,
3938 					NULL,
3939 					dpg_width,
3940 					height,
3941 					0);
3942 			}
3943 			opp->funcs->opp_set_disp_pattern_generator(opp,
3944 				CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
3945 				CONTROLLER_DP_COLOR_SPACE_UDEFINED,
3946 				color_depth,
3947 				NULL,
3948 				dpg_width,
3949 				height,
3950 				0);
3951 		}
3952 	}
3953 	break;
3954 
3955 	default:
3956 	break;
3957 	}
3958 }
3959 
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)3960 bool dc_link_dp_set_test_pattern(
3961 	struct dc_link *link,
3962 	enum dp_test_pattern test_pattern,
3963 	enum dp_test_pattern_color_space test_pattern_color_space,
3964 	const struct link_training_settings *p_link_settings,
3965 	const unsigned char *p_custom_pattern,
3966 	unsigned int cust_pattern_size)
3967 {
3968 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
3969 	struct pipe_ctx *pipe_ctx = &pipes[0];
3970 	unsigned int lane;
3971 	unsigned int i;
3972 	unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
3973 	union dpcd_training_pattern training_pattern;
3974 	enum dpcd_phy_test_patterns pattern;
3975 
3976 	memset(&training_pattern, 0, sizeof(training_pattern));
3977 
3978 	for (i = 0; i < MAX_PIPES; i++) {
3979 		if (pipes[i].stream->link == link && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe) {
3980 			pipe_ctx = &pipes[i];
3981 			break;
3982 		}
3983 	}
3984 
3985 	/* Reset CRTC Test Pattern if it is currently running and request
3986 	 * is VideoMode Reset DP Phy Test Pattern if it is currently running
3987 	 * and request is VideoMode
3988 	 */
3989 	if (link->test_pattern_enabled && test_pattern ==
3990 			DP_TEST_PATTERN_VIDEO_MODE) {
3991 		/* Set CRTC Test Pattern */
3992 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
3993 		dp_set_hw_test_pattern(link, test_pattern,
3994 				(uint8_t *)p_custom_pattern,
3995 				(uint32_t)cust_pattern_size);
3996 
3997 		/* Unblank Stream */
3998 		link->dc->hwss.unblank_stream(
3999 			pipe_ctx,
4000 			&link->verified_link_cap);
4001 		/* TODO:m_pHwss->MuteAudioEndpoint
4002 		 * (pPathMode->pDisplayPath, false);
4003 		 */
4004 
4005 		/* Reset Test Pattern state */
4006 		link->test_pattern_enabled = false;
4007 
4008 		return true;
4009 	}
4010 
4011 	/* Check for PHY Test Patterns */
4012 	if (is_dp_phy_pattern(test_pattern)) {
4013 		/* Set DPCD Lane Settings before running test pattern */
4014 		if (p_link_settings != NULL) {
4015 			dp_set_hw_lane_settings(link, p_link_settings, DPRX);
4016 			dpcd_set_lane_settings(link, p_link_settings, DPRX);
4017 		}
4018 
4019 		/* Blank stream if running test pattern */
4020 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
4021 			/*TODO:
4022 			 * m_pHwss->
4023 			 * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
4024 			 */
4025 			/* Blank stream */
4026 			pipes->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
4027 		}
4028 
4029 		dp_set_hw_test_pattern(link, test_pattern,
4030 				(uint8_t *)p_custom_pattern,
4031 				(uint32_t)cust_pattern_size);
4032 
4033 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
4034 			/* Set Test Pattern state */
4035 			link->test_pattern_enabled = true;
4036 			if (p_link_settings != NULL)
4037 				dpcd_set_link_settings(link,
4038 						p_link_settings);
4039 		}
4040 
4041 		switch (test_pattern) {
4042 		case DP_TEST_PATTERN_VIDEO_MODE:
4043 			pattern = PHY_TEST_PATTERN_NONE;
4044 			break;
4045 		case DP_TEST_PATTERN_D102:
4046 			pattern = PHY_TEST_PATTERN_D10_2;
4047 			break;
4048 		case DP_TEST_PATTERN_SYMBOL_ERROR:
4049 			pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
4050 			break;
4051 		case DP_TEST_PATTERN_PRBS7:
4052 			pattern = PHY_TEST_PATTERN_PRBS7;
4053 			break;
4054 		case DP_TEST_PATTERN_80BIT_CUSTOM:
4055 			pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
4056 			break;
4057 		case DP_TEST_PATTERN_CP2520_1:
4058 			pattern = PHY_TEST_PATTERN_CP2520_1;
4059 			break;
4060 		case DP_TEST_PATTERN_CP2520_2:
4061 			pattern = PHY_TEST_PATTERN_CP2520_2;
4062 			break;
4063 		case DP_TEST_PATTERN_CP2520_3:
4064 			pattern = PHY_TEST_PATTERN_CP2520_3;
4065 			break;
4066 		default:
4067 			return false;
4068 		}
4069 
4070 		if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
4071 		/*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
4072 			return false;
4073 
4074 		if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
4075 			/* tell receiver that we are sending qualification
4076 			 * pattern DP 1.2 or later - DP receiver's link quality
4077 			 * pattern is set using DPCD LINK_QUAL_LANEx_SET
4078 			 * register (0x10B~0x10E)\
4079 			 */
4080 			for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
4081 				link_qual_pattern[lane] =
4082 						(unsigned char)(pattern);
4083 
4084 			core_link_write_dpcd(link,
4085 					DP_LINK_QUAL_LANE0_SET,
4086 					link_qual_pattern,
4087 					sizeof(link_qual_pattern));
4088 		} else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
4089 			   link->dpcd_caps.dpcd_rev.raw == 0) {
4090 			/* tell receiver that we are sending qualification
4091 			 * pattern DP 1.1a or earlier - DP receiver's link
4092 			 * quality pattern is set using
4093 			 * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
4094 			 * register (0x102). We will use v_1.3 when we are
4095 			 * setting test pattern for DP 1.1.
4096 			 */
4097 			core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
4098 					    &training_pattern.raw,
4099 					    sizeof(training_pattern));
4100 			training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
4101 			core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
4102 					     &training_pattern.raw,
4103 					     sizeof(training_pattern));
4104 		}
4105 	} else {
4106 		enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
4107 
4108 		switch (test_pattern_color_space) {
4109 		case DP_TEST_PATTERN_COLOR_SPACE_RGB:
4110 			color_space = COLOR_SPACE_SRGB;
4111 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
4112 				color_space = COLOR_SPACE_SRGB_LIMITED;
4113 			break;
4114 
4115 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
4116 			color_space = COLOR_SPACE_YCBCR601;
4117 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
4118 				color_space = COLOR_SPACE_YCBCR601_LIMITED;
4119 			break;
4120 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
4121 			color_space = COLOR_SPACE_YCBCR709;
4122 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
4123 				color_space = COLOR_SPACE_YCBCR709_LIMITED;
4124 			break;
4125 		default:
4126 			break;
4127 		}
4128 
4129 		if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
4130 			if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
4131 				union dmub_hw_lock_flags hw_locks = { 0 };
4132 				struct dmub_hw_lock_inst_flags inst_flags = { 0 };
4133 
4134 				hw_locks.bits.lock_dig = 1;
4135 				inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
4136 
4137 				dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
4138 							true,
4139 							&hw_locks,
4140 							&inst_flags);
4141 			} else
4142 				pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
4143 						pipe_ctx->stream_res.tg);
4144 		}
4145 
4146 		pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
4147 		/* update MSA to requested color space */
4148 		pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
4149 				&pipe_ctx->stream->timing,
4150 				color_space,
4151 				pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
4152 				link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
4153 
4154 		if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
4155 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
4156 				pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
4157 			else
4158 				pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
4159 			resource_build_info_frame(pipe_ctx);
4160 			link->dc->hwss.update_info_frame(pipe_ctx);
4161 		}
4162 
4163 		/* CRTC Patterns */
4164 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
4165 		pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
4166 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
4167 				CRTC_STATE_VACTIVE);
4168 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
4169 				CRTC_STATE_VBLANK);
4170 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
4171 				CRTC_STATE_VACTIVE);
4172 
4173 		if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
4174 			if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
4175 				union dmub_hw_lock_flags hw_locks = { 0 };
4176 				struct dmub_hw_lock_inst_flags inst_flags = { 0 };
4177 
4178 				hw_locks.bits.lock_dig = 1;
4179 				inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
4180 
4181 				dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
4182 							false,
4183 							&hw_locks,
4184 							&inst_flags);
4185 			} else
4186 				pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
4187 						pipe_ctx->stream_res.tg);
4188 		}
4189 
4190 		/* Set Test Pattern state */
4191 		link->test_pattern_enabled = true;
4192 	}
4193 
4194 	return true;
4195 }
4196 
dp_enable_mst_on_sink(struct dc_link * link,bool enable)4197 void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
4198 {
4199 	unsigned char mstmCntl;
4200 
4201 	core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
4202 	if (enable)
4203 		mstmCntl |= DP_MST_EN;
4204 	else
4205 		mstmCntl &= (~DP_MST_EN);
4206 
4207 	core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
4208 }
4209 
dp_set_panel_mode(struct dc_link * link,enum dp_panel_mode panel_mode)4210 void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
4211 {
4212 	union dpcd_edp_config edp_config_set;
4213 	bool panel_mode_edp = false;
4214 
4215 	memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
4216 
4217 	if (panel_mode != DP_PANEL_MODE_DEFAULT) {
4218 
4219 		switch (panel_mode) {
4220 		case DP_PANEL_MODE_EDP:
4221 		case DP_PANEL_MODE_SPECIAL:
4222 			panel_mode_edp = true;
4223 			break;
4224 
4225 		default:
4226 				break;
4227 		}
4228 
4229 		/*set edp panel mode in receiver*/
4230 		core_link_read_dpcd(
4231 			link,
4232 			DP_EDP_CONFIGURATION_SET,
4233 			&edp_config_set.raw,
4234 			sizeof(edp_config_set.raw));
4235 
4236 		if (edp_config_set.bits.PANEL_MODE_EDP
4237 			!= panel_mode_edp) {
4238 			enum dc_status result = DC_ERROR_UNEXPECTED;
4239 
4240 			edp_config_set.bits.PANEL_MODE_EDP =
4241 			panel_mode_edp;
4242 			result = core_link_write_dpcd(
4243 				link,
4244 				DP_EDP_CONFIGURATION_SET,
4245 				&edp_config_set.raw,
4246 				sizeof(edp_config_set.raw));
4247 
4248 			ASSERT(result == DC_OK);
4249 		}
4250 	}
4251 	DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
4252 		 "eDP panel mode enabled: %d \n",
4253 		 link->link_index,
4254 		 link->dpcd_caps.panel_mode_edp,
4255 		 panel_mode_edp);
4256 }
4257 
dp_get_panel_mode(struct dc_link * link)4258 enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
4259 {
4260 	/* We need to explicitly check that connector
4261 	 * is not DP. Some Travis_VGA get reported
4262 	 * by video bios as DP.
4263 	 */
4264 	if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
4265 
4266 		switch (link->dpcd_caps.branch_dev_id) {
4267 		case DP_BRANCH_DEVICE_ID_0022B9:
4268 			/* alternate scrambler reset is required for Travis
4269 			 * for the case when external chip does not
4270 			 * provide sink device id, alternate scrambler
4271 			 * scheme will  be overriden later by querying
4272 			 * Encoder features
4273 			 */
4274 			if (strncmp(
4275 				link->dpcd_caps.branch_dev_name,
4276 				DP_VGA_LVDS_CONVERTER_ID_2,
4277 				sizeof(
4278 				link->dpcd_caps.
4279 				branch_dev_name)) == 0) {
4280 					return DP_PANEL_MODE_SPECIAL;
4281 			}
4282 			break;
4283 		case DP_BRANCH_DEVICE_ID_00001A:
4284 			/* alternate scrambler reset is required for Travis
4285 			 * for the case when external chip does not provide
4286 			 * sink device id, alternate scrambler scheme will
4287 			 * be overriden later by querying Encoder feature
4288 			 */
4289 			if (strncmp(link->dpcd_caps.branch_dev_name,
4290 				DP_VGA_LVDS_CONVERTER_ID_3,
4291 				sizeof(
4292 				link->dpcd_caps.
4293 				branch_dev_name)) == 0) {
4294 					return DP_PANEL_MODE_SPECIAL;
4295 			}
4296 			break;
4297 		default:
4298 			break;
4299 		}
4300 	}
4301 
4302 	if (link->dpcd_caps.panel_mode_edp) {
4303 		return DP_PANEL_MODE_EDP;
4304 	}
4305 
4306 	return DP_PANEL_MODE_DEFAULT;
4307 }
4308 
dp_set_fec_ready(struct dc_link * link,bool ready)4309 void dp_set_fec_ready(struct dc_link *link, bool ready)
4310 {
4311 	/* FEC has to be "set ready" before the link training.
4312 	 * The policy is to always train with FEC
4313 	 * if the sink supports it and leave it enabled on link.
4314 	 * If FEC is not supported, disable it.
4315 	 */
4316 	struct link_encoder *link_enc = link->link_enc;
4317 	uint8_t fec_config = 0;
4318 
4319 	if (!dc_link_is_fec_supported(link) || link->dc->debug.disable_fec)
4320 		return;
4321 
4322 	if (link_enc->funcs->fec_set_ready &&
4323 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
4324 		if (ready) {
4325 			fec_config = 1;
4326 			if (core_link_write_dpcd(link,
4327 					DP_FEC_CONFIGURATION,
4328 					&fec_config,
4329 					sizeof(fec_config)) == DC_OK) {
4330 				link_enc->funcs->fec_set_ready(link_enc, true);
4331 				link->fec_state = dc_link_fec_ready;
4332 			} else {
4333 				link->link_enc->funcs->fec_set_ready(link->link_enc, false);
4334 				link->fec_state = dc_link_fec_not_ready;
4335 				dm_error("dpcd write failed to set fec_ready");
4336 			}
4337 		} else if (link->fec_state == dc_link_fec_ready) {
4338 			fec_config = 0;
4339 			core_link_write_dpcd(link,
4340 					DP_FEC_CONFIGURATION,
4341 					&fec_config,
4342 					sizeof(fec_config));
4343 			link->link_enc->funcs->fec_set_ready(
4344 					link->link_enc, false);
4345 			link->fec_state = dc_link_fec_not_ready;
4346 		}
4347 	}
4348 }
4349 
dp_set_fec_enable(struct dc_link * link,bool enable)4350 void dp_set_fec_enable(struct dc_link *link, bool enable)
4351 {
4352 	struct link_encoder *link_enc = link->link_enc;
4353 
4354 	if (!dc_link_is_fec_supported(link) || link->dc->debug.disable_fec)
4355 		return;
4356 
4357 	if (link_enc->funcs->fec_set_enable &&
4358 			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
4359 		if (link->fec_state == dc_link_fec_ready && enable) {
4360 			/* Accord to DP spec, FEC enable sequence can first
4361 			 * be transmitted anytime after 1000 LL codes have
4362 			 * been transmitted on the link after link training
4363 			 * completion. Using 1 lane RBR should have the maximum
4364 			 * time for transmitting 1000 LL codes which is 6.173 us.
4365 			 * So use 7 microseconds delay instead.
4366 			 */
4367 			udelay(7);
4368 			link_enc->funcs->fec_set_enable(link_enc, true);
4369 			link->fec_state = dc_link_fec_enabled;
4370 		} else if (link->fec_state == dc_link_fec_enabled && !enable) {
4371 			link_enc->funcs->fec_set_enable(link_enc, false);
4372 			link->fec_state = dc_link_fec_ready;
4373 		}
4374 	}
4375 }
4376 
dpcd_set_source_specific_data(struct dc_link * link)4377 void dpcd_set_source_specific_data(struct dc_link *link)
4378 {
4379 	if (!link->dc->vendor_signature.is_valid) {
4380 		struct dpcd_amd_signature amd_signature;
4381 		amd_signature.AMD_IEEE_TxSignature_byte1 = 0x0;
4382 		amd_signature.AMD_IEEE_TxSignature_byte2 = 0x0;
4383 		amd_signature.AMD_IEEE_TxSignature_byte3 = 0x1A;
4384 		amd_signature.device_id_byte1 =
4385 				(uint8_t)(link->ctx->asic_id.chip_id);
4386 		amd_signature.device_id_byte2 =
4387 				(uint8_t)(link->ctx->asic_id.chip_id >> 8);
4388 		memset(&amd_signature.zero, 0, 4);
4389 		amd_signature.dce_version =
4390 				(uint8_t)(link->ctx->dce_version);
4391 		amd_signature.dal_version_byte1 = 0x0; // needed? where to get?
4392 		amd_signature.dal_version_byte2 = 0x0; // needed? where to get?
4393 
4394 		core_link_write_dpcd(link, DP_SOURCE_OUI,
4395 				(uint8_t *)(&amd_signature),
4396 				sizeof(amd_signature));
4397 
4398 	} else {
4399 		core_link_write_dpcd(link, DP_SOURCE_OUI,
4400 				link->dc->vendor_signature.data.raw,
4401 				sizeof(link->dc->vendor_signature.data.raw));
4402 	}
4403 }
4404 
dc_link_set_backlight_level_nits(struct dc_link * link,bool isHDR,uint32_t backlight_millinits,uint32_t transition_time_in_ms)4405 bool dc_link_set_backlight_level_nits(struct dc_link *link,
4406 		bool isHDR,
4407 		uint32_t backlight_millinits,
4408 		uint32_t transition_time_in_ms)
4409 {
4410 	struct dpcd_source_backlight_set dpcd_backlight_set;
4411 	uint8_t backlight_control = isHDR ? 1 : 0;
4412 
4413 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
4414 			link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
4415 		return false;
4416 
4417 	// OLEDs have no PWM, they can only use AUX
4418 	if (link->dpcd_sink_ext_caps.bits.oled == 1)
4419 		backlight_control = 1;
4420 
4421 	*(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits;
4422 	*(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms;
4423 
4424 
4425 	if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
4426 			(uint8_t *)(&dpcd_backlight_set),
4427 			sizeof(dpcd_backlight_set)) != DC_OK)
4428 		return false;
4429 
4430 	if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
4431 			&backlight_control, 1) != DC_OK)
4432 		return false;
4433 
4434 	return true;
4435 }
4436 
dc_link_get_backlight_level_nits(struct dc_link * link,uint32_t * backlight_millinits_avg,uint32_t * backlight_millinits_peak)4437 bool dc_link_get_backlight_level_nits(struct dc_link *link,
4438 		uint32_t *backlight_millinits_avg,
4439 		uint32_t *backlight_millinits_peak)
4440 {
4441 	union dpcd_source_backlight_get dpcd_backlight_get;
4442 
4443 	memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get));
4444 
4445 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
4446 			link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
4447 		return false;
4448 
4449 	if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
4450 			dpcd_backlight_get.raw,
4451 			sizeof(union dpcd_source_backlight_get)) != DC_OK)
4452 		return false;
4453 
4454 	*backlight_millinits_avg =
4455 		dpcd_backlight_get.bytes.backlight_millinits_avg;
4456 	*backlight_millinits_peak =
4457 		dpcd_backlight_get.bytes.backlight_millinits_peak;
4458 
4459 	/* On non-supported panels dpcd_read usually succeeds with 0 returned */
4460 	if (*backlight_millinits_avg == 0 ||
4461 			*backlight_millinits_avg > *backlight_millinits_peak)
4462 		return false;
4463 
4464 	return true;
4465 }
4466 
dc_link_backlight_enable_aux(struct dc_link * link,bool enable)4467 bool dc_link_backlight_enable_aux(struct dc_link *link, bool enable)
4468 {
4469 	uint8_t backlight_enable = enable ? 1 : 0;
4470 
4471 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
4472 		link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
4473 		return false;
4474 
4475 	if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE,
4476 		&backlight_enable, 1) != DC_OK)
4477 		return false;
4478 
4479 	return true;
4480 }
4481 
4482 // we read default from 0x320 because we expect BIOS wrote it there
4483 // regular get_backlight_nit reads from panel set at 0x326
dc_link_read_default_bl_aux(struct dc_link * link,uint32_t * backlight_millinits)4484 bool dc_link_read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits)
4485 {
4486 	if (!link || (link->connector_signal != SIGNAL_TYPE_EDP &&
4487 		link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
4488 		return false;
4489 
4490 	if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
4491 		(uint8_t *) backlight_millinits,
4492 		sizeof(uint32_t)) != DC_OK)
4493 		return false;
4494 
4495 	return true;
4496 }
4497 
dc_link_set_default_brightness_aux(struct dc_link * link)4498 bool dc_link_set_default_brightness_aux(struct dc_link *link)
4499 {
4500 	uint32_t default_backlight;
4501 
4502 	if (link &&
4503 		(link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 ||
4504 		link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) {
4505 		if (!dc_link_read_default_bl_aux(link, &default_backlight))
4506 			default_backlight = 150000;
4507 		// if < 5 nits or > 5000, it might be wrong readback
4508 		if (default_backlight < 5000 || default_backlight > 5000000)
4509 			default_backlight = 150000; //
4510 
4511 		return dc_link_set_backlight_level_nits(link, true,
4512 				default_backlight, 0);
4513 	}
4514 	return false;
4515 }
4516