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