1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "reg_helper.h" 27 28 #include "core_types.h" 29 #include "link_encoder.h" 30 #include "dce_link_encoder.h" 31 #include "stream_encoder.h" 32 #include "dc_bios_types.h" 33 34 #include "gpio_service_interface.h" 35 36 #include "dce/dce_11_0_d.h" 37 #include "dce/dce_11_0_sh_mask.h" 38 #include "dce/dce_11_0_enum.h" 39 40 #ifndef DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE__SHIFT 41 #define DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE__SHIFT 0xa 42 #endif 43 44 #ifndef DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE_MASK 45 #define DMU_MEM_PWR_CNTL__DMCU_IRAM_MEM_PWR_STATE_MASK 0x00000400L 46 #endif 47 48 #ifndef HPD0_DC_HPD_CONTROL__DC_HPD_EN_MASK 49 #define HPD0_DC_HPD_CONTROL__DC_HPD_EN_MASK 0x10000000L 50 #endif 51 52 #ifndef HPD0_DC_HPD_CONTROL__DC_HPD_EN__SHIFT 53 #define HPD0_DC_HPD_CONTROL__DC_HPD_EN__SHIFT 0x1c 54 #endif 55 56 #define CTX \ 57 enc110->base.ctx 58 #define DC_LOGGER \ 59 enc110->base.ctx->logger 60 61 #define REG(reg)\ 62 (enc110->link_regs->reg) 63 64 #define AUX_REG(reg)\ 65 (enc110->aux_regs->reg) 66 67 #define HPD_REG(reg)\ 68 (enc110->hpd_regs->reg) 69 70 #define DEFAULT_AUX_MAX_DATA_SIZE 16 71 #define AUX_MAX_DEFER_WRITE_RETRY 20 72 /* 73 * @brief 74 * Trigger Source Select 75 * ASIC-dependent, actual values for register programming 76 */ 77 #define DCE110_DIG_FE_SOURCE_SELECT_INVALID 0x0 78 #define DCE110_DIG_FE_SOURCE_SELECT_DIGA 0x1 79 #define DCE110_DIG_FE_SOURCE_SELECT_DIGB 0x2 80 #define DCE110_DIG_FE_SOURCE_SELECT_DIGC 0x4 81 #define DCE110_DIG_FE_SOURCE_SELECT_DIGD 0x08 82 #define DCE110_DIG_FE_SOURCE_SELECT_DIGE 0x10 83 #define DCE110_DIG_FE_SOURCE_SELECT_DIGF 0x20 84 #define DCE110_DIG_FE_SOURCE_SELECT_DIGG 0x40 85 86 enum { 87 DP_MST_UPDATE_MAX_RETRY = 50 88 }; 89 90 #define DIG_REG(reg)\ 91 (reg + enc110->offsets.dig) 92 93 #define DP_REG(reg)\ 94 (reg + enc110->offsets.dp) 95 96 static const struct link_encoder_funcs dce110_lnk_enc_funcs = { 97 .validate_output_with_stream = 98 dce110_link_encoder_validate_output_with_stream, 99 .hw_init = dce110_link_encoder_hw_init, 100 .setup = dce110_link_encoder_setup, 101 .enable_tmds_output = dce110_link_encoder_enable_tmds_output, 102 .enable_dp_output = dce110_link_encoder_enable_dp_output, 103 .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output, 104 .enable_lvds_output = dce110_link_encoder_enable_lvds_output, 105 .disable_output = dce110_link_encoder_disable_output, 106 .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, 107 .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern, 108 .update_mst_stream_allocation_table = 109 dce110_link_encoder_update_mst_stream_allocation_table, 110 .psr_program_dp_dphy_fast_training = 111 dce110_psr_program_dp_dphy_fast_training, 112 .psr_program_secondary_packet = dce110_psr_program_secondary_packet, 113 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, 114 .enable_hpd = dce110_link_encoder_enable_hpd, 115 .disable_hpd = dce110_link_encoder_disable_hpd, 116 .is_dig_enabled = dce110_is_dig_enabled, 117 .destroy = dce110_link_encoder_destroy, 118 .get_max_link_cap = dce110_link_encoder_get_max_link_cap, 119 .get_dig_frontend = dce110_get_dig_frontend, 120 }; 121 122 static enum bp_result link_transmitter_control( 123 struct dce110_link_encoder *enc110, 124 struct bp_transmitter_control *cntl) 125 { 126 enum bp_result result; 127 struct dc_bios *bp = enc110->base.ctx->dc_bios; 128 129 result = bp->funcs->transmitter_control(bp, cntl); 130 131 return result; 132 } 133 134 static void enable_phy_bypass_mode( 135 struct dce110_link_encoder *enc110, 136 bool enable) 137 { 138 /* This register resides in DP back end block; 139 * transmitter is used for the offset */ 140 141 REG_UPDATE(DP_DPHY_CNTL, DPHY_BYPASS, enable); 142 143 } 144 145 static void disable_prbs_symbols( 146 struct dce110_link_encoder *enc110, 147 bool disable) 148 { 149 /* This register resides in DP back end block; 150 * transmitter is used for the offset */ 151 152 REG_UPDATE_4(DP_DPHY_CNTL, 153 DPHY_ATEST_SEL_LANE0, disable, 154 DPHY_ATEST_SEL_LANE1, disable, 155 DPHY_ATEST_SEL_LANE2, disable, 156 DPHY_ATEST_SEL_LANE3, disable); 157 } 158 159 static void disable_prbs_mode( 160 struct dce110_link_encoder *enc110) 161 { 162 REG_UPDATE(DP_DPHY_PRBS_CNTL, DPHY_PRBS_EN, 0); 163 } 164 165 static void program_pattern_symbols( 166 struct dce110_link_encoder *enc110, 167 uint16_t pattern_symbols[8]) 168 { 169 /* This register resides in DP back end block; 170 * transmitter is used for the offset */ 171 172 REG_SET_3(DP_DPHY_SYM0, 0, 173 DPHY_SYM1, pattern_symbols[0], 174 DPHY_SYM2, pattern_symbols[1], 175 DPHY_SYM3, pattern_symbols[2]); 176 177 /* This register resides in DP back end block; 178 * transmitter is used for the offset */ 179 180 REG_SET_3(DP_DPHY_SYM1, 0, 181 DPHY_SYM4, pattern_symbols[3], 182 DPHY_SYM5, pattern_symbols[4], 183 DPHY_SYM6, pattern_symbols[5]); 184 185 /* This register resides in DP back end block; 186 * transmitter is used for the offset */ 187 188 REG_SET_2(DP_DPHY_SYM2, 0, 189 DPHY_SYM7, pattern_symbols[6], 190 DPHY_SYM8, pattern_symbols[7]); 191 } 192 193 static void set_dp_phy_pattern_d102( 194 struct dce110_link_encoder *enc110) 195 { 196 /* Disable PHY Bypass mode to setup the test pattern */ 197 enable_phy_bypass_mode(enc110, false); 198 199 /* For 10-bit PRBS or debug symbols 200 * please use the following sequence: */ 201 202 /* Enable debug symbols on the lanes */ 203 204 disable_prbs_symbols(enc110, true); 205 206 /* Disable PRBS mode */ 207 disable_prbs_mode(enc110); 208 209 /* Program debug symbols to be output */ 210 { 211 uint16_t pattern_symbols[8] = { 212 0x2AA, 0x2AA, 0x2AA, 0x2AA, 213 0x2AA, 0x2AA, 0x2AA, 0x2AA 214 }; 215 216 program_pattern_symbols(enc110, pattern_symbols); 217 } 218 219 /* Enable phy bypass mode to enable the test pattern */ 220 221 enable_phy_bypass_mode(enc110, true); 222 } 223 224 static void set_link_training_complete( 225 struct dce110_link_encoder *enc110, 226 bool complete) 227 { 228 /* This register resides in DP back end block; 229 * transmitter is used for the offset */ 230 231 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, complete); 232 233 } 234 235 unsigned int dce110_get_dig_frontend(struct link_encoder *enc) 236 { 237 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 238 u32 value; 239 enum engine_id result; 240 241 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value); 242 243 switch (value) { 244 case DCE110_DIG_FE_SOURCE_SELECT_DIGA: 245 result = ENGINE_ID_DIGA; 246 break; 247 case DCE110_DIG_FE_SOURCE_SELECT_DIGB: 248 result = ENGINE_ID_DIGB; 249 break; 250 case DCE110_DIG_FE_SOURCE_SELECT_DIGC: 251 result = ENGINE_ID_DIGC; 252 break; 253 case DCE110_DIG_FE_SOURCE_SELECT_DIGD: 254 result = ENGINE_ID_DIGD; 255 break; 256 case DCE110_DIG_FE_SOURCE_SELECT_DIGE: 257 result = ENGINE_ID_DIGE; 258 break; 259 case DCE110_DIG_FE_SOURCE_SELECT_DIGF: 260 result = ENGINE_ID_DIGF; 261 break; 262 case DCE110_DIG_FE_SOURCE_SELECT_DIGG: 263 result = ENGINE_ID_DIGG; 264 break; 265 default: 266 // invalid source select DIG 267 result = ENGINE_ID_UNKNOWN; 268 } 269 270 return result; 271 } 272 273 void dce110_link_encoder_set_dp_phy_pattern_training_pattern( 274 struct link_encoder *enc, 275 uint32_t index) 276 { 277 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 278 /* Write Training Pattern */ 279 280 REG_WRITE(DP_DPHY_TRAINING_PATTERN_SEL, index); 281 282 /* Set HW Register Training Complete to false */ 283 284 set_link_training_complete(enc110, false); 285 286 /* Disable PHY Bypass mode to output Training Pattern */ 287 288 enable_phy_bypass_mode(enc110, false); 289 290 /* Disable PRBS mode */ 291 disable_prbs_mode(enc110); 292 } 293 294 static void setup_panel_mode( 295 struct dce110_link_encoder *enc110, 296 enum dp_panel_mode panel_mode) 297 { 298 uint32_t value; 299 struct dc_context *ctx = enc110->base.ctx; 300 301 /* if psp set panel mode, dal should be program it */ 302 if (ctx->dc->caps.psp_setup_panel_mode) 303 return; 304 305 ASSERT(REG(DP_DPHY_INTERNAL_CTRL)); 306 value = REG_READ(DP_DPHY_INTERNAL_CTRL); 307 308 switch (panel_mode) { 309 case DP_PANEL_MODE_EDP: 310 value = 0x1; 311 break; 312 case DP_PANEL_MODE_SPECIAL: 313 value = 0x11; 314 break; 315 default: 316 value = 0x0; 317 break; 318 } 319 320 REG_WRITE(DP_DPHY_INTERNAL_CTRL, value); 321 } 322 323 static void set_dp_phy_pattern_symbol_error( 324 struct dce110_link_encoder *enc110) 325 { 326 /* Disable PHY Bypass mode to setup the test pattern */ 327 enable_phy_bypass_mode(enc110, false); 328 329 /* program correct panel mode*/ 330 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT); 331 332 /* A PRBS23 pattern is used for most DP electrical measurements. */ 333 334 /* Enable PRBS symbols on the lanes */ 335 disable_prbs_symbols(enc110, false); 336 337 /* For PRBS23 Set bit DPHY_PRBS_SEL=1 and Set bit DPHY_PRBS_EN=1 */ 338 REG_UPDATE_2(DP_DPHY_PRBS_CNTL, 339 DPHY_PRBS_SEL, 1, 340 DPHY_PRBS_EN, 1); 341 342 /* Enable phy bypass mode to enable the test pattern */ 343 enable_phy_bypass_mode(enc110, true); 344 } 345 346 static void set_dp_phy_pattern_prbs7( 347 struct dce110_link_encoder *enc110) 348 { 349 /* Disable PHY Bypass mode to setup the test pattern */ 350 enable_phy_bypass_mode(enc110, false); 351 352 /* A PRBS7 pattern is used for most DP electrical measurements. */ 353 354 /* Enable PRBS symbols on the lanes */ 355 disable_prbs_symbols(enc110, false); 356 357 /* For PRBS7 Set bit DPHY_PRBS_SEL=0 and Set bit DPHY_PRBS_EN=1 */ 358 REG_UPDATE_2(DP_DPHY_PRBS_CNTL, 359 DPHY_PRBS_SEL, 0, 360 DPHY_PRBS_EN, 1); 361 362 /* Enable phy bypass mode to enable the test pattern */ 363 enable_phy_bypass_mode(enc110, true); 364 } 365 366 static void set_dp_phy_pattern_80bit_custom( 367 struct dce110_link_encoder *enc110, 368 const uint8_t *pattern) 369 { 370 /* Disable PHY Bypass mode to setup the test pattern */ 371 enable_phy_bypass_mode(enc110, false); 372 373 /* Enable debug symbols on the lanes */ 374 375 disable_prbs_symbols(enc110, true); 376 377 /* Enable PHY bypass mode to enable the test pattern */ 378 /* TODO is it really needed ? */ 379 380 enable_phy_bypass_mode(enc110, true); 381 382 /* Program 80 bit custom pattern */ 383 { 384 uint16_t pattern_symbols[8]; 385 386 pattern_symbols[0] = 387 ((pattern[1] & 0x03) << 8) | pattern[0]; 388 pattern_symbols[1] = 389 ((pattern[2] & 0x0f) << 6) | ((pattern[1] >> 2) & 0x3f); 390 pattern_symbols[2] = 391 ((pattern[3] & 0x3f) << 4) | ((pattern[2] >> 4) & 0x0f); 392 pattern_symbols[3] = 393 (pattern[4] << 2) | ((pattern[3] >> 6) & 0x03); 394 pattern_symbols[4] = 395 ((pattern[6] & 0x03) << 8) | pattern[5]; 396 pattern_symbols[5] = 397 ((pattern[7] & 0x0f) << 6) | ((pattern[6] >> 2) & 0x3f); 398 pattern_symbols[6] = 399 ((pattern[8] & 0x3f) << 4) | ((pattern[7] >> 4) & 0x0f); 400 pattern_symbols[7] = 401 (pattern[9] << 2) | ((pattern[8] >> 6) & 0x03); 402 403 program_pattern_symbols(enc110, pattern_symbols); 404 } 405 406 /* Enable phy bypass mode to enable the test pattern */ 407 408 enable_phy_bypass_mode(enc110, true); 409 } 410 411 static void set_dp_phy_pattern_hbr2_compliance_cp2520_2( 412 struct dce110_link_encoder *enc110, 413 unsigned int cp2520_pattern) 414 { 415 416 /* previously there is a register DP_HBR2_EYE_PATTERN 417 * that is enabled to get the pattern. 418 * But it does not work with the latest spec change, 419 * so we are programming the following registers manually. 420 * 421 * The following settings have been confirmed 422 * by Nick Chorney and Sandra Liu */ 423 424 /* Disable PHY Bypass mode to setup the test pattern */ 425 426 enable_phy_bypass_mode(enc110, false); 427 428 /* Setup DIG encoder in DP SST mode */ 429 enc110->base.funcs->setup(&enc110->base, SIGNAL_TYPE_DISPLAY_PORT); 430 431 /* ensure normal panel mode. */ 432 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT); 433 434 /* no vbid after BS (SR) 435 * DP_LINK_FRAMING_CNTL changed history Sandra Liu 436 * 11000260 / 11000104 / 110000FC */ 437 REG_UPDATE_3(DP_LINK_FRAMING_CNTL, 438 DP_IDLE_BS_INTERVAL, 0xFC, 439 DP_VBID_DISABLE, 1, 440 DP_VID_ENHANCED_FRAME_MODE, 1); 441 442 /* swap every BS with SR */ 443 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0); 444 445 /* select cp2520 patterns */ 446 if (REG(DP_DPHY_HBR2_PATTERN_CONTROL)) 447 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL, 448 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern); 449 else 450 /* pre-DCE11 can only generate CP2520 pattern 2 */ 451 ASSERT(cp2520_pattern == 2); 452 453 /* set link training complete */ 454 set_link_training_complete(enc110, true); 455 456 /* disable video stream */ 457 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); 458 459 /* Disable PHY Bypass mode to setup the test pattern */ 460 enable_phy_bypass_mode(enc110, false); 461 } 462 463 #if defined(CONFIG_DRM_AMD_DC_SI) 464 static void dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2( 465 struct dce110_link_encoder *enc110, 466 unsigned int cp2520_pattern) 467 { 468 469 /* previously there is a register DP_HBR2_EYE_PATTERN 470 * that is enabled to get the pattern. 471 * But it does not work with the latest spec change, 472 * so we are programming the following registers manually. 473 * 474 * The following settings have been confirmed 475 * by Nick Chorney and Sandra Liu */ 476 477 /* Disable PHY Bypass mode to setup the test pattern */ 478 479 enable_phy_bypass_mode(enc110, false); 480 481 /* Setup DIG encoder in DP SST mode */ 482 enc110->base.funcs->setup(&enc110->base, SIGNAL_TYPE_DISPLAY_PORT); 483 484 /* ensure normal panel mode. */ 485 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT); 486 487 /* no vbid after BS (SR) 488 * DP_LINK_FRAMING_CNTL changed history Sandra Liu 489 * 11000260 / 11000104 / 110000FC */ 490 REG_UPDATE_3(DP_LINK_FRAMING_CNTL, 491 DP_IDLE_BS_INTERVAL, 0xFC, 492 DP_VBID_DISABLE, 1, 493 DP_VID_ENHANCED_FRAME_MODE, 1); 494 495 /* DCE6 has no DP_DPHY_SCRAM_CNTL register, skip swap BS with SR */ 496 497 /* select cp2520 patterns */ 498 if (REG(DP_DPHY_HBR2_PATTERN_CONTROL)) 499 REG_UPDATE(DP_DPHY_HBR2_PATTERN_CONTROL, 500 DP_DPHY_HBR2_PATTERN_CONTROL, cp2520_pattern); 501 else 502 /* pre-DCE11 can only generate CP2520 pattern 2 */ 503 ASSERT(cp2520_pattern == 2); 504 505 /* set link training complete */ 506 set_link_training_complete(enc110, true); 507 508 /* disable video stream */ 509 REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); 510 511 /* Disable PHY Bypass mode to setup the test pattern */ 512 enable_phy_bypass_mode(enc110, false); 513 } 514 #endif 515 516 static void set_dp_phy_pattern_passthrough_mode( 517 struct dce110_link_encoder *enc110, 518 enum dp_panel_mode panel_mode) 519 { 520 /* program correct panel mode */ 521 setup_panel_mode(enc110, panel_mode); 522 523 /* restore LINK_FRAMING_CNTL and DPHY_SCRAMBLER_BS_COUNT 524 * in case we were doing HBR2 compliance pattern before 525 */ 526 REG_UPDATE_3(DP_LINK_FRAMING_CNTL, 527 DP_IDLE_BS_INTERVAL, 0x2000, 528 DP_VBID_DISABLE, 0, 529 DP_VID_ENHANCED_FRAME_MODE, 1); 530 531 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_BS_COUNT, 0x1FF); 532 533 /* set link training complete */ 534 set_link_training_complete(enc110, true); 535 536 /* Disable PHY Bypass mode to setup the test pattern */ 537 enable_phy_bypass_mode(enc110, false); 538 539 /* Disable PRBS mode */ 540 disable_prbs_mode(enc110); 541 } 542 543 #if defined(CONFIG_DRM_AMD_DC_SI) 544 static void dce60_set_dp_phy_pattern_passthrough_mode( 545 struct dce110_link_encoder *enc110, 546 enum dp_panel_mode panel_mode) 547 { 548 /* program correct panel mode */ 549 setup_panel_mode(enc110, panel_mode); 550 551 /* restore LINK_FRAMING_CNTL 552 * in case we were doing HBR2 compliance pattern before 553 */ 554 REG_UPDATE_3(DP_LINK_FRAMING_CNTL, 555 DP_IDLE_BS_INTERVAL, 0x2000, 556 DP_VBID_DISABLE, 0, 557 DP_VID_ENHANCED_FRAME_MODE, 1); 558 559 /* DCE6 has no DP_DPHY_SCRAM_CNTL register, skip DPHY_SCRAMBLER_BS_COUNT restore */ 560 561 /* set link training complete */ 562 set_link_training_complete(enc110, true); 563 564 /* Disable PHY Bypass mode to setup the test pattern */ 565 enable_phy_bypass_mode(enc110, false); 566 567 /* Disable PRBS mode */ 568 disable_prbs_mode(enc110); 569 } 570 #endif 571 572 /* return value is bit-vector */ 573 static uint8_t get_frontend_source( 574 enum engine_id engine) 575 { 576 switch (engine) { 577 case ENGINE_ID_DIGA: 578 return DCE110_DIG_FE_SOURCE_SELECT_DIGA; 579 case ENGINE_ID_DIGB: 580 return DCE110_DIG_FE_SOURCE_SELECT_DIGB; 581 case ENGINE_ID_DIGC: 582 return DCE110_DIG_FE_SOURCE_SELECT_DIGC; 583 case ENGINE_ID_DIGD: 584 return DCE110_DIG_FE_SOURCE_SELECT_DIGD; 585 case ENGINE_ID_DIGE: 586 return DCE110_DIG_FE_SOURCE_SELECT_DIGE; 587 case ENGINE_ID_DIGF: 588 return DCE110_DIG_FE_SOURCE_SELECT_DIGF; 589 case ENGINE_ID_DIGG: 590 return DCE110_DIG_FE_SOURCE_SELECT_DIGG; 591 default: 592 ASSERT_CRITICAL(false); 593 return DCE110_DIG_FE_SOURCE_SELECT_INVALID; 594 } 595 } 596 597 static void configure_encoder( 598 struct dce110_link_encoder *enc110, 599 const struct dc_link_settings *link_settings) 600 { 601 /* set number of lanes */ 602 603 REG_SET(DP_CONFIG, 0, 604 DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE); 605 606 /* setup scrambler */ 607 REG_UPDATE(DP_DPHY_SCRAM_CNTL, DPHY_SCRAMBLER_ADVANCE, 1); 608 } 609 610 #if defined(CONFIG_DRM_AMD_DC_SI) 611 static void dce60_configure_encoder( 612 struct dce110_link_encoder *enc110, 613 const struct dc_link_settings *link_settings) 614 { 615 /* set number of lanes */ 616 617 REG_SET(DP_CONFIG, 0, 618 DP_UDI_LANES, link_settings->lane_count - LANE_COUNT_ONE); 619 620 /* DCE6 has no DP_DPHY_SCRAM_CNTL register, skip setup scrambler */ 621 } 622 #endif 623 624 static void aux_initialize( 625 struct dce110_link_encoder *enc110) 626 { 627 struct dc_context *ctx = enc110->base.ctx; 628 enum hpd_source_id hpd_source = enc110->base.hpd_source; 629 uint32_t addr = AUX_REG(AUX_CONTROL); 630 uint32_t value = dm_read_reg(ctx, addr); 631 632 set_reg_field_value(value, hpd_source, AUX_CONTROL, AUX_HPD_SEL); 633 set_reg_field_value(value, 0, AUX_CONTROL, AUX_LS_READ_EN); 634 dm_write_reg(ctx, addr, value); 635 636 addr = AUX_REG(AUX_DPHY_RX_CONTROL0); 637 value = dm_read_reg(ctx, addr); 638 639 /* 1/4 window (the maximum allowed) */ 640 set_reg_field_value(value, 1, 641 AUX_DPHY_RX_CONTROL0, AUX_RX_RECEIVE_WINDOW); 642 dm_write_reg(ctx, addr, value); 643 644 } 645 646 void dce110_psr_program_dp_dphy_fast_training(struct link_encoder *enc, 647 bool exit_link_training_required) 648 { 649 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 650 651 if (exit_link_training_required) 652 REG_UPDATE(DP_DPHY_FAST_TRAINING, 653 DPHY_RX_FAST_TRAINING_CAPABLE, 1); 654 else { 655 REG_UPDATE(DP_DPHY_FAST_TRAINING, 656 DPHY_RX_FAST_TRAINING_CAPABLE, 0); 657 /*In DCE 11, we are able to pre-program a Force SR register 658 * to be able to trigger SR symbol after 5 idle patterns 659 * transmitted. Upon PSR Exit, DMCU can trigger 660 * DPHY_LOAD_BS_COUNT_START = 1. Upon writing 1 to 661 * DPHY_LOAD_BS_COUNT_START and the internal counter 662 * reaches DPHY_LOAD_BS_COUNT, the next BS symbol will be 663 * replaced by SR symbol once. 664 */ 665 666 REG_UPDATE(DP_DPHY_BS_SR_SWAP_CNTL, DPHY_LOAD_BS_COUNT, 0x5); 667 } 668 } 669 670 void dce110_psr_program_secondary_packet(struct link_encoder *enc, 671 unsigned int sdp_transmit_line_num_deadline) 672 { 673 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 674 675 REG_UPDATE_2(DP_SEC_CNTL1, 676 DP_SEC_GSP0_LINE_NUM, sdp_transmit_line_num_deadline, 677 DP_SEC_GSP0_PRIORITY, 1); 678 } 679 680 bool dce110_is_dig_enabled(struct link_encoder *enc) 681 { 682 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 683 uint32_t value; 684 685 REG_GET(DIG_BE_EN_CNTL, DIG_ENABLE, &value); 686 return value; 687 } 688 689 static void link_encoder_disable(struct dce110_link_encoder *enc110) 690 { 691 /* reset training pattern */ 692 REG_SET(DP_DPHY_TRAINING_PATTERN_SEL, 0, 693 DPHY_TRAINING_PATTERN_SEL, 0); 694 695 /* reset training complete */ 696 REG_UPDATE(DP_LINK_CNTL, DP_LINK_TRAINING_COMPLETE, 0); 697 698 /* reset panel mode */ 699 setup_panel_mode(enc110, DP_PANEL_MODE_DEFAULT); 700 } 701 702 static void hpd_initialize( 703 struct dce110_link_encoder *enc110) 704 { 705 /* Associate HPD with DIG_BE */ 706 enum hpd_source_id hpd_source = enc110->base.hpd_source; 707 708 REG_UPDATE(DIG_BE_CNTL, DIG_HPD_SELECT, hpd_source); 709 } 710 711 bool dce110_link_encoder_validate_dvi_output( 712 const struct dce110_link_encoder *enc110, 713 enum signal_type connector_signal, 714 enum signal_type signal, 715 const struct dc_crtc_timing *crtc_timing) 716 { 717 uint32_t max_pixel_clock = TMDS_MAX_PIXEL_CLOCK; 718 719 if (signal == SIGNAL_TYPE_DVI_DUAL_LINK) 720 max_pixel_clock *= 2; 721 722 /* This handles the case of HDMI downgrade to DVI we don't want to 723 * we don't want to cap the pixel clock if the DDI is not DVI. 724 */ 725 if (connector_signal != SIGNAL_TYPE_DVI_DUAL_LINK && 726 connector_signal != SIGNAL_TYPE_DVI_SINGLE_LINK) 727 max_pixel_clock = enc110->base.features.max_hdmi_pixel_clock; 728 729 /* DVI only support RGB pixel encoding */ 730 if (crtc_timing->pixel_encoding != PIXEL_ENCODING_RGB) 731 return false; 732 733 /*connect DVI via adpater's HDMI connector*/ 734 if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK || 735 connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) && 736 signal != SIGNAL_TYPE_HDMI_TYPE_A && 737 crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10)) 738 return false; 739 if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10)) 740 return false; 741 742 if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10)) 743 return false; 744 745 /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */ 746 switch (crtc_timing->display_color_depth) { 747 case COLOR_DEPTH_666: 748 case COLOR_DEPTH_888: 749 break; 750 case COLOR_DEPTH_101010: 751 case COLOR_DEPTH_161616: 752 if (signal != SIGNAL_TYPE_DVI_DUAL_LINK) 753 return false; 754 break; 755 default: 756 return false; 757 } 758 759 return true; 760 } 761 762 static bool dce110_link_encoder_validate_hdmi_output( 763 const struct dce110_link_encoder *enc110, 764 const struct dc_crtc_timing *crtc_timing, 765 int adjusted_pix_clk_khz) 766 { 767 enum dc_color_depth max_deep_color = 768 enc110->base.features.max_hdmi_deep_color; 769 770 if (max_deep_color < crtc_timing->display_color_depth) 771 return false; 772 773 if (crtc_timing->display_color_depth < COLOR_DEPTH_888) 774 return false; 775 if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK) 776 return false; 777 778 if ((adjusted_pix_clk_khz == 0) || 779 (adjusted_pix_clk_khz > enc110->base.features.max_hdmi_pixel_clock)) 780 return false; 781 782 /* DCE11 HW does not support 420 */ 783 if (!enc110->base.features.hdmi_ycbcr420_supported && 784 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) 785 return false; 786 787 if ((!enc110->base.features.flags.bits.HDMI_6GB_EN || 788 enc110->base.ctx->dc->debug.hdmi20_disable) && 789 adjusted_pix_clk_khz >= 300000) 790 return false; 791 if (enc110->base.ctx->dc->debug.hdmi20_disable && 792 crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) 793 return false; 794 return true; 795 } 796 797 bool dce110_link_encoder_validate_dp_output( 798 const struct dce110_link_encoder *enc110, 799 const struct dc_crtc_timing *crtc_timing) 800 { 801 if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) 802 return false; 803 804 return true; 805 } 806 807 void dce110_link_encoder_construct( 808 struct dce110_link_encoder *enc110, 809 const struct encoder_init_data *init_data, 810 const struct encoder_feature_support *enc_features, 811 const struct dce110_link_enc_registers *link_regs, 812 const struct dce110_link_enc_aux_registers *aux_regs, 813 const struct dce110_link_enc_hpd_registers *hpd_regs) 814 { 815 struct bp_encoder_cap_info bp_cap_info = {0}; 816 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; 817 enum bp_result result = BP_RESULT_OK; 818 819 enc110->base.funcs = &dce110_lnk_enc_funcs; 820 enc110->base.ctx = init_data->ctx; 821 enc110->base.id = init_data->encoder; 822 823 enc110->base.hpd_source = init_data->hpd_source; 824 enc110->base.connector = init_data->connector; 825 826 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; 827 828 enc110->base.features = *enc_features; 829 830 enc110->base.transmitter = init_data->transmitter; 831 832 /* set the flag to indicate whether driver poll the I2C data pin 833 * while doing the DP sink detect 834 */ 835 836 /* if (dal_adapter_service_is_feature_supported(as, 837 FEATURE_DP_SINK_DETECT_POLL_DATA_PIN)) 838 enc110->base.features.flags.bits. 839 DP_SINK_DETECT_POLL_DATA_PIN = true;*/ 840 841 enc110->base.output_signals = 842 SIGNAL_TYPE_DVI_SINGLE_LINK | 843 SIGNAL_TYPE_DVI_DUAL_LINK | 844 SIGNAL_TYPE_LVDS | 845 SIGNAL_TYPE_DISPLAY_PORT | 846 SIGNAL_TYPE_DISPLAY_PORT_MST | 847 SIGNAL_TYPE_EDP | 848 SIGNAL_TYPE_HDMI_TYPE_A; 849 850 /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. 851 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. 852 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer 853 * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. 854 * Prefer DIG assignment is decided by board design. 855 * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design 856 * and VBIOS will filter out 7 UNIPHY for DCE 8.0. 857 * By this, adding DIGG should not hurt DCE 8.0. 858 * This will let DCE 8.1 share DCE 8.0 as much as possible 859 */ 860 861 enc110->link_regs = link_regs; 862 enc110->aux_regs = aux_regs; 863 enc110->hpd_regs = hpd_regs; 864 865 switch (enc110->base.transmitter) { 866 case TRANSMITTER_UNIPHY_A: 867 enc110->base.preferred_engine = ENGINE_ID_DIGA; 868 break; 869 case TRANSMITTER_UNIPHY_B: 870 enc110->base.preferred_engine = ENGINE_ID_DIGB; 871 break; 872 case TRANSMITTER_UNIPHY_C: 873 enc110->base.preferred_engine = ENGINE_ID_DIGC; 874 break; 875 case TRANSMITTER_UNIPHY_D: 876 enc110->base.preferred_engine = ENGINE_ID_DIGD; 877 break; 878 case TRANSMITTER_UNIPHY_E: 879 enc110->base.preferred_engine = ENGINE_ID_DIGE; 880 break; 881 case TRANSMITTER_UNIPHY_F: 882 enc110->base.preferred_engine = ENGINE_ID_DIGF; 883 break; 884 case TRANSMITTER_UNIPHY_G: 885 enc110->base.preferred_engine = ENGINE_ID_DIGG; 886 break; 887 default: 888 ASSERT_CRITICAL(false); 889 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; 890 } 891 892 /* default to one to mirror Windows behavior */ 893 enc110->base.features.flags.bits.HDMI_6GB_EN = 1; 894 895 result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, 896 enc110->base.id, &bp_cap_info); 897 898 /* Override features with DCE-specific values */ 899 if (BP_RESULT_OK == result) { 900 enc110->base.features.flags.bits.IS_HBR2_CAPABLE = 901 bp_cap_info.DP_HBR2_EN; 902 enc110->base.features.flags.bits.IS_HBR3_CAPABLE = 903 bp_cap_info.DP_HBR3_EN; 904 enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; 905 } else { 906 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", 907 __func__, 908 result); 909 } 910 if (enc110->base.ctx->dc->debug.hdmi20_disable) { 911 enc110->base.features.flags.bits.HDMI_6GB_EN = 0; 912 } 913 } 914 915 bool dce110_link_encoder_validate_output_with_stream( 916 struct link_encoder *enc, 917 const struct dc_stream_state *stream) 918 { 919 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 920 bool is_valid; 921 922 switch (stream->signal) { 923 case SIGNAL_TYPE_DVI_SINGLE_LINK: 924 case SIGNAL_TYPE_DVI_DUAL_LINK: 925 is_valid = dce110_link_encoder_validate_dvi_output( 926 enc110, 927 stream->link->connector_signal, 928 stream->signal, 929 &stream->timing); 930 break; 931 case SIGNAL_TYPE_HDMI_TYPE_A: 932 is_valid = dce110_link_encoder_validate_hdmi_output( 933 enc110, 934 &stream->timing, 935 stream->phy_pix_clk); 936 break; 937 case SIGNAL_TYPE_DISPLAY_PORT: 938 case SIGNAL_TYPE_DISPLAY_PORT_MST: 939 is_valid = dce110_link_encoder_validate_dp_output( 940 enc110, &stream->timing); 941 break; 942 case SIGNAL_TYPE_EDP: 943 case SIGNAL_TYPE_LVDS: 944 is_valid = 945 (stream->timing. 946 pixel_encoding == PIXEL_ENCODING_RGB) ? true : false; 947 break; 948 case SIGNAL_TYPE_VIRTUAL: 949 is_valid = true; 950 break; 951 default: 952 is_valid = false; 953 break; 954 } 955 956 return is_valid; 957 } 958 959 void dce110_link_encoder_hw_init( 960 struct link_encoder *enc) 961 { 962 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 963 struct bp_transmitter_control cntl = { 0 }; 964 enum bp_result result; 965 966 cntl.action = TRANSMITTER_CONTROL_INIT; 967 cntl.engine_id = ENGINE_ID_UNKNOWN; 968 cntl.transmitter = enc110->base.transmitter; 969 cntl.connector_obj_id = enc110->base.connector; 970 cntl.lanes_number = LANE_COUNT_FOUR; 971 cntl.coherent = false; 972 cntl.hpd_sel = enc110->base.hpd_source; 973 974 if (enc110->base.connector.id == CONNECTOR_ID_EDP) 975 cntl.signal = SIGNAL_TYPE_EDP; 976 977 result = link_transmitter_control(enc110, &cntl); 978 979 if (result != BP_RESULT_OK) { 980 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 981 __func__); 982 BREAK_TO_DEBUGGER(); 983 return; 984 } 985 986 if (enc110->base.connector.id == CONNECTOR_ID_LVDS) { 987 cntl.action = TRANSMITTER_CONTROL_BACKLIGHT_BRIGHTNESS; 988 989 result = link_transmitter_control(enc110, &cntl); 990 991 ASSERT(result == BP_RESULT_OK); 992 993 } 994 aux_initialize(enc110); 995 996 /* reinitialize HPD. 997 * hpd_initialize() will pass DIG_FE id to HW context. 998 * All other routine within HW context will use fe_engine_offset 999 * as DIG_FE id even caller pass DIG_FE id. 1000 * So this routine must be called first. */ 1001 hpd_initialize(enc110); 1002 } 1003 1004 void dce110_link_encoder_destroy(struct link_encoder **enc) 1005 { 1006 kfree(TO_DCE110_LINK_ENC(*enc)); 1007 *enc = NULL; 1008 } 1009 1010 void dce110_link_encoder_setup( 1011 struct link_encoder *enc, 1012 enum signal_type signal) 1013 { 1014 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1015 1016 switch (signal) { 1017 case SIGNAL_TYPE_EDP: 1018 case SIGNAL_TYPE_DISPLAY_PORT: 1019 /* DP SST */ 1020 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 0); 1021 break; 1022 case SIGNAL_TYPE_LVDS: 1023 /* LVDS */ 1024 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 1); 1025 break; 1026 case SIGNAL_TYPE_DVI_SINGLE_LINK: 1027 case SIGNAL_TYPE_DVI_DUAL_LINK: 1028 /* TMDS-DVI */ 1029 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 2); 1030 break; 1031 case SIGNAL_TYPE_HDMI_TYPE_A: 1032 /* TMDS-HDMI */ 1033 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 3); 1034 break; 1035 case SIGNAL_TYPE_DISPLAY_PORT_MST: 1036 /* DP MST */ 1037 REG_UPDATE(DIG_BE_CNTL, DIG_MODE, 5); 1038 break; 1039 default: 1040 ASSERT_CRITICAL(false); 1041 /* invalid mode ! */ 1042 break; 1043 } 1044 1045 } 1046 1047 /* TODO: still need depth or just pass in adjusted pixel clock? */ 1048 void dce110_link_encoder_enable_tmds_output( 1049 struct link_encoder *enc, 1050 enum clock_source_id clock_source, 1051 enum dc_color_depth color_depth, 1052 enum signal_type signal, 1053 uint32_t pixel_clock) 1054 { 1055 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1056 struct bp_transmitter_control cntl = { 0 }; 1057 enum bp_result result; 1058 1059 /* Enable the PHY */ 1060 cntl.connector_obj_id = enc110->base.connector; 1061 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1062 cntl.engine_id = enc->preferred_engine; 1063 cntl.transmitter = enc110->base.transmitter; 1064 cntl.pll_id = clock_source; 1065 cntl.signal = signal; 1066 if (cntl.signal == SIGNAL_TYPE_DVI_DUAL_LINK) 1067 cntl.lanes_number = 8; 1068 else 1069 cntl.lanes_number = 4; 1070 1071 cntl.hpd_sel = enc110->base.hpd_source; 1072 1073 cntl.pixel_clock = pixel_clock; 1074 cntl.color_depth = color_depth; 1075 1076 result = link_transmitter_control(enc110, &cntl); 1077 1078 if (result != BP_RESULT_OK) { 1079 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1080 __func__); 1081 BREAK_TO_DEBUGGER(); 1082 } 1083 } 1084 1085 /* TODO: still need depth or just pass in adjusted pixel clock? */ 1086 void dce110_link_encoder_enable_lvds_output( 1087 struct link_encoder *enc, 1088 enum clock_source_id clock_source, 1089 uint32_t pixel_clock) 1090 { 1091 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1092 struct bp_transmitter_control cntl = { 0 }; 1093 enum bp_result result; 1094 1095 /* Enable the PHY */ 1096 cntl.connector_obj_id = enc110->base.connector; 1097 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1098 cntl.engine_id = enc->preferred_engine; 1099 cntl.transmitter = enc110->base.transmitter; 1100 cntl.pll_id = clock_source; 1101 cntl.signal = SIGNAL_TYPE_LVDS; 1102 cntl.lanes_number = 4; 1103 1104 cntl.hpd_sel = enc110->base.hpd_source; 1105 1106 cntl.pixel_clock = pixel_clock; 1107 1108 result = link_transmitter_control(enc110, &cntl); 1109 1110 if (result != BP_RESULT_OK) { 1111 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1112 __func__); 1113 BREAK_TO_DEBUGGER(); 1114 } 1115 } 1116 1117 /* enables DP PHY output */ 1118 void dce110_link_encoder_enable_dp_output( 1119 struct link_encoder *enc, 1120 const struct dc_link_settings *link_settings, 1121 enum clock_source_id clock_source) 1122 { 1123 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1124 struct bp_transmitter_control cntl = { 0 }; 1125 enum bp_result result; 1126 1127 /* Enable the PHY */ 1128 1129 /* number_of_lanes is used for pixel clock adjust, 1130 * but it's not passed to asic_control. 1131 * We need to set number of lanes manually. 1132 */ 1133 configure_encoder(enc110, link_settings); 1134 cntl.connector_obj_id = enc110->base.connector; 1135 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1136 cntl.engine_id = enc->preferred_engine; 1137 cntl.transmitter = enc110->base.transmitter; 1138 cntl.pll_id = clock_source; 1139 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT; 1140 cntl.lanes_number = link_settings->lane_count; 1141 cntl.hpd_sel = enc110->base.hpd_source; 1142 cntl.pixel_clock = link_settings->link_rate 1143 * LINK_RATE_REF_FREQ_IN_KHZ; 1144 /* TODO: check if undefined works */ 1145 cntl.color_depth = COLOR_DEPTH_UNDEFINED; 1146 1147 result = link_transmitter_control(enc110, &cntl); 1148 1149 if (result != BP_RESULT_OK) { 1150 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1151 __func__); 1152 BREAK_TO_DEBUGGER(); 1153 } 1154 } 1155 1156 /* enables DP PHY output in MST mode */ 1157 void dce110_link_encoder_enable_dp_mst_output( 1158 struct link_encoder *enc, 1159 const struct dc_link_settings *link_settings, 1160 enum clock_source_id clock_source) 1161 { 1162 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1163 struct bp_transmitter_control cntl = { 0 }; 1164 enum bp_result result; 1165 1166 /* Enable the PHY */ 1167 1168 /* number_of_lanes is used for pixel clock adjust, 1169 * but it's not passed to asic_control. 1170 * We need to set number of lanes manually. 1171 */ 1172 configure_encoder(enc110, link_settings); 1173 1174 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1175 cntl.engine_id = ENGINE_ID_UNKNOWN; 1176 cntl.transmitter = enc110->base.transmitter; 1177 cntl.pll_id = clock_source; 1178 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST; 1179 cntl.lanes_number = link_settings->lane_count; 1180 cntl.hpd_sel = enc110->base.hpd_source; 1181 cntl.pixel_clock = link_settings->link_rate 1182 * LINK_RATE_REF_FREQ_IN_KHZ; 1183 /* TODO: check if undefined works */ 1184 cntl.color_depth = COLOR_DEPTH_UNDEFINED; 1185 1186 result = link_transmitter_control(enc110, &cntl); 1187 1188 if (result != BP_RESULT_OK) { 1189 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1190 __func__); 1191 BREAK_TO_DEBUGGER(); 1192 } 1193 } 1194 1195 #if defined(CONFIG_DRM_AMD_DC_SI) 1196 /* enables DP PHY output */ 1197 static void dce60_link_encoder_enable_dp_output( 1198 struct link_encoder *enc, 1199 const struct dc_link_settings *link_settings, 1200 enum clock_source_id clock_source) 1201 { 1202 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1203 struct bp_transmitter_control cntl = { 0 }; 1204 enum bp_result result; 1205 1206 /* Enable the PHY */ 1207 1208 /* number_of_lanes is used for pixel clock adjust, 1209 * but it's not passed to asic_control. 1210 * We need to set number of lanes manually. 1211 */ 1212 dce60_configure_encoder(enc110, link_settings); 1213 cntl.connector_obj_id = enc110->base.connector; 1214 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1215 cntl.engine_id = enc->preferred_engine; 1216 cntl.transmitter = enc110->base.transmitter; 1217 cntl.pll_id = clock_source; 1218 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT; 1219 cntl.lanes_number = link_settings->lane_count; 1220 cntl.hpd_sel = enc110->base.hpd_source; 1221 cntl.pixel_clock = link_settings->link_rate 1222 * LINK_RATE_REF_FREQ_IN_KHZ; 1223 /* TODO: check if undefined works */ 1224 cntl.color_depth = COLOR_DEPTH_UNDEFINED; 1225 1226 result = link_transmitter_control(enc110, &cntl); 1227 1228 if (result != BP_RESULT_OK) { 1229 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1230 __func__); 1231 BREAK_TO_DEBUGGER(); 1232 } 1233 } 1234 1235 /* enables DP PHY output in MST mode */ 1236 static void dce60_link_encoder_enable_dp_mst_output( 1237 struct link_encoder *enc, 1238 const struct dc_link_settings *link_settings, 1239 enum clock_source_id clock_source) 1240 { 1241 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1242 struct bp_transmitter_control cntl = { 0 }; 1243 enum bp_result result; 1244 1245 /* Enable the PHY */ 1246 1247 /* number_of_lanes is used for pixel clock adjust, 1248 * but it's not passed to asic_control. 1249 * We need to set number of lanes manually. 1250 */ 1251 dce60_configure_encoder(enc110, link_settings); 1252 1253 cntl.action = TRANSMITTER_CONTROL_ENABLE; 1254 cntl.engine_id = ENGINE_ID_UNKNOWN; 1255 cntl.transmitter = enc110->base.transmitter; 1256 cntl.pll_id = clock_source; 1257 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST; 1258 cntl.lanes_number = link_settings->lane_count; 1259 cntl.hpd_sel = enc110->base.hpd_source; 1260 cntl.pixel_clock = link_settings->link_rate 1261 * LINK_RATE_REF_FREQ_IN_KHZ; 1262 /* TODO: check if undefined works */ 1263 cntl.color_depth = COLOR_DEPTH_UNDEFINED; 1264 1265 result = link_transmitter_control(enc110, &cntl); 1266 1267 if (result != BP_RESULT_OK) { 1268 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1269 __func__); 1270 BREAK_TO_DEBUGGER(); 1271 } 1272 } 1273 #endif 1274 1275 /* 1276 * @brief 1277 * Disable transmitter and its encoder 1278 */ 1279 void dce110_link_encoder_disable_output( 1280 struct link_encoder *enc, 1281 enum signal_type signal) 1282 { 1283 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1284 struct bp_transmitter_control cntl = { 0 }; 1285 enum bp_result result; 1286 1287 if (!dce110_is_dig_enabled(enc)) { 1288 /* OF_SKIP_POWER_DOWN_INACTIVE_ENCODER */ 1289 return; 1290 } 1291 /* Power-down RX and disable GPU PHY should be paired. 1292 * Disabling PHY without powering down RX may cause 1293 * symbol lock loss, on which we will get DP Sink interrupt. */ 1294 1295 /* There is a case for the DP active dongles 1296 * where we want to disable the PHY but keep RX powered, 1297 * for those we need to ignore DP Sink interrupt 1298 * by checking lane count that has been set 1299 * on the last do_enable_output(). */ 1300 1301 /* disable transmitter */ 1302 cntl.action = TRANSMITTER_CONTROL_DISABLE; 1303 cntl.transmitter = enc110->base.transmitter; 1304 cntl.hpd_sel = enc110->base.hpd_source; 1305 cntl.signal = signal; 1306 cntl.connector_obj_id = enc110->base.connector; 1307 1308 result = link_transmitter_control(enc110, &cntl); 1309 1310 if (result != BP_RESULT_OK) { 1311 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 1312 __func__); 1313 BREAK_TO_DEBUGGER(); 1314 return; 1315 } 1316 1317 /* disable encoder */ 1318 if (dc_is_dp_signal(signal)) 1319 link_encoder_disable(enc110); 1320 } 1321 1322 void dce110_link_encoder_dp_set_lane_settings( 1323 struct link_encoder *enc, 1324 const struct dc_link_settings *link_settings, 1325 const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) 1326 { 1327 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1328 union dpcd_training_lane_set training_lane_set = { { 0 } }; 1329 int32_t lane = 0; 1330 struct bp_transmitter_control cntl = { 0 }; 1331 1332 if (!link_settings) { 1333 BREAK_TO_DEBUGGER(); 1334 return; 1335 } 1336 1337 cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS; 1338 cntl.transmitter = enc110->base.transmitter; 1339 cntl.connector_obj_id = enc110->base.connector; 1340 cntl.lanes_number = link_settings->lane_count; 1341 cntl.hpd_sel = enc110->base.hpd_source; 1342 cntl.pixel_clock = link_settings->link_rate * 1343 LINK_RATE_REF_FREQ_IN_KHZ; 1344 1345 for (lane = 0; lane < link_settings->lane_count; lane++) { 1346 /* translate lane settings */ 1347 1348 training_lane_set.bits.VOLTAGE_SWING_SET = 1349 lane_settings[lane].VOLTAGE_SWING; 1350 training_lane_set.bits.PRE_EMPHASIS_SET = 1351 lane_settings[lane].PRE_EMPHASIS; 1352 1353 /* post cursor 2 setting only applies to HBR2 link rate */ 1354 if (link_settings->link_rate == LINK_RATE_HIGH2) { 1355 /* this is passed to VBIOS 1356 * to program post cursor 2 level */ 1357 1358 training_lane_set.bits.POST_CURSOR2_SET = 1359 lane_settings[lane].POST_CURSOR2; 1360 } 1361 1362 cntl.lane_select = lane; 1363 cntl.lane_settings = training_lane_set.raw; 1364 1365 /* call VBIOS table to set voltage swing and pre-emphasis */ 1366 link_transmitter_control(enc110, &cntl); 1367 } 1368 } 1369 1370 /* set DP PHY test and training patterns */ 1371 void dce110_link_encoder_dp_set_phy_pattern( 1372 struct link_encoder *enc, 1373 const struct encoder_set_dp_phy_pattern_param *param) 1374 { 1375 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1376 1377 switch (param->dp_phy_pattern) { 1378 case DP_TEST_PATTERN_TRAINING_PATTERN1: 1379 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0); 1380 break; 1381 case DP_TEST_PATTERN_TRAINING_PATTERN2: 1382 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1); 1383 break; 1384 case DP_TEST_PATTERN_TRAINING_PATTERN3: 1385 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2); 1386 break; 1387 case DP_TEST_PATTERN_TRAINING_PATTERN4: 1388 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3); 1389 break; 1390 case DP_TEST_PATTERN_D102: 1391 set_dp_phy_pattern_d102(enc110); 1392 break; 1393 case DP_TEST_PATTERN_SYMBOL_ERROR: 1394 set_dp_phy_pattern_symbol_error(enc110); 1395 break; 1396 case DP_TEST_PATTERN_PRBS7: 1397 set_dp_phy_pattern_prbs7(enc110); 1398 break; 1399 case DP_TEST_PATTERN_80BIT_CUSTOM: 1400 set_dp_phy_pattern_80bit_custom( 1401 enc110, param->custom_pattern); 1402 break; 1403 case DP_TEST_PATTERN_CP2520_1: 1404 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 1); 1405 break; 1406 case DP_TEST_PATTERN_CP2520_2: 1407 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 2); 1408 break; 1409 case DP_TEST_PATTERN_CP2520_3: 1410 set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 3); 1411 break; 1412 case DP_TEST_PATTERN_VIDEO_MODE: { 1413 set_dp_phy_pattern_passthrough_mode( 1414 enc110, param->dp_panel_mode); 1415 break; 1416 } 1417 1418 default: 1419 /* invalid phy pattern */ 1420 ASSERT_CRITICAL(false); 1421 break; 1422 } 1423 } 1424 1425 #if defined(CONFIG_DRM_AMD_DC_SI) 1426 /* set DP PHY test and training patterns */ 1427 static void dce60_link_encoder_dp_set_phy_pattern( 1428 struct link_encoder *enc, 1429 const struct encoder_set_dp_phy_pattern_param *param) 1430 { 1431 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1432 1433 switch (param->dp_phy_pattern) { 1434 case DP_TEST_PATTERN_TRAINING_PATTERN1: 1435 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 0); 1436 break; 1437 case DP_TEST_PATTERN_TRAINING_PATTERN2: 1438 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 1); 1439 break; 1440 case DP_TEST_PATTERN_TRAINING_PATTERN3: 1441 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 2); 1442 break; 1443 case DP_TEST_PATTERN_TRAINING_PATTERN4: 1444 dce110_link_encoder_set_dp_phy_pattern_training_pattern(enc, 3); 1445 break; 1446 case DP_TEST_PATTERN_D102: 1447 set_dp_phy_pattern_d102(enc110); 1448 break; 1449 case DP_TEST_PATTERN_SYMBOL_ERROR: 1450 set_dp_phy_pattern_symbol_error(enc110); 1451 break; 1452 case DP_TEST_PATTERN_PRBS7: 1453 set_dp_phy_pattern_prbs7(enc110); 1454 break; 1455 case DP_TEST_PATTERN_80BIT_CUSTOM: 1456 set_dp_phy_pattern_80bit_custom( 1457 enc110, param->custom_pattern); 1458 break; 1459 case DP_TEST_PATTERN_CP2520_1: 1460 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 1); 1461 break; 1462 case DP_TEST_PATTERN_CP2520_2: 1463 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 2); 1464 break; 1465 case DP_TEST_PATTERN_CP2520_3: 1466 dce60_set_dp_phy_pattern_hbr2_compliance_cp2520_2(enc110, 3); 1467 break; 1468 case DP_TEST_PATTERN_VIDEO_MODE: { 1469 dce60_set_dp_phy_pattern_passthrough_mode( 1470 enc110, param->dp_panel_mode); 1471 break; 1472 } 1473 1474 default: 1475 /* invalid phy pattern */ 1476 ASSERT_CRITICAL(false); 1477 break; 1478 } 1479 } 1480 #endif 1481 1482 static void fill_stream_allocation_row_info( 1483 const struct link_mst_stream_allocation *stream_allocation, 1484 uint32_t *src, 1485 uint32_t *slots) 1486 { 1487 const struct stream_encoder *stream_enc = stream_allocation->stream_enc; 1488 1489 if (stream_enc) { 1490 *src = stream_enc->id; 1491 *slots = stream_allocation->slot_count; 1492 } else { 1493 *src = 0; 1494 *slots = 0; 1495 } 1496 } 1497 1498 /* programs DP MST VC payload allocation */ 1499 void dce110_link_encoder_update_mst_stream_allocation_table( 1500 struct link_encoder *enc, 1501 const struct link_mst_stream_allocation_table *table) 1502 { 1503 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1504 uint32_t value1 = 0; 1505 uint32_t value2 = 0; 1506 uint32_t slots = 0; 1507 uint32_t src = 0; 1508 uint32_t retries = 0; 1509 1510 /* For CZ, there are only 3 pipes. So Virtual channel is up 3.*/ 1511 1512 /* --- Set MSE Stream Attribute - 1513 * Setup VC Payload Table on Tx Side, 1514 * Issue allocation change trigger 1515 * to commit payload on both tx and rx side */ 1516 1517 /* we should clean-up table each time */ 1518 1519 if (table->stream_count >= 1) { 1520 fill_stream_allocation_row_info( 1521 &table->stream_allocations[0], 1522 &src, 1523 &slots); 1524 } else { 1525 src = 0; 1526 slots = 0; 1527 } 1528 1529 REG_UPDATE_2(DP_MSE_SAT0, 1530 DP_MSE_SAT_SRC0, src, 1531 DP_MSE_SAT_SLOT_COUNT0, slots); 1532 1533 if (table->stream_count >= 2) { 1534 fill_stream_allocation_row_info( 1535 &table->stream_allocations[1], 1536 &src, 1537 &slots); 1538 } else { 1539 src = 0; 1540 slots = 0; 1541 } 1542 1543 REG_UPDATE_2(DP_MSE_SAT0, 1544 DP_MSE_SAT_SRC1, src, 1545 DP_MSE_SAT_SLOT_COUNT1, slots); 1546 1547 if (table->stream_count >= 3) { 1548 fill_stream_allocation_row_info( 1549 &table->stream_allocations[2], 1550 &src, 1551 &slots); 1552 } else { 1553 src = 0; 1554 slots = 0; 1555 } 1556 1557 REG_UPDATE_2(DP_MSE_SAT1, 1558 DP_MSE_SAT_SRC2, src, 1559 DP_MSE_SAT_SLOT_COUNT2, slots); 1560 1561 if (table->stream_count >= 4) { 1562 fill_stream_allocation_row_info( 1563 &table->stream_allocations[3], 1564 &src, 1565 &slots); 1566 } else { 1567 src = 0; 1568 slots = 0; 1569 } 1570 1571 REG_UPDATE_2(DP_MSE_SAT1, 1572 DP_MSE_SAT_SRC3, src, 1573 DP_MSE_SAT_SLOT_COUNT3, slots); 1574 1575 /* --- wait for transaction finish */ 1576 1577 /* send allocation change trigger (ACT) ? 1578 * this step first sends the ACT, 1579 * then double buffers the SAT into the hardware 1580 * making the new allocation active on the DP MST mode link */ 1581 1582 1583 /* DP_MSE_SAT_UPDATE: 1584 * 0 - No Action 1585 * 1 - Update SAT with trigger 1586 * 2 - Update SAT without trigger */ 1587 1588 REG_UPDATE(DP_MSE_SAT_UPDATE, 1589 DP_MSE_SAT_UPDATE, 1); 1590 1591 /* wait for update to complete 1592 * (i.e. DP_MSE_SAT_UPDATE field is reset to 0) 1593 * then wait for the transmission 1594 * of at least 16 MTP headers on immediate local link. 1595 * i.e. DP_MSE_16_MTP_KEEPOUT field (read only) is reset to 0 1596 * a value of 1 indicates that DP MST mode 1597 * is in the 16 MTP keepout region after a VC has been added. 1598 * MST stream bandwidth (VC rate) can be configured 1599 * after this bit is cleared */ 1600 1601 do { 1602 udelay(10); 1603 1604 REG_READ(DP_MSE_SAT_UPDATE); 1605 1606 REG_GET(DP_MSE_SAT_UPDATE, 1607 DP_MSE_SAT_UPDATE, &value1); 1608 1609 REG_GET(DP_MSE_SAT_UPDATE, 1610 DP_MSE_16_MTP_KEEPOUT, &value2); 1611 1612 /* bit field DP_MSE_SAT_UPDATE is set to 1 already */ 1613 if (!value1 && !value2) 1614 break; 1615 ++retries; 1616 } while (retries < DP_MST_UPDATE_MAX_RETRY); 1617 } 1618 1619 void dce110_link_encoder_connect_dig_be_to_fe( 1620 struct link_encoder *enc, 1621 enum engine_id engine, 1622 bool connect) 1623 { 1624 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1625 uint32_t field; 1626 1627 if (engine != ENGINE_ID_UNKNOWN) { 1628 1629 REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &field); 1630 1631 if (connect) 1632 field |= get_frontend_source(engine); 1633 else 1634 field &= ~get_frontend_source(engine); 1635 1636 REG_UPDATE(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, field); 1637 } 1638 } 1639 1640 void dce110_link_encoder_enable_hpd(struct link_encoder *enc) 1641 { 1642 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1643 struct dc_context *ctx = enc110->base.ctx; 1644 uint32_t addr = HPD_REG(DC_HPD_CONTROL); 1645 uint32_t hpd_enable = 0; 1646 uint32_t value = dm_read_reg(ctx, addr); 1647 1648 get_reg_field_value(hpd_enable, DC_HPD_CONTROL, DC_HPD_EN); 1649 1650 if (hpd_enable == 0) 1651 set_reg_field_value(value, 1, DC_HPD_CONTROL, DC_HPD_EN); 1652 } 1653 1654 void dce110_link_encoder_disable_hpd(struct link_encoder *enc) 1655 { 1656 struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); 1657 struct dc_context *ctx = enc110->base.ctx; 1658 uint32_t addr = HPD_REG(DC_HPD_CONTROL); 1659 uint32_t value = dm_read_reg(ctx, addr); 1660 1661 set_reg_field_value(value, 0, DC_HPD_CONTROL, DC_HPD_EN); 1662 } 1663 1664 void dce110_link_encoder_get_max_link_cap(struct link_encoder *enc, 1665 struct dc_link_settings *link_settings) 1666 { 1667 /* Set Default link settings */ 1668 struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH, 1669 LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0}; 1670 1671 /* Higher link settings based on feature supported */ 1672 if (enc->features.flags.bits.IS_HBR2_CAPABLE) 1673 max_link_cap.link_rate = LINK_RATE_HIGH2; 1674 1675 if (enc->features.flags.bits.IS_HBR3_CAPABLE) 1676 max_link_cap.link_rate = LINK_RATE_HIGH3; 1677 1678 *link_settings = max_link_cap; 1679 } 1680 1681 #if defined(CONFIG_DRM_AMD_DC_SI) 1682 static const struct link_encoder_funcs dce60_lnk_enc_funcs = { 1683 .validate_output_with_stream = 1684 dce110_link_encoder_validate_output_with_stream, 1685 .hw_init = dce110_link_encoder_hw_init, 1686 .setup = dce110_link_encoder_setup, 1687 .enable_tmds_output = dce110_link_encoder_enable_tmds_output, 1688 .enable_dp_output = dce60_link_encoder_enable_dp_output, 1689 .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output, 1690 .enable_lvds_output = dce110_link_encoder_enable_lvds_output, 1691 .disable_output = dce110_link_encoder_disable_output, 1692 .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, 1693 .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern, 1694 .update_mst_stream_allocation_table = 1695 dce110_link_encoder_update_mst_stream_allocation_table, 1696 .psr_program_dp_dphy_fast_training = 1697 dce110_psr_program_dp_dphy_fast_training, 1698 .psr_program_secondary_packet = dce110_psr_program_secondary_packet, 1699 .connect_dig_be_to_fe = dce110_link_encoder_connect_dig_be_to_fe, 1700 .enable_hpd = dce110_link_encoder_enable_hpd, 1701 .disable_hpd = dce110_link_encoder_disable_hpd, 1702 .is_dig_enabled = dce110_is_dig_enabled, 1703 .destroy = dce110_link_encoder_destroy, 1704 .get_max_link_cap = dce110_link_encoder_get_max_link_cap, 1705 .get_dig_frontend = dce110_get_dig_frontend 1706 }; 1707 1708 void dce60_link_encoder_construct( 1709 struct dce110_link_encoder *enc110, 1710 const struct encoder_init_data *init_data, 1711 const struct encoder_feature_support *enc_features, 1712 const struct dce110_link_enc_registers *link_regs, 1713 const struct dce110_link_enc_aux_registers *aux_regs, 1714 const struct dce110_link_enc_hpd_registers *hpd_regs) 1715 { 1716 struct bp_encoder_cap_info bp_cap_info = {0}; 1717 const struct dc_vbios_funcs *bp_funcs = init_data->ctx->dc_bios->funcs; 1718 enum bp_result result = BP_RESULT_OK; 1719 1720 enc110->base.funcs = &dce60_lnk_enc_funcs; 1721 enc110->base.ctx = init_data->ctx; 1722 enc110->base.id = init_data->encoder; 1723 1724 enc110->base.hpd_source = init_data->hpd_source; 1725 enc110->base.connector = init_data->connector; 1726 1727 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; 1728 1729 enc110->base.features = *enc_features; 1730 1731 enc110->base.transmitter = init_data->transmitter; 1732 1733 /* set the flag to indicate whether driver poll the I2C data pin 1734 * while doing the DP sink detect 1735 */ 1736 1737 /* if (dal_adapter_service_is_feature_supported(as, 1738 FEATURE_DP_SINK_DETECT_POLL_DATA_PIN)) 1739 enc110->base.features.flags.bits. 1740 DP_SINK_DETECT_POLL_DATA_PIN = true;*/ 1741 1742 enc110->base.output_signals = 1743 SIGNAL_TYPE_DVI_SINGLE_LINK | 1744 SIGNAL_TYPE_DVI_DUAL_LINK | 1745 SIGNAL_TYPE_LVDS | 1746 SIGNAL_TYPE_DISPLAY_PORT | 1747 SIGNAL_TYPE_DISPLAY_PORT_MST | 1748 SIGNAL_TYPE_EDP | 1749 SIGNAL_TYPE_HDMI_TYPE_A; 1750 1751 /* For DCE 8.0 and 8.1, by design, UNIPHY is hardwired to DIG_BE. 1752 * SW always assign DIG_FE 1:1 mapped to DIG_FE for non-MST UNIPHY. 1753 * SW assign DIG_FE to non-MST UNIPHY first and MST last. So prefer 1754 * DIG is per UNIPHY and used by SST DP, eDP, HDMI, DVI and LVDS. 1755 * Prefer DIG assignment is decided by board design. 1756 * For DCE 8.0, there are only max 6 UNIPHYs, we assume board design 1757 * and VBIOS will filter out 7 UNIPHY for DCE 8.0. 1758 * By this, adding DIGG should not hurt DCE 8.0. 1759 * This will let DCE 8.1 share DCE 8.0 as much as possible 1760 */ 1761 1762 enc110->link_regs = link_regs; 1763 enc110->aux_regs = aux_regs; 1764 enc110->hpd_regs = hpd_regs; 1765 1766 switch (enc110->base.transmitter) { 1767 case TRANSMITTER_UNIPHY_A: 1768 enc110->base.preferred_engine = ENGINE_ID_DIGA; 1769 break; 1770 case TRANSMITTER_UNIPHY_B: 1771 enc110->base.preferred_engine = ENGINE_ID_DIGB; 1772 break; 1773 case TRANSMITTER_UNIPHY_C: 1774 enc110->base.preferred_engine = ENGINE_ID_DIGC; 1775 break; 1776 case TRANSMITTER_UNIPHY_D: 1777 enc110->base.preferred_engine = ENGINE_ID_DIGD; 1778 break; 1779 case TRANSMITTER_UNIPHY_E: 1780 enc110->base.preferred_engine = ENGINE_ID_DIGE; 1781 break; 1782 case TRANSMITTER_UNIPHY_F: 1783 enc110->base.preferred_engine = ENGINE_ID_DIGF; 1784 break; 1785 case TRANSMITTER_UNIPHY_G: 1786 enc110->base.preferred_engine = ENGINE_ID_DIGG; 1787 break; 1788 default: 1789 ASSERT_CRITICAL(false); 1790 enc110->base.preferred_engine = ENGINE_ID_UNKNOWN; 1791 } 1792 1793 /* default to one to mirror Windows behavior */ 1794 enc110->base.features.flags.bits.HDMI_6GB_EN = 1; 1795 1796 result = bp_funcs->get_encoder_cap_info(enc110->base.ctx->dc_bios, 1797 enc110->base.id, &bp_cap_info); 1798 1799 /* Override features with DCE-specific values */ 1800 if (BP_RESULT_OK == result) { 1801 enc110->base.features.flags.bits.IS_HBR2_CAPABLE = 1802 bp_cap_info.DP_HBR2_EN; 1803 enc110->base.features.flags.bits.IS_HBR3_CAPABLE = 1804 bp_cap_info.DP_HBR3_EN; 1805 enc110->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; 1806 } else { 1807 DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", 1808 __func__, 1809 result); 1810 } 1811 if (enc110->base.ctx->dc->debug.hdmi20_disable) { 1812 enc110->base.features.flags.bits.HDMI_6GB_EN = 0; 1813 } 1814 } 1815 #endif 1816