intel_pch_refclk.c (17725B)
1// SPDX-License-Identifier: MIT 2/* 3 * Copyright © 2021 Intel Corporation 4 */ 5 6#include "intel_de.h" 7#include "intel_display_types.h" 8#include "intel_panel.h" 9#include "intel_pch_refclk.h" 10#include "intel_sbi.h" 11 12static void lpt_fdi_reset_mphy(struct drm_i915_private *dev_priv) 13{ 14 u32 tmp; 15 16 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); 17 tmp |= FDI_MPHY_IOSFSB_RESET_CTL; 18 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); 19 20 if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) & 21 FDI_MPHY_IOSFSB_RESET_STATUS, 100)) 22 drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n"); 23 24 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2); 25 tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL; 26 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp); 27 28 if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) & 29 FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) 30 drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n"); 31} 32 33/* WaMPhyProgramming:hsw */ 34static void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) 35{ 36 u32 tmp; 37 38 lpt_fdi_reset_mphy(dev_priv); 39 40 tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); 41 tmp &= ~(0xFF << 24); 42 tmp |= (0x12 << 24); 43 intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY); 44 45 tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY); 46 tmp |= (1 << 11); 47 intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY); 48 49 tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY); 50 tmp |= (1 << 11); 51 intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY); 52 53 tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY); 54 tmp |= (1 << 24) | (1 << 21) | (1 << 18); 55 intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY); 56 57 tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY); 58 tmp |= (1 << 24) | (1 << 21) | (1 << 18); 59 intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY); 60 61 tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY); 62 tmp &= ~(7 << 13); 63 tmp |= (5 << 13); 64 intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY); 65 66 tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY); 67 tmp &= ~(7 << 13); 68 tmp |= (5 << 13); 69 intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY); 70 71 tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY); 72 tmp &= ~0xFF; 73 tmp |= 0x1C; 74 intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY); 75 76 tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY); 77 tmp &= ~0xFF; 78 tmp |= 0x1C; 79 intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY); 80 81 tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY); 82 tmp &= ~(0xFF << 16); 83 tmp |= (0x1C << 16); 84 intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY); 85 86 tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY); 87 tmp &= ~(0xFF << 16); 88 tmp |= (0x1C << 16); 89 intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY); 90 91 tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY); 92 tmp |= (1 << 27); 93 intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY); 94 95 tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY); 96 tmp |= (1 << 27); 97 intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY); 98 99 tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY); 100 tmp &= ~(0xF << 28); 101 tmp |= (4 << 28); 102 intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY); 103 104 tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY); 105 tmp &= ~(0xF << 28); 106 tmp |= (4 << 28); 107 intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); 108} 109 110void lpt_disable_iclkip(struct drm_i915_private *dev_priv) 111{ 112 u32 temp; 113 114 intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_GATE); 115 116 mutex_lock(&dev_priv->sb_lock); 117 118 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); 119 temp |= SBI_SSCCTL_DISABLE; 120 intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK); 121 122 mutex_unlock(&dev_priv->sb_lock); 123} 124 125/* Program iCLKIP clock to the desired frequency */ 126void lpt_program_iclkip(const struct intel_crtc_state *crtc_state) 127{ 128 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 129 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 130 int clock = crtc_state->hw.adjusted_mode.crtc_clock; 131 u32 divsel, phaseinc, auxdiv, phasedir = 0; 132 u32 temp; 133 134 lpt_disable_iclkip(dev_priv); 135 136 /* The iCLK virtual clock root frequency is in MHz, 137 * but the adjusted_mode->crtc_clock in KHz. To get the 138 * divisors, it is necessary to divide one by another, so we 139 * convert the virtual clock precision to KHz here for higher 140 * precision. 141 */ 142 for (auxdiv = 0; auxdiv < 2; auxdiv++) { 143 u32 iclk_virtual_root_freq = 172800 * 1000; 144 u32 iclk_pi_range = 64; 145 u32 desired_divisor; 146 147 desired_divisor = DIV_ROUND_CLOSEST(iclk_virtual_root_freq, 148 clock << auxdiv); 149 divsel = (desired_divisor / iclk_pi_range) - 2; 150 phaseinc = desired_divisor % iclk_pi_range; 151 152 /* 153 * Near 20MHz is a corner case which is 154 * out of range for the 7-bit divisor 155 */ 156 if (divsel <= 0x7f) 157 break; 158 } 159 160 /* This should not happen with any sane values */ 161 drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIVSEL(divsel) & 162 ~SBI_SSCDIVINTPHASE_DIVSEL_MASK); 163 drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIR(phasedir) & 164 ~SBI_SSCDIVINTPHASE_INCVAL_MASK); 165 166 drm_dbg_kms(&dev_priv->drm, 167 "iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n", 168 clock, auxdiv, divsel, phasedir, phaseinc); 169 170 mutex_lock(&dev_priv->sb_lock); 171 172 /* Program SSCDIVINTPHASE6 */ 173 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK); 174 temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK; 175 temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel); 176 temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK; 177 temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc); 178 temp |= SBI_SSCDIVINTPHASE_DIR(phasedir); 179 temp |= SBI_SSCDIVINTPHASE_PROPAGATE; 180 intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK); 181 182 /* Program SSCAUXDIV */ 183 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK); 184 temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1); 185 temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv); 186 intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK); 187 188 /* Enable modulator and associated divider */ 189 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); 190 temp &= ~SBI_SSCCTL_DISABLE; 191 intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK); 192 193 mutex_unlock(&dev_priv->sb_lock); 194 195 /* Wait for initialization time */ 196 udelay(24); 197 198 intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_UNGATE); 199} 200 201int lpt_get_iclkip(struct drm_i915_private *dev_priv) 202{ 203 u32 divsel, phaseinc, auxdiv; 204 u32 iclk_virtual_root_freq = 172800 * 1000; 205 u32 iclk_pi_range = 64; 206 u32 desired_divisor; 207 u32 temp; 208 209 if ((intel_de_read(dev_priv, PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0) 210 return 0; 211 212 mutex_lock(&dev_priv->sb_lock); 213 214 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK); 215 if (temp & SBI_SSCCTL_DISABLE) { 216 mutex_unlock(&dev_priv->sb_lock); 217 return 0; 218 } 219 220 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK); 221 divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >> 222 SBI_SSCDIVINTPHASE_DIVSEL_SHIFT; 223 phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >> 224 SBI_SSCDIVINTPHASE_INCVAL_SHIFT; 225 226 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK); 227 auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >> 228 SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT; 229 230 mutex_unlock(&dev_priv->sb_lock); 231 232 desired_divisor = (divsel + 2) * iclk_pi_range + phaseinc; 233 234 return DIV_ROUND_CLOSEST(iclk_virtual_root_freq, 235 desired_divisor << auxdiv); 236} 237 238/* Implements 3 different sequences from BSpec chapter "Display iCLK 239 * Programming" based on the parameters passed: 240 * - Sequence to enable CLKOUT_DP 241 * - Sequence to enable CLKOUT_DP without spread 242 * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O 243 */ 244static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, 245 bool with_spread, bool with_fdi) 246{ 247 u32 reg, tmp; 248 249 if (drm_WARN(&dev_priv->drm, with_fdi && !with_spread, 250 "FDI requires downspread\n")) 251 with_spread = true; 252 if (drm_WARN(&dev_priv->drm, HAS_PCH_LPT_LP(dev_priv) && 253 with_fdi, "LP PCH doesn't have FDI\n")) 254 with_fdi = false; 255 256 mutex_lock(&dev_priv->sb_lock); 257 258 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); 259 tmp &= ~SBI_SSCCTL_DISABLE; 260 tmp |= SBI_SSCCTL_PATHALT; 261 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); 262 263 udelay(24); 264 265 if (with_spread) { 266 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); 267 tmp &= ~SBI_SSCCTL_PATHALT; 268 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); 269 270 if (with_fdi) 271 lpt_fdi_program_mphy(dev_priv); 272 } 273 274 reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; 275 tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); 276 tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE; 277 intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); 278 279 mutex_unlock(&dev_priv->sb_lock); 280} 281 282/* Sequence to disable CLKOUT_DP */ 283void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv) 284{ 285 u32 reg, tmp; 286 287 mutex_lock(&dev_priv->sb_lock); 288 289 reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; 290 tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); 291 tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE; 292 intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); 293 294 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK); 295 if (!(tmp & SBI_SSCCTL_DISABLE)) { 296 if (!(tmp & SBI_SSCCTL_PATHALT)) { 297 tmp |= SBI_SSCCTL_PATHALT; 298 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); 299 udelay(32); 300 } 301 tmp |= SBI_SSCCTL_DISABLE; 302 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); 303 } 304 305 mutex_unlock(&dev_priv->sb_lock); 306} 307 308#define BEND_IDX(steps) ((50 + (steps)) / 5) 309 310static const u16 sscdivintphase[] = { 311 [BEND_IDX( 50)] = 0x3B23, 312 [BEND_IDX( 45)] = 0x3B23, 313 [BEND_IDX( 40)] = 0x3C23, 314 [BEND_IDX( 35)] = 0x3C23, 315 [BEND_IDX( 30)] = 0x3D23, 316 [BEND_IDX( 25)] = 0x3D23, 317 [BEND_IDX( 20)] = 0x3E23, 318 [BEND_IDX( 15)] = 0x3E23, 319 [BEND_IDX( 10)] = 0x3F23, 320 [BEND_IDX( 5)] = 0x3F23, 321 [BEND_IDX( 0)] = 0x0025, 322 [BEND_IDX( -5)] = 0x0025, 323 [BEND_IDX(-10)] = 0x0125, 324 [BEND_IDX(-15)] = 0x0125, 325 [BEND_IDX(-20)] = 0x0225, 326 [BEND_IDX(-25)] = 0x0225, 327 [BEND_IDX(-30)] = 0x0325, 328 [BEND_IDX(-35)] = 0x0325, 329 [BEND_IDX(-40)] = 0x0425, 330 [BEND_IDX(-45)] = 0x0425, 331 [BEND_IDX(-50)] = 0x0525, 332}; 333 334/* 335 * Bend CLKOUT_DP 336 * steps -50 to 50 inclusive, in steps of 5 337 * < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz) 338 * change in clock period = -(steps / 10) * 5.787 ps 339 */ 340static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps) 341{ 342 u32 tmp; 343 int idx = BEND_IDX(steps); 344 345 if (drm_WARN_ON(&dev_priv->drm, steps % 5 != 0)) 346 return; 347 348 if (drm_WARN_ON(&dev_priv->drm, idx >= ARRAY_SIZE(sscdivintphase))) 349 return; 350 351 mutex_lock(&dev_priv->sb_lock); 352 353 if (steps % 10 != 0) 354 tmp = 0xAAAAAAAB; 355 else 356 tmp = 0x00000000; 357 intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK); 358 359 tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK); 360 tmp &= 0xffff0000; 361 tmp |= sscdivintphase[idx]; 362 intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK); 363 364 mutex_unlock(&dev_priv->sb_lock); 365} 366 367#undef BEND_IDX 368 369static bool spll_uses_pch_ssc(struct drm_i915_private *dev_priv) 370{ 371 u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); 372 u32 ctl = intel_de_read(dev_priv, SPLL_CTL); 373 374 if ((ctl & SPLL_PLL_ENABLE) == 0) 375 return false; 376 377 if ((ctl & SPLL_REF_MASK) == SPLL_REF_MUXED_SSC && 378 (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) 379 return true; 380 381 if (IS_BROADWELL(dev_priv) && 382 (ctl & SPLL_REF_MASK) == SPLL_REF_PCH_SSC_BDW) 383 return true; 384 385 return false; 386} 387 388static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, 389 enum intel_dpll_id id) 390{ 391 u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); 392 u32 ctl = intel_de_read(dev_priv, WRPLL_CTL(id)); 393 394 if ((ctl & WRPLL_PLL_ENABLE) == 0) 395 return false; 396 397 if ((ctl & WRPLL_REF_MASK) == WRPLL_REF_PCH_SSC) 398 return true; 399 400 if ((IS_BROADWELL(dev_priv) || IS_HSW_ULT(dev_priv)) && 401 (ctl & WRPLL_REF_MASK) == WRPLL_REF_MUXED_SSC_BDW && 402 (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) 403 return true; 404 405 return false; 406} 407 408static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) 409{ 410 struct intel_encoder *encoder; 411 bool has_fdi = false; 412 413 for_each_intel_encoder(&dev_priv->drm, encoder) { 414 switch (encoder->type) { 415 case INTEL_OUTPUT_ANALOG: 416 has_fdi = true; 417 break; 418 default: 419 break; 420 } 421 } 422 423 /* 424 * The BIOS may have decided to use the PCH SSC 425 * reference so we must not disable it until the 426 * relevant PLLs have stopped relying on it. We'll 427 * just leave the PCH SSC reference enabled in case 428 * any active PLL is using it. It will get disabled 429 * after runtime suspend if we don't have FDI. 430 * 431 * TODO: Move the whole reference clock handling 432 * to the modeset sequence proper so that we can 433 * actually enable/disable/reconfigure these things 434 * safely. To do that we need to introduce a real 435 * clock hierarchy. That would also allow us to do 436 * clock bending finally. 437 */ 438 dev_priv->pch_ssc_use = 0; 439 440 if (spll_uses_pch_ssc(dev_priv)) { 441 drm_dbg_kms(&dev_priv->drm, "SPLL using PCH SSC\n"); 442 dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL); 443 } 444 445 if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) { 446 drm_dbg_kms(&dev_priv->drm, "WRPLL1 using PCH SSC\n"); 447 dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1); 448 } 449 450 if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) { 451 drm_dbg_kms(&dev_priv->drm, "WRPLL2 using PCH SSC\n"); 452 dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2); 453 } 454 455 if (dev_priv->pch_ssc_use) 456 return; 457 458 if (has_fdi) { 459 lpt_bend_clkout_dp(dev_priv, 0); 460 lpt_enable_clkout_dp(dev_priv, true, true); 461 } else { 462 lpt_disable_clkout_dp(dev_priv); 463 } 464} 465 466static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) 467{ 468 struct intel_encoder *encoder; 469 int i; 470 u32 val, final; 471 bool has_lvds = false; 472 bool has_cpu_edp = false; 473 bool has_panel = false; 474 bool has_ck505 = false; 475 bool can_ssc = false; 476 bool using_ssc_source = false; 477 478 /* We need to take the global config into account */ 479 for_each_intel_encoder(&dev_priv->drm, encoder) { 480 switch (encoder->type) { 481 case INTEL_OUTPUT_LVDS: 482 has_panel = true; 483 has_lvds = true; 484 break; 485 case INTEL_OUTPUT_EDP: 486 has_panel = true; 487 if (encoder->port == PORT_A) 488 has_cpu_edp = true; 489 break; 490 default: 491 break; 492 } 493 } 494 495 if (HAS_PCH_IBX(dev_priv)) { 496 has_ck505 = dev_priv->vbt.display_clock_mode; 497 can_ssc = has_ck505; 498 } else { 499 has_ck505 = false; 500 can_ssc = true; 501 } 502 503 /* Check if any DPLLs are using the SSC source */ 504 for (i = 0; i < dev_priv->dpll.num_shared_dpll; i++) { 505 u32 temp = intel_de_read(dev_priv, PCH_DPLL(i)); 506 507 if (!(temp & DPLL_VCO_ENABLE)) 508 continue; 509 510 if ((temp & PLL_REF_INPUT_MASK) == 511 PLLB_REF_INPUT_SPREADSPECTRUMIN) { 512 using_ssc_source = true; 513 break; 514 } 515 } 516 517 drm_dbg_kms(&dev_priv->drm, 518 "has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n", 519 has_panel, has_lvds, has_ck505, using_ssc_source); 520 521 /* Ironlake: try to setup display ref clock before DPLL 522 * enabling. This is only under driver's control after 523 * PCH B stepping, previous chipset stepping should be 524 * ignoring this setting. 525 */ 526 val = intel_de_read(dev_priv, PCH_DREF_CONTROL); 527 528 /* As we must carefully and slowly disable/enable each source in turn, 529 * compute the final state we want first and check if we need to 530 * make any changes at all. 531 */ 532 final = val; 533 final &= ~DREF_NONSPREAD_SOURCE_MASK; 534 if (has_ck505) 535 final |= DREF_NONSPREAD_CK505_ENABLE; 536 else 537 final |= DREF_NONSPREAD_SOURCE_ENABLE; 538 539 final &= ~DREF_SSC_SOURCE_MASK; 540 final &= ~DREF_CPU_SOURCE_OUTPUT_MASK; 541 final &= ~DREF_SSC1_ENABLE; 542 543 if (has_panel) { 544 final |= DREF_SSC_SOURCE_ENABLE; 545 546 if (intel_panel_use_ssc(dev_priv) && can_ssc) 547 final |= DREF_SSC1_ENABLE; 548 549 if (has_cpu_edp) { 550 if (intel_panel_use_ssc(dev_priv) && can_ssc) 551 final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; 552 else 553 final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; 554 } else { 555 final |= DREF_CPU_SOURCE_OUTPUT_DISABLE; 556 } 557 } else if (using_ssc_source) { 558 final |= DREF_SSC_SOURCE_ENABLE; 559 final |= DREF_SSC1_ENABLE; 560 } 561 562 if (final == val) 563 return; 564 565 /* Always enable nonspread source */ 566 val &= ~DREF_NONSPREAD_SOURCE_MASK; 567 568 if (has_ck505) 569 val |= DREF_NONSPREAD_CK505_ENABLE; 570 else 571 val |= DREF_NONSPREAD_SOURCE_ENABLE; 572 573 if (has_panel) { 574 val &= ~DREF_SSC_SOURCE_MASK; 575 val |= DREF_SSC_SOURCE_ENABLE; 576 577 /* SSC must be turned on before enabling the CPU output */ 578 if (intel_panel_use_ssc(dev_priv) && can_ssc) { 579 drm_dbg_kms(&dev_priv->drm, "Using SSC on panel\n"); 580 val |= DREF_SSC1_ENABLE; 581 } else { 582 val &= ~DREF_SSC1_ENABLE; 583 } 584 585 /* Get SSC going before enabling the outputs */ 586 intel_de_write(dev_priv, PCH_DREF_CONTROL, val); 587 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); 588 udelay(200); 589 590 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; 591 592 /* Enable CPU source on CPU attached eDP */ 593 if (has_cpu_edp) { 594 if (intel_panel_use_ssc(dev_priv) && can_ssc) { 595 drm_dbg_kms(&dev_priv->drm, 596 "Using SSC on eDP\n"); 597 val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; 598 } else { 599 val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; 600 } 601 } else { 602 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; 603 } 604 605 intel_de_write(dev_priv, PCH_DREF_CONTROL, val); 606 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); 607 udelay(200); 608 } else { 609 drm_dbg_kms(&dev_priv->drm, "Disabling CPU source output\n"); 610 611 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK; 612 613 /* Turn off CPU output */ 614 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE; 615 616 intel_de_write(dev_priv, PCH_DREF_CONTROL, val); 617 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); 618 udelay(200); 619 620 if (!using_ssc_source) { 621 drm_dbg_kms(&dev_priv->drm, "Disabling SSC source\n"); 622 623 /* Turn off the SSC source */ 624 val &= ~DREF_SSC_SOURCE_MASK; 625 val |= DREF_SSC_SOURCE_DISABLE; 626 627 /* Turn off SSC1 */ 628 val &= ~DREF_SSC1_ENABLE; 629 630 intel_de_write(dev_priv, PCH_DREF_CONTROL, val); 631 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL); 632 udelay(200); 633 } 634 } 635 636 BUG_ON(val != final); 637} 638 639/* 640 * Initialize reference clocks when the driver loads 641 */ 642void intel_init_pch_refclk(struct drm_i915_private *dev_priv) 643{ 644 if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) 645 ilk_init_pch_refclk(dev_priv); 646 else if (HAS_PCH_LPT(dev_priv)) 647 lpt_init_pch_refclk(dev_priv); 648}