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