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
26 /* FILE POLICY AND INTENDED USAGE:
27 * This file implements 8b/10b link training specially modified to support an
28 * embedded retimer chip. This retimer chip is referred as fixed vs pe retimer.
29 * Unlike native dp connection this chip requires a modified link training
30 * protocol based on 8b/10b link training. Since this is a non standard sequence
31 * and we must support this hardware, we decided to isolate it in its own
32 * training sequence inside its own file.
33 */
34 #include "link_dp_training_fixed_vs_pe_retimer.h"
35 #include "link_dp_training_8b_10b.h"
36 #include "link_dpcd.h"
37 #include "link_dp_phy.h"
38 #include "link_dp_capability.h"
39
40 #define DC_LOGGER \
41 link->ctx->logger
42
dp_fixed_vs_pe_read_lane_adjust(struct dc_link * link,union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX])43 void dp_fixed_vs_pe_read_lane_adjust(
44 struct dc_link *link,
45 union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX])
46 {
47 const uint8_t vendor_lttpr_write_data_vs[3] = {0x0, 0x53, 0x63};
48 const uint8_t vendor_lttpr_write_data_pe[3] = {0x0, 0x54, 0x63};
49 const uint8_t offset = dp_parse_lttpr_repeater_count(
50 link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
51 uint32_t vendor_lttpr_write_address = 0xF004F;
52 uint32_t vendor_lttpr_read_address = 0xF0053;
53 uint8_t dprx_vs = 0;
54 uint8_t dprx_pe = 0;
55 uint8_t lane;
56
57 if (offset != 0xFF) {
58 vendor_lttpr_write_address +=
59 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
60 vendor_lttpr_read_address +=
61 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
62 }
63
64 /* W/A to read lane settings requested by DPRX */
65 core_link_write_dpcd(
66 link,
67 vendor_lttpr_write_address,
68 &vendor_lttpr_write_data_vs[0],
69 sizeof(vendor_lttpr_write_data_vs));
70 core_link_read_dpcd(
71 link,
72 vendor_lttpr_read_address,
73 &dprx_vs,
74 1);
75 core_link_write_dpcd(
76 link,
77 vendor_lttpr_write_address,
78 &vendor_lttpr_write_data_pe[0],
79 sizeof(vendor_lttpr_write_data_pe));
80 core_link_read_dpcd(
81 link,
82 vendor_lttpr_read_address,
83 &dprx_pe,
84 1);
85
86 for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
87 dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET = (dprx_vs >> (2 * lane)) & 0x3;
88 dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET = (dprx_pe >> (2 * lane)) & 0x3;
89 }
90 }
91
92
dp_fixed_vs_pe_set_retimer_lane_settings(struct dc_link * link,const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX],uint8_t lane_count)93 void dp_fixed_vs_pe_set_retimer_lane_settings(
94 struct dc_link *link,
95 const union dpcd_training_lane dpcd_lane_adjust[LANE_COUNT_DP_MAX],
96 uint8_t lane_count)
97 {
98 const uint8_t offset = dp_parse_lttpr_repeater_count(
99 link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
100 const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
101 uint32_t vendor_lttpr_write_address = 0xF004F;
102 uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0};
103 uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0};
104 uint8_t lane = 0;
105
106 if (offset != 0xFF) {
107 vendor_lttpr_write_address +=
108 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
109 }
110
111 for (lane = 0; lane < lane_count; lane++) {
112 vendor_lttpr_write_data_vs[3] |=
113 dpcd_lane_adjust[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
114 vendor_lttpr_write_data_pe[3] |=
115 dpcd_lane_adjust[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
116 }
117
118 /* Force LTTPR to output desired VS and PE */
119 core_link_write_dpcd(
120 link,
121 vendor_lttpr_write_address,
122 &vendor_lttpr_write_data_reset[0],
123 sizeof(vendor_lttpr_write_data_reset));
124 core_link_write_dpcd(
125 link,
126 vendor_lttpr_write_address,
127 &vendor_lttpr_write_data_vs[0],
128 sizeof(vendor_lttpr_write_data_vs));
129 core_link_write_dpcd(
130 link,
131 vendor_lttpr_write_address,
132 &vendor_lttpr_write_data_pe[0],
133 sizeof(vendor_lttpr_write_data_pe));
134 }
135
perform_fixed_vs_pe_nontransparent_training_sequence(struct dc_link * link,const struct link_resource * link_res,struct link_training_settings * lt_settings)136 static enum link_training_result perform_fixed_vs_pe_nontransparent_training_sequence(
137 struct dc_link *link,
138 const struct link_resource *link_res,
139 struct link_training_settings *lt_settings)
140 {
141 enum link_training_result status = LINK_TRAINING_SUCCESS;
142 uint8_t lane = 0;
143 uint8_t toggle_rate = 0x6;
144 uint8_t target_rate = 0x6;
145 bool apply_toggle_rate_wa = false;
146 uint8_t repeater_cnt;
147 uint8_t repeater_id;
148
149 /* Fixed VS/PE specific: Force CR AUX RD Interval to at least 16ms */
150 if (lt_settings->cr_pattern_time < 16000)
151 lt_settings->cr_pattern_time = 16000;
152
153 /* Fixed VS/PE specific: Toggle link rate */
154 apply_toggle_rate_wa = (link->vendor_specific_lttpr_link_rate_wa == target_rate);
155 target_rate = get_dpcd_link_rate(<_settings->link_settings);
156 toggle_rate = (target_rate == 0x6) ? 0xA : 0x6;
157
158 if (apply_toggle_rate_wa)
159 lt_settings->link_settings.link_rate = toggle_rate;
160
161 if (link->ctx->dc->work_arounds.lt_early_cr_pattern)
162 start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
163
164 /* 1. set link rate, lane count and spread. */
165 dpcd_set_link_settings(link, lt_settings);
166
167 /* Fixed VS/PE specific: Toggle link rate back*/
168 if (apply_toggle_rate_wa) {
169 core_link_write_dpcd(
170 link,
171 DP_LINK_BW_SET,
172 &target_rate,
173 1);
174 }
175
176 link->vendor_specific_lttpr_link_rate_wa = target_rate;
177
178 if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
179
180 /* 2. perform link training (set link training done
181 * to false is done as well)
182 */
183 repeater_cnt = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
184
185 for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS);
186 repeater_id--) {
187 status = perform_8b_10b_clock_recovery_sequence(link, link_res, lt_settings, repeater_id);
188
189 if (status != LINK_TRAINING_SUCCESS) {
190 repeater_training_done(link, repeater_id);
191 break;
192 }
193
194 status = perform_8b_10b_channel_equalization_sequence(link,
195 link_res,
196 lt_settings,
197 repeater_id);
198
199 repeater_training_done(link, repeater_id);
200
201 if (status != LINK_TRAINING_SUCCESS)
202 break;
203
204 for (lane = 0; lane < LANE_COUNT_DP_MAX; lane++) {
205 lt_settings->dpcd_lane_settings[lane].raw = 0;
206 lt_settings->hw_lane_settings[lane].VOLTAGE_SWING = 0;
207 lt_settings->hw_lane_settings[lane].PRE_EMPHASIS = 0;
208 }
209 }
210 }
211
212 if (status == LINK_TRAINING_SUCCESS) {
213 status = perform_8b_10b_clock_recovery_sequence(link, link_res, lt_settings, DPRX);
214 if (status == LINK_TRAINING_SUCCESS) {
215 status = perform_8b_10b_channel_equalization_sequence(link,
216 link_res,
217 lt_settings,
218 DPRX);
219 }
220 }
221
222 return status;
223 }
224
225
dp_perform_fixed_vs_pe_training_sequence(struct dc_link * link,const struct link_resource * link_res,struct link_training_settings * lt_settings)226 enum link_training_result dp_perform_fixed_vs_pe_training_sequence(
227 struct dc_link *link,
228 const struct link_resource *link_res,
229 struct link_training_settings *lt_settings)
230 {
231 const uint8_t vendor_lttpr_write_data_reset[4] = {0x1, 0x50, 0x63, 0xFF};
232 const uint8_t offset = dp_parse_lttpr_repeater_count(
233 link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
234 const uint8_t vendor_lttpr_write_data_intercept_en[4] = {0x1, 0x55, 0x63, 0x0};
235 const uint8_t vendor_lttpr_write_data_intercept_dis[4] = {0x1, 0x55, 0x63, 0x68};
236 uint32_t pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa;
237 uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0};
238 uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0};
239 uint32_t vendor_lttpr_write_address = 0xF004F;
240 enum link_training_result status = LINK_TRAINING_SUCCESS;
241 uint8_t lane = 0;
242 union down_spread_ctrl downspread = {0};
243 union lane_count_set lane_count_set = {0};
244 uint8_t toggle_rate;
245 uint8_t rate;
246
247 /* Only 8b/10b is supported */
248 ASSERT(link_dp_get_encoding_format(<_settings->link_settings) ==
249 DP_8b_10b_ENCODING);
250
251 if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
252 status = perform_fixed_vs_pe_nontransparent_training_sequence(link, link_res, lt_settings);
253 return status;
254 }
255
256 if (offset != 0xFF) {
257 vendor_lttpr_write_address +=
258 ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1));
259
260 /* Certain display and cable configuration require extra delay */
261 if (offset > 2)
262 pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2;
263 }
264
265 /* Vendor specific: Reset lane settings */
266 core_link_write_dpcd(
267 link,
268 vendor_lttpr_write_address,
269 &vendor_lttpr_write_data_reset[0],
270 sizeof(vendor_lttpr_write_data_reset));
271 core_link_write_dpcd(
272 link,
273 vendor_lttpr_write_address,
274 &vendor_lttpr_write_data_vs[0],
275 sizeof(vendor_lttpr_write_data_vs));
276 core_link_write_dpcd(
277 link,
278 vendor_lttpr_write_address,
279 &vendor_lttpr_write_data_pe[0],
280 sizeof(vendor_lttpr_write_data_pe));
281
282 /* Vendor specific: Enable intercept */
283 core_link_write_dpcd(
284 link,
285 vendor_lttpr_write_address,
286 &vendor_lttpr_write_data_intercept_en[0],
287 sizeof(vendor_lttpr_write_data_intercept_en));
288
289 /* 1. set link rate, lane count and spread. */
290
291 downspread.raw = (uint8_t)(lt_settings->link_settings.link_spread);
292
293 lane_count_set.bits.LANE_COUNT_SET =
294 lt_settings->link_settings.lane_count;
295
296 lane_count_set.bits.ENHANCED_FRAMING = lt_settings->enhanced_framing;
297 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED = 0;
298
299
300 if (lt_settings->pattern_for_eq < DP_TRAINING_PATTERN_SEQUENCE_4) {
301 lane_count_set.bits.POST_LT_ADJ_REQ_GRANTED =
302 link->dpcd_caps.max_ln_count.bits.POST_LT_ADJ_REQ_SUPPORTED;
303 }
304
305 core_link_write_dpcd(link, DP_DOWNSPREAD_CTRL,
306 &downspread.raw, sizeof(downspread));
307
308 core_link_write_dpcd(link, DP_LANE_COUNT_SET,
309 &lane_count_set.raw, 1);
310
311 rate = get_dpcd_link_rate(<_settings->link_settings);
312
313 /* Vendor specific: Toggle link rate */
314 toggle_rate = (rate == 0x6) ? 0xA : 0x6;
315
316 if (link->vendor_specific_lttpr_link_rate_wa == rate) {
317 core_link_write_dpcd(
318 link,
319 DP_LINK_BW_SET,
320 &toggle_rate,
321 1);
322 }
323
324 link->vendor_specific_lttpr_link_rate_wa = rate;
325
326 core_link_write_dpcd(link, DP_LINK_BW_SET, &rate, 1);
327
328 DC_LOG_HW_LINK_TRAINING("%s\n %x rate = %x\n %x lane = %x framing = %x\n %x spread = %x\n",
329 __func__,
330 DP_LINK_BW_SET,
331 lt_settings->link_settings.link_rate,
332 DP_LANE_COUNT_SET,
333 lt_settings->link_settings.lane_count,
334 lt_settings->enhanced_framing,
335 DP_DOWNSPREAD_CTRL,
336 lt_settings->link_settings.link_spread);
337
338 /* 2. Perform link training */
339
340 /* Perform Clock Recovery Sequence */
341 if (status == LINK_TRAINING_SUCCESS) {
342 const uint8_t max_vendor_dpcd_retries = 10;
343 uint32_t retries_cr;
344 uint32_t retry_count;
345 uint32_t wait_time_microsec;
346 enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
347 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
348 union lane_align_status_updated dpcd_lane_status_updated;
349 union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
350 enum dc_status dpcd_status = DC_OK;
351 uint8_t i = 0;
352
353 retries_cr = 0;
354 retry_count = 0;
355
356 memset(&dpcd_lane_status, '\0', sizeof(dpcd_lane_status));
357 memset(&dpcd_lane_status_updated, '\0',
358 sizeof(dpcd_lane_status_updated));
359
360 while ((retries_cr < LINK_TRAINING_MAX_RETRY_COUNT) &&
361 (retry_count < LINK_TRAINING_MAX_CR_RETRY)) {
362
363
364 /* 1. call HWSS to set lane settings */
365 dp_set_hw_lane_settings(
366 link,
367 link_res,
368 lt_settings,
369 0);
370
371 /* 2. update DPCD of the receiver */
372 if (!retry_count) {
373 /* EPR #361076 - write as a 5-byte burst,
374 * but only for the 1-st iteration.
375 */
376 dpcd_set_lt_pattern_and_lane_settings(
377 link,
378 lt_settings,
379 lt_settings->pattern_for_cr,
380 0);
381 /* Vendor specific: Disable intercept */
382 for (i = 0; i < max_vendor_dpcd_retries; i++) {
383 msleep(pre_disable_intercept_delay_ms);
384 dpcd_status = core_link_write_dpcd(
385 link,
386 vendor_lttpr_write_address,
387 &vendor_lttpr_write_data_intercept_dis[0],
388 sizeof(vendor_lttpr_write_data_intercept_dis));
389
390 if (dpcd_status == DC_OK)
391 break;
392
393 core_link_write_dpcd(
394 link,
395 vendor_lttpr_write_address,
396 &vendor_lttpr_write_data_intercept_en[0],
397 sizeof(vendor_lttpr_write_data_intercept_en));
398 }
399 } else {
400 vendor_lttpr_write_data_vs[3] = 0;
401 vendor_lttpr_write_data_pe[3] = 0;
402
403 for (lane = 0; lane < lane_count; lane++) {
404 vendor_lttpr_write_data_vs[3] |=
405 lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
406 vendor_lttpr_write_data_pe[3] |=
407 lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
408 }
409
410 /* Vendor specific: Update VS and PE to DPRX requested value */
411 core_link_write_dpcd(
412 link,
413 vendor_lttpr_write_address,
414 &vendor_lttpr_write_data_vs[0],
415 sizeof(vendor_lttpr_write_data_vs));
416 core_link_write_dpcd(
417 link,
418 vendor_lttpr_write_address,
419 &vendor_lttpr_write_data_pe[0],
420 sizeof(vendor_lttpr_write_data_pe));
421
422 dpcd_set_lane_settings(
423 link,
424 lt_settings,
425 0);
426 }
427
428 /* 3. wait receiver to lock-on*/
429 wait_time_microsec = lt_settings->cr_pattern_time;
430
431 dp_wait_for_training_aux_rd_interval(
432 link,
433 wait_time_microsec);
434
435 /* 4. Read lane status and requested drive
436 * settings as set by the sink
437 */
438 dp_get_lane_status_and_lane_adjust(
439 link,
440 lt_settings,
441 dpcd_lane_status,
442 &dpcd_lane_status_updated,
443 dpcd_lane_adjust,
444 0);
445
446 /* 5. check CR done*/
447 if (dp_is_cr_done(lane_count, dpcd_lane_status)) {
448 status = LINK_TRAINING_SUCCESS;
449 break;
450 }
451
452 /* 6. max VS reached*/
453 if (dp_is_max_vs_reached(lt_settings))
454 break;
455
456 /* 7. same lane settings */
457 /* Note: settings are the same for all lanes,
458 * so comparing first lane is sufficient
459 */
460 if (lt_settings->dpcd_lane_settings[0].bits.VOLTAGE_SWING_SET ==
461 dpcd_lane_adjust[0].bits.VOLTAGE_SWING_LANE)
462 retries_cr++;
463 else
464 retries_cr = 0;
465
466 /* 8. update VS/PE/PC2 in lt_settings*/
467 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
468 lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
469 retry_count++;
470 }
471
472 if (retry_count >= LINK_TRAINING_MAX_CR_RETRY) {
473 ASSERT(0);
474 DC_LOG_ERROR("%s: Link Training Error, could not get CR after %d tries. Possibly voltage swing issue",
475 __func__,
476 LINK_TRAINING_MAX_CR_RETRY);
477
478 }
479
480 status = dp_get_cr_failure(lane_count, dpcd_lane_status);
481 }
482
483 /* Perform Channel EQ Sequence */
484 if (status == LINK_TRAINING_SUCCESS) {
485 enum dc_dp_training_pattern tr_pattern;
486 uint32_t retries_ch_eq;
487 uint32_t wait_time_microsec;
488 enum dc_lane_count lane_count = lt_settings->link_settings.lane_count;
489 union lane_align_status_updated dpcd_lane_status_updated = {0};
490 union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0};
491 union lane_adjust dpcd_lane_adjust[LANE_COUNT_DP_MAX] = {0};
492
493 /* Note: also check that TPS4 is a supported feature*/
494 tr_pattern = lt_settings->pattern_for_eq;
495
496 dp_set_hw_training_pattern(link, link_res, tr_pattern, 0);
497
498 status = LINK_TRAINING_EQ_FAIL_EQ;
499
500 for (retries_ch_eq = 0; retries_ch_eq <= LINK_TRAINING_MAX_RETRY_COUNT;
501 retries_ch_eq++) {
502
503 dp_set_hw_lane_settings(link, link_res, lt_settings, 0);
504
505 vendor_lttpr_write_data_vs[3] = 0;
506 vendor_lttpr_write_data_pe[3] = 0;
507
508 for (lane = 0; lane < lane_count; lane++) {
509 vendor_lttpr_write_data_vs[3] |=
510 lt_settings->dpcd_lane_settings[lane].bits.VOLTAGE_SWING_SET << (2 * lane);
511 vendor_lttpr_write_data_pe[3] |=
512 lt_settings->dpcd_lane_settings[lane].bits.PRE_EMPHASIS_SET << (2 * lane);
513 }
514
515 /* Vendor specific: Update VS and PE to DPRX requested value */
516 core_link_write_dpcd(
517 link,
518 vendor_lttpr_write_address,
519 &vendor_lttpr_write_data_vs[0],
520 sizeof(vendor_lttpr_write_data_vs));
521 core_link_write_dpcd(
522 link,
523 vendor_lttpr_write_address,
524 &vendor_lttpr_write_data_pe[0],
525 sizeof(vendor_lttpr_write_data_pe));
526
527 /* 2. update DPCD*/
528 if (!retries_ch_eq)
529 /* EPR #361076 - write as a 5-byte burst,
530 * but only for the 1-st iteration
531 */
532
533 dpcd_set_lt_pattern_and_lane_settings(
534 link,
535 lt_settings,
536 tr_pattern, 0);
537 else
538 dpcd_set_lane_settings(link, lt_settings, 0);
539
540 /* 3. wait for receiver to lock-on*/
541 wait_time_microsec = lt_settings->eq_pattern_time;
542
543 dp_wait_for_training_aux_rd_interval(
544 link,
545 wait_time_microsec);
546
547 /* 4. Read lane status and requested
548 * drive settings as set by the sink
549 */
550 dp_get_lane_status_and_lane_adjust(
551 link,
552 lt_settings,
553 dpcd_lane_status,
554 &dpcd_lane_status_updated,
555 dpcd_lane_adjust,
556 0);
557
558 /* 5. check CR done*/
559 if (!dp_is_cr_done(lane_count, dpcd_lane_status)) {
560 status = LINK_TRAINING_EQ_FAIL_CR;
561 break;
562 }
563
564 /* 6. check CHEQ done*/
565 if (dp_is_ch_eq_done(lane_count, dpcd_lane_status) &&
566 dp_is_symbol_locked(lane_count, dpcd_lane_status) &&
567 dp_is_interlane_aligned(dpcd_lane_status_updated)) {
568 status = LINK_TRAINING_SUCCESS;
569 break;
570 }
571
572 /* 7. update VS/PE/PC2 in lt_settings*/
573 dp_decide_lane_settings(lt_settings, dpcd_lane_adjust,
574 lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings);
575 }
576 }
577
578 return status;
579 }
580