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