Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

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