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