1 /*
2  * Copyright 2022 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  */
25 #include "link_dp_cts.h"
26 #include "link/link_resource.h"
27 #include "link/protocols/link_dpcd.h"
28 #include "link/protocols/link_dp_training.h"
29 #include "link/protocols/link_dp_phy.h"
30 #include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h"
31 #include "link/protocols/link_dp_capability.h"
32 #include "link/link_dpms.h"
33 #include "resource.h"
34 #include "dm_helpers.h"
35 #include "dc_dmub_srv.h"
36 #include "dce/dmub_hw_lock_mgr.h"
37 
38 #define DC_LOGGER \
39 	link->ctx->logger
40 
get_link_rate_from_test_link_rate(uint8_t test_rate)41 static enum dc_link_rate get_link_rate_from_test_link_rate(uint8_t test_rate)
42 {
43 	switch (test_rate) {
44 	case DP_TEST_LINK_RATE_RBR:
45 		return LINK_RATE_LOW;
46 	case DP_TEST_LINK_RATE_HBR:
47 		return LINK_RATE_HIGH;
48 	case DP_TEST_LINK_RATE_HBR2:
49 		return LINK_RATE_HIGH2;
50 	case DP_TEST_LINK_RATE_HBR3:
51 		return LINK_RATE_HIGH3;
52 	case DP_TEST_LINK_RATE_UHBR10:
53 		return LINK_RATE_UHBR10;
54 	case DP_TEST_LINK_RATE_UHBR20:
55 		return LINK_RATE_UHBR20;
56 	case DP_TEST_LINK_RATE_UHBR13_5_LEGACY:
57 	case DP_TEST_LINK_RATE_UHBR13_5:
58 		return LINK_RATE_UHBR13_5;
59 	default:
60 		return LINK_RATE_UNKNOWN;
61 	}
62 }
63 
is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)64 static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern)
65 {
66 	return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&
67 			test_pattern <= DP_TEST_PATTERN_SQUARE_END);
68 }
69 
is_dp_phy_pattern(enum dp_test_pattern test_pattern)70 static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern)
71 {
72 	if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&
73 			test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||
74 			test_pattern == DP_TEST_PATTERN_VIDEO_MODE)
75 		return true;
76 	else
77 		return false;
78 }
79 
dp_retrain_link_dp_test(struct dc_link * link,struct dc_link_settings * link_setting,bool skip_video_pattern)80 static void dp_retrain_link_dp_test(struct dc_link *link,
81 			struct dc_link_settings *link_setting,
82 			bool skip_video_pattern)
83 {
84 	struct pipe_ctx *pipes[MAX_PIPES];
85 	struct dc_state *state = link->dc->current_state;
86 	uint8_t count;
87 	int i;
88 
89 	udelay(100);
90 
91 	link_get_master_pipes_with_dpms_on(link, state, &count, pipes);
92 
93 	for (i = 0; i < count; i++) {
94 		link_set_dpms_off(pipes[i]);
95 		pipes[i]->link_config.dp_link_settings = *link_setting;
96 		update_dp_encoder_resources_for_test_harness(
97 				link->dc,
98 				state,
99 				pipes[i]);
100 	}
101 
102 	for (i = count-1; i >= 0; i--)
103 		link_set_dpms_on(state, pipes[i]);
104 }
105 
dp_test_send_link_training(struct dc_link * link)106 static void dp_test_send_link_training(struct dc_link *link)
107 {
108 	struct dc_link_settings link_settings = {0};
109 	uint8_t test_rate = 0;
110 
111 	core_link_read_dpcd(
112 			link,
113 			DP_TEST_LANE_COUNT,
114 			(unsigned char *)(&link_settings.lane_count),
115 			1);
116 	core_link_read_dpcd(
117 			link,
118 			DP_TEST_LINK_RATE,
119 			&test_rate,
120 			1);
121 	link_settings.link_rate = get_link_rate_from_test_link_rate(test_rate);
122 
123 	if (link_settings.link_rate == LINK_RATE_UNKNOWN) {
124 		DC_LOG_ERROR("%s: Invalid test link rate.", __func__);
125 		ASSERT(0);
126 	}
127 
128 	/* Set preferred link settings */
129 	link->verified_link_cap.lane_count = link_settings.lane_count;
130 	link->verified_link_cap.link_rate = link_settings.link_rate;
131 
132 	dp_retrain_link_dp_test(link, &link_settings, false);
133 }
134 
dp_test_get_audio_test_data(struct dc_link * link,bool disable_video)135 static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video)
136 {
137 	union audio_test_mode            dpcd_test_mode = {0};
138 	struct audio_test_pattern_type   dpcd_pattern_type = {0};
139 	union audio_test_pattern_period  dpcd_pattern_period[AUDIO_CHANNELS_COUNT] = {0};
140 	enum dp_test_pattern test_pattern = DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
141 
142 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
143 	struct pipe_ctx *pipe_ctx = &pipes[0];
144 	unsigned int channel_count;
145 	unsigned int channel = 0;
146 	unsigned int modes = 0;
147 	unsigned int sampling_rate_in_hz = 0;
148 
149 	// get audio test mode and test pattern parameters
150 	core_link_read_dpcd(
151 		link,
152 		DP_TEST_AUDIO_MODE,
153 		&dpcd_test_mode.raw,
154 		sizeof(dpcd_test_mode));
155 
156 	core_link_read_dpcd(
157 		link,
158 		DP_TEST_AUDIO_PATTERN_TYPE,
159 		&dpcd_pattern_type.value,
160 		sizeof(dpcd_pattern_type));
161 
162 	channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT);
163 
164 	// read pattern periods for requested channels when sawTooth pattern is requested
165 	if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH ||
166 			dpcd_pattern_type.value == AUDIO_TEST_PATTERN_OPERATOR_DEFINED) {
167 
168 		test_pattern = (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH) ?
169 				DP_TEST_PATTERN_AUDIO_SAWTOOTH : DP_TEST_PATTERN_AUDIO_OPERATOR_DEFINED;
170 		// read period for each channel
171 		for (channel = 0; channel < channel_count; channel++) {
172 			core_link_read_dpcd(
173 							link,
174 							DP_TEST_AUDIO_PERIOD_CH1 + channel,
175 							&dpcd_pattern_period[channel].raw,
176 							sizeof(dpcd_pattern_period[channel]));
177 		}
178 	}
179 
180 	// translate sampling rate
181 	switch (dpcd_test_mode.bits.sampling_rate) {
182 	case AUDIO_SAMPLING_RATE_32KHZ:
183 		sampling_rate_in_hz = 32000;
184 		break;
185 	case AUDIO_SAMPLING_RATE_44_1KHZ:
186 		sampling_rate_in_hz = 44100;
187 		break;
188 	case AUDIO_SAMPLING_RATE_48KHZ:
189 		sampling_rate_in_hz = 48000;
190 		break;
191 	case AUDIO_SAMPLING_RATE_88_2KHZ:
192 		sampling_rate_in_hz = 88200;
193 		break;
194 	case AUDIO_SAMPLING_RATE_96KHZ:
195 		sampling_rate_in_hz = 96000;
196 		break;
197 	case AUDIO_SAMPLING_RATE_176_4KHZ:
198 		sampling_rate_in_hz = 176400;
199 		break;
200 	case AUDIO_SAMPLING_RATE_192KHZ:
201 		sampling_rate_in_hz = 192000;
202 		break;
203 	default:
204 		sampling_rate_in_hz = 0;
205 		break;
206 	}
207 
208 	link->audio_test_data.flags.test_requested = 1;
209 	link->audio_test_data.flags.disable_video = disable_video;
210 	link->audio_test_data.sampling_rate = sampling_rate_in_hz;
211 	link->audio_test_data.channel_count = channel_count;
212 	link->audio_test_data.pattern_type = test_pattern;
213 
214 	if (test_pattern == DP_TEST_PATTERN_AUDIO_SAWTOOTH) {
215 		for (modes = 0; modes < pipe_ctx->stream->audio_info.mode_count; modes++) {
216 			link->audio_test_data.pattern_period[modes] = dpcd_pattern_period[modes].bits.pattern_period;
217 		}
218 	}
219 }
220 
221 /* TODO Raven hbr2 compliance eye output is unstable
222  * (toggling on and off) with debugger break
223  * This caueses intermittent PHY automation failure
224  * Need to look into the root cause */
dp_test_send_phy_test_pattern(struct dc_link * link)225 static void dp_test_send_phy_test_pattern(struct dc_link *link)
226 {
227 	union phy_test_pattern dpcd_test_pattern;
228 	union lane_adjust dpcd_lane_adjustment[2];
229 	unsigned char dpcd_post_cursor_2_adjustment = 0;
230 	unsigned char test_pattern_buffer[
231 			(DP_TEST_264BIT_CUSTOM_PATTERN_263_256 -
232 			DP_TEST_264BIT_CUSTOM_PATTERN_7_0)+1] = {0};
233 	unsigned int test_pattern_size = 0;
234 	enum dp_test_pattern test_pattern;
235 	union lane_adjust dpcd_lane_adjust;
236 	unsigned int lane;
237 	struct link_training_settings link_training_settings;
238 	unsigned char no_preshoot = 0;
239 	unsigned char no_deemphasis = 0;
240 
241 	dpcd_test_pattern.raw = 0;
242 	memset(dpcd_lane_adjustment, 0, sizeof(dpcd_lane_adjustment));
243 	memset(&link_training_settings, 0, sizeof(link_training_settings));
244 
245 	/* get phy test pattern and pattern parameters from DP receiver */
246 	core_link_read_dpcd(
247 			link,
248 			DP_PHY_TEST_PATTERN,
249 			&dpcd_test_pattern.raw,
250 			sizeof(dpcd_test_pattern));
251 	core_link_read_dpcd(
252 			link,
253 			DP_ADJUST_REQUEST_LANE0_1,
254 			&dpcd_lane_adjustment[0].raw,
255 			sizeof(dpcd_lane_adjustment));
256 
257 	/* prepare link training settings */
258 	link_training_settings.link_settings = link->cur_link_settings;
259 
260 	link_training_settings.lttpr_mode = dp_decide_lttpr_mode(link, &link->cur_link_settings);
261 
262 	if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
263 			link_training_settings.lttpr_mode == LTTPR_MODE_TRANSPARENT)
264 		dp_fixed_vs_pe_read_lane_adjust(
265 				link,
266 				link_training_settings.dpcd_lane_settings);
267 
268 	/*get post cursor 2 parameters
269 	 * For DP 1.1a or eariler, this DPCD register's value is 0
270 	 * For DP 1.2 or later:
271 	 * Bits 1:0 = POST_CURSOR2_LANE0; Bits 3:2 = POST_CURSOR2_LANE1
272 	 * Bits 5:4 = POST_CURSOR2_LANE2; Bits 7:6 = POST_CURSOR2_LANE3
273 	 */
274 	core_link_read_dpcd(
275 			link,
276 			DP_ADJUST_REQUEST_POST_CURSOR2,
277 			&dpcd_post_cursor_2_adjustment,
278 			sizeof(dpcd_post_cursor_2_adjustment));
279 
280 	/* translate request */
281 	switch (dpcd_test_pattern.bits.PATTERN) {
282 	case PHY_TEST_PATTERN_D10_2:
283 		test_pattern = DP_TEST_PATTERN_D102;
284 		break;
285 	case PHY_TEST_PATTERN_SYMBOL_ERROR:
286 		test_pattern = DP_TEST_PATTERN_SYMBOL_ERROR;
287 		break;
288 	case PHY_TEST_PATTERN_PRBS7:
289 		test_pattern = DP_TEST_PATTERN_PRBS7;
290 		break;
291 	case PHY_TEST_PATTERN_80BIT_CUSTOM:
292 		test_pattern = DP_TEST_PATTERN_80BIT_CUSTOM;
293 		break;
294 	case PHY_TEST_PATTERN_CP2520_1:
295 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
296 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
297 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
298 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
299 		break;
300 	case PHY_TEST_PATTERN_CP2520_2:
301 		/* CP2520 pattern is unstable, temporarily use TPS4 instead */
302 		test_pattern = (link->dc->caps.force_dp_tps4_for_cp2520 == 1) ?
303 				DP_TEST_PATTERN_TRAINING_PATTERN4 :
304 				DP_TEST_PATTERN_HBR2_COMPLIANCE_EYE;
305 		break;
306 	case PHY_TEST_PATTERN_CP2520_3:
307 		test_pattern = DP_TEST_PATTERN_TRAINING_PATTERN4;
308 		break;
309 	case PHY_TEST_PATTERN_128b_132b_TPS1:
310 		test_pattern = DP_TEST_PATTERN_128b_132b_TPS1;
311 		break;
312 	case PHY_TEST_PATTERN_128b_132b_TPS2:
313 		test_pattern = DP_TEST_PATTERN_128b_132b_TPS2;
314 		break;
315 	case PHY_TEST_PATTERN_PRBS9:
316 		test_pattern = DP_TEST_PATTERN_PRBS9;
317 		break;
318 	case PHY_TEST_PATTERN_PRBS11:
319 		test_pattern = DP_TEST_PATTERN_PRBS11;
320 		break;
321 	case PHY_TEST_PATTERN_PRBS15:
322 		test_pattern = DP_TEST_PATTERN_PRBS15;
323 		break;
324 	case PHY_TEST_PATTERN_PRBS23:
325 		test_pattern = DP_TEST_PATTERN_PRBS23;
326 		break;
327 	case PHY_TEST_PATTERN_PRBS31:
328 		test_pattern = DP_TEST_PATTERN_PRBS31;
329 		break;
330 	case PHY_TEST_PATTERN_264BIT_CUSTOM:
331 		test_pattern = DP_TEST_PATTERN_264BIT_CUSTOM;
332 		break;
333 	case PHY_TEST_PATTERN_SQUARE:
334 		test_pattern = DP_TEST_PATTERN_SQUARE;
335 		break;
336 	case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
337 		test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
338 		no_preshoot = 1;
339 		break;
340 	case PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
341 		test_pattern = DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
342 		no_deemphasis = 1;
343 		break;
344 	case PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
345 		test_pattern = DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
346 		no_preshoot = 1;
347 		no_deemphasis = 1;
348 		break;
349 	default:
350 		test_pattern = DP_TEST_PATTERN_VIDEO_MODE;
351 	break;
352 	}
353 
354 	if (test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM) {
355 		test_pattern_size = (DP_TEST_80BIT_CUSTOM_PATTERN_79_72 -
356 				DP_TEST_80BIT_CUSTOM_PATTERN_7_0) + 1;
357 		core_link_read_dpcd(
358 				link,
359 				DP_TEST_80BIT_CUSTOM_PATTERN_7_0,
360 				test_pattern_buffer,
361 				test_pattern_size);
362 	}
363 
364 	if (is_dp_phy_sqaure_pattern(test_pattern)) {
365 		test_pattern_size = 1; // Square pattern data is 1 byte (DP spec)
366 		core_link_read_dpcd(
367 				link,
368 				DP_PHY_SQUARE_PATTERN,
369 				test_pattern_buffer,
370 				test_pattern_size);
371 	}
372 
373 	if (test_pattern == DP_TEST_PATTERN_264BIT_CUSTOM) {
374 		test_pattern_size = (DP_TEST_264BIT_CUSTOM_PATTERN_263_256-
375 				DP_TEST_264BIT_CUSTOM_PATTERN_7_0) + 1;
376 		core_link_read_dpcd(
377 				link,
378 				DP_TEST_264BIT_CUSTOM_PATTERN_7_0,
379 				test_pattern_buffer,
380 				test_pattern_size);
381 	}
382 
383 	for (lane = 0; lane <
384 		(unsigned int)(link->cur_link_settings.lane_count);
385 		lane++) {
386 		dpcd_lane_adjust.raw =
387 			dp_get_nibble_at_index(&dpcd_lane_adjustment[0].raw, lane);
388 		if (link_dp_get_encoding_format(&link->cur_link_settings) ==
389 				DP_8b_10b_ENCODING) {
390 			link_training_settings.hw_lane_settings[lane].VOLTAGE_SWING =
391 				(enum dc_voltage_swing)
392 				(dpcd_lane_adjust.bits.VOLTAGE_SWING_LANE);
393 			link_training_settings.hw_lane_settings[lane].PRE_EMPHASIS =
394 				(enum dc_pre_emphasis)
395 				(dpcd_lane_adjust.bits.PRE_EMPHASIS_LANE);
396 			link_training_settings.hw_lane_settings[lane].POST_CURSOR2 =
397 				(enum dc_post_cursor2)
398 				((dpcd_post_cursor_2_adjustment >> (lane * 2)) & 0x03);
399 		} else if (link_dp_get_encoding_format(&link->cur_link_settings) ==
400 				DP_128b_132b_ENCODING) {
401 			link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.level =
402 					dpcd_lane_adjust.tx_ffe.PRESET_VALUE;
403 			link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_preshoot = no_preshoot;
404 			link_training_settings.hw_lane_settings[lane].FFE_PRESET.settings.no_deemphasis = no_deemphasis;
405 		}
406 	}
407 
408 	dp_hw_to_dpcd_lane_settings(&link_training_settings,
409 			link_training_settings.hw_lane_settings,
410 			link_training_settings.dpcd_lane_settings);
411 	/*Usage: Measure DP physical lane signal
412 	 * by DP SI test equipment automatically.
413 	 * PHY test pattern request is generated by equipment via HPD interrupt.
414 	 * HPD needs to be active all the time. HPD should be active
415 	 * all the time. Do not touch it.
416 	 * forward request to DS
417 	 */
418 	dp_set_test_pattern(
419 		link,
420 		test_pattern,
421 		DP_TEST_PATTERN_COLOR_SPACE_UNDEFINED,
422 		&link_training_settings,
423 		test_pattern_buffer,
424 		test_pattern_size);
425 }
426 
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)427 static void set_crtc_test_pattern(struct dc_link *link,
428 				struct pipe_ctx *pipe_ctx,
429 				enum dp_test_pattern test_pattern,
430 				enum dp_test_pattern_color_space test_pattern_color_space)
431 {
432 	enum controller_dp_test_pattern controller_test_pattern;
433 	enum dc_color_depth color_depth = pipe_ctx->
434 		stream->timing.display_color_depth;
435 	struct bit_depth_reduction_params params;
436 	struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
437 	struct pipe_ctx *odm_pipe;
438 	struct test_pattern_params *tp_params;
439 
440 	memset(&params, 0, sizeof(params));
441 
442 	resource_build_test_pattern_params(&link->dc->current_state->res_ctx,
443 			pipe_ctx);
444 	controller_test_pattern = pipe_ctx->stream_res.test_pattern_params.test_pattern;
445 
446 	switch (test_pattern) {
447 	case DP_TEST_PATTERN_COLOR_SQUARES:
448 	case DP_TEST_PATTERN_COLOR_SQUARES_CEA:
449 	case DP_TEST_PATTERN_VERTICAL_BARS:
450 	case DP_TEST_PATTERN_HORIZONTAL_BARS:
451 	case DP_TEST_PATTERN_COLOR_RAMP:
452 	{
453 		/* disable bit depth reduction */
454 		pipe_ctx->stream->bit_depth_params = params;
455 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
456 			opp->funcs->opp_program_bit_depth_reduction(opp, &params);
457 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
458 				controller_test_pattern, color_depth);
459 		} else if (link->dc->hwss.set_disp_pattern_generator) {
460 			enum controller_dp_color_space controller_color_space;
461 			struct output_pixel_processor *odm_opp;
462 
463 			controller_color_space = pipe_ctx->stream_res.test_pattern_params.color_space;
464 
465 			if (controller_color_space == CONTROLLER_DP_COLOR_SPACE_UDEFINED) {
466 				DC_LOG_ERROR("%s: Color space must be defined for test pattern", __func__);
467 				ASSERT(0);
468 			}
469 
470 			odm_pipe = pipe_ctx;
471 			while (odm_pipe) {
472 				tp_params = &odm_pipe->stream_res.test_pattern_params;
473 				odm_opp = odm_pipe->stream_res.opp;
474 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
475 				link->dc->hwss.set_disp_pattern_generator(link->dc,
476 						odm_pipe,
477 						tp_params->test_pattern,
478 						tp_params->color_space,
479 						tp_params->color_depth,
480 						NULL,
481 						tp_params->width,
482 						tp_params->height,
483 						tp_params->offset);
484 				odm_pipe = odm_pipe->next_odm_pipe;
485 			}
486 		}
487 	}
488 	break;
489 	case DP_TEST_PATTERN_VIDEO_MODE:
490 	{
491 		/* restore bitdepth reduction */
492 		resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
493 		pipe_ctx->stream->bit_depth_params = params;
494 		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
495 			opp->funcs->opp_program_bit_depth_reduction(opp, &params);
496 			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
497 					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
498 					color_depth);
499 		} else if (link->dc->hwss.set_disp_pattern_generator) {
500 			struct output_pixel_processor *odm_opp;
501 
502 			odm_pipe = pipe_ctx;
503 			while (odm_pipe) {
504 				tp_params = &odm_pipe->stream_res.test_pattern_params;
505 				odm_opp = odm_pipe->stream_res.opp;
506 				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
507 				link->dc->hwss.set_disp_pattern_generator(link->dc,
508 						odm_pipe,
509 						tp_params->test_pattern,
510 						tp_params->color_space,
511 						tp_params->color_depth,
512 						NULL,
513 						tp_params->width,
514 						tp_params->height,
515 						tp_params->offset);
516 				odm_pipe = odm_pipe->next_odm_pipe;
517 			}
518 		}
519 	}
520 	break;
521 
522 	default:
523 	break;
524 	}
525 }
526 
dp_handle_automated_test(struct dc_link * link)527 void dp_handle_automated_test(struct dc_link *link)
528 {
529 	union test_request test_request;
530 	union test_response test_response;
531 
532 	memset(&test_request, 0, sizeof(test_request));
533 	memset(&test_response, 0, sizeof(test_response));
534 
535 	core_link_read_dpcd(
536 		link,
537 		DP_TEST_REQUEST,
538 		&test_request.raw,
539 		sizeof(union test_request));
540 	if (test_request.bits.LINK_TRAINING) {
541 		/* ACK first to let DP RX test box monitor LT sequence */
542 		test_response.bits.ACK = 1;
543 		core_link_write_dpcd(
544 			link,
545 			DP_TEST_RESPONSE,
546 			&test_response.raw,
547 			sizeof(test_response));
548 		dp_test_send_link_training(link);
549 		/* no acknowledge request is needed again */
550 		test_response.bits.ACK = 0;
551 	}
552 	if (test_request.bits.LINK_TEST_PATTRN) {
553 		union test_misc dpcd_test_params;
554 		union link_test_pattern dpcd_test_pattern;
555 
556 		memset(&dpcd_test_pattern, 0, sizeof(dpcd_test_pattern));
557 		memset(&dpcd_test_params, 0, sizeof(dpcd_test_params));
558 
559 		/* get link test pattern and pattern parameters */
560 		core_link_read_dpcd(
561 				link,
562 				DP_TEST_PATTERN,
563 				&dpcd_test_pattern.raw,
564 				sizeof(dpcd_test_pattern));
565 		core_link_read_dpcd(
566 				link,
567 				DP_TEST_MISC0,
568 				&dpcd_test_params.raw,
569 				sizeof(dpcd_test_params));
570 		test_response.bits.ACK = dm_helpers_dp_handle_test_pattern_request(link->ctx, link,
571 				dpcd_test_pattern, dpcd_test_params) ? 1 : 0;
572 	}
573 
574 	if (test_request.bits.AUDIO_TEST_PATTERN) {
575 		dp_test_get_audio_test_data(link, test_request.bits.TEST_AUDIO_DISABLED_VIDEO);
576 		test_response.bits.ACK = 1;
577 	}
578 
579 	if (test_request.bits.PHY_TEST_PATTERN) {
580 		dp_test_send_phy_test_pattern(link);
581 		test_response.bits.ACK = 1;
582 	}
583 
584 	/* send request acknowledgment */
585 	if (test_response.bits.ACK)
586 		core_link_write_dpcd(
587 			link,
588 			DP_TEST_RESPONSE,
589 			&test_response.raw,
590 			sizeof(test_response));
591 }
592 
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)593 bool dp_set_test_pattern(
594 	struct dc_link *link,
595 	enum dp_test_pattern test_pattern,
596 	enum dp_test_pattern_color_space test_pattern_color_space,
597 	const struct link_training_settings *p_link_settings,
598 	const unsigned char *p_custom_pattern,
599 	unsigned int cust_pattern_size)
600 {
601 	const struct link_hwss *link_hwss;
602 	struct pipe_ctx *pipes = link->dc->current_state->res_ctx.pipe_ctx;
603 	struct pipe_ctx *pipe_ctx = NULL;
604 	unsigned int lane;
605 	unsigned int i;
606 	unsigned char link_qual_pattern[LANE_COUNT_DP_MAX] = {0};
607 	union dpcd_training_pattern training_pattern;
608 	enum dpcd_phy_test_patterns pattern;
609 
610 	memset(&training_pattern, 0, sizeof(training_pattern));
611 
612 	for (i = 0; i < MAX_PIPES; i++) {
613 		if (pipes[i].stream == NULL)
614 			continue;
615 
616 		if (resource_is_pipe_type(&pipes[i], OTG_MASTER) &&
617 				pipes[i].stream->link == link) {
618 			pipe_ctx = &pipes[i];
619 			break;
620 		}
621 	}
622 
623 	if (pipe_ctx == NULL)
624 		return false;
625 
626 	/* Reset CRTC Test Pattern if it is currently running and request is VideoMode */
627 	if (link->test_pattern_enabled && test_pattern ==
628 			DP_TEST_PATTERN_VIDEO_MODE) {
629 		/* Set CRTC Test Pattern */
630 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
631 		dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
632 				(uint8_t *)p_custom_pattern,
633 				(uint32_t)cust_pattern_size);
634 
635 		/* Unblank Stream */
636 		link->dc->hwss.unblank_stream(
637 			pipe_ctx,
638 			&link->verified_link_cap);
639 		/* TODO:m_pHwss->MuteAudioEndpoint
640 		 * (pPathMode->pDisplayPath, false);
641 		 */
642 
643 		/* Reset Test Pattern state */
644 		link->test_pattern_enabled = false;
645 		link->current_test_pattern = test_pattern;
646 
647 		return true;
648 	}
649 
650 	/* Check for PHY Test Patterns */
651 	if (is_dp_phy_pattern(test_pattern)) {
652 		/* Set DPCD Lane Settings before running test pattern */
653 		if (p_link_settings != NULL) {
654 			if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) &&
655 					p_link_settings->lttpr_mode == LTTPR_MODE_TRANSPARENT) {
656 				dp_fixed_vs_pe_set_retimer_lane_settings(
657 						link,
658 						p_link_settings->dpcd_lane_settings,
659 						p_link_settings->link_settings.lane_count);
660 			} else {
661 				dp_set_hw_lane_settings(link, &pipe_ctx->link_res, p_link_settings, DPRX);
662 			}
663 			dpcd_set_lane_settings(link, p_link_settings, DPRX);
664 		}
665 
666 		/* Blank stream if running test pattern */
667 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
668 			/*TODO:
669 			 * m_pHwss->
670 			 * MuteAudioEndpoint(pPathMode->pDisplayPath, true);
671 			 */
672 			/* Blank stream */
673 			link->dc->hwss.blank_stream(pipe_ctx);
674 		}
675 
676 		dp_set_hw_test_pattern(link, &pipe_ctx->link_res, test_pattern,
677 				(uint8_t *)p_custom_pattern,
678 				(uint32_t)cust_pattern_size);
679 
680 		if (test_pattern != DP_TEST_PATTERN_VIDEO_MODE) {
681 			/* Set Test Pattern state */
682 			link->test_pattern_enabled = true;
683 			link->current_test_pattern = test_pattern;
684 			if (p_link_settings != NULL)
685 				dpcd_set_link_settings(link,
686 						p_link_settings);
687 		}
688 
689 		switch (test_pattern) {
690 		case DP_TEST_PATTERN_VIDEO_MODE:
691 			pattern = PHY_TEST_PATTERN_NONE;
692 			break;
693 		case DP_TEST_PATTERN_D102:
694 			pattern = PHY_TEST_PATTERN_D10_2;
695 			break;
696 		case DP_TEST_PATTERN_SYMBOL_ERROR:
697 			pattern = PHY_TEST_PATTERN_SYMBOL_ERROR;
698 			break;
699 		case DP_TEST_PATTERN_PRBS7:
700 			pattern = PHY_TEST_PATTERN_PRBS7;
701 			break;
702 		case DP_TEST_PATTERN_80BIT_CUSTOM:
703 			pattern = PHY_TEST_PATTERN_80BIT_CUSTOM;
704 			break;
705 		case DP_TEST_PATTERN_CP2520_1:
706 			pattern = PHY_TEST_PATTERN_CP2520_1;
707 			break;
708 		case DP_TEST_PATTERN_CP2520_2:
709 			pattern = PHY_TEST_PATTERN_CP2520_2;
710 			break;
711 		case DP_TEST_PATTERN_CP2520_3:
712 			pattern = PHY_TEST_PATTERN_CP2520_3;
713 			break;
714 		case DP_TEST_PATTERN_128b_132b_TPS1:
715 			pattern = PHY_TEST_PATTERN_128b_132b_TPS1;
716 			break;
717 		case DP_TEST_PATTERN_128b_132b_TPS2:
718 			pattern = PHY_TEST_PATTERN_128b_132b_TPS2;
719 			break;
720 		case DP_TEST_PATTERN_PRBS9:
721 			pattern = PHY_TEST_PATTERN_PRBS9;
722 			break;
723 		case DP_TEST_PATTERN_PRBS11:
724 			pattern = PHY_TEST_PATTERN_PRBS11;
725 			break;
726 		case DP_TEST_PATTERN_PRBS15:
727 			pattern = PHY_TEST_PATTERN_PRBS15;
728 			break;
729 		case DP_TEST_PATTERN_PRBS23:
730 			pattern = PHY_TEST_PATTERN_PRBS23;
731 			break;
732 		case DP_TEST_PATTERN_PRBS31:
733 			pattern = PHY_TEST_PATTERN_PRBS31;
734 			break;
735 		case DP_TEST_PATTERN_264BIT_CUSTOM:
736 			pattern = PHY_TEST_PATTERN_264BIT_CUSTOM;
737 			break;
738 		case DP_TEST_PATTERN_SQUARE:
739 			pattern = PHY_TEST_PATTERN_SQUARE;
740 			break;
741 		case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED:
742 			pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED;
743 			break;
744 		case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED:
745 			pattern = PHY_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED;
746 			break;
747 		case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED:
748 			pattern = PHY_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED;
749 			break;
750 		default:
751 			return false;
752 		}
753 
754 		if (test_pattern == DP_TEST_PATTERN_VIDEO_MODE
755 		/*TODO:&& !pPathMode->pDisplayPath->IsTargetPoweredOn()*/)
756 			return false;
757 
758 		if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) {
759 			if (is_dp_phy_sqaure_pattern(test_pattern))
760 				core_link_write_dpcd(link,
761 						DP_LINK_SQUARE_PATTERN,
762 						p_custom_pattern,
763 						1);
764 
765 			/* tell receiver that we are sending qualification
766 			 * pattern DP 1.2 or later - DP receiver's link quality
767 			 * pattern is set using DPCD LINK_QUAL_LANEx_SET
768 			 * register (0x10B~0x10E)\
769 			 */
770 			for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++)
771 				link_qual_pattern[lane] =
772 						(unsigned char)(pattern);
773 
774 			core_link_write_dpcd(link,
775 					DP_LINK_QUAL_LANE0_SET,
776 					link_qual_pattern,
777 					sizeof(link_qual_pattern));
778 		} else if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_10 ||
779 			   link->dpcd_caps.dpcd_rev.raw == 0) {
780 			/* tell receiver that we are sending qualification
781 			 * pattern DP 1.1a or earlier - DP receiver's link
782 			 * quality pattern is set using
783 			 * DPCD TRAINING_PATTERN_SET -> LINK_QUAL_PATTERN_SET
784 			 * register (0x102). We will use v_1.3 when we are
785 			 * setting test pattern for DP 1.1.
786 			 */
787 			core_link_read_dpcd(link, DP_TRAINING_PATTERN_SET,
788 					    &training_pattern.raw,
789 					    sizeof(training_pattern));
790 			training_pattern.v1_3.LINK_QUAL_PATTERN_SET = pattern;
791 			core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET,
792 					     &training_pattern.raw,
793 					     sizeof(training_pattern));
794 		}
795 	} else {
796 		enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
797 
798 		switch (test_pattern_color_space) {
799 		case DP_TEST_PATTERN_COLOR_SPACE_RGB:
800 			color_space = COLOR_SPACE_SRGB;
801 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
802 				color_space = COLOR_SPACE_SRGB_LIMITED;
803 			break;
804 
805 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
806 			color_space = COLOR_SPACE_YCBCR601;
807 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
808 				color_space = COLOR_SPACE_YCBCR601_LIMITED;
809 			break;
810 		case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
811 			color_space = COLOR_SPACE_YCBCR709;
812 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
813 				color_space = COLOR_SPACE_YCBCR709_LIMITED;
814 			break;
815 		default:
816 			break;
817 		}
818 
819 		if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
820 			if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
821 				union dmub_hw_lock_flags hw_locks = { 0 };
822 				struct dmub_hw_lock_inst_flags inst_flags = { 0 };
823 
824 				hw_locks.bits.lock_dig = 1;
825 				inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
826 
827 				dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
828 							true,
829 							&hw_locks,
830 							&inst_flags);
831 			} else
832 				pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable(
833 						pipe_ctx->stream_res.tg);
834 		}
835 
836 		pipe_ctx->stream_res.tg->funcs->lock(pipe_ctx->stream_res.tg);
837 		/* update MSA to requested color space */
838 		link_hwss = get_link_hwss(link, &pipe_ctx->link_res);
839 		pipe_ctx->stream->output_color_space = color_space;
840 		link_hwss->setup_stream_attribute(pipe_ctx);
841 
842 		if (pipe_ctx->stream->use_vsc_sdp_for_colorimetry) {
843 			if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
844 				pipe_ctx->stream->vsc_infopacket.sb[17] |= (1 << 7); // sb17 bit 7 Dynamic Range: 0 = VESA range, 1 = CTA range
845 			else
846 				pipe_ctx->stream->vsc_infopacket.sb[17] &= ~(1 << 7);
847 
848 			if (color_space == COLOR_SPACE_YCBCR601_LIMITED)
849 				pipe_ctx->stream->vsc_infopacket.sb[16] &= 0xf0;
850 			else if (color_space == COLOR_SPACE_YCBCR709_LIMITED)
851 				pipe_ctx->stream->vsc_infopacket.sb[16] |= 1;
852 
853 			resource_build_info_frame(pipe_ctx);
854 			link->dc->hwss.update_info_frame(pipe_ctx);
855 		}
856 
857 		/* CRTC Patterns */
858 		set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
859 		pipe_ctx->stream_res.tg->funcs->unlock(pipe_ctx->stream_res.tg);
860 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
861 				CRTC_STATE_VACTIVE);
862 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
863 				CRTC_STATE_VBLANK);
864 		pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg,
865 				CRTC_STATE_VACTIVE);
866 
867 		if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable) {
868 			if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
869 				union dmub_hw_lock_flags hw_locks = { 0 };
870 				struct dmub_hw_lock_inst_flags inst_flags = { 0 };
871 
872 				hw_locks.bits.lock_dig = 1;
873 				inst_flags.dig_inst = pipe_ctx->stream_res.tg->inst;
874 
875 				dmub_hw_lock_mgr_cmd(link->ctx->dmub_srv,
876 							false,
877 							&hw_locks,
878 							&inst_flags);
879 			} else
880 				pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_disable(
881 						pipe_ctx->stream_res.tg);
882 		}
883 
884 		/* Set Test Pattern state */
885 		link->test_pattern_enabled = true;
886 		link->current_test_pattern = test_pattern;
887 	}
888 
889 	return true;
890 }
891 
dp_set_preferred_link_settings(struct dc * dc,struct dc_link_settings * link_setting,struct dc_link * link)892 void dp_set_preferred_link_settings(struct dc *dc,
893 		struct dc_link_settings *link_setting,
894 		struct dc_link *link)
895 {
896 	int i;
897 	struct pipe_ctx *pipe;
898 	struct dc_stream_state *link_stream;
899 	struct dc_link_settings store_settings = *link_setting;
900 
901 	link->preferred_link_setting = store_settings;
902 
903 	/* Retrain with preferred link settings only relevant for
904 	 * DP signal type
905 	 * Check for non-DP signal or if passive dongle present
906 	 */
907 	if (!dc_is_dp_signal(link->connector_signal) ||
908 		link->dongle_max_pix_clk > 0)
909 		return;
910 
911 	for (i = 0; i < MAX_PIPES; i++) {
912 		pipe = &dc->current_state->res_ctx.pipe_ctx[i];
913 		if (pipe->stream && pipe->stream->link) {
914 			if (pipe->stream->link == link) {
915 				link_stream = pipe->stream;
916 				break;
917 			}
918 		}
919 	}
920 
921 	/* Stream not found */
922 	if (i == MAX_PIPES)
923 		return;
924 
925 	/* Cannot retrain link if backend is off */
926 	if (link_stream->dpms_off)
927 		return;
928 
929 	if (link_decide_link_settings(link_stream, &store_settings))
930 		dp_retrain_link_dp_test(link, &store_settings, false);
931 }
932 
dp_set_preferred_training_settings(struct dc * dc,struct dc_link_settings * link_setting,struct dc_link_training_overrides * lt_overrides,struct dc_link * link,bool skip_immediate_retrain)933 void dp_set_preferred_training_settings(struct dc *dc,
934 		struct dc_link_settings *link_setting,
935 		struct dc_link_training_overrides *lt_overrides,
936 		struct dc_link *link,
937 		bool skip_immediate_retrain)
938 {
939 	if (lt_overrides != NULL)
940 		link->preferred_training_settings = *lt_overrides;
941 	else
942 		memset(&link->preferred_training_settings, 0, sizeof(link->preferred_training_settings));
943 
944 	if (link_setting != NULL) {
945 		link->preferred_link_setting = *link_setting;
946 	} else {
947 		link->preferred_link_setting.lane_count = LANE_COUNT_UNKNOWN;
948 		link->preferred_link_setting.link_rate = LINK_RATE_UNKNOWN;
949 	}
950 
951 	if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
952 			link->type == dc_connection_mst_branch)
953 		dm_helpers_dp_mst_update_branch_bandwidth(dc->ctx, link);
954 
955 	/* Retrain now, or wait until next stream update to apply */
956 	if (skip_immediate_retrain == false)
957 		dp_set_preferred_link_settings(dc, &link->preferred_link_setting, link);
958 }
959