0001
0002
0003
0004
0005
0006 #include "intel_de.h"
0007 #include "intel_display_types.h"
0008 #include "intel_panel.h"
0009 #include "intel_pch_refclk.h"
0010 #include "intel_sbi.h"
0011
0012 static void lpt_fdi_reset_mphy(struct drm_i915_private *dev_priv)
0013 {
0014 u32 tmp;
0015
0016 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2);
0017 tmp |= FDI_MPHY_IOSFSB_RESET_CTL;
0018 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp);
0019
0020 if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) &
0021 FDI_MPHY_IOSFSB_RESET_STATUS, 100))
0022 drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n");
0023
0024 tmp = intel_de_read(dev_priv, SOUTH_CHICKEN2);
0025 tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL;
0026 intel_de_write(dev_priv, SOUTH_CHICKEN2, tmp);
0027
0028 if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) &
0029 FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100))
0030 drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n");
0031 }
0032
0033
0034 static void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv)
0035 {
0036 u32 tmp;
0037
0038 lpt_fdi_reset_mphy(dev_priv);
0039
0040 tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY);
0041 tmp &= ~(0xFF << 24);
0042 tmp |= (0x12 << 24);
0043 intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY);
0044
0045 tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY);
0046 tmp |= (1 << 11);
0047 intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY);
0048
0049 tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY);
0050 tmp |= (1 << 11);
0051 intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY);
0052
0053 tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY);
0054 tmp |= (1 << 24) | (1 << 21) | (1 << 18);
0055 intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY);
0056
0057 tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY);
0058 tmp |= (1 << 24) | (1 << 21) | (1 << 18);
0059 intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY);
0060
0061 tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY);
0062 tmp &= ~(7 << 13);
0063 tmp |= (5 << 13);
0064 intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY);
0065
0066 tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY);
0067 tmp &= ~(7 << 13);
0068 tmp |= (5 << 13);
0069 intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY);
0070
0071 tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY);
0072 tmp &= ~0xFF;
0073 tmp |= 0x1C;
0074 intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY);
0075
0076 tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY);
0077 tmp &= ~0xFF;
0078 tmp |= 0x1C;
0079 intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY);
0080
0081 tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY);
0082 tmp &= ~(0xFF << 16);
0083 tmp |= (0x1C << 16);
0084 intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY);
0085
0086 tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY);
0087 tmp &= ~(0xFF << 16);
0088 tmp |= (0x1C << 16);
0089 intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY);
0090
0091 tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY);
0092 tmp |= (1 << 27);
0093 intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY);
0094
0095 tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY);
0096 tmp |= (1 << 27);
0097 intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY);
0098
0099 tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY);
0100 tmp &= ~(0xF << 28);
0101 tmp |= (4 << 28);
0102 intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY);
0103
0104 tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY);
0105 tmp &= ~(0xF << 28);
0106 tmp |= (4 << 28);
0107 intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY);
0108 }
0109
0110 void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
0111 {
0112 u32 temp;
0113
0114 intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_GATE);
0115
0116 mutex_lock(&dev_priv->sb_lock);
0117
0118 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
0119 temp |= SBI_SSCCTL_DISABLE;
0120 intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
0121
0122 mutex_unlock(&dev_priv->sb_lock);
0123 }
0124
0125 struct iclkip_params {
0126 u32 iclk_virtual_root_freq;
0127 u32 iclk_pi_range;
0128 u32 divsel, phaseinc, auxdiv, phasedir, desired_divisor;
0129 };
0130
0131 static void iclkip_params_init(struct iclkip_params *p)
0132 {
0133 memset(p, 0, sizeof(*p));
0134
0135 p->iclk_virtual_root_freq = 172800 * 1000;
0136 p->iclk_pi_range = 64;
0137 }
0138
0139 static int lpt_iclkip_freq(struct iclkip_params *p)
0140 {
0141 return DIV_ROUND_CLOSEST(p->iclk_virtual_root_freq,
0142 p->desired_divisor << p->auxdiv);
0143 }
0144
0145 static void lpt_compute_iclkip(struct iclkip_params *p, int clock)
0146 {
0147 iclkip_params_init(p);
0148
0149
0150
0151
0152
0153
0154
0155 for (p->auxdiv = 0; p->auxdiv < 2; p->auxdiv++) {
0156 p->desired_divisor = DIV_ROUND_CLOSEST(p->iclk_virtual_root_freq,
0157 clock << p->auxdiv);
0158 p->divsel = (p->desired_divisor / p->iclk_pi_range) - 2;
0159 p->phaseinc = p->desired_divisor % p->iclk_pi_range;
0160
0161
0162
0163
0164
0165 if (p->divsel <= 0x7f)
0166 break;
0167 }
0168 }
0169
0170
0171 void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
0172 {
0173 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0174 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0175 int clock = crtc_state->hw.adjusted_mode.crtc_clock;
0176 struct iclkip_params p;
0177 u32 temp;
0178
0179 lpt_disable_iclkip(dev_priv);
0180
0181 lpt_compute_iclkip(&p, clock);
0182
0183
0184 drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIVSEL(p.divsel) &
0185 ~SBI_SSCDIVINTPHASE_DIVSEL_MASK);
0186 drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIR(p.phasedir) &
0187 ~SBI_SSCDIVINTPHASE_INCVAL_MASK);
0188
0189 drm_dbg_kms(&dev_priv->drm,
0190 "iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
0191 clock, p.auxdiv, p.divsel, p.phasedir, p.phaseinc);
0192
0193 mutex_lock(&dev_priv->sb_lock);
0194
0195
0196 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
0197 temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
0198 temp |= SBI_SSCDIVINTPHASE_DIVSEL(p.divsel);
0199 temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
0200 temp |= SBI_SSCDIVINTPHASE_INCVAL(p.phaseinc);
0201 temp |= SBI_SSCDIVINTPHASE_DIR(p.phasedir);
0202 temp |= SBI_SSCDIVINTPHASE_PROPAGATE;
0203 intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);
0204
0205
0206 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
0207 temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
0208 temp |= SBI_SSCAUXDIV_FINALDIV2SEL(p.auxdiv);
0209 intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK);
0210
0211
0212 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
0213 temp &= ~SBI_SSCCTL_DISABLE;
0214 intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
0215
0216 mutex_unlock(&dev_priv->sb_lock);
0217
0218
0219 udelay(24);
0220
0221 intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_UNGATE);
0222 }
0223
0224 int lpt_get_iclkip(struct drm_i915_private *dev_priv)
0225 {
0226 struct iclkip_params p;
0227 u32 temp;
0228
0229 if ((intel_de_read(dev_priv, PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0)
0230 return 0;
0231
0232 iclkip_params_init(&p);
0233
0234 mutex_lock(&dev_priv->sb_lock);
0235
0236 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
0237 if (temp & SBI_SSCCTL_DISABLE) {
0238 mutex_unlock(&dev_priv->sb_lock);
0239 return 0;
0240 }
0241
0242 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
0243 p.divsel = (temp & SBI_SSCDIVINTPHASE_DIVSEL_MASK) >>
0244 SBI_SSCDIVINTPHASE_DIVSEL_SHIFT;
0245 p.phaseinc = (temp & SBI_SSCDIVINTPHASE_INCVAL_MASK) >>
0246 SBI_SSCDIVINTPHASE_INCVAL_SHIFT;
0247
0248 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
0249 p.auxdiv = (temp & SBI_SSCAUXDIV_FINALDIV2SEL_MASK) >>
0250 SBI_SSCAUXDIV_FINALDIV2SEL_SHIFT;
0251
0252 mutex_unlock(&dev_priv->sb_lock);
0253
0254 p.desired_divisor = (p.divsel + 2) * p.iclk_pi_range + p.phaseinc;
0255
0256 return lpt_iclkip_freq(&p);
0257 }
0258
0259
0260
0261
0262
0263
0264
0265 static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv,
0266 bool with_spread, bool with_fdi)
0267 {
0268 u32 reg, tmp;
0269
0270 if (drm_WARN(&dev_priv->drm, with_fdi && !with_spread,
0271 "FDI requires downspread\n"))
0272 with_spread = true;
0273 if (drm_WARN(&dev_priv->drm, HAS_PCH_LPT_LP(dev_priv) &&
0274 with_fdi, "LP PCH doesn't have FDI\n"))
0275 with_fdi = false;
0276
0277 mutex_lock(&dev_priv->sb_lock);
0278
0279 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
0280 tmp &= ~SBI_SSCCTL_DISABLE;
0281 tmp |= SBI_SSCCTL_PATHALT;
0282 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
0283
0284 udelay(24);
0285
0286 if (with_spread) {
0287 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
0288 tmp &= ~SBI_SSCCTL_PATHALT;
0289 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
0290
0291 if (with_fdi)
0292 lpt_fdi_program_mphy(dev_priv);
0293 }
0294
0295 reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0;
0296 tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
0297 tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE;
0298 intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
0299
0300 mutex_unlock(&dev_priv->sb_lock);
0301 }
0302
0303
0304 void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv)
0305 {
0306 u32 reg, tmp;
0307
0308 mutex_lock(&dev_priv->sb_lock);
0309
0310 reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0;
0311 tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK);
0312 tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE;
0313 intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK);
0314
0315 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
0316 if (!(tmp & SBI_SSCCTL_DISABLE)) {
0317 if (!(tmp & SBI_SSCCTL_PATHALT)) {
0318 tmp |= SBI_SSCCTL_PATHALT;
0319 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
0320 udelay(32);
0321 }
0322 tmp |= SBI_SSCCTL_DISABLE;
0323 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
0324 }
0325
0326 mutex_unlock(&dev_priv->sb_lock);
0327 }
0328
0329 #define BEND_IDX(steps) ((50 + (steps)) / 5)
0330
0331 static const u16 sscdivintphase[] = {
0332 [BEND_IDX( 50)] = 0x3B23,
0333 [BEND_IDX( 45)] = 0x3B23,
0334 [BEND_IDX( 40)] = 0x3C23,
0335 [BEND_IDX( 35)] = 0x3C23,
0336 [BEND_IDX( 30)] = 0x3D23,
0337 [BEND_IDX( 25)] = 0x3D23,
0338 [BEND_IDX( 20)] = 0x3E23,
0339 [BEND_IDX( 15)] = 0x3E23,
0340 [BEND_IDX( 10)] = 0x3F23,
0341 [BEND_IDX( 5)] = 0x3F23,
0342 [BEND_IDX( 0)] = 0x0025,
0343 [BEND_IDX( -5)] = 0x0025,
0344 [BEND_IDX(-10)] = 0x0125,
0345 [BEND_IDX(-15)] = 0x0125,
0346 [BEND_IDX(-20)] = 0x0225,
0347 [BEND_IDX(-25)] = 0x0225,
0348 [BEND_IDX(-30)] = 0x0325,
0349 [BEND_IDX(-35)] = 0x0325,
0350 [BEND_IDX(-40)] = 0x0425,
0351 [BEND_IDX(-45)] = 0x0425,
0352 [BEND_IDX(-50)] = 0x0525,
0353 };
0354
0355
0356
0357
0358
0359
0360
0361 static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
0362 {
0363 u32 tmp;
0364 int idx = BEND_IDX(steps);
0365
0366 if (drm_WARN_ON(&dev_priv->drm, steps % 5 != 0))
0367 return;
0368
0369 if (drm_WARN_ON(&dev_priv->drm, idx >= ARRAY_SIZE(sscdivintphase)))
0370 return;
0371
0372 mutex_lock(&dev_priv->sb_lock);
0373
0374 if (steps % 10 != 0)
0375 tmp = 0xAAAAAAAB;
0376 else
0377 tmp = 0x00000000;
0378 intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK);
0379
0380 tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK);
0381 tmp &= 0xffff0000;
0382 tmp |= sscdivintphase[idx];
0383 intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
0384
0385 mutex_unlock(&dev_priv->sb_lock);
0386 }
0387
0388 #undef BEND_IDX
0389
0390 static bool spll_uses_pch_ssc(struct drm_i915_private *dev_priv)
0391 {
0392 u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP);
0393 u32 ctl = intel_de_read(dev_priv, SPLL_CTL);
0394
0395 if ((ctl & SPLL_PLL_ENABLE) == 0)
0396 return false;
0397
0398 if ((ctl & SPLL_REF_MASK) == SPLL_REF_MUXED_SSC &&
0399 (fuse_strap & HSW_CPU_SSC_ENABLE) == 0)
0400 return true;
0401
0402 if (IS_BROADWELL(dev_priv) &&
0403 (ctl & SPLL_REF_MASK) == SPLL_REF_PCH_SSC_BDW)
0404 return true;
0405
0406 return false;
0407 }
0408
0409 static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv,
0410 enum intel_dpll_id id)
0411 {
0412 u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP);
0413 u32 ctl = intel_de_read(dev_priv, WRPLL_CTL(id));
0414
0415 if ((ctl & WRPLL_PLL_ENABLE) == 0)
0416 return false;
0417
0418 if ((ctl & WRPLL_REF_MASK) == WRPLL_REF_PCH_SSC)
0419 return true;
0420
0421 if ((IS_BROADWELL(dev_priv) || IS_HSW_ULT(dev_priv)) &&
0422 (ctl & WRPLL_REF_MASK) == WRPLL_REF_MUXED_SSC_BDW &&
0423 (fuse_strap & HSW_CPU_SSC_ENABLE) == 0)
0424 return true;
0425
0426 return false;
0427 }
0428
0429 static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv)
0430 {
0431 struct intel_encoder *encoder;
0432 bool has_fdi = false;
0433
0434 for_each_intel_encoder(&dev_priv->drm, encoder) {
0435 switch (encoder->type) {
0436 case INTEL_OUTPUT_ANALOG:
0437 has_fdi = true;
0438 break;
0439 default:
0440 break;
0441 }
0442 }
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 dev_priv->pch_ssc_use = 0;
0460
0461 if (spll_uses_pch_ssc(dev_priv)) {
0462 drm_dbg_kms(&dev_priv->drm, "SPLL using PCH SSC\n");
0463 dev_priv->pch_ssc_use |= BIT(DPLL_ID_SPLL);
0464 }
0465
0466 if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) {
0467 drm_dbg_kms(&dev_priv->drm, "WRPLL1 using PCH SSC\n");
0468 dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL1);
0469 }
0470
0471 if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) {
0472 drm_dbg_kms(&dev_priv->drm, "WRPLL2 using PCH SSC\n");
0473 dev_priv->pch_ssc_use |= BIT(DPLL_ID_WRPLL2);
0474 }
0475
0476 if (dev_priv->pch_ssc_use)
0477 return;
0478
0479 if (has_fdi) {
0480 lpt_bend_clkout_dp(dev_priv, 0);
0481 lpt_enable_clkout_dp(dev_priv, true, true);
0482 } else {
0483 lpt_disable_clkout_dp(dev_priv);
0484 }
0485 }
0486
0487 static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv)
0488 {
0489 struct intel_encoder *encoder;
0490 int i;
0491 u32 val, final;
0492 bool has_lvds = false;
0493 bool has_cpu_edp = false;
0494 bool has_panel = false;
0495 bool has_ck505 = false;
0496 bool can_ssc = false;
0497 bool using_ssc_source = false;
0498
0499
0500 for_each_intel_encoder(&dev_priv->drm, encoder) {
0501 switch (encoder->type) {
0502 case INTEL_OUTPUT_LVDS:
0503 has_panel = true;
0504 has_lvds = true;
0505 break;
0506 case INTEL_OUTPUT_EDP:
0507 has_panel = true;
0508 if (encoder->port == PORT_A)
0509 has_cpu_edp = true;
0510 break;
0511 default:
0512 break;
0513 }
0514 }
0515
0516 if (HAS_PCH_IBX(dev_priv)) {
0517 has_ck505 = dev_priv->vbt.display_clock_mode;
0518 can_ssc = has_ck505;
0519 } else {
0520 has_ck505 = false;
0521 can_ssc = true;
0522 }
0523
0524
0525 for (i = 0; i < dev_priv->dpll.num_shared_dpll; i++) {
0526 u32 temp = intel_de_read(dev_priv, PCH_DPLL(i));
0527
0528 if (!(temp & DPLL_VCO_ENABLE))
0529 continue;
0530
0531 if ((temp & PLL_REF_INPUT_MASK) ==
0532 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
0533 using_ssc_source = true;
0534 break;
0535 }
0536 }
0537
0538 drm_dbg_kms(&dev_priv->drm,
0539 "has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
0540 has_panel, has_lvds, has_ck505, using_ssc_source);
0541
0542
0543
0544
0545
0546
0547 val = intel_de_read(dev_priv, PCH_DREF_CONTROL);
0548
0549
0550
0551
0552
0553 final = val;
0554 final &= ~DREF_NONSPREAD_SOURCE_MASK;
0555 if (has_ck505)
0556 final |= DREF_NONSPREAD_CK505_ENABLE;
0557 else
0558 final |= DREF_NONSPREAD_SOURCE_ENABLE;
0559
0560 final &= ~DREF_SSC_SOURCE_MASK;
0561 final &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
0562 final &= ~DREF_SSC1_ENABLE;
0563
0564 if (has_panel) {
0565 final |= DREF_SSC_SOURCE_ENABLE;
0566
0567 if (intel_panel_use_ssc(dev_priv) && can_ssc)
0568 final |= DREF_SSC1_ENABLE;
0569
0570 if (has_cpu_edp) {
0571 if (intel_panel_use_ssc(dev_priv) && can_ssc)
0572 final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
0573 else
0574 final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
0575 } else {
0576 final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
0577 }
0578 } else if (using_ssc_source) {
0579 final |= DREF_SSC_SOURCE_ENABLE;
0580 final |= DREF_SSC1_ENABLE;
0581 }
0582
0583 if (final == val)
0584 return;
0585
0586
0587 val &= ~DREF_NONSPREAD_SOURCE_MASK;
0588
0589 if (has_ck505)
0590 val |= DREF_NONSPREAD_CK505_ENABLE;
0591 else
0592 val |= DREF_NONSPREAD_SOURCE_ENABLE;
0593
0594 if (has_panel) {
0595 val &= ~DREF_SSC_SOURCE_MASK;
0596 val |= DREF_SSC_SOURCE_ENABLE;
0597
0598
0599 if (intel_panel_use_ssc(dev_priv) && can_ssc) {
0600 drm_dbg_kms(&dev_priv->drm, "Using SSC on panel\n");
0601 val |= DREF_SSC1_ENABLE;
0602 } else {
0603 val &= ~DREF_SSC1_ENABLE;
0604 }
0605
0606
0607 intel_de_write(dev_priv, PCH_DREF_CONTROL, val);
0608 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL);
0609 udelay(200);
0610
0611 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
0612
0613
0614 if (has_cpu_edp) {
0615 if (intel_panel_use_ssc(dev_priv) && can_ssc) {
0616 drm_dbg_kms(&dev_priv->drm,
0617 "Using SSC on eDP\n");
0618 val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
0619 } else {
0620 val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
0621 }
0622 } else {
0623 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
0624 }
0625
0626 intel_de_write(dev_priv, PCH_DREF_CONTROL, val);
0627 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL);
0628 udelay(200);
0629 } else {
0630 drm_dbg_kms(&dev_priv->drm, "Disabling CPU source output\n");
0631
0632 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
0633
0634
0635 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
0636
0637 intel_de_write(dev_priv, PCH_DREF_CONTROL, val);
0638 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL);
0639 udelay(200);
0640
0641 if (!using_ssc_source) {
0642 drm_dbg_kms(&dev_priv->drm, "Disabling SSC source\n");
0643
0644
0645 val &= ~DREF_SSC_SOURCE_MASK;
0646 val |= DREF_SSC_SOURCE_DISABLE;
0647
0648
0649 val &= ~DREF_SSC1_ENABLE;
0650
0651 intel_de_write(dev_priv, PCH_DREF_CONTROL, val);
0652 intel_de_posting_read(dev_priv, PCH_DREF_CONTROL);
0653 udelay(200);
0654 }
0655 }
0656
0657 BUG_ON(val != final);
0658 }
0659
0660
0661
0662
0663 void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
0664 {
0665 if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))
0666 ilk_init_pch_refclk(dev_priv);
0667 else if (HAS_PCH_LPT(dev_priv))
0668 lpt_init_pch_refclk(dev_priv);
0669 }