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