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