1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2020 Intel Corporation 4 */ 5 6 #include "intel_atomic.h" 7 #include "intel_ddi.h" 8 #include "intel_de.h" 9 #include "intel_display_types.h" 10 #include "intel_fdi.h" 11 #include "intel_sbi.h" 12 13 static void assert_fdi_tx(struct drm_i915_private *dev_priv, 14 enum pipe pipe, bool state) 15 { 16 bool cur_state; 17 18 if (HAS_DDI(dev_priv)) { 19 /* 20 * DDI does not have a specific FDI_TX register. 21 * 22 * FDI is never fed from EDP transcoder 23 * so pipe->transcoder cast is fine here. 24 */ 25 enum transcoder cpu_transcoder = (enum transcoder)pipe; 26 cur_state = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE; 27 } else { 28 cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE; 29 } 30 I915_STATE_WARN(cur_state != state, 31 "FDI TX state assertion failure (expected %s, current %s)\n", 32 onoff(state), onoff(cur_state)); 33 } 34 35 void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe) 36 { 37 assert_fdi_tx(i915, pipe, true); 38 } 39 40 void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe) 41 { 42 assert_fdi_tx(i915, pipe, false); 43 } 44 45 static void assert_fdi_rx(struct drm_i915_private *dev_priv, 46 enum pipe pipe, bool state) 47 { 48 bool cur_state; 49 50 cur_state = intel_de_read(dev_priv, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE; 51 I915_STATE_WARN(cur_state != state, 52 "FDI RX state assertion failure (expected %s, current %s)\n", 53 onoff(state), onoff(cur_state)); 54 } 55 56 void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe) 57 { 58 assert_fdi_rx(i915, pipe, true); 59 } 60 61 void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe) 62 { 63 assert_fdi_rx(i915, pipe, false); 64 } 65 66 void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915, 67 enum pipe pipe) 68 { 69 bool cur_state; 70 71 /* ILK FDI PLL is always enabled */ 72 if (IS_IRONLAKE(i915)) 73 return; 74 75 /* On Haswell, DDI ports are responsible for the FDI PLL setup */ 76 if (HAS_DDI(i915)) 77 return; 78 79 cur_state = intel_de_read(i915, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE; 80 I915_STATE_WARN(!cur_state, "FDI TX PLL assertion failure, should be active but is disabled\n"); 81 } 82 83 static void assert_fdi_rx_pll(struct drm_i915_private *i915, 84 enum pipe pipe, bool state) 85 { 86 bool cur_state; 87 88 cur_state = intel_de_read(i915, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE; 89 I915_STATE_WARN(cur_state != state, 90 "FDI RX PLL assertion failure (expected %s, current %s)\n", 91 onoff(state), onoff(cur_state)); 92 } 93 94 void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe) 95 { 96 assert_fdi_rx_pll(i915, pipe, true); 97 } 98 99 void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe) 100 { 101 assert_fdi_rx_pll(i915, pipe, false); 102 } 103 104 void intel_fdi_link_train(struct intel_crtc *crtc, 105 const struct intel_crtc_state *crtc_state) 106 { 107 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 108 109 dev_priv->fdi_funcs->fdi_link_train(crtc, crtc_state); 110 } 111 112 /* units of 100MHz */ 113 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state) 114 { 115 if (crtc_state->hw.enable && crtc_state->has_pch_encoder) 116 return crtc_state->fdi_lanes; 117 118 return 0; 119 } 120 121 static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe, 122 struct intel_crtc_state *pipe_config) 123 { 124 struct drm_i915_private *dev_priv = to_i915(dev); 125 struct drm_atomic_state *state = pipe_config->uapi.state; 126 struct intel_crtc *other_crtc; 127 struct intel_crtc_state *other_crtc_state; 128 129 drm_dbg_kms(&dev_priv->drm, 130 "checking fdi config on pipe %c, lanes %i\n", 131 pipe_name(pipe), pipe_config->fdi_lanes); 132 if (pipe_config->fdi_lanes > 4) { 133 drm_dbg_kms(&dev_priv->drm, 134 "invalid fdi lane config on pipe %c: %i lanes\n", 135 pipe_name(pipe), pipe_config->fdi_lanes); 136 return -EINVAL; 137 } 138 139 if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { 140 if (pipe_config->fdi_lanes > 2) { 141 drm_dbg_kms(&dev_priv->drm, 142 "only 2 lanes on haswell, required: %i lanes\n", 143 pipe_config->fdi_lanes); 144 return -EINVAL; 145 } else { 146 return 0; 147 } 148 } 149 150 if (INTEL_NUM_PIPES(dev_priv) == 2) 151 return 0; 152 153 /* Ivybridge 3 pipe is really complicated */ 154 switch (pipe) { 155 case PIPE_A: 156 return 0; 157 case PIPE_B: 158 if (pipe_config->fdi_lanes <= 2) 159 return 0; 160 161 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_C); 162 other_crtc_state = 163 intel_atomic_get_crtc_state(state, other_crtc); 164 if (IS_ERR(other_crtc_state)) 165 return PTR_ERR(other_crtc_state); 166 167 if (pipe_required_fdi_lanes(other_crtc_state) > 0) { 168 drm_dbg_kms(&dev_priv->drm, 169 "invalid shared fdi lane config on pipe %c: %i lanes\n", 170 pipe_name(pipe), pipe_config->fdi_lanes); 171 return -EINVAL; 172 } 173 return 0; 174 case PIPE_C: 175 if (pipe_config->fdi_lanes > 2) { 176 drm_dbg_kms(&dev_priv->drm, 177 "only 2 lanes on pipe %c: required %i lanes\n", 178 pipe_name(pipe), pipe_config->fdi_lanes); 179 return -EINVAL; 180 } 181 182 other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_B); 183 other_crtc_state = 184 intel_atomic_get_crtc_state(state, other_crtc); 185 if (IS_ERR(other_crtc_state)) 186 return PTR_ERR(other_crtc_state); 187 188 if (pipe_required_fdi_lanes(other_crtc_state) > 2) { 189 drm_dbg_kms(&dev_priv->drm, 190 "fdi link B uses too many lanes to enable link C\n"); 191 return -EINVAL; 192 } 193 return 0; 194 default: 195 MISSING_CASE(pipe); 196 return 0; 197 } 198 } 199 200 void intel_fdi_pll_freq_update(struct drm_i915_private *i915) 201 { 202 if (IS_IRONLAKE(i915)) { 203 u32 fdi_pll_clk = 204 intel_de_read(i915, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK; 205 206 i915->fdi_pll_freq = (fdi_pll_clk + 2) * 10000; 207 } else if (IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) { 208 i915->fdi_pll_freq = 270000; 209 } else { 210 return; 211 } 212 213 drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->fdi_pll_freq); 214 } 215 216 int intel_fdi_link_freq(struct drm_i915_private *i915, 217 const struct intel_crtc_state *pipe_config) 218 { 219 if (HAS_DDI(i915)) 220 return pipe_config->port_clock; /* SPLL */ 221 else 222 return i915->fdi_pll_freq; 223 } 224 225 int ilk_fdi_compute_config(struct intel_crtc *crtc, 226 struct intel_crtc_state *pipe_config) 227 { 228 struct drm_device *dev = crtc->base.dev; 229 struct drm_i915_private *i915 = to_i915(dev); 230 const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; 231 int lane, link_bw, fdi_dotclock, ret; 232 bool needs_recompute = false; 233 234 retry: 235 /* FDI is a binary signal running at ~2.7GHz, encoding 236 * each output octet as 10 bits. The actual frequency 237 * is stored as a divider into a 100MHz clock, and the 238 * mode pixel clock is stored in units of 1KHz. 239 * Hence the bw of each lane in terms of the mode signal 240 * is: 241 */ 242 link_bw = intel_fdi_link_freq(i915, pipe_config); 243 244 fdi_dotclock = adjusted_mode->crtc_clock; 245 246 lane = ilk_get_lanes_required(fdi_dotclock, link_bw, 247 pipe_config->pipe_bpp); 248 249 pipe_config->fdi_lanes = lane; 250 251 intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock, 252 link_bw, &pipe_config->fdi_m_n, false, false); 253 254 ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config); 255 if (ret == -EDEADLK) 256 return ret; 257 258 if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) { 259 pipe_config->pipe_bpp -= 2*3; 260 drm_dbg_kms(&i915->drm, 261 "fdi link bw constraint, reducing pipe bpp to %i\n", 262 pipe_config->pipe_bpp); 263 needs_recompute = true; 264 pipe_config->bw_constrained = true; 265 266 goto retry; 267 } 268 269 if (needs_recompute) 270 return -EAGAIN; 271 272 return ret; 273 } 274 275 static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable) 276 { 277 u32 temp; 278 279 temp = intel_de_read(dev_priv, SOUTH_CHICKEN1); 280 if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable) 281 return; 282 283 drm_WARN_ON(&dev_priv->drm, 284 intel_de_read(dev_priv, FDI_RX_CTL(PIPE_B)) & 285 FDI_RX_ENABLE); 286 drm_WARN_ON(&dev_priv->drm, 287 intel_de_read(dev_priv, FDI_RX_CTL(PIPE_C)) & 288 FDI_RX_ENABLE); 289 290 temp &= ~FDI_BC_BIFURCATION_SELECT; 291 if (enable) 292 temp |= FDI_BC_BIFURCATION_SELECT; 293 294 drm_dbg_kms(&dev_priv->drm, "%sabling fdi C rx\n", 295 enable ? "en" : "dis"); 296 intel_de_write(dev_priv, SOUTH_CHICKEN1, temp); 297 intel_de_posting_read(dev_priv, SOUTH_CHICKEN1); 298 } 299 300 static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state) 301 { 302 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 303 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 304 305 switch (crtc->pipe) { 306 case PIPE_A: 307 break; 308 case PIPE_B: 309 if (crtc_state->fdi_lanes > 2) 310 cpt_set_fdi_bc_bifurcation(dev_priv, false); 311 else 312 cpt_set_fdi_bc_bifurcation(dev_priv, true); 313 314 break; 315 case PIPE_C: 316 cpt_set_fdi_bc_bifurcation(dev_priv, true); 317 318 break; 319 default: 320 MISSING_CASE(crtc->pipe); 321 } 322 } 323 324 void intel_fdi_normal_train(struct intel_crtc *crtc) 325 { 326 struct drm_device *dev = crtc->base.dev; 327 struct drm_i915_private *dev_priv = to_i915(dev); 328 enum pipe pipe = crtc->pipe; 329 i915_reg_t reg; 330 u32 temp; 331 332 /* enable normal train */ 333 reg = FDI_TX_CTL(pipe); 334 temp = intel_de_read(dev_priv, reg); 335 if (IS_IVYBRIDGE(dev_priv)) { 336 temp &= ~FDI_LINK_TRAIN_NONE_IVB; 337 temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE; 338 } else { 339 temp &= ~FDI_LINK_TRAIN_NONE; 340 temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; 341 } 342 intel_de_write(dev_priv, reg, temp); 343 344 reg = FDI_RX_CTL(pipe); 345 temp = intel_de_read(dev_priv, reg); 346 if (HAS_PCH_CPT(dev_priv)) { 347 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 348 temp |= FDI_LINK_TRAIN_NORMAL_CPT; 349 } else { 350 temp &= ~FDI_LINK_TRAIN_NONE; 351 temp |= FDI_LINK_TRAIN_NONE; 352 } 353 intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE); 354 355 /* wait one idle pattern time */ 356 intel_de_posting_read(dev_priv, reg); 357 udelay(1000); 358 359 /* IVB wants error correction enabled */ 360 if (IS_IVYBRIDGE(dev_priv)) 361 intel_de_write(dev_priv, reg, 362 intel_de_read(dev_priv, reg) | FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE); 363 } 364 365 /* The FDI link training functions for ILK/Ibexpeak. */ 366 static void ilk_fdi_link_train(struct intel_crtc *crtc, 367 const struct intel_crtc_state *crtc_state) 368 { 369 struct drm_device *dev = crtc->base.dev; 370 struct drm_i915_private *dev_priv = to_i915(dev); 371 enum pipe pipe = crtc->pipe; 372 i915_reg_t reg; 373 u32 temp, tries; 374 375 /* 376 * Write the TU size bits before fdi link training, so that error 377 * detection works. 378 */ 379 intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), 380 intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); 381 382 /* FDI needs bits from pipe first */ 383 assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder); 384 385 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit 386 for train result */ 387 reg = FDI_RX_IMR(pipe); 388 temp = intel_de_read(dev_priv, reg); 389 temp &= ~FDI_RX_SYMBOL_LOCK; 390 temp &= ~FDI_RX_BIT_LOCK; 391 intel_de_write(dev_priv, reg, temp); 392 intel_de_read(dev_priv, reg); 393 udelay(150); 394 395 /* enable CPU FDI TX and PCH FDI RX */ 396 reg = FDI_TX_CTL(pipe); 397 temp = intel_de_read(dev_priv, reg); 398 temp &= ~FDI_DP_PORT_WIDTH_MASK; 399 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); 400 temp &= ~FDI_LINK_TRAIN_NONE; 401 temp |= FDI_LINK_TRAIN_PATTERN_1; 402 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); 403 404 reg = FDI_RX_CTL(pipe); 405 temp = intel_de_read(dev_priv, reg); 406 temp &= ~FDI_LINK_TRAIN_NONE; 407 temp |= FDI_LINK_TRAIN_PATTERN_1; 408 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); 409 410 intel_de_posting_read(dev_priv, reg); 411 udelay(150); 412 413 /* Ironlake workaround, enable clock pointer after FDI enable*/ 414 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), 415 FDI_RX_PHASE_SYNC_POINTER_OVR); 416 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), 417 FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN); 418 419 reg = FDI_RX_IIR(pipe); 420 for (tries = 0; tries < 5; tries++) { 421 temp = intel_de_read(dev_priv, reg); 422 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 423 424 if ((temp & FDI_RX_BIT_LOCK)) { 425 drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n"); 426 intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK); 427 break; 428 } 429 } 430 if (tries == 5) 431 drm_err(&dev_priv->drm, "FDI train 1 fail!\n"); 432 433 /* Train 2 */ 434 reg = FDI_TX_CTL(pipe); 435 temp = intel_de_read(dev_priv, reg); 436 temp &= ~FDI_LINK_TRAIN_NONE; 437 temp |= FDI_LINK_TRAIN_PATTERN_2; 438 intel_de_write(dev_priv, reg, temp); 439 440 reg = FDI_RX_CTL(pipe); 441 temp = intel_de_read(dev_priv, reg); 442 temp &= ~FDI_LINK_TRAIN_NONE; 443 temp |= FDI_LINK_TRAIN_PATTERN_2; 444 intel_de_write(dev_priv, reg, temp); 445 446 intel_de_posting_read(dev_priv, reg); 447 udelay(150); 448 449 reg = FDI_RX_IIR(pipe); 450 for (tries = 0; tries < 5; tries++) { 451 temp = intel_de_read(dev_priv, reg); 452 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 453 454 if (temp & FDI_RX_SYMBOL_LOCK) { 455 intel_de_write(dev_priv, reg, 456 temp | FDI_RX_SYMBOL_LOCK); 457 drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n"); 458 break; 459 } 460 } 461 if (tries == 5) 462 drm_err(&dev_priv->drm, "FDI train 2 fail!\n"); 463 464 drm_dbg_kms(&dev_priv->drm, "FDI train done\n"); 465 466 } 467 468 static const int snb_b_fdi_train_param[] = { 469 FDI_LINK_TRAIN_400MV_0DB_SNB_B, 470 FDI_LINK_TRAIN_400MV_6DB_SNB_B, 471 FDI_LINK_TRAIN_600MV_3_5DB_SNB_B, 472 FDI_LINK_TRAIN_800MV_0DB_SNB_B, 473 }; 474 475 /* The FDI link training functions for SNB/Cougarpoint. */ 476 static void gen6_fdi_link_train(struct intel_crtc *crtc, 477 const struct intel_crtc_state *crtc_state) 478 { 479 struct drm_device *dev = crtc->base.dev; 480 struct drm_i915_private *dev_priv = to_i915(dev); 481 enum pipe pipe = crtc->pipe; 482 i915_reg_t reg; 483 u32 temp, i, retry; 484 485 /* 486 * Write the TU size bits before fdi link training, so that error 487 * detection works. 488 */ 489 intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), 490 intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); 491 492 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit 493 for train result */ 494 reg = FDI_RX_IMR(pipe); 495 temp = intel_de_read(dev_priv, reg); 496 temp &= ~FDI_RX_SYMBOL_LOCK; 497 temp &= ~FDI_RX_BIT_LOCK; 498 intel_de_write(dev_priv, reg, temp); 499 500 intel_de_posting_read(dev_priv, reg); 501 udelay(150); 502 503 /* enable CPU FDI TX and PCH FDI RX */ 504 reg = FDI_TX_CTL(pipe); 505 temp = intel_de_read(dev_priv, reg); 506 temp &= ~FDI_DP_PORT_WIDTH_MASK; 507 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); 508 temp &= ~FDI_LINK_TRAIN_NONE; 509 temp |= FDI_LINK_TRAIN_PATTERN_1; 510 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; 511 /* SNB-B */ 512 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; 513 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); 514 515 intel_de_write(dev_priv, FDI_RX_MISC(pipe), 516 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); 517 518 reg = FDI_RX_CTL(pipe); 519 temp = intel_de_read(dev_priv, reg); 520 if (HAS_PCH_CPT(dev_priv)) { 521 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 522 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; 523 } else { 524 temp &= ~FDI_LINK_TRAIN_NONE; 525 temp |= FDI_LINK_TRAIN_PATTERN_1; 526 } 527 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); 528 529 intel_de_posting_read(dev_priv, reg); 530 udelay(150); 531 532 for (i = 0; i < 4; i++) { 533 reg = FDI_TX_CTL(pipe); 534 temp = intel_de_read(dev_priv, reg); 535 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; 536 temp |= snb_b_fdi_train_param[i]; 537 intel_de_write(dev_priv, reg, temp); 538 539 intel_de_posting_read(dev_priv, reg); 540 udelay(500); 541 542 for (retry = 0; retry < 5; retry++) { 543 reg = FDI_RX_IIR(pipe); 544 temp = intel_de_read(dev_priv, reg); 545 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 546 if (temp & FDI_RX_BIT_LOCK) { 547 intel_de_write(dev_priv, reg, 548 temp | FDI_RX_BIT_LOCK); 549 drm_dbg_kms(&dev_priv->drm, 550 "FDI train 1 done.\n"); 551 break; 552 } 553 udelay(50); 554 } 555 if (retry < 5) 556 break; 557 } 558 if (i == 4) 559 drm_err(&dev_priv->drm, "FDI train 1 fail!\n"); 560 561 /* Train 2 */ 562 reg = FDI_TX_CTL(pipe); 563 temp = intel_de_read(dev_priv, reg); 564 temp &= ~FDI_LINK_TRAIN_NONE; 565 temp |= FDI_LINK_TRAIN_PATTERN_2; 566 if (IS_SANDYBRIDGE(dev_priv)) { 567 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; 568 /* SNB-B */ 569 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B; 570 } 571 intel_de_write(dev_priv, reg, temp); 572 573 reg = FDI_RX_CTL(pipe); 574 temp = intel_de_read(dev_priv, reg); 575 if (HAS_PCH_CPT(dev_priv)) { 576 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 577 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; 578 } else { 579 temp &= ~FDI_LINK_TRAIN_NONE; 580 temp |= FDI_LINK_TRAIN_PATTERN_2; 581 } 582 intel_de_write(dev_priv, reg, temp); 583 584 intel_de_posting_read(dev_priv, reg); 585 udelay(150); 586 587 for (i = 0; i < 4; i++) { 588 reg = FDI_TX_CTL(pipe); 589 temp = intel_de_read(dev_priv, reg); 590 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; 591 temp |= snb_b_fdi_train_param[i]; 592 intel_de_write(dev_priv, reg, temp); 593 594 intel_de_posting_read(dev_priv, reg); 595 udelay(500); 596 597 for (retry = 0; retry < 5; retry++) { 598 reg = FDI_RX_IIR(pipe); 599 temp = intel_de_read(dev_priv, reg); 600 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 601 if (temp & FDI_RX_SYMBOL_LOCK) { 602 intel_de_write(dev_priv, reg, 603 temp | FDI_RX_SYMBOL_LOCK); 604 drm_dbg_kms(&dev_priv->drm, 605 "FDI train 2 done.\n"); 606 break; 607 } 608 udelay(50); 609 } 610 if (retry < 5) 611 break; 612 } 613 if (i == 4) 614 drm_err(&dev_priv->drm, "FDI train 2 fail!\n"); 615 616 drm_dbg_kms(&dev_priv->drm, "FDI train done.\n"); 617 } 618 619 /* Manual link training for Ivy Bridge A0 parts */ 620 static void ivb_manual_fdi_link_train(struct intel_crtc *crtc, 621 const struct intel_crtc_state *crtc_state) 622 { 623 struct drm_device *dev = crtc->base.dev; 624 struct drm_i915_private *dev_priv = to_i915(dev); 625 enum pipe pipe = crtc->pipe; 626 i915_reg_t reg; 627 u32 temp, i, j; 628 629 ivb_update_fdi_bc_bifurcation(crtc_state); 630 631 /* 632 * Write the TU size bits before fdi link training, so that error 633 * detection works. 634 */ 635 intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe), 636 intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK); 637 638 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit 639 for train result */ 640 reg = FDI_RX_IMR(pipe); 641 temp = intel_de_read(dev_priv, reg); 642 temp &= ~FDI_RX_SYMBOL_LOCK; 643 temp &= ~FDI_RX_BIT_LOCK; 644 intel_de_write(dev_priv, reg, temp); 645 646 intel_de_posting_read(dev_priv, reg); 647 udelay(150); 648 649 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n", 650 intel_de_read(dev_priv, FDI_RX_IIR(pipe))); 651 652 /* Try each vswing and preemphasis setting twice before moving on */ 653 for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) { 654 /* disable first in case we need to retry */ 655 reg = FDI_TX_CTL(pipe); 656 temp = intel_de_read(dev_priv, reg); 657 temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB); 658 temp &= ~FDI_TX_ENABLE; 659 intel_de_write(dev_priv, reg, temp); 660 661 reg = FDI_RX_CTL(pipe); 662 temp = intel_de_read(dev_priv, reg); 663 temp &= ~FDI_LINK_TRAIN_AUTO; 664 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 665 temp &= ~FDI_RX_ENABLE; 666 intel_de_write(dev_priv, reg, temp); 667 668 /* enable CPU FDI TX and PCH FDI RX */ 669 reg = FDI_TX_CTL(pipe); 670 temp = intel_de_read(dev_priv, reg); 671 temp &= ~FDI_DP_PORT_WIDTH_MASK; 672 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); 673 temp |= FDI_LINK_TRAIN_PATTERN_1_IVB; 674 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; 675 temp |= snb_b_fdi_train_param[j/2]; 676 temp |= FDI_COMPOSITE_SYNC; 677 intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE); 678 679 intel_de_write(dev_priv, FDI_RX_MISC(pipe), 680 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); 681 682 reg = FDI_RX_CTL(pipe); 683 temp = intel_de_read(dev_priv, reg); 684 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; 685 temp |= FDI_COMPOSITE_SYNC; 686 intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE); 687 688 intel_de_posting_read(dev_priv, reg); 689 udelay(1); /* should be 0.5us */ 690 691 for (i = 0; i < 4; i++) { 692 reg = FDI_RX_IIR(pipe); 693 temp = intel_de_read(dev_priv, reg); 694 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 695 696 if (temp & FDI_RX_BIT_LOCK || 697 (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) { 698 intel_de_write(dev_priv, reg, 699 temp | FDI_RX_BIT_LOCK); 700 drm_dbg_kms(&dev_priv->drm, 701 "FDI train 1 done, level %i.\n", 702 i); 703 break; 704 } 705 udelay(1); /* should be 0.5us */ 706 } 707 if (i == 4) { 708 drm_dbg_kms(&dev_priv->drm, 709 "FDI train 1 fail on vswing %d\n", j / 2); 710 continue; 711 } 712 713 /* Train 2 */ 714 reg = FDI_TX_CTL(pipe); 715 temp = intel_de_read(dev_priv, reg); 716 temp &= ~FDI_LINK_TRAIN_NONE_IVB; 717 temp |= FDI_LINK_TRAIN_PATTERN_2_IVB; 718 intel_de_write(dev_priv, reg, temp); 719 720 reg = FDI_RX_CTL(pipe); 721 temp = intel_de_read(dev_priv, reg); 722 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 723 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; 724 intel_de_write(dev_priv, reg, temp); 725 726 intel_de_posting_read(dev_priv, reg); 727 udelay(2); /* should be 1.5us */ 728 729 for (i = 0; i < 4; i++) { 730 reg = FDI_RX_IIR(pipe); 731 temp = intel_de_read(dev_priv, reg); 732 drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp); 733 734 if (temp & FDI_RX_SYMBOL_LOCK || 735 (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) { 736 intel_de_write(dev_priv, reg, 737 temp | FDI_RX_SYMBOL_LOCK); 738 drm_dbg_kms(&dev_priv->drm, 739 "FDI train 2 done, level %i.\n", 740 i); 741 goto train_done; 742 } 743 udelay(2); /* should be 1.5us */ 744 } 745 if (i == 4) 746 drm_dbg_kms(&dev_priv->drm, 747 "FDI train 2 fail on vswing %d\n", j / 2); 748 } 749 750 train_done: 751 drm_dbg_kms(&dev_priv->drm, "FDI train done.\n"); 752 } 753 754 /* Starting with Haswell, different DDI ports can work in FDI mode for 755 * connection to the PCH-located connectors. For this, it is necessary to train 756 * both the DDI port and PCH receiver for the desired DDI buffer settings. 757 * 758 * The recommended port to work in FDI mode is DDI E, which we use here. Also, 759 * please note that when FDI mode is active on DDI E, it shares 2 lines with 760 * DDI A (which is used for eDP) 761 */ 762 void hsw_fdi_link_train(struct intel_encoder *encoder, 763 const struct intel_crtc_state *crtc_state) 764 { 765 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 766 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 767 u32 temp, i, rx_ctl_val; 768 int n_entries; 769 770 encoder->get_buf_trans(encoder, crtc_state, &n_entries); 771 772 hsw_prepare_dp_ddi_buffers(encoder, crtc_state); 773 774 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the 775 * mode set "sequence for CRT port" document: 776 * - TP1 to TP2 time with the default value 777 * - FDI delay to 90h 778 * 779 * WaFDIAutoLinkSetTimingOverrride:hsw 780 */ 781 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), 782 FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90); 783 784 /* Enable the PCH Receiver FDI PLL */ 785 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE | 786 FDI_RX_PLL_ENABLE | 787 FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); 788 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); 789 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); 790 udelay(220); 791 792 /* Switch from Rawclk to PCDclk */ 793 rx_ctl_val |= FDI_PCDCLK; 794 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); 795 796 /* Configure Port Clock Select */ 797 drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL); 798 intel_ddi_enable_clock(encoder, crtc_state); 799 800 /* Start the training iterating through available voltages and emphasis, 801 * testing each value twice. */ 802 for (i = 0; i < n_entries * 2; i++) { 803 /* Configure DP_TP_CTL with auto-training */ 804 intel_de_write(dev_priv, DP_TP_CTL(PORT_E), 805 DP_TP_CTL_FDI_AUTOTRAIN | 806 DP_TP_CTL_ENHANCED_FRAME_ENABLE | 807 DP_TP_CTL_LINK_TRAIN_PAT1 | 808 DP_TP_CTL_ENABLE); 809 810 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage. 811 * DDI E does not support port reversal, the functionality is 812 * achieved on the PCH side in FDI_RX_CTL, so no need to set the 813 * port reversal bit */ 814 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), 815 DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2)); 816 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E)); 817 818 udelay(600); 819 820 /* Program PCH FDI Receiver TU */ 821 intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64)); 822 823 /* Enable PCH FDI Receiver with auto-training */ 824 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO; 825 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); 826 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); 827 828 /* Wait for FDI receiver lane calibration */ 829 udelay(30); 830 831 /* Unset FDI_RX_MISC pwrdn lanes */ 832 temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A)); 833 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); 834 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp); 835 intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A)); 836 837 /* Wait for FDI auto training time */ 838 udelay(5); 839 840 temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E)); 841 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) { 842 drm_dbg_kms(&dev_priv->drm, 843 "FDI link training done on step %d\n", i); 844 break; 845 } 846 847 /* 848 * Leave things enabled even if we failed to train FDI. 849 * Results in less fireworks from the state checker. 850 */ 851 if (i == n_entries * 2 - 1) { 852 drm_err(&dev_priv->drm, "FDI link training failed!\n"); 853 break; 854 } 855 856 rx_ctl_val &= ~FDI_RX_ENABLE; 857 intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val); 858 intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A)); 859 860 temp = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_E)); 861 temp &= ~DDI_BUF_CTL_ENABLE; 862 intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), temp); 863 intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E)); 864 865 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */ 866 temp = intel_de_read(dev_priv, DP_TP_CTL(PORT_E)); 867 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK); 868 temp |= DP_TP_CTL_LINK_TRAIN_PAT1; 869 intel_de_write(dev_priv, DP_TP_CTL(PORT_E), temp); 870 intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E)); 871 872 intel_wait_ddi_buf_idle(dev_priv, PORT_E); 873 874 /* Reset FDI_RX_MISC pwrdn lanes */ 875 temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A)); 876 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK); 877 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2); 878 intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp); 879 intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A)); 880 } 881 882 /* Enable normal pixel sending for FDI */ 883 intel_de_write(dev_priv, DP_TP_CTL(PORT_E), 884 DP_TP_CTL_FDI_AUTOTRAIN | 885 DP_TP_CTL_LINK_TRAIN_NORMAL | 886 DP_TP_CTL_ENHANCED_FRAME_ENABLE | 887 DP_TP_CTL_ENABLE); 888 } 889 890 void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state) 891 { 892 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 893 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 894 enum pipe pipe = crtc->pipe; 895 i915_reg_t reg; 896 u32 temp; 897 898 /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ 899 reg = FDI_RX_CTL(pipe); 900 temp = intel_de_read(dev_priv, reg); 901 temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16)); 902 temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes); 903 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11; 904 intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE); 905 906 intel_de_posting_read(dev_priv, reg); 907 udelay(200); 908 909 /* Switch from Rawclk to PCDclk */ 910 temp = intel_de_read(dev_priv, reg); 911 intel_de_write(dev_priv, reg, temp | FDI_PCDCLK); 912 913 intel_de_posting_read(dev_priv, reg); 914 udelay(200); 915 916 /* Enable CPU FDI TX PLL, always on for Ironlake */ 917 reg = FDI_TX_CTL(pipe); 918 temp = intel_de_read(dev_priv, reg); 919 if ((temp & FDI_TX_PLL_ENABLE) == 0) { 920 intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE); 921 922 intel_de_posting_read(dev_priv, reg); 923 udelay(100); 924 } 925 } 926 927 void ilk_fdi_pll_disable(struct intel_crtc *crtc) 928 { 929 struct drm_device *dev = crtc->base.dev; 930 struct drm_i915_private *dev_priv = to_i915(dev); 931 enum pipe pipe = crtc->pipe; 932 i915_reg_t reg; 933 u32 temp; 934 935 /* Switch from PCDclk to Rawclk */ 936 reg = FDI_RX_CTL(pipe); 937 temp = intel_de_read(dev_priv, reg); 938 intel_de_write(dev_priv, reg, temp & ~FDI_PCDCLK); 939 940 /* Disable CPU FDI TX PLL */ 941 reg = FDI_TX_CTL(pipe); 942 temp = intel_de_read(dev_priv, reg); 943 intel_de_write(dev_priv, reg, temp & ~FDI_TX_PLL_ENABLE); 944 945 intel_de_posting_read(dev_priv, reg); 946 udelay(100); 947 948 reg = FDI_RX_CTL(pipe); 949 temp = intel_de_read(dev_priv, reg); 950 intel_de_write(dev_priv, reg, temp & ~FDI_RX_PLL_ENABLE); 951 952 /* Wait for the clocks to turn off. */ 953 intel_de_posting_read(dev_priv, reg); 954 udelay(100); 955 } 956 957 void ilk_fdi_disable(struct intel_crtc *crtc) 958 { 959 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 960 enum pipe pipe = crtc->pipe; 961 i915_reg_t reg; 962 u32 temp; 963 964 /* disable CPU FDI tx and PCH FDI rx */ 965 reg = FDI_TX_CTL(pipe); 966 temp = intel_de_read(dev_priv, reg); 967 intel_de_write(dev_priv, reg, temp & ~FDI_TX_ENABLE); 968 intel_de_posting_read(dev_priv, reg); 969 970 reg = FDI_RX_CTL(pipe); 971 temp = intel_de_read(dev_priv, reg); 972 temp &= ~(0x7 << 16); 973 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11; 974 intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE); 975 976 intel_de_posting_read(dev_priv, reg); 977 udelay(100); 978 979 /* Ironlake workaround, disable clock pointer after downing FDI */ 980 if (HAS_PCH_IBX(dev_priv)) 981 intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe), 982 FDI_RX_PHASE_SYNC_POINTER_OVR); 983 984 /* still set train pattern 1 */ 985 reg = FDI_TX_CTL(pipe); 986 temp = intel_de_read(dev_priv, reg); 987 temp &= ~FDI_LINK_TRAIN_NONE; 988 temp |= FDI_LINK_TRAIN_PATTERN_1; 989 intel_de_write(dev_priv, reg, temp); 990 991 reg = FDI_RX_CTL(pipe); 992 temp = intel_de_read(dev_priv, reg); 993 if (HAS_PCH_CPT(dev_priv)) { 994 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; 995 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; 996 } else { 997 temp &= ~FDI_LINK_TRAIN_NONE; 998 temp |= FDI_LINK_TRAIN_PATTERN_1; 999 } 1000 /* BPC in FDI rx is consistent with that in PIPECONF */ 1001 temp &= ~(0x07 << 16); 1002 temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11; 1003 intel_de_write(dev_priv, reg, temp); 1004 1005 intel_de_posting_read(dev_priv, reg); 1006 udelay(100); 1007 } 1008 1009 static void lpt_fdi_reset_mphy(struct drm_i915_private *dev_priv) 1010 { 1011 u32 tmp; 1012 1013 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); 1014 tmp |= FDI_MPHY_IOSFSB_RESET_CTL; 1015 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); 1016 1017 if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) & 1018 FDI_MPHY_IOSFSB_RESET_STATUS, 100)) 1019 drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n"); 1020 1021 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); 1022 tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; 1023 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); 1024 1025 if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) & 1026 FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) 1027 drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n"); 1028 } 1029 1030 /* WaMPhyProgramming:hsw */ 1031 void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) 1032 { 1033 u32 tmp; 1034 1035 lpt_fdi_reset_mphy(dev_priv); 1036 1037 tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); 1038 tmp &= ~(0xFF << 24); 1039 tmp |= (0x12 << 24); 1040 intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY); 1041 1042 tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY); 1043 tmp |= (1 << 11); 1044 intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY); 1045 1046 tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY); 1047 tmp |= (1 << 11); 1048 intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY); 1049 1050 tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY); 1051 tmp |= (1 << 24) | (1 << 21) | (1 << 18); 1052 intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY); 1053 1054 tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY); 1055 tmp |= (1 << 24) | (1 << 21) | (1 << 18); 1056 intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY); 1057 1058 tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); 1059 tmp &= ~(7 << 13); 1060 tmp |= (5 << 13); 1061 intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); 1062 1063 tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); 1064 tmp &= ~(7 << 13); 1065 tmp |= (5 << 13); 1066 intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); 1067 1068 tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY); 1069 tmp &= ~0xFF; 1070 tmp |= 0x1C; 1071 intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY); 1072 1073 tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY); 1074 tmp &= ~0xFF; 1075 tmp |= 0x1C; 1076 intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY); 1077 1078 tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY); 1079 tmp &= ~(0xFF << 16); 1080 tmp |= (0x1C << 16); 1081 intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY); 1082 1083 tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY); 1084 tmp &= ~(0xFF << 16); 1085 tmp |= (0x1C << 16); 1086 intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY); 1087 1088 tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); 1089 tmp |= (1 << 27); 1090 intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); 1091 1092 tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); 1093 tmp |= (1 << 27); 1094 intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); 1095 1096 tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); 1097 tmp &= ~(0xF << 28); 1098 tmp |= (4 << 28); 1099 intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); 1100 1101 tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); 1102 tmp &= ~(0xF << 28); 1103 tmp |= (4 << 28); 1104 intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); 1105 } 1106 1107 static const struct intel_fdi_funcs ilk_funcs = { 1108 .fdi_link_train = ilk_fdi_link_train, 1109 }; 1110 1111 static const struct intel_fdi_funcs gen6_funcs = { 1112 .fdi_link_train = gen6_fdi_link_train, 1113 }; 1114 1115 static const struct intel_fdi_funcs ivb_funcs = { 1116 .fdi_link_train = ivb_manual_fdi_link_train, 1117 }; 1118 1119 void 1120 intel_fdi_init_hook(struct drm_i915_private *dev_priv) 1121 { 1122 if (IS_IRONLAKE(dev_priv)) { 1123 dev_priv->fdi_funcs = &ilk_funcs; 1124 } else if (IS_SANDYBRIDGE(dev_priv)) { 1125 dev_priv->fdi_funcs = &gen6_funcs; 1126 } else if (IS_IVYBRIDGE(dev_priv)) { 1127 /* FIXME: detect B0+ stepping and use auto training */ 1128 dev_priv->fdi_funcs = &ivb_funcs; 1129 } 1130 } 1131