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