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