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