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