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