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