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