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