xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/i915/display/intel_cdclk.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2006-2017 Intel Corporation
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the next
12*4882a593Smuzhiyun  * paragraph) shall be included in all copies or substantial portions of the
13*4882a593Smuzhiyun  * Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*4882a593Smuzhiyun  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*4882a593Smuzhiyun  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*4882a593Smuzhiyun  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*4882a593Smuzhiyun  * DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #include <linux/time.h>
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include "intel_atomic.h"
27*4882a593Smuzhiyun #include "intel_bw.h"
28*4882a593Smuzhiyun #include "intel_cdclk.h"
29*4882a593Smuzhiyun #include "intel_display_types.h"
30*4882a593Smuzhiyun #include "intel_sideband.h"
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /**
33*4882a593Smuzhiyun  * DOC: CDCLK / RAWCLK
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * The display engine uses several different clocks to do its work. There
36*4882a593Smuzhiyun  * are two main clocks involved that aren't directly related to the actual
37*4882a593Smuzhiyun  * pixel clock or any symbol/bit clock of the actual output port. These
38*4882a593Smuzhiyun  * are the core display clock (CDCLK) and RAWCLK.
39*4882a593Smuzhiyun  *
40*4882a593Smuzhiyun  * CDCLK clocks most of the display pipe logic, and thus its frequency
41*4882a593Smuzhiyun  * must be high enough to support the rate at which pixels are flowing
42*4882a593Smuzhiyun  * through the pipes. Downscaling must also be accounted as that increases
43*4882a593Smuzhiyun  * the effective pixel rate.
44*4882a593Smuzhiyun  *
45*4882a593Smuzhiyun  * On several platforms the CDCLK frequency can be changed dynamically
46*4882a593Smuzhiyun  * to minimize power consumption for a given display configuration.
47*4882a593Smuzhiyun  * Typically changes to the CDCLK frequency require all the display pipes
48*4882a593Smuzhiyun  * to be shut down while the frequency is being changed.
49*4882a593Smuzhiyun  *
50*4882a593Smuzhiyun  * On SKL+ the DMC will toggle the CDCLK off/on during DC5/6 entry/exit.
51*4882a593Smuzhiyun  * DMC will not change the active CDCLK frequency however, so that part
52*4882a593Smuzhiyun  * will still be performed by the driver directly.
53*4882a593Smuzhiyun  *
54*4882a593Smuzhiyun  * RAWCLK is a fixed frequency clock, often used by various auxiliary
55*4882a593Smuzhiyun  * blocks such as AUX CH or backlight PWM. Hence the only thing we
56*4882a593Smuzhiyun  * really need to know about RAWCLK is its frequency so that various
57*4882a593Smuzhiyun  * dividers can be programmed correctly.
58*4882a593Smuzhiyun  */
59*4882a593Smuzhiyun 
fixed_133mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)60*4882a593Smuzhiyun static void fixed_133mhz_get_cdclk(struct drm_i915_private *dev_priv,
61*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun 	cdclk_config->cdclk = 133333;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
fixed_200mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)66*4882a593Smuzhiyun static void fixed_200mhz_get_cdclk(struct drm_i915_private *dev_priv,
67*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun 	cdclk_config->cdclk = 200000;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
fixed_266mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)72*4882a593Smuzhiyun static void fixed_266mhz_get_cdclk(struct drm_i915_private *dev_priv,
73*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	cdclk_config->cdclk = 266667;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun 
fixed_333mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)78*4882a593Smuzhiyun static void fixed_333mhz_get_cdclk(struct drm_i915_private *dev_priv,
79*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	cdclk_config->cdclk = 333333;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
fixed_400mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)84*4882a593Smuzhiyun static void fixed_400mhz_get_cdclk(struct drm_i915_private *dev_priv,
85*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	cdclk_config->cdclk = 400000;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
fixed_450mhz_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)90*4882a593Smuzhiyun static void fixed_450mhz_get_cdclk(struct drm_i915_private *dev_priv,
91*4882a593Smuzhiyun 				   struct intel_cdclk_config *cdclk_config)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	cdclk_config->cdclk = 450000;
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun 
i85x_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)96*4882a593Smuzhiyun static void i85x_get_cdclk(struct drm_i915_private *dev_priv,
97*4882a593Smuzhiyun 			   struct intel_cdclk_config *cdclk_config)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
100*4882a593Smuzhiyun 	u16 hpllcc = 0;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/*
103*4882a593Smuzhiyun 	 * 852GM/852GMV only supports 133 MHz and the HPLLCC
104*4882a593Smuzhiyun 	 * encoding is different :(
105*4882a593Smuzhiyun 	 * FIXME is this the right way to detect 852GM/852GMV?
106*4882a593Smuzhiyun 	 */
107*4882a593Smuzhiyun 	if (pdev->revision == 0x1) {
108*4882a593Smuzhiyun 		cdclk_config->cdclk = 133333;
109*4882a593Smuzhiyun 		return;
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	pci_bus_read_config_word(pdev->bus,
113*4882a593Smuzhiyun 				 PCI_DEVFN(0, 3), HPLLCC, &hpllcc);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	/* Assume that the hardware is in the high speed state.  This
116*4882a593Smuzhiyun 	 * should be the default.
117*4882a593Smuzhiyun 	 */
118*4882a593Smuzhiyun 	switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
119*4882a593Smuzhiyun 	case GC_CLOCK_133_200:
120*4882a593Smuzhiyun 	case GC_CLOCK_133_200_2:
121*4882a593Smuzhiyun 	case GC_CLOCK_100_200:
122*4882a593Smuzhiyun 		cdclk_config->cdclk = 200000;
123*4882a593Smuzhiyun 		break;
124*4882a593Smuzhiyun 	case GC_CLOCK_166_250:
125*4882a593Smuzhiyun 		cdclk_config->cdclk = 250000;
126*4882a593Smuzhiyun 		break;
127*4882a593Smuzhiyun 	case GC_CLOCK_100_133:
128*4882a593Smuzhiyun 		cdclk_config->cdclk = 133333;
129*4882a593Smuzhiyun 		break;
130*4882a593Smuzhiyun 	case GC_CLOCK_133_266:
131*4882a593Smuzhiyun 	case GC_CLOCK_133_266_2:
132*4882a593Smuzhiyun 	case GC_CLOCK_166_266:
133*4882a593Smuzhiyun 		cdclk_config->cdclk = 266667;
134*4882a593Smuzhiyun 		break;
135*4882a593Smuzhiyun 	}
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
i915gm_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)138*4882a593Smuzhiyun static void i915gm_get_cdclk(struct drm_i915_private *dev_priv,
139*4882a593Smuzhiyun 			     struct intel_cdclk_config *cdclk_config)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
142*4882a593Smuzhiyun 	u16 gcfgc = 0;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &gcfgc);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	if (gcfgc & GC_LOW_FREQUENCY_ENABLE) {
147*4882a593Smuzhiyun 		cdclk_config->cdclk = 133333;
148*4882a593Smuzhiyun 		return;
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
152*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_333_320_MHZ:
153*4882a593Smuzhiyun 		cdclk_config->cdclk = 333333;
154*4882a593Smuzhiyun 		break;
155*4882a593Smuzhiyun 	default:
156*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_190_200_MHZ:
157*4882a593Smuzhiyun 		cdclk_config->cdclk = 190000;
158*4882a593Smuzhiyun 		break;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
i945gm_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)162*4882a593Smuzhiyun static void i945gm_get_cdclk(struct drm_i915_private *dev_priv,
163*4882a593Smuzhiyun 			     struct intel_cdclk_config *cdclk_config)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
166*4882a593Smuzhiyun 	u16 gcfgc = 0;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &gcfgc);
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	if (gcfgc & GC_LOW_FREQUENCY_ENABLE) {
171*4882a593Smuzhiyun 		cdclk_config->cdclk = 133333;
172*4882a593Smuzhiyun 		return;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
176*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_333_320_MHZ:
177*4882a593Smuzhiyun 		cdclk_config->cdclk = 320000;
178*4882a593Smuzhiyun 		break;
179*4882a593Smuzhiyun 	default:
180*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_190_200_MHZ:
181*4882a593Smuzhiyun 		cdclk_config->cdclk = 200000;
182*4882a593Smuzhiyun 		break;
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
intel_hpll_vco(struct drm_i915_private * dev_priv)186*4882a593Smuzhiyun static unsigned int intel_hpll_vco(struct drm_i915_private *dev_priv)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun 	static const unsigned int blb_vco[8] = {
189*4882a593Smuzhiyun 		[0] = 3200000,
190*4882a593Smuzhiyun 		[1] = 4000000,
191*4882a593Smuzhiyun 		[2] = 5333333,
192*4882a593Smuzhiyun 		[3] = 4800000,
193*4882a593Smuzhiyun 		[4] = 6400000,
194*4882a593Smuzhiyun 	};
195*4882a593Smuzhiyun 	static const unsigned int pnv_vco[8] = {
196*4882a593Smuzhiyun 		[0] = 3200000,
197*4882a593Smuzhiyun 		[1] = 4000000,
198*4882a593Smuzhiyun 		[2] = 5333333,
199*4882a593Smuzhiyun 		[3] = 4800000,
200*4882a593Smuzhiyun 		[4] = 2666667,
201*4882a593Smuzhiyun 	};
202*4882a593Smuzhiyun 	static const unsigned int cl_vco[8] = {
203*4882a593Smuzhiyun 		[0] = 3200000,
204*4882a593Smuzhiyun 		[1] = 4000000,
205*4882a593Smuzhiyun 		[2] = 5333333,
206*4882a593Smuzhiyun 		[3] = 6400000,
207*4882a593Smuzhiyun 		[4] = 3333333,
208*4882a593Smuzhiyun 		[5] = 3566667,
209*4882a593Smuzhiyun 		[6] = 4266667,
210*4882a593Smuzhiyun 	};
211*4882a593Smuzhiyun 	static const unsigned int elk_vco[8] = {
212*4882a593Smuzhiyun 		[0] = 3200000,
213*4882a593Smuzhiyun 		[1] = 4000000,
214*4882a593Smuzhiyun 		[2] = 5333333,
215*4882a593Smuzhiyun 		[3] = 4800000,
216*4882a593Smuzhiyun 	};
217*4882a593Smuzhiyun 	static const unsigned int ctg_vco[8] = {
218*4882a593Smuzhiyun 		[0] = 3200000,
219*4882a593Smuzhiyun 		[1] = 4000000,
220*4882a593Smuzhiyun 		[2] = 5333333,
221*4882a593Smuzhiyun 		[3] = 6400000,
222*4882a593Smuzhiyun 		[4] = 2666667,
223*4882a593Smuzhiyun 		[5] = 4266667,
224*4882a593Smuzhiyun 	};
225*4882a593Smuzhiyun 	const unsigned int *vco_table;
226*4882a593Smuzhiyun 	unsigned int vco;
227*4882a593Smuzhiyun 	u8 tmp = 0;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	/* FIXME other chipsets? */
230*4882a593Smuzhiyun 	if (IS_GM45(dev_priv))
231*4882a593Smuzhiyun 		vco_table = ctg_vco;
232*4882a593Smuzhiyun 	else if (IS_G45(dev_priv))
233*4882a593Smuzhiyun 		vco_table = elk_vco;
234*4882a593Smuzhiyun 	else if (IS_I965GM(dev_priv))
235*4882a593Smuzhiyun 		vco_table = cl_vco;
236*4882a593Smuzhiyun 	else if (IS_PINEVIEW(dev_priv))
237*4882a593Smuzhiyun 		vco_table = pnv_vco;
238*4882a593Smuzhiyun 	else if (IS_G33(dev_priv))
239*4882a593Smuzhiyun 		vco_table = blb_vco;
240*4882a593Smuzhiyun 	else
241*4882a593Smuzhiyun 		return 0;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	tmp = intel_de_read(dev_priv,
244*4882a593Smuzhiyun 			    IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv) ? HPLLVCO_MOBILE : HPLLVCO);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	vco = vco_table[tmp & 0x7];
247*4882a593Smuzhiyun 	if (vco == 0)
248*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "Bad HPLL VCO (HPLLVCO=0x%02x)\n",
249*4882a593Smuzhiyun 			tmp);
250*4882a593Smuzhiyun 	else
251*4882a593Smuzhiyun 		drm_dbg_kms(&dev_priv->drm, "HPLL VCO %u kHz\n", vco);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	return vco;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
g33_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)256*4882a593Smuzhiyun static void g33_get_cdclk(struct drm_i915_private *dev_priv,
257*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
260*4882a593Smuzhiyun 	static const u8 div_3200[] = { 12, 10,  8,  7, 5, 16 };
261*4882a593Smuzhiyun 	static const u8 div_4000[] = { 14, 12, 10,  8, 6, 20 };
262*4882a593Smuzhiyun 	static const u8 div_4800[] = { 20, 14, 12, 10, 8, 24 };
263*4882a593Smuzhiyun 	static const u8 div_5333[] = { 20, 16, 12, 12, 8, 28 };
264*4882a593Smuzhiyun 	const u8 *div_table;
265*4882a593Smuzhiyun 	unsigned int cdclk_sel;
266*4882a593Smuzhiyun 	u16 tmp = 0;
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	cdclk_config->vco = intel_hpll_vco(dev_priv);
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &tmp);
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	cdclk_sel = (tmp >> 4) & 0x7;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	if (cdclk_sel >= ARRAY_SIZE(div_3200))
275*4882a593Smuzhiyun 		goto fail;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	switch (cdclk_config->vco) {
278*4882a593Smuzhiyun 	case 3200000:
279*4882a593Smuzhiyun 		div_table = div_3200;
280*4882a593Smuzhiyun 		break;
281*4882a593Smuzhiyun 	case 4000000:
282*4882a593Smuzhiyun 		div_table = div_4000;
283*4882a593Smuzhiyun 		break;
284*4882a593Smuzhiyun 	case 4800000:
285*4882a593Smuzhiyun 		div_table = div_4800;
286*4882a593Smuzhiyun 		break;
287*4882a593Smuzhiyun 	case 5333333:
288*4882a593Smuzhiyun 		div_table = div_5333;
289*4882a593Smuzhiyun 		break;
290*4882a593Smuzhiyun 	default:
291*4882a593Smuzhiyun 		goto fail;
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco,
295*4882a593Smuzhiyun 						div_table[cdclk_sel]);
296*4882a593Smuzhiyun 	return;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun fail:
299*4882a593Smuzhiyun 	drm_err(&dev_priv->drm,
300*4882a593Smuzhiyun 		"Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%08x\n",
301*4882a593Smuzhiyun 		cdclk_config->vco, tmp);
302*4882a593Smuzhiyun 	cdclk_config->cdclk = 190476;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
pnv_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)305*4882a593Smuzhiyun static void pnv_get_cdclk(struct drm_i915_private *dev_priv,
306*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
309*4882a593Smuzhiyun 	u16 gcfgc = 0;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &gcfgc);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
314*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_267_MHZ_PNV:
315*4882a593Smuzhiyun 		cdclk_config->cdclk = 266667;
316*4882a593Smuzhiyun 		break;
317*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_333_MHZ_PNV:
318*4882a593Smuzhiyun 		cdclk_config->cdclk = 333333;
319*4882a593Smuzhiyun 		break;
320*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_444_MHZ_PNV:
321*4882a593Smuzhiyun 		cdclk_config->cdclk = 444444;
322*4882a593Smuzhiyun 		break;
323*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_200_MHZ_PNV:
324*4882a593Smuzhiyun 		cdclk_config->cdclk = 200000;
325*4882a593Smuzhiyun 		break;
326*4882a593Smuzhiyun 	default:
327*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
328*4882a593Smuzhiyun 			"Unknown pnv display core clock 0x%04x\n", gcfgc);
329*4882a593Smuzhiyun 		fallthrough;
330*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_133_MHZ_PNV:
331*4882a593Smuzhiyun 		cdclk_config->cdclk = 133333;
332*4882a593Smuzhiyun 		break;
333*4882a593Smuzhiyun 	case GC_DISPLAY_CLOCK_167_MHZ_PNV:
334*4882a593Smuzhiyun 		cdclk_config->cdclk = 166667;
335*4882a593Smuzhiyun 		break;
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun 
i965gm_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)339*4882a593Smuzhiyun static void i965gm_get_cdclk(struct drm_i915_private *dev_priv,
340*4882a593Smuzhiyun 			     struct intel_cdclk_config *cdclk_config)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
343*4882a593Smuzhiyun 	static const u8 div_3200[] = { 16, 10,  8 };
344*4882a593Smuzhiyun 	static const u8 div_4000[] = { 20, 12, 10 };
345*4882a593Smuzhiyun 	static const u8 div_5333[] = { 24, 16, 14 };
346*4882a593Smuzhiyun 	const u8 *div_table;
347*4882a593Smuzhiyun 	unsigned int cdclk_sel;
348*4882a593Smuzhiyun 	u16 tmp = 0;
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	cdclk_config->vco = intel_hpll_vco(dev_priv);
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &tmp);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	cdclk_sel = ((tmp >> 8) & 0x1f) - 1;
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (cdclk_sel >= ARRAY_SIZE(div_3200))
357*4882a593Smuzhiyun 		goto fail;
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	switch (cdclk_config->vco) {
360*4882a593Smuzhiyun 	case 3200000:
361*4882a593Smuzhiyun 		div_table = div_3200;
362*4882a593Smuzhiyun 		break;
363*4882a593Smuzhiyun 	case 4000000:
364*4882a593Smuzhiyun 		div_table = div_4000;
365*4882a593Smuzhiyun 		break;
366*4882a593Smuzhiyun 	case 5333333:
367*4882a593Smuzhiyun 		div_table = div_5333;
368*4882a593Smuzhiyun 		break;
369*4882a593Smuzhiyun 	default:
370*4882a593Smuzhiyun 		goto fail;
371*4882a593Smuzhiyun 	}
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco,
374*4882a593Smuzhiyun 						div_table[cdclk_sel]);
375*4882a593Smuzhiyun 	return;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun fail:
378*4882a593Smuzhiyun 	drm_err(&dev_priv->drm,
379*4882a593Smuzhiyun 		"Unable to determine CDCLK. HPLL VCO=%u kHz, CFGC=0x%04x\n",
380*4882a593Smuzhiyun 		cdclk_config->vco, tmp);
381*4882a593Smuzhiyun 	cdclk_config->cdclk = 200000;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
gm45_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)384*4882a593Smuzhiyun static void gm45_get_cdclk(struct drm_i915_private *dev_priv,
385*4882a593Smuzhiyun 			   struct intel_cdclk_config *cdclk_config)
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun 	struct pci_dev *pdev = dev_priv->drm.pdev;
388*4882a593Smuzhiyun 	unsigned int cdclk_sel;
389*4882a593Smuzhiyun 	u16 tmp = 0;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	cdclk_config->vco = intel_hpll_vco(dev_priv);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	pci_read_config_word(pdev, GCFGC, &tmp);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	cdclk_sel = (tmp >> 12) & 0x1;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	switch (cdclk_config->vco) {
398*4882a593Smuzhiyun 	case 2666667:
399*4882a593Smuzhiyun 	case 4000000:
400*4882a593Smuzhiyun 	case 5333333:
401*4882a593Smuzhiyun 		cdclk_config->cdclk = cdclk_sel ? 333333 : 222222;
402*4882a593Smuzhiyun 		break;
403*4882a593Smuzhiyun 	case 3200000:
404*4882a593Smuzhiyun 		cdclk_config->cdclk = cdclk_sel ? 320000 : 228571;
405*4882a593Smuzhiyun 		break;
406*4882a593Smuzhiyun 	default:
407*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
408*4882a593Smuzhiyun 			"Unable to determine CDCLK. HPLL VCO=%u, CFGC=0x%04x\n",
409*4882a593Smuzhiyun 			cdclk_config->vco, tmp);
410*4882a593Smuzhiyun 		cdclk_config->cdclk = 222222;
411*4882a593Smuzhiyun 		break;
412*4882a593Smuzhiyun 	}
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
hsw_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)415*4882a593Smuzhiyun static void hsw_get_cdclk(struct drm_i915_private *dev_priv,
416*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);
419*4882a593Smuzhiyun 	u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (lcpll & LCPLL_CD_SOURCE_FCLK)
422*4882a593Smuzhiyun 		cdclk_config->cdclk = 800000;
423*4882a593Smuzhiyun 	else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
424*4882a593Smuzhiyun 		cdclk_config->cdclk = 450000;
425*4882a593Smuzhiyun 	else if (freq == LCPLL_CLK_FREQ_450)
426*4882a593Smuzhiyun 		cdclk_config->cdclk = 450000;
427*4882a593Smuzhiyun 	else if (IS_HSW_ULT(dev_priv))
428*4882a593Smuzhiyun 		cdclk_config->cdclk = 337500;
429*4882a593Smuzhiyun 	else
430*4882a593Smuzhiyun 		cdclk_config->cdclk = 540000;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
vlv_calc_cdclk(struct drm_i915_private * dev_priv,int min_cdclk)433*4882a593Smuzhiyun static int vlv_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun 	int freq_320 = (dev_priv->hpll_freq <<  1) % 320000 != 0 ?
436*4882a593Smuzhiyun 		333333 : 320000;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	/*
439*4882a593Smuzhiyun 	 * We seem to get an unstable or solid color picture at 200MHz.
440*4882a593Smuzhiyun 	 * Not sure what's wrong. For now use 200MHz only when all pipes
441*4882a593Smuzhiyun 	 * are off.
442*4882a593Smuzhiyun 	 */
443*4882a593Smuzhiyun 	if (IS_VALLEYVIEW(dev_priv) && min_cdclk > freq_320)
444*4882a593Smuzhiyun 		return 400000;
445*4882a593Smuzhiyun 	else if (min_cdclk > 266667)
446*4882a593Smuzhiyun 		return freq_320;
447*4882a593Smuzhiyun 	else if (min_cdclk > 0)
448*4882a593Smuzhiyun 		return 266667;
449*4882a593Smuzhiyun 	else
450*4882a593Smuzhiyun 		return 200000;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
vlv_calc_voltage_level(struct drm_i915_private * dev_priv,int cdclk)453*4882a593Smuzhiyun static u8 vlv_calc_voltage_level(struct drm_i915_private *dev_priv, int cdclk)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	if (IS_VALLEYVIEW(dev_priv)) {
456*4882a593Smuzhiyun 		if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
457*4882a593Smuzhiyun 			return 2;
458*4882a593Smuzhiyun 		else if (cdclk >= 266667)
459*4882a593Smuzhiyun 			return 1;
460*4882a593Smuzhiyun 		else
461*4882a593Smuzhiyun 			return 0;
462*4882a593Smuzhiyun 	} else {
463*4882a593Smuzhiyun 		/*
464*4882a593Smuzhiyun 		 * Specs are full of misinformation, but testing on actual
465*4882a593Smuzhiyun 		 * hardware has shown that we just need to write the desired
466*4882a593Smuzhiyun 		 * CCK divider into the Punit register.
467*4882a593Smuzhiyun 		 */
468*4882a593Smuzhiyun 		return DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1, cdclk) - 1;
469*4882a593Smuzhiyun 	}
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun 
vlv_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)472*4882a593Smuzhiyun static void vlv_get_cdclk(struct drm_i915_private *dev_priv,
473*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	u32 val;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	vlv_iosf_sb_get(dev_priv,
478*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	cdclk_config->vco = vlv_get_hpll_vco(dev_priv);
481*4882a593Smuzhiyun 	cdclk_config->cdclk = vlv_get_cck_clock(dev_priv, "cdclk",
482*4882a593Smuzhiyun 						CCK_DISPLAY_CLOCK_CONTROL,
483*4882a593Smuzhiyun 						cdclk_config->vco);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	vlv_iosf_sb_put(dev_priv,
488*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_CCK) | BIT(VLV_IOSF_SB_PUNIT));
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	if (IS_VALLEYVIEW(dev_priv))
491*4882a593Smuzhiyun 		cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK) >>
492*4882a593Smuzhiyun 			DSPFREQGUAR_SHIFT;
493*4882a593Smuzhiyun 	else
494*4882a593Smuzhiyun 		cdclk_config->voltage_level = (val & DSPFREQGUAR_MASK_CHV) >>
495*4882a593Smuzhiyun 			DSPFREQGUAR_SHIFT_CHV;
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun 
vlv_program_pfi_credits(struct drm_i915_private * dev_priv)498*4882a593Smuzhiyun static void vlv_program_pfi_credits(struct drm_i915_private *dev_priv)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun 	unsigned int credits, default_credits;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	if (IS_CHERRYVIEW(dev_priv))
503*4882a593Smuzhiyun 		default_credits = PFI_CREDIT(12);
504*4882a593Smuzhiyun 	else
505*4882a593Smuzhiyun 		default_credits = PFI_CREDIT(8);
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.cdclk >= dev_priv->czclk_freq) {
508*4882a593Smuzhiyun 		/* CHV suggested value is 31 or 63 */
509*4882a593Smuzhiyun 		if (IS_CHERRYVIEW(dev_priv))
510*4882a593Smuzhiyun 			credits = PFI_CREDIT_63;
511*4882a593Smuzhiyun 		else
512*4882a593Smuzhiyun 			credits = PFI_CREDIT(15);
513*4882a593Smuzhiyun 	} else {
514*4882a593Smuzhiyun 		credits = default_credits;
515*4882a593Smuzhiyun 	}
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun 	/*
518*4882a593Smuzhiyun 	 * WA - write default credits before re-programming
519*4882a593Smuzhiyun 	 * FIXME: should we also set the resend bit here?
520*4882a593Smuzhiyun 	 */
521*4882a593Smuzhiyun 	intel_de_write(dev_priv, GCI_CONTROL,
522*4882a593Smuzhiyun 		       VGA_FAST_MODE_DISABLE | default_credits);
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	intel_de_write(dev_priv, GCI_CONTROL,
525*4882a593Smuzhiyun 		       VGA_FAST_MODE_DISABLE | credits | PFI_CREDIT_RESEND);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	/*
528*4882a593Smuzhiyun 	 * FIXME is this guaranteed to clear
529*4882a593Smuzhiyun 	 * immediately or should we poll for it?
530*4882a593Smuzhiyun 	 */
531*4882a593Smuzhiyun 	drm_WARN_ON(&dev_priv->drm,
532*4882a593Smuzhiyun 		    intel_de_read(dev_priv, GCI_CONTROL) & PFI_CREDIT_RESEND);
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
vlv_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)535*4882a593Smuzhiyun static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
536*4882a593Smuzhiyun 			  const struct intel_cdclk_config *cdclk_config,
537*4882a593Smuzhiyun 			  enum pipe pipe)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun 	int cdclk = cdclk_config->cdclk;
540*4882a593Smuzhiyun 	u32 val, cmd = cdclk_config->voltage_level;
541*4882a593Smuzhiyun 	intel_wakeref_t wakeref;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	switch (cdclk) {
544*4882a593Smuzhiyun 	case 400000:
545*4882a593Smuzhiyun 	case 333333:
546*4882a593Smuzhiyun 	case 320000:
547*4882a593Smuzhiyun 	case 266667:
548*4882a593Smuzhiyun 	case 200000:
549*4882a593Smuzhiyun 		break;
550*4882a593Smuzhiyun 	default:
551*4882a593Smuzhiyun 		MISSING_CASE(cdclk);
552*4882a593Smuzhiyun 		return;
553*4882a593Smuzhiyun 	}
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	/* There are cases where we can end up here with power domains
556*4882a593Smuzhiyun 	 * off and a CDCLK frequency other than the minimum, like when
557*4882a593Smuzhiyun 	 * issuing a modeset without actually changing any display after
558*4882a593Smuzhiyun 	 * a system suspend.  So grab the display core domain, which covers
559*4882a593Smuzhiyun 	 * the HW blocks needed for the following programming.
560*4882a593Smuzhiyun 	 */
561*4882a593Smuzhiyun 	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	vlv_iosf_sb_get(dev_priv,
564*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_CCK) |
565*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_BUNIT) |
566*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_PUNIT));
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
569*4882a593Smuzhiyun 	val &= ~DSPFREQGUAR_MASK;
570*4882a593Smuzhiyun 	val |= (cmd << DSPFREQGUAR_SHIFT);
571*4882a593Smuzhiyun 	vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);
572*4882a593Smuzhiyun 	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
573*4882a593Smuzhiyun 		      DSPFREQSTAT_MASK) == (cmd << DSPFREQSTAT_SHIFT),
574*4882a593Smuzhiyun 		     50)) {
575*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
576*4882a593Smuzhiyun 			"timed out waiting for CDclk change\n");
577*4882a593Smuzhiyun 	}
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	if (cdclk == 400000) {
580*4882a593Smuzhiyun 		u32 divider;
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 		divider = DIV_ROUND_CLOSEST(dev_priv->hpll_freq << 1,
583*4882a593Smuzhiyun 					    cdclk) - 1;
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 		/* adjust cdclk divider */
586*4882a593Smuzhiyun 		val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL);
587*4882a593Smuzhiyun 		val &= ~CCK_FREQUENCY_VALUES;
588*4882a593Smuzhiyun 		val |= divider;
589*4882a593Smuzhiyun 		vlv_cck_write(dev_priv, CCK_DISPLAY_CLOCK_CONTROL, val);
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 		if (wait_for((vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL) &
592*4882a593Smuzhiyun 			      CCK_FREQUENCY_STATUS) == (divider << CCK_FREQUENCY_STATUS_SHIFT),
593*4882a593Smuzhiyun 			     50))
594*4882a593Smuzhiyun 			drm_err(&dev_priv->drm,
595*4882a593Smuzhiyun 				"timed out waiting for CDclk change\n");
596*4882a593Smuzhiyun 	}
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	/* adjust self-refresh exit latency value */
599*4882a593Smuzhiyun 	val = vlv_bunit_read(dev_priv, BUNIT_REG_BISOC);
600*4882a593Smuzhiyun 	val &= ~0x7f;
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	/*
603*4882a593Smuzhiyun 	 * For high bandwidth configs, we set a higher latency in the bunit
604*4882a593Smuzhiyun 	 * so that the core display fetch happens in time to avoid underruns.
605*4882a593Smuzhiyun 	 */
606*4882a593Smuzhiyun 	if (cdclk == 400000)
607*4882a593Smuzhiyun 		val |= 4500 / 250; /* 4.5 usec */
608*4882a593Smuzhiyun 	else
609*4882a593Smuzhiyun 		val |= 3000 / 250; /* 3.0 usec */
610*4882a593Smuzhiyun 	vlv_bunit_write(dev_priv, BUNIT_REG_BISOC, val);
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	vlv_iosf_sb_put(dev_priv,
613*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_CCK) |
614*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_BUNIT) |
615*4882a593Smuzhiyun 			BIT(VLV_IOSF_SB_PUNIT));
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	vlv_program_pfi_credits(dev_priv);
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun 
chv_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)624*4882a593Smuzhiyun static void chv_set_cdclk(struct drm_i915_private *dev_priv,
625*4882a593Smuzhiyun 			  const struct intel_cdclk_config *cdclk_config,
626*4882a593Smuzhiyun 			  enum pipe pipe)
627*4882a593Smuzhiyun {
628*4882a593Smuzhiyun 	int cdclk = cdclk_config->cdclk;
629*4882a593Smuzhiyun 	u32 val, cmd = cdclk_config->voltage_level;
630*4882a593Smuzhiyun 	intel_wakeref_t wakeref;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	switch (cdclk) {
633*4882a593Smuzhiyun 	case 333333:
634*4882a593Smuzhiyun 	case 320000:
635*4882a593Smuzhiyun 	case 266667:
636*4882a593Smuzhiyun 	case 200000:
637*4882a593Smuzhiyun 		break;
638*4882a593Smuzhiyun 	default:
639*4882a593Smuzhiyun 		MISSING_CASE(cdclk);
640*4882a593Smuzhiyun 		return;
641*4882a593Smuzhiyun 	}
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	/* There are cases where we can end up here with power domains
644*4882a593Smuzhiyun 	 * off and a CDCLK frequency other than the minimum, like when
645*4882a593Smuzhiyun 	 * issuing a modeset without actually changing any display after
646*4882a593Smuzhiyun 	 * a system suspend.  So grab the display core domain, which covers
647*4882a593Smuzhiyun 	 * the HW blocks needed for the following programming.
648*4882a593Smuzhiyun 	 */
649*4882a593Smuzhiyun 	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DISPLAY_CORE);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	vlv_punit_get(dev_priv);
652*4882a593Smuzhiyun 	val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM);
653*4882a593Smuzhiyun 	val &= ~DSPFREQGUAR_MASK_CHV;
654*4882a593Smuzhiyun 	val |= (cmd << DSPFREQGUAR_SHIFT_CHV);
655*4882a593Smuzhiyun 	vlv_punit_write(dev_priv, PUNIT_REG_DSPSSPM, val);
656*4882a593Smuzhiyun 	if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM) &
657*4882a593Smuzhiyun 		      DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV),
658*4882a593Smuzhiyun 		     50)) {
659*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
660*4882a593Smuzhiyun 			"timed out waiting for CDclk change\n");
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	vlv_punit_put(dev_priv);
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	vlv_program_pfi_credits(dev_priv);
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun 
bdw_calc_cdclk(int min_cdclk)672*4882a593Smuzhiyun static int bdw_calc_cdclk(int min_cdclk)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun 	if (min_cdclk > 540000)
675*4882a593Smuzhiyun 		return 675000;
676*4882a593Smuzhiyun 	else if (min_cdclk > 450000)
677*4882a593Smuzhiyun 		return 540000;
678*4882a593Smuzhiyun 	else if (min_cdclk > 337500)
679*4882a593Smuzhiyun 		return 450000;
680*4882a593Smuzhiyun 	else
681*4882a593Smuzhiyun 		return 337500;
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun 
bdw_calc_voltage_level(int cdclk)684*4882a593Smuzhiyun static u8 bdw_calc_voltage_level(int cdclk)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun 	switch (cdclk) {
687*4882a593Smuzhiyun 	default:
688*4882a593Smuzhiyun 	case 337500:
689*4882a593Smuzhiyun 		return 2;
690*4882a593Smuzhiyun 	case 450000:
691*4882a593Smuzhiyun 		return 0;
692*4882a593Smuzhiyun 	case 540000:
693*4882a593Smuzhiyun 		return 1;
694*4882a593Smuzhiyun 	case 675000:
695*4882a593Smuzhiyun 		return 3;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun }
698*4882a593Smuzhiyun 
bdw_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)699*4882a593Smuzhiyun static void bdw_get_cdclk(struct drm_i915_private *dev_priv,
700*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun 	u32 lcpll = intel_de_read(dev_priv, LCPLL_CTL);
703*4882a593Smuzhiyun 	u32 freq = lcpll & LCPLL_CLK_FREQ_MASK;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	if (lcpll & LCPLL_CD_SOURCE_FCLK)
706*4882a593Smuzhiyun 		cdclk_config->cdclk = 800000;
707*4882a593Smuzhiyun 	else if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
708*4882a593Smuzhiyun 		cdclk_config->cdclk = 450000;
709*4882a593Smuzhiyun 	else if (freq == LCPLL_CLK_FREQ_450)
710*4882a593Smuzhiyun 		cdclk_config->cdclk = 450000;
711*4882a593Smuzhiyun 	else if (freq == LCPLL_CLK_FREQ_54O_BDW)
712*4882a593Smuzhiyun 		cdclk_config->cdclk = 540000;
713*4882a593Smuzhiyun 	else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
714*4882a593Smuzhiyun 		cdclk_config->cdclk = 337500;
715*4882a593Smuzhiyun 	else
716*4882a593Smuzhiyun 		cdclk_config->cdclk = 675000;
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun 	/*
719*4882a593Smuzhiyun 	 * Can't read this out :( Let's assume it's
720*4882a593Smuzhiyun 	 * at least what the CDCLK frequency requires.
721*4882a593Smuzhiyun 	 */
722*4882a593Smuzhiyun 	cdclk_config->voltage_level =
723*4882a593Smuzhiyun 		bdw_calc_voltage_level(cdclk_config->cdclk);
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun 
bdw_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)726*4882a593Smuzhiyun static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
727*4882a593Smuzhiyun 			  const struct intel_cdclk_config *cdclk_config,
728*4882a593Smuzhiyun 			  enum pipe pipe)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun 	int cdclk = cdclk_config->cdclk;
731*4882a593Smuzhiyun 	u32 val;
732*4882a593Smuzhiyun 	int ret;
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 	if (drm_WARN(&dev_priv->drm,
735*4882a593Smuzhiyun 		     (intel_de_read(dev_priv, LCPLL_CTL) &
736*4882a593Smuzhiyun 		      (LCPLL_PLL_DISABLE | LCPLL_PLL_LOCK |
737*4882a593Smuzhiyun 		       LCPLL_CD_CLOCK_DISABLE | LCPLL_ROOT_CD_CLOCK_DISABLE |
738*4882a593Smuzhiyun 		       LCPLL_CD2X_CLOCK_DISABLE | LCPLL_POWER_DOWN_ALLOW |
739*4882a593Smuzhiyun 		       LCPLL_CD_SOURCE_FCLK)) != LCPLL_PLL_LOCK,
740*4882a593Smuzhiyun 		     "trying to change cdclk frequency with cdclk not enabled\n"))
741*4882a593Smuzhiyun 		return;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	ret = sandybridge_pcode_write(dev_priv,
744*4882a593Smuzhiyun 				      BDW_PCODE_DISPLAY_FREQ_CHANGE_REQ, 0x0);
745*4882a593Smuzhiyun 	if (ret) {
746*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
747*4882a593Smuzhiyun 			"failed to inform pcode about cdclk change\n");
748*4882a593Smuzhiyun 		return;
749*4882a593Smuzhiyun 	}
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, LCPLL_CTL);
752*4882a593Smuzhiyun 	val |= LCPLL_CD_SOURCE_FCLK;
753*4882a593Smuzhiyun 	intel_de_write(dev_priv, LCPLL_CTL, val);
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 	/*
756*4882a593Smuzhiyun 	 * According to the spec, it should be enough to poll for this 1 us.
757*4882a593Smuzhiyun 	 * However, extensive testing shows that this can take longer.
758*4882a593Smuzhiyun 	 */
759*4882a593Smuzhiyun 	if (wait_for_us(intel_de_read(dev_priv, LCPLL_CTL) &
760*4882a593Smuzhiyun 			LCPLL_CD_SOURCE_FCLK_DONE, 100))
761*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "Switching to FCLK failed\n");
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, LCPLL_CTL);
764*4882a593Smuzhiyun 	val &= ~LCPLL_CLK_FREQ_MASK;
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 	switch (cdclk) {
767*4882a593Smuzhiyun 	default:
768*4882a593Smuzhiyun 		MISSING_CASE(cdclk);
769*4882a593Smuzhiyun 		fallthrough;
770*4882a593Smuzhiyun 	case 337500:
771*4882a593Smuzhiyun 		val |= LCPLL_CLK_FREQ_337_5_BDW;
772*4882a593Smuzhiyun 		break;
773*4882a593Smuzhiyun 	case 450000:
774*4882a593Smuzhiyun 		val |= LCPLL_CLK_FREQ_450;
775*4882a593Smuzhiyun 		break;
776*4882a593Smuzhiyun 	case 540000:
777*4882a593Smuzhiyun 		val |= LCPLL_CLK_FREQ_54O_BDW;
778*4882a593Smuzhiyun 		break;
779*4882a593Smuzhiyun 	case 675000:
780*4882a593Smuzhiyun 		val |= LCPLL_CLK_FREQ_675_BDW;
781*4882a593Smuzhiyun 		break;
782*4882a593Smuzhiyun 	}
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	intel_de_write(dev_priv, LCPLL_CTL, val);
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, LCPLL_CTL);
787*4882a593Smuzhiyun 	val &= ~LCPLL_CD_SOURCE_FCLK;
788*4882a593Smuzhiyun 	intel_de_write(dev_priv, LCPLL_CTL, val);
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	if (wait_for_us((intel_de_read(dev_priv, LCPLL_CTL) &
791*4882a593Smuzhiyun 			 LCPLL_CD_SOURCE_FCLK_DONE) == 0, 1))
792*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "Switching back to LCPLL failed\n");
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
795*4882a593Smuzhiyun 				cdclk_config->voltage_level);
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_FREQ,
798*4882a593Smuzhiyun 		       DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun 
skl_calc_cdclk(int min_cdclk,int vco)803*4882a593Smuzhiyun static int skl_calc_cdclk(int min_cdclk, int vco)
804*4882a593Smuzhiyun {
805*4882a593Smuzhiyun 	if (vco == 8640000) {
806*4882a593Smuzhiyun 		if (min_cdclk > 540000)
807*4882a593Smuzhiyun 			return 617143;
808*4882a593Smuzhiyun 		else if (min_cdclk > 432000)
809*4882a593Smuzhiyun 			return 540000;
810*4882a593Smuzhiyun 		else if (min_cdclk > 308571)
811*4882a593Smuzhiyun 			return 432000;
812*4882a593Smuzhiyun 		else
813*4882a593Smuzhiyun 			return 308571;
814*4882a593Smuzhiyun 	} else {
815*4882a593Smuzhiyun 		if (min_cdclk > 540000)
816*4882a593Smuzhiyun 			return 675000;
817*4882a593Smuzhiyun 		else if (min_cdclk > 450000)
818*4882a593Smuzhiyun 			return 540000;
819*4882a593Smuzhiyun 		else if (min_cdclk > 337500)
820*4882a593Smuzhiyun 			return 450000;
821*4882a593Smuzhiyun 		else
822*4882a593Smuzhiyun 			return 337500;
823*4882a593Smuzhiyun 	}
824*4882a593Smuzhiyun }
825*4882a593Smuzhiyun 
skl_calc_voltage_level(int cdclk)826*4882a593Smuzhiyun static u8 skl_calc_voltage_level(int cdclk)
827*4882a593Smuzhiyun {
828*4882a593Smuzhiyun 	if (cdclk > 540000)
829*4882a593Smuzhiyun 		return 3;
830*4882a593Smuzhiyun 	else if (cdclk > 450000)
831*4882a593Smuzhiyun 		return 2;
832*4882a593Smuzhiyun 	else if (cdclk > 337500)
833*4882a593Smuzhiyun 		return 1;
834*4882a593Smuzhiyun 	else
835*4882a593Smuzhiyun 		return 0;
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun 
skl_dpll0_update(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)838*4882a593Smuzhiyun static void skl_dpll0_update(struct drm_i915_private *dev_priv,
839*4882a593Smuzhiyun 			     struct intel_cdclk_config *cdclk_config)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun 	u32 val;
842*4882a593Smuzhiyun 
843*4882a593Smuzhiyun 	cdclk_config->ref = 24000;
844*4882a593Smuzhiyun 	cdclk_config->vco = 0;
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, LCPLL1_CTL);
847*4882a593Smuzhiyun 	if ((val & LCPLL_PLL_ENABLE) == 0)
848*4882a593Smuzhiyun 		return;
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	if (drm_WARN_ON(&dev_priv->drm, (val & LCPLL_PLL_LOCK) == 0))
851*4882a593Smuzhiyun 		return;
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, DPLL_CTRL1);
854*4882a593Smuzhiyun 
855*4882a593Smuzhiyun 	if (drm_WARN_ON(&dev_priv->drm,
856*4882a593Smuzhiyun 			(val & (DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) |
857*4882a593Smuzhiyun 				DPLL_CTRL1_SSC(SKL_DPLL0) |
858*4882a593Smuzhiyun 				DPLL_CTRL1_OVERRIDE(SKL_DPLL0))) !=
859*4882a593Smuzhiyun 			DPLL_CTRL1_OVERRIDE(SKL_DPLL0)))
860*4882a593Smuzhiyun 		return;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	switch (val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0)) {
863*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, SKL_DPLL0):
864*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, SKL_DPLL0):
865*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, SKL_DPLL0):
866*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, SKL_DPLL0):
867*4882a593Smuzhiyun 		cdclk_config->vco = 8100000;
868*4882a593Smuzhiyun 		break;
869*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080, SKL_DPLL0):
870*4882a593Smuzhiyun 	case DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2160, SKL_DPLL0):
871*4882a593Smuzhiyun 		cdclk_config->vco = 8640000;
872*4882a593Smuzhiyun 		break;
873*4882a593Smuzhiyun 	default:
874*4882a593Smuzhiyun 		MISSING_CASE(val & DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
875*4882a593Smuzhiyun 		break;
876*4882a593Smuzhiyun 	}
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun 
skl_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)879*4882a593Smuzhiyun static void skl_get_cdclk(struct drm_i915_private *dev_priv,
880*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
881*4882a593Smuzhiyun {
882*4882a593Smuzhiyun 	u32 cdctl;
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun 	skl_dpll0_update(dev_priv, cdclk_config);
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	cdclk_config->cdclk = cdclk_config->bypass = cdclk_config->ref;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 	if (cdclk_config->vco == 0)
889*4882a593Smuzhiyun 		goto out;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	cdctl = intel_de_read(dev_priv, CDCLK_CTL);
892*4882a593Smuzhiyun 
893*4882a593Smuzhiyun 	if (cdclk_config->vco == 8640000) {
894*4882a593Smuzhiyun 		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
895*4882a593Smuzhiyun 		case CDCLK_FREQ_450_432:
896*4882a593Smuzhiyun 			cdclk_config->cdclk = 432000;
897*4882a593Smuzhiyun 			break;
898*4882a593Smuzhiyun 		case CDCLK_FREQ_337_308:
899*4882a593Smuzhiyun 			cdclk_config->cdclk = 308571;
900*4882a593Smuzhiyun 			break;
901*4882a593Smuzhiyun 		case CDCLK_FREQ_540:
902*4882a593Smuzhiyun 			cdclk_config->cdclk = 540000;
903*4882a593Smuzhiyun 			break;
904*4882a593Smuzhiyun 		case CDCLK_FREQ_675_617:
905*4882a593Smuzhiyun 			cdclk_config->cdclk = 617143;
906*4882a593Smuzhiyun 			break;
907*4882a593Smuzhiyun 		default:
908*4882a593Smuzhiyun 			MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
909*4882a593Smuzhiyun 			break;
910*4882a593Smuzhiyun 		}
911*4882a593Smuzhiyun 	} else {
912*4882a593Smuzhiyun 		switch (cdctl & CDCLK_FREQ_SEL_MASK) {
913*4882a593Smuzhiyun 		case CDCLK_FREQ_450_432:
914*4882a593Smuzhiyun 			cdclk_config->cdclk = 450000;
915*4882a593Smuzhiyun 			break;
916*4882a593Smuzhiyun 		case CDCLK_FREQ_337_308:
917*4882a593Smuzhiyun 			cdclk_config->cdclk = 337500;
918*4882a593Smuzhiyun 			break;
919*4882a593Smuzhiyun 		case CDCLK_FREQ_540:
920*4882a593Smuzhiyun 			cdclk_config->cdclk = 540000;
921*4882a593Smuzhiyun 			break;
922*4882a593Smuzhiyun 		case CDCLK_FREQ_675_617:
923*4882a593Smuzhiyun 			cdclk_config->cdclk = 675000;
924*4882a593Smuzhiyun 			break;
925*4882a593Smuzhiyun 		default:
926*4882a593Smuzhiyun 			MISSING_CASE(cdctl & CDCLK_FREQ_SEL_MASK);
927*4882a593Smuzhiyun 			break;
928*4882a593Smuzhiyun 		}
929*4882a593Smuzhiyun 	}
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun  out:
932*4882a593Smuzhiyun 	/*
933*4882a593Smuzhiyun 	 * Can't read this out :( Let's assume it's
934*4882a593Smuzhiyun 	 * at least what the CDCLK frequency requires.
935*4882a593Smuzhiyun 	 */
936*4882a593Smuzhiyun 	cdclk_config->voltage_level =
937*4882a593Smuzhiyun 		skl_calc_voltage_level(cdclk_config->cdclk);
938*4882a593Smuzhiyun }
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun /* convert from kHz to .1 fixpoint MHz with -1MHz offset */
skl_cdclk_decimal(int cdclk)941*4882a593Smuzhiyun static int skl_cdclk_decimal(int cdclk)
942*4882a593Smuzhiyun {
943*4882a593Smuzhiyun 	return DIV_ROUND_CLOSEST(cdclk - 1000, 500);
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun 
skl_set_preferred_cdclk_vco(struct drm_i915_private * dev_priv,int vco)946*4882a593Smuzhiyun static void skl_set_preferred_cdclk_vco(struct drm_i915_private *dev_priv,
947*4882a593Smuzhiyun 					int vco)
948*4882a593Smuzhiyun {
949*4882a593Smuzhiyun 	bool changed = dev_priv->skl_preferred_vco_freq != vco;
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	dev_priv->skl_preferred_vco_freq = vco;
952*4882a593Smuzhiyun 
953*4882a593Smuzhiyun 	if (changed)
954*4882a593Smuzhiyun 		intel_update_max_cdclk(dev_priv);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun 
skl_dpll0_enable(struct drm_i915_private * dev_priv,int vco)957*4882a593Smuzhiyun static void skl_dpll0_enable(struct drm_i915_private *dev_priv, int vco)
958*4882a593Smuzhiyun {
959*4882a593Smuzhiyun 	u32 val;
960*4882a593Smuzhiyun 
961*4882a593Smuzhiyun 	drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	/*
964*4882a593Smuzhiyun 	 * We always enable DPLL0 with the lowest link rate possible, but still
965*4882a593Smuzhiyun 	 * taking into account the VCO required to operate the eDP panel at the
966*4882a593Smuzhiyun 	 * desired frequency. The usual DP link rates operate with a VCO of
967*4882a593Smuzhiyun 	 * 8100 while the eDP 1.4 alternate link rates need a VCO of 8640.
968*4882a593Smuzhiyun 	 * The modeset code is responsible for the selection of the exact link
969*4882a593Smuzhiyun 	 * rate later on, with the constraint of choosing a frequency that
970*4882a593Smuzhiyun 	 * works with vco.
971*4882a593Smuzhiyun 	 */
972*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, DPLL_CTRL1);
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	val &= ~(DPLL_CTRL1_HDMI_MODE(SKL_DPLL0) | DPLL_CTRL1_SSC(SKL_DPLL0) |
975*4882a593Smuzhiyun 		 DPLL_CTRL1_LINK_RATE_MASK(SKL_DPLL0));
976*4882a593Smuzhiyun 	val |= DPLL_CTRL1_OVERRIDE(SKL_DPLL0);
977*4882a593Smuzhiyun 	if (vco == 8640000)
978*4882a593Smuzhiyun 		val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1080,
979*4882a593Smuzhiyun 					    SKL_DPLL0);
980*4882a593Smuzhiyun 	else
981*4882a593Smuzhiyun 		val |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810,
982*4882a593Smuzhiyun 					    SKL_DPLL0);
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	intel_de_write(dev_priv, DPLL_CTRL1, val);
985*4882a593Smuzhiyun 	intel_de_posting_read(dev_priv, DPLL_CTRL1);
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 	intel_de_write(dev_priv, LCPLL1_CTL,
988*4882a593Smuzhiyun 		       intel_de_read(dev_priv, LCPLL1_CTL) | LCPLL_PLL_ENABLE);
989*4882a593Smuzhiyun 
990*4882a593Smuzhiyun 	if (intel_de_wait_for_set(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 5))
991*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "DPLL0 not locked\n");
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = vco;
994*4882a593Smuzhiyun 
995*4882a593Smuzhiyun 	/* We'll want to keep using the current vco from now on. */
996*4882a593Smuzhiyun 	skl_set_preferred_cdclk_vco(dev_priv, vco);
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun 
skl_dpll0_disable(struct drm_i915_private * dev_priv)999*4882a593Smuzhiyun static void skl_dpll0_disable(struct drm_i915_private *dev_priv)
1000*4882a593Smuzhiyun {
1001*4882a593Smuzhiyun 	intel_de_write(dev_priv, LCPLL1_CTL,
1002*4882a593Smuzhiyun 		       intel_de_read(dev_priv, LCPLL1_CTL) & ~LCPLL_PLL_ENABLE);
1003*4882a593Smuzhiyun 	if (intel_de_wait_for_clear(dev_priv, LCPLL1_CTL, LCPLL_PLL_LOCK, 1))
1004*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "Couldn't disable DPLL0\n");
1005*4882a593Smuzhiyun 
1006*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = 0;
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun 
skl_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)1009*4882a593Smuzhiyun static void skl_set_cdclk(struct drm_i915_private *dev_priv,
1010*4882a593Smuzhiyun 			  const struct intel_cdclk_config *cdclk_config,
1011*4882a593Smuzhiyun 			  enum pipe pipe)
1012*4882a593Smuzhiyun {
1013*4882a593Smuzhiyun 	int cdclk = cdclk_config->cdclk;
1014*4882a593Smuzhiyun 	int vco = cdclk_config->vco;
1015*4882a593Smuzhiyun 	u32 freq_select, cdclk_ctl;
1016*4882a593Smuzhiyun 	int ret;
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun 	/*
1019*4882a593Smuzhiyun 	 * Based on WA#1183 CDCLK rates 308 and 617MHz CDCLK rates are
1020*4882a593Smuzhiyun 	 * unsupported on SKL. In theory this should never happen since only
1021*4882a593Smuzhiyun 	 * the eDP1.4 2.16 and 4.32Gbps rates require it, but eDP1.4 is not
1022*4882a593Smuzhiyun 	 * supported on SKL either, see the above WA. WARN whenever trying to
1023*4882a593Smuzhiyun 	 * use the corresponding VCO freq as that always leads to using the
1024*4882a593Smuzhiyun 	 * minimum 308MHz CDCLK.
1025*4882a593Smuzhiyun 	 */
1026*4882a593Smuzhiyun 	drm_WARN_ON_ONCE(&dev_priv->drm,
1027*4882a593Smuzhiyun 			 IS_SKYLAKE(dev_priv) && vco == 8640000);
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 	ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
1030*4882a593Smuzhiyun 				SKL_CDCLK_PREPARE_FOR_CHANGE,
1031*4882a593Smuzhiyun 				SKL_CDCLK_READY_FOR_CHANGE,
1032*4882a593Smuzhiyun 				SKL_CDCLK_READY_FOR_CHANGE, 3);
1033*4882a593Smuzhiyun 	if (ret) {
1034*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
1035*4882a593Smuzhiyun 			"Failed to inform PCU about cdclk change (%d)\n", ret);
1036*4882a593Smuzhiyun 		return;
1037*4882a593Smuzhiyun 	}
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 	/* Choose frequency for this cdclk */
1040*4882a593Smuzhiyun 	switch (cdclk) {
1041*4882a593Smuzhiyun 	default:
1042*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm,
1043*4882a593Smuzhiyun 			    cdclk != dev_priv->cdclk.hw.bypass);
1044*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm, vco != 0);
1045*4882a593Smuzhiyun 		fallthrough;
1046*4882a593Smuzhiyun 	case 308571:
1047*4882a593Smuzhiyun 	case 337500:
1048*4882a593Smuzhiyun 		freq_select = CDCLK_FREQ_337_308;
1049*4882a593Smuzhiyun 		break;
1050*4882a593Smuzhiyun 	case 450000:
1051*4882a593Smuzhiyun 	case 432000:
1052*4882a593Smuzhiyun 		freq_select = CDCLK_FREQ_450_432;
1053*4882a593Smuzhiyun 		break;
1054*4882a593Smuzhiyun 	case 540000:
1055*4882a593Smuzhiyun 		freq_select = CDCLK_FREQ_540;
1056*4882a593Smuzhiyun 		break;
1057*4882a593Smuzhiyun 	case 617143:
1058*4882a593Smuzhiyun 	case 675000:
1059*4882a593Smuzhiyun 		freq_select = CDCLK_FREQ_675_617;
1060*4882a593Smuzhiyun 		break;
1061*4882a593Smuzhiyun 	}
1062*4882a593Smuzhiyun 
1063*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.vco != 0 &&
1064*4882a593Smuzhiyun 	    dev_priv->cdclk.hw.vco != vco)
1065*4882a593Smuzhiyun 		skl_dpll0_disable(dev_priv);
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 	cdclk_ctl = intel_de_read(dev_priv, CDCLK_CTL);
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.vco != vco) {
1070*4882a593Smuzhiyun 		/* Wa Display #1183: skl,kbl,cfl */
1071*4882a593Smuzhiyun 		cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
1072*4882a593Smuzhiyun 		cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
1073*4882a593Smuzhiyun 		intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
1074*4882a593Smuzhiyun 	}
1075*4882a593Smuzhiyun 
1076*4882a593Smuzhiyun 	/* Wa Display #1183: skl,kbl,cfl */
1077*4882a593Smuzhiyun 	cdclk_ctl |= CDCLK_DIVMUX_CD_OVERRIDE;
1078*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
1079*4882a593Smuzhiyun 	intel_de_posting_read(dev_priv, CDCLK_CTL);
1080*4882a593Smuzhiyun 
1081*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.vco != vco)
1082*4882a593Smuzhiyun 		skl_dpll0_enable(dev_priv, vco);
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	/* Wa Display #1183: skl,kbl,cfl */
1085*4882a593Smuzhiyun 	cdclk_ctl &= ~(CDCLK_FREQ_SEL_MASK | CDCLK_FREQ_DECIMAL_MASK);
1086*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	cdclk_ctl |= freq_select | skl_cdclk_decimal(cdclk);
1089*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	/* Wa Display #1183: skl,kbl,cfl */
1092*4882a593Smuzhiyun 	cdclk_ctl &= ~CDCLK_DIVMUX_CD_OVERRIDE;
1093*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_CTL, cdclk_ctl);
1094*4882a593Smuzhiyun 	intel_de_posting_read(dev_priv, CDCLK_CTL);
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 	/* inform PCU of the change */
1097*4882a593Smuzhiyun 	sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
1098*4882a593Smuzhiyun 				cdclk_config->voltage_level);
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun 
skl_sanitize_cdclk(struct drm_i915_private * dev_priv)1103*4882a593Smuzhiyun static void skl_sanitize_cdclk(struct drm_i915_private *dev_priv)
1104*4882a593Smuzhiyun {
1105*4882a593Smuzhiyun 	u32 cdctl, expected;
1106*4882a593Smuzhiyun 
1107*4882a593Smuzhiyun 	/*
1108*4882a593Smuzhiyun 	 * check if the pre-os initialized the display
1109*4882a593Smuzhiyun 	 * There is SWF18 scratchpad register defined which is set by the
1110*4882a593Smuzhiyun 	 * pre-os which can be used by the OS drivers to check the status
1111*4882a593Smuzhiyun 	 */
1112*4882a593Smuzhiyun 	if ((intel_de_read(dev_priv, SWF_ILK(0x18)) & 0x00FFFFFF) == 0)
1113*4882a593Smuzhiyun 		goto sanitize;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
1116*4882a593Smuzhiyun 	intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
1117*4882a593Smuzhiyun 
1118*4882a593Smuzhiyun 	/* Is PLL enabled and locked ? */
1119*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.vco == 0 ||
1120*4882a593Smuzhiyun 	    dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
1121*4882a593Smuzhiyun 		goto sanitize;
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	/* DPLL okay; verify the cdclock
1124*4882a593Smuzhiyun 	 *
1125*4882a593Smuzhiyun 	 * Noticed in some instances that the freq selection is correct but
1126*4882a593Smuzhiyun 	 * decimal part is programmed wrong from BIOS where pre-os does not
1127*4882a593Smuzhiyun 	 * enable display. Verify the same as well.
1128*4882a593Smuzhiyun 	 */
1129*4882a593Smuzhiyun 	cdctl = intel_de_read(dev_priv, CDCLK_CTL);
1130*4882a593Smuzhiyun 	expected = (cdctl & CDCLK_FREQ_SEL_MASK) |
1131*4882a593Smuzhiyun 		skl_cdclk_decimal(dev_priv->cdclk.hw.cdclk);
1132*4882a593Smuzhiyun 	if (cdctl == expected)
1133*4882a593Smuzhiyun 		/* All well; nothing to sanitize */
1134*4882a593Smuzhiyun 		return;
1135*4882a593Smuzhiyun 
1136*4882a593Smuzhiyun sanitize:
1137*4882a593Smuzhiyun 	drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 	/* force cdclk programming */
1140*4882a593Smuzhiyun 	dev_priv->cdclk.hw.cdclk = 0;
1141*4882a593Smuzhiyun 	/* force full PLL disable + enable */
1142*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = -1;
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun 
skl_cdclk_init_hw(struct drm_i915_private * dev_priv)1145*4882a593Smuzhiyun static void skl_cdclk_init_hw(struct drm_i915_private *dev_priv)
1146*4882a593Smuzhiyun {
1147*4882a593Smuzhiyun 	struct intel_cdclk_config cdclk_config;
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 	skl_sanitize_cdclk(dev_priv);
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.cdclk != 0 &&
1152*4882a593Smuzhiyun 	    dev_priv->cdclk.hw.vco != 0) {
1153*4882a593Smuzhiyun 		/*
1154*4882a593Smuzhiyun 		 * Use the current vco as our initial
1155*4882a593Smuzhiyun 		 * guess as to what the preferred vco is.
1156*4882a593Smuzhiyun 		 */
1157*4882a593Smuzhiyun 		if (dev_priv->skl_preferred_vco_freq == 0)
1158*4882a593Smuzhiyun 			skl_set_preferred_cdclk_vco(dev_priv,
1159*4882a593Smuzhiyun 						    dev_priv->cdclk.hw.vco);
1160*4882a593Smuzhiyun 		return;
1161*4882a593Smuzhiyun 	}
1162*4882a593Smuzhiyun 
1163*4882a593Smuzhiyun 	cdclk_config = dev_priv->cdclk.hw;
1164*4882a593Smuzhiyun 
1165*4882a593Smuzhiyun 	cdclk_config.vco = dev_priv->skl_preferred_vco_freq;
1166*4882a593Smuzhiyun 	if (cdclk_config.vco == 0)
1167*4882a593Smuzhiyun 		cdclk_config.vco = 8100000;
1168*4882a593Smuzhiyun 	cdclk_config.cdclk = skl_calc_cdclk(0, cdclk_config.vco);
1169*4882a593Smuzhiyun 	cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
1172*4882a593Smuzhiyun }
1173*4882a593Smuzhiyun 
skl_cdclk_uninit_hw(struct drm_i915_private * dev_priv)1174*4882a593Smuzhiyun static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
1175*4882a593Smuzhiyun {
1176*4882a593Smuzhiyun 	struct intel_cdclk_config cdclk_config = dev_priv->cdclk.hw;
1177*4882a593Smuzhiyun 
1178*4882a593Smuzhiyun 	cdclk_config.cdclk = cdclk_config.bypass;
1179*4882a593Smuzhiyun 	cdclk_config.vco = 0;
1180*4882a593Smuzhiyun 	cdclk_config.voltage_level = skl_calc_voltage_level(cdclk_config.cdclk);
1181*4882a593Smuzhiyun 
1182*4882a593Smuzhiyun 	skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun static const struct intel_cdclk_vals bxt_cdclk_table[] = {
1186*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 144000, .divider = 8, .ratio = 60 },
1187*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 288000, .divider = 4, .ratio = 60 },
1188*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 384000, .divider = 3, .ratio = 60 },
1189*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 576000, .divider = 2, .ratio = 60 },
1190*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 624000, .divider = 2, .ratio = 65 },
1191*4882a593Smuzhiyun 	{}
1192*4882a593Smuzhiyun };
1193*4882a593Smuzhiyun 
1194*4882a593Smuzhiyun static const struct intel_cdclk_vals glk_cdclk_table[] = {
1195*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk =  79200, .divider = 8, .ratio = 33 },
1196*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 158400, .divider = 4, .ratio = 33 },
1197*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 316800, .divider = 2, .ratio = 33 },
1198*4882a593Smuzhiyun 	{}
1199*4882a593Smuzhiyun };
1200*4882a593Smuzhiyun 
1201*4882a593Smuzhiyun static const struct intel_cdclk_vals cnl_cdclk_table[] = {
1202*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 168000, .divider = 4, .ratio = 35 },
1203*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 336000, .divider = 2, .ratio = 35 },
1204*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 528000, .divider = 2, .ratio = 55 },
1205*4882a593Smuzhiyun 
1206*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 168000, .divider = 4, .ratio = 28 },
1207*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 336000, .divider = 2, .ratio = 28 },
1208*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 528000, .divider = 2, .ratio = 44 },
1209*4882a593Smuzhiyun 	{}
1210*4882a593Smuzhiyun };
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun static const struct intel_cdclk_vals icl_cdclk_table[] = {
1213*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 172800, .divider = 2, .ratio = 18 },
1214*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
1215*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
1216*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
1217*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
1218*4882a593Smuzhiyun 	{ .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
1219*4882a593Smuzhiyun 
1220*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 180000, .divider = 2, .ratio = 15 },
1221*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
1222*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
1223*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
1224*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
1225*4882a593Smuzhiyun 	{ .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
1226*4882a593Smuzhiyun 
1227*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio =  9 },
1228*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
1229*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
1230*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
1231*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
1232*4882a593Smuzhiyun 	{ .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
1233*4882a593Smuzhiyun 	{}
1234*4882a593Smuzhiyun };
1235*4882a593Smuzhiyun 
bxt_calc_cdclk(struct drm_i915_private * dev_priv,int min_cdclk)1236*4882a593Smuzhiyun static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
1237*4882a593Smuzhiyun {
1238*4882a593Smuzhiyun 	const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
1239*4882a593Smuzhiyun 	int i;
1240*4882a593Smuzhiyun 
1241*4882a593Smuzhiyun 	for (i = 0; table[i].refclk; i++)
1242*4882a593Smuzhiyun 		if (table[i].refclk == dev_priv->cdclk.hw.ref &&
1243*4882a593Smuzhiyun 		    table[i].cdclk >= min_cdclk)
1244*4882a593Smuzhiyun 			return table[i].cdclk;
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun 	drm_WARN(&dev_priv->drm, 1,
1247*4882a593Smuzhiyun 		 "Cannot satisfy minimum cdclk %d with refclk %u\n",
1248*4882a593Smuzhiyun 		 min_cdclk, dev_priv->cdclk.hw.ref);
1249*4882a593Smuzhiyun 	return 0;
1250*4882a593Smuzhiyun }
1251*4882a593Smuzhiyun 
bxt_calc_cdclk_pll_vco(struct drm_i915_private * dev_priv,int cdclk)1252*4882a593Smuzhiyun static int bxt_calc_cdclk_pll_vco(struct drm_i915_private *dev_priv, int cdclk)
1253*4882a593Smuzhiyun {
1254*4882a593Smuzhiyun 	const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
1255*4882a593Smuzhiyun 	int i;
1256*4882a593Smuzhiyun 
1257*4882a593Smuzhiyun 	if (cdclk == dev_priv->cdclk.hw.bypass)
1258*4882a593Smuzhiyun 		return 0;
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	for (i = 0; table[i].refclk; i++)
1261*4882a593Smuzhiyun 		if (table[i].refclk == dev_priv->cdclk.hw.ref &&
1262*4882a593Smuzhiyun 		    table[i].cdclk == cdclk)
1263*4882a593Smuzhiyun 			return dev_priv->cdclk.hw.ref * table[i].ratio;
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun 	drm_WARN(&dev_priv->drm, 1, "cdclk %d not valid for refclk %u\n",
1266*4882a593Smuzhiyun 		 cdclk, dev_priv->cdclk.hw.ref);
1267*4882a593Smuzhiyun 	return 0;
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun 
bxt_calc_voltage_level(int cdclk)1270*4882a593Smuzhiyun static u8 bxt_calc_voltage_level(int cdclk)
1271*4882a593Smuzhiyun {
1272*4882a593Smuzhiyun 	return DIV_ROUND_UP(cdclk, 25000);
1273*4882a593Smuzhiyun }
1274*4882a593Smuzhiyun 
cnl_calc_voltage_level(int cdclk)1275*4882a593Smuzhiyun static u8 cnl_calc_voltage_level(int cdclk)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun 	if (cdclk > 336000)
1278*4882a593Smuzhiyun 		return 2;
1279*4882a593Smuzhiyun 	else if (cdclk > 168000)
1280*4882a593Smuzhiyun 		return 1;
1281*4882a593Smuzhiyun 	else
1282*4882a593Smuzhiyun 		return 0;
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun 
icl_calc_voltage_level(int cdclk)1285*4882a593Smuzhiyun static u8 icl_calc_voltage_level(int cdclk)
1286*4882a593Smuzhiyun {
1287*4882a593Smuzhiyun 	if (cdclk > 556800)
1288*4882a593Smuzhiyun 		return 2;
1289*4882a593Smuzhiyun 	else if (cdclk > 312000)
1290*4882a593Smuzhiyun 		return 1;
1291*4882a593Smuzhiyun 	else
1292*4882a593Smuzhiyun 		return 0;
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun 
ehl_calc_voltage_level(int cdclk)1295*4882a593Smuzhiyun static u8 ehl_calc_voltage_level(int cdclk)
1296*4882a593Smuzhiyun {
1297*4882a593Smuzhiyun 	if (cdclk > 326400)
1298*4882a593Smuzhiyun 		return 3;
1299*4882a593Smuzhiyun 	else if (cdclk > 312000)
1300*4882a593Smuzhiyun 		return 2;
1301*4882a593Smuzhiyun 	else if (cdclk > 180000)
1302*4882a593Smuzhiyun 		return 1;
1303*4882a593Smuzhiyun 	else
1304*4882a593Smuzhiyun 		return 0;
1305*4882a593Smuzhiyun }
1306*4882a593Smuzhiyun 
tgl_calc_voltage_level(int cdclk)1307*4882a593Smuzhiyun static u8 tgl_calc_voltage_level(int cdclk)
1308*4882a593Smuzhiyun {
1309*4882a593Smuzhiyun 	if (cdclk > 556800)
1310*4882a593Smuzhiyun 		return 3;
1311*4882a593Smuzhiyun 	else if (cdclk > 326400)
1312*4882a593Smuzhiyun 		return 2;
1313*4882a593Smuzhiyun 	else if (cdclk > 312000)
1314*4882a593Smuzhiyun 		return 1;
1315*4882a593Smuzhiyun 	else
1316*4882a593Smuzhiyun 		return 0;
1317*4882a593Smuzhiyun }
1318*4882a593Smuzhiyun 
cnl_readout_refclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)1319*4882a593Smuzhiyun static void cnl_readout_refclk(struct drm_i915_private *dev_priv,
1320*4882a593Smuzhiyun 			       struct intel_cdclk_config *cdclk_config)
1321*4882a593Smuzhiyun {
1322*4882a593Smuzhiyun 	if (intel_de_read(dev_priv, SKL_DSSM) & CNL_DSSM_CDCLK_PLL_REFCLK_24MHz)
1323*4882a593Smuzhiyun 		cdclk_config->ref = 24000;
1324*4882a593Smuzhiyun 	else
1325*4882a593Smuzhiyun 		cdclk_config->ref = 19200;
1326*4882a593Smuzhiyun }
1327*4882a593Smuzhiyun 
icl_readout_refclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)1328*4882a593Smuzhiyun static void icl_readout_refclk(struct drm_i915_private *dev_priv,
1329*4882a593Smuzhiyun 			       struct intel_cdclk_config *cdclk_config)
1330*4882a593Smuzhiyun {
1331*4882a593Smuzhiyun 	u32 dssm = intel_de_read(dev_priv, SKL_DSSM) & ICL_DSSM_CDCLK_PLL_REFCLK_MASK;
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun 	switch (dssm) {
1334*4882a593Smuzhiyun 	default:
1335*4882a593Smuzhiyun 		MISSING_CASE(dssm);
1336*4882a593Smuzhiyun 		fallthrough;
1337*4882a593Smuzhiyun 	case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:
1338*4882a593Smuzhiyun 		cdclk_config->ref = 24000;
1339*4882a593Smuzhiyun 		break;
1340*4882a593Smuzhiyun 	case ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz:
1341*4882a593Smuzhiyun 		cdclk_config->ref = 19200;
1342*4882a593Smuzhiyun 		break;
1343*4882a593Smuzhiyun 	case ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz:
1344*4882a593Smuzhiyun 		cdclk_config->ref = 38400;
1345*4882a593Smuzhiyun 		break;
1346*4882a593Smuzhiyun 	}
1347*4882a593Smuzhiyun }
1348*4882a593Smuzhiyun 
bxt_de_pll_readout(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)1349*4882a593Smuzhiyun static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,
1350*4882a593Smuzhiyun 			       struct intel_cdclk_config *cdclk_config)
1351*4882a593Smuzhiyun {
1352*4882a593Smuzhiyun 	u32 val, ratio;
1353*4882a593Smuzhiyun 
1354*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 11)
1355*4882a593Smuzhiyun 		icl_readout_refclk(dev_priv, cdclk_config);
1356*4882a593Smuzhiyun 	else if (IS_CANNONLAKE(dev_priv))
1357*4882a593Smuzhiyun 		cnl_readout_refclk(dev_priv, cdclk_config);
1358*4882a593Smuzhiyun 	else
1359*4882a593Smuzhiyun 		cdclk_config->ref = 19200;
1360*4882a593Smuzhiyun 
1361*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);
1362*4882a593Smuzhiyun 	if ((val & BXT_DE_PLL_PLL_ENABLE) == 0 ||
1363*4882a593Smuzhiyun 	    (val & BXT_DE_PLL_LOCK) == 0) {
1364*4882a593Smuzhiyun 		/*
1365*4882a593Smuzhiyun 		 * CDCLK PLL is disabled, the VCO/ratio doesn't matter, but
1366*4882a593Smuzhiyun 		 * setting it to zero is a way to signal that.
1367*4882a593Smuzhiyun 		 */
1368*4882a593Smuzhiyun 		cdclk_config->vco = 0;
1369*4882a593Smuzhiyun 		return;
1370*4882a593Smuzhiyun 	}
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	/*
1373*4882a593Smuzhiyun 	 * CNL+ have the ratio directly in the PLL enable register, gen9lp had
1374*4882a593Smuzhiyun 	 * it in a separate PLL control register.
1375*4882a593Smuzhiyun 	 */
1376*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10)
1377*4882a593Smuzhiyun 		ratio = val & CNL_CDCLK_PLL_RATIO_MASK;
1378*4882a593Smuzhiyun 	else
1379*4882a593Smuzhiyun 		ratio = intel_de_read(dev_priv, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	cdclk_config->vco = ratio * cdclk_config->ref;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun 
bxt_get_cdclk(struct drm_i915_private * dev_priv,struct intel_cdclk_config * cdclk_config)1384*4882a593Smuzhiyun static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
1385*4882a593Smuzhiyun 			  struct intel_cdclk_config *cdclk_config)
1386*4882a593Smuzhiyun {
1387*4882a593Smuzhiyun 	u32 divider;
1388*4882a593Smuzhiyun 	int div;
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	bxt_de_pll_readout(dev_priv, cdclk_config);
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 12)
1393*4882a593Smuzhiyun 		cdclk_config->bypass = cdclk_config->ref / 2;
1394*4882a593Smuzhiyun 	else if (INTEL_GEN(dev_priv) >= 11)
1395*4882a593Smuzhiyun 		cdclk_config->bypass = 50000;
1396*4882a593Smuzhiyun 	else
1397*4882a593Smuzhiyun 		cdclk_config->bypass = cdclk_config->ref;
1398*4882a593Smuzhiyun 
1399*4882a593Smuzhiyun 	if (cdclk_config->vco == 0) {
1400*4882a593Smuzhiyun 		cdclk_config->cdclk = cdclk_config->bypass;
1401*4882a593Smuzhiyun 		goto out;
1402*4882a593Smuzhiyun 	}
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 	divider = intel_de_read(dev_priv, CDCLK_CTL) & BXT_CDCLK_CD2X_DIV_SEL_MASK;
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun 	switch (divider) {
1407*4882a593Smuzhiyun 	case BXT_CDCLK_CD2X_DIV_SEL_1:
1408*4882a593Smuzhiyun 		div = 2;
1409*4882a593Smuzhiyun 		break;
1410*4882a593Smuzhiyun 	case BXT_CDCLK_CD2X_DIV_SEL_1_5:
1411*4882a593Smuzhiyun 		drm_WARN(&dev_priv->drm,
1412*4882a593Smuzhiyun 			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
1413*4882a593Smuzhiyun 			 "Unsupported divider\n");
1414*4882a593Smuzhiyun 		div = 3;
1415*4882a593Smuzhiyun 		break;
1416*4882a593Smuzhiyun 	case BXT_CDCLK_CD2X_DIV_SEL_2:
1417*4882a593Smuzhiyun 		div = 4;
1418*4882a593Smuzhiyun 		break;
1419*4882a593Smuzhiyun 	case BXT_CDCLK_CD2X_DIV_SEL_4:
1420*4882a593Smuzhiyun 		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
1421*4882a593Smuzhiyun 			 "Unsupported divider\n");
1422*4882a593Smuzhiyun 		div = 8;
1423*4882a593Smuzhiyun 		break;
1424*4882a593Smuzhiyun 	default:
1425*4882a593Smuzhiyun 		MISSING_CASE(divider);
1426*4882a593Smuzhiyun 		return;
1427*4882a593Smuzhiyun 	}
1428*4882a593Smuzhiyun 
1429*4882a593Smuzhiyun 	cdclk_config->cdclk = DIV_ROUND_CLOSEST(cdclk_config->vco, div);
1430*4882a593Smuzhiyun 
1431*4882a593Smuzhiyun  out:
1432*4882a593Smuzhiyun 	/*
1433*4882a593Smuzhiyun 	 * Can't read this out :( Let's assume it's
1434*4882a593Smuzhiyun 	 * at least what the CDCLK frequency requires.
1435*4882a593Smuzhiyun 	 */
1436*4882a593Smuzhiyun 	cdclk_config->voltage_level =
1437*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level(cdclk_config->cdclk);
1438*4882a593Smuzhiyun }
1439*4882a593Smuzhiyun 
bxt_de_pll_disable(struct drm_i915_private * dev_priv)1440*4882a593Smuzhiyun static void bxt_de_pll_disable(struct drm_i915_private *dev_priv)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, 0);
1443*4882a593Smuzhiyun 
1444*4882a593Smuzhiyun 	/* Timeout 200us */
1445*4882a593Smuzhiyun 	if (intel_de_wait_for_clear(dev_priv,
1446*4882a593Smuzhiyun 				    BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
1447*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "timeout waiting for DE PLL unlock\n");
1448*4882a593Smuzhiyun 
1449*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = 0;
1450*4882a593Smuzhiyun }
1451*4882a593Smuzhiyun 
bxt_de_pll_enable(struct drm_i915_private * dev_priv,int vco)1452*4882a593Smuzhiyun static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
1453*4882a593Smuzhiyun {
1454*4882a593Smuzhiyun 	int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
1455*4882a593Smuzhiyun 	u32 val;
1456*4882a593Smuzhiyun 
1457*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, BXT_DE_PLL_CTL);
1458*4882a593Smuzhiyun 	val &= ~BXT_DE_PLL_RATIO_MASK;
1459*4882a593Smuzhiyun 	val |= BXT_DE_PLL_RATIO(ratio);
1460*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_CTL, val);
1461*4882a593Smuzhiyun 
1462*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, BXT_DE_PLL_PLL_ENABLE);
1463*4882a593Smuzhiyun 
1464*4882a593Smuzhiyun 	/* Timeout 200us */
1465*4882a593Smuzhiyun 	if (intel_de_wait_for_set(dev_priv,
1466*4882a593Smuzhiyun 				  BXT_DE_PLL_ENABLE, BXT_DE_PLL_LOCK, 1))
1467*4882a593Smuzhiyun 		drm_err(&dev_priv->drm, "timeout waiting for DE PLL lock\n");
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = vco;
1470*4882a593Smuzhiyun }
1471*4882a593Smuzhiyun 
cnl_cdclk_pll_disable(struct drm_i915_private * dev_priv)1472*4882a593Smuzhiyun static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
1473*4882a593Smuzhiyun {
1474*4882a593Smuzhiyun 	u32 val;
1475*4882a593Smuzhiyun 
1476*4882a593Smuzhiyun 	val = intel_de_read(dev_priv, BXT_DE_PLL_ENABLE);
1477*4882a593Smuzhiyun 	val &= ~BXT_DE_PLL_PLL_ENABLE;
1478*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
1479*4882a593Smuzhiyun 
1480*4882a593Smuzhiyun 	/* Timeout 200us */
1481*4882a593Smuzhiyun 	if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) == 0, 1))
1482*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
1483*4882a593Smuzhiyun 			"timeout waiting for CDCLK PLL unlock\n");
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = 0;
1486*4882a593Smuzhiyun }
1487*4882a593Smuzhiyun 
cnl_cdclk_pll_enable(struct drm_i915_private * dev_priv,int vco)1488*4882a593Smuzhiyun static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
1489*4882a593Smuzhiyun {
1490*4882a593Smuzhiyun 	int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
1491*4882a593Smuzhiyun 	u32 val;
1492*4882a593Smuzhiyun 
1493*4882a593Smuzhiyun 	val = CNL_CDCLK_PLL_RATIO(ratio);
1494*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
1495*4882a593Smuzhiyun 
1496*4882a593Smuzhiyun 	val |= BXT_DE_PLL_PLL_ENABLE;
1497*4882a593Smuzhiyun 	intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
1498*4882a593Smuzhiyun 
1499*4882a593Smuzhiyun 	/* Timeout 200us */
1500*4882a593Smuzhiyun 	if (wait_for((intel_de_read(dev_priv, BXT_DE_PLL_ENABLE) & BXT_DE_PLL_LOCK) != 0, 1))
1501*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
1502*4882a593Smuzhiyun 			"timeout waiting for CDCLK PLL lock\n");
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = vco;
1505*4882a593Smuzhiyun }
1506*4882a593Smuzhiyun 
bxt_cdclk_cd2x_pipe(struct drm_i915_private * dev_priv,enum pipe pipe)1507*4882a593Smuzhiyun static u32 bxt_cdclk_cd2x_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
1508*4882a593Smuzhiyun {
1509*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 12) {
1510*4882a593Smuzhiyun 		if (pipe == INVALID_PIPE)
1511*4882a593Smuzhiyun 			return TGL_CDCLK_CD2X_PIPE_NONE;
1512*4882a593Smuzhiyun 		else
1513*4882a593Smuzhiyun 			return TGL_CDCLK_CD2X_PIPE(pipe);
1514*4882a593Smuzhiyun 	} else if (INTEL_GEN(dev_priv) >= 11) {
1515*4882a593Smuzhiyun 		if (pipe == INVALID_PIPE)
1516*4882a593Smuzhiyun 			return ICL_CDCLK_CD2X_PIPE_NONE;
1517*4882a593Smuzhiyun 		else
1518*4882a593Smuzhiyun 			return ICL_CDCLK_CD2X_PIPE(pipe);
1519*4882a593Smuzhiyun 	} else {
1520*4882a593Smuzhiyun 		if (pipe == INVALID_PIPE)
1521*4882a593Smuzhiyun 			return BXT_CDCLK_CD2X_PIPE_NONE;
1522*4882a593Smuzhiyun 		else
1523*4882a593Smuzhiyun 			return BXT_CDCLK_CD2X_PIPE(pipe);
1524*4882a593Smuzhiyun 	}
1525*4882a593Smuzhiyun }
1526*4882a593Smuzhiyun 
bxt_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)1527*4882a593Smuzhiyun static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
1528*4882a593Smuzhiyun 			  const struct intel_cdclk_config *cdclk_config,
1529*4882a593Smuzhiyun 			  enum pipe pipe)
1530*4882a593Smuzhiyun {
1531*4882a593Smuzhiyun 	int cdclk = cdclk_config->cdclk;
1532*4882a593Smuzhiyun 	int vco = cdclk_config->vco;
1533*4882a593Smuzhiyun 	u32 val, divider;
1534*4882a593Smuzhiyun 	int ret;
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	/* Inform power controller of upcoming frequency change. */
1537*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10)
1538*4882a593Smuzhiyun 		ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
1539*4882a593Smuzhiyun 					SKL_CDCLK_PREPARE_FOR_CHANGE,
1540*4882a593Smuzhiyun 					SKL_CDCLK_READY_FOR_CHANGE,
1541*4882a593Smuzhiyun 					SKL_CDCLK_READY_FOR_CHANGE, 3);
1542*4882a593Smuzhiyun 	else
1543*4882a593Smuzhiyun 		/*
1544*4882a593Smuzhiyun 		 * BSpec requires us to wait up to 150usec, but that leads to
1545*4882a593Smuzhiyun 		 * timeouts; the 2ms used here is based on experiment.
1546*4882a593Smuzhiyun 		 */
1547*4882a593Smuzhiyun 		ret = sandybridge_pcode_write_timeout(dev_priv,
1548*4882a593Smuzhiyun 						      HSW_PCODE_DE_WRITE_FREQ_REQ,
1549*4882a593Smuzhiyun 						      0x80000000, 150, 2);
1550*4882a593Smuzhiyun 
1551*4882a593Smuzhiyun 	if (ret) {
1552*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
1553*4882a593Smuzhiyun 			"Failed to inform PCU about cdclk change (err %d, freq %d)\n",
1554*4882a593Smuzhiyun 			ret, cdclk);
1555*4882a593Smuzhiyun 		return;
1556*4882a593Smuzhiyun 	}
1557*4882a593Smuzhiyun 
1558*4882a593Smuzhiyun 	/* cdclk = vco / 2 / div{1,1.5,2,4} */
1559*4882a593Smuzhiyun 	switch (DIV_ROUND_CLOSEST(vco, cdclk)) {
1560*4882a593Smuzhiyun 	default:
1561*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm,
1562*4882a593Smuzhiyun 			    cdclk != dev_priv->cdclk.hw.bypass);
1563*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm, vco != 0);
1564*4882a593Smuzhiyun 		fallthrough;
1565*4882a593Smuzhiyun 	case 2:
1566*4882a593Smuzhiyun 		divider = BXT_CDCLK_CD2X_DIV_SEL_1;
1567*4882a593Smuzhiyun 		break;
1568*4882a593Smuzhiyun 	case 3:
1569*4882a593Smuzhiyun 		drm_WARN(&dev_priv->drm,
1570*4882a593Smuzhiyun 			 IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10,
1571*4882a593Smuzhiyun 			 "Unsupported divider\n");
1572*4882a593Smuzhiyun 		divider = BXT_CDCLK_CD2X_DIV_SEL_1_5;
1573*4882a593Smuzhiyun 		break;
1574*4882a593Smuzhiyun 	case 4:
1575*4882a593Smuzhiyun 		divider = BXT_CDCLK_CD2X_DIV_SEL_2;
1576*4882a593Smuzhiyun 		break;
1577*4882a593Smuzhiyun 	case 8:
1578*4882a593Smuzhiyun 		drm_WARN(&dev_priv->drm, INTEL_GEN(dev_priv) >= 10,
1579*4882a593Smuzhiyun 			 "Unsupported divider\n");
1580*4882a593Smuzhiyun 		divider = BXT_CDCLK_CD2X_DIV_SEL_4;
1581*4882a593Smuzhiyun 		break;
1582*4882a593Smuzhiyun 	}
1583*4882a593Smuzhiyun 
1584*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10) {
1585*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.vco != 0 &&
1586*4882a593Smuzhiyun 		    dev_priv->cdclk.hw.vco != vco)
1587*4882a593Smuzhiyun 			cnl_cdclk_pll_disable(dev_priv);
1588*4882a593Smuzhiyun 
1589*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.vco != vco)
1590*4882a593Smuzhiyun 			cnl_cdclk_pll_enable(dev_priv, vco);
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun 	} else {
1593*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.vco != 0 &&
1594*4882a593Smuzhiyun 		    dev_priv->cdclk.hw.vco != vco)
1595*4882a593Smuzhiyun 			bxt_de_pll_disable(dev_priv);
1596*4882a593Smuzhiyun 
1597*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.vco != vco)
1598*4882a593Smuzhiyun 			bxt_de_pll_enable(dev_priv, vco);
1599*4882a593Smuzhiyun 	}
1600*4882a593Smuzhiyun 
1601*4882a593Smuzhiyun 	val = divider | skl_cdclk_decimal(cdclk) |
1602*4882a593Smuzhiyun 		bxt_cdclk_cd2x_pipe(dev_priv, pipe);
1603*4882a593Smuzhiyun 
1604*4882a593Smuzhiyun 	/*
1605*4882a593Smuzhiyun 	 * Disable SSA Precharge when CD clock frequency < 500 MHz,
1606*4882a593Smuzhiyun 	 * enable otherwise.
1607*4882a593Smuzhiyun 	 */
1608*4882a593Smuzhiyun 	if (IS_GEN9_LP(dev_priv) && cdclk >= 500000)
1609*4882a593Smuzhiyun 		val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
1610*4882a593Smuzhiyun 	intel_de_write(dev_priv, CDCLK_CTL, val);
1611*4882a593Smuzhiyun 
1612*4882a593Smuzhiyun 	if (pipe != INVALID_PIPE)
1613*4882a593Smuzhiyun 		intel_wait_for_vblank(dev_priv, pipe);
1614*4882a593Smuzhiyun 
1615*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10) {
1616*4882a593Smuzhiyun 		ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
1617*4882a593Smuzhiyun 					      cdclk_config->voltage_level);
1618*4882a593Smuzhiyun 	} else {
1619*4882a593Smuzhiyun 		/*
1620*4882a593Smuzhiyun 		 * The timeout isn't specified, the 2ms used here is based on
1621*4882a593Smuzhiyun 		 * experiment.
1622*4882a593Smuzhiyun 		 * FIXME: Waiting for the request completion could be delayed
1623*4882a593Smuzhiyun 		 * until the next PCODE request based on BSpec.
1624*4882a593Smuzhiyun 		 */
1625*4882a593Smuzhiyun 		ret = sandybridge_pcode_write_timeout(dev_priv,
1626*4882a593Smuzhiyun 						      HSW_PCODE_DE_WRITE_FREQ_REQ,
1627*4882a593Smuzhiyun 						      cdclk_config->voltage_level,
1628*4882a593Smuzhiyun 						      150, 2);
1629*4882a593Smuzhiyun 	}
1630*4882a593Smuzhiyun 
1631*4882a593Smuzhiyun 	if (ret) {
1632*4882a593Smuzhiyun 		drm_err(&dev_priv->drm,
1633*4882a593Smuzhiyun 			"PCode CDCLK freq set failed, (err %d, freq %d)\n",
1634*4882a593Smuzhiyun 			ret, cdclk);
1635*4882a593Smuzhiyun 		return;
1636*4882a593Smuzhiyun 	}
1637*4882a593Smuzhiyun 
1638*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
1639*4882a593Smuzhiyun 
1640*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10)
1641*4882a593Smuzhiyun 		/*
1642*4882a593Smuzhiyun 		 * Can't read out the voltage level :(
1643*4882a593Smuzhiyun 		 * Let's just assume everything is as expected.
1644*4882a593Smuzhiyun 		 */
1645*4882a593Smuzhiyun 		dev_priv->cdclk.hw.voltage_level = cdclk_config->voltage_level;
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun 
bxt_sanitize_cdclk(struct drm_i915_private * dev_priv)1648*4882a593Smuzhiyun static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
1649*4882a593Smuzhiyun {
1650*4882a593Smuzhiyun 	u32 cdctl, expected;
1651*4882a593Smuzhiyun 	int cdclk, vco;
1652*4882a593Smuzhiyun 
1653*4882a593Smuzhiyun 	intel_update_cdclk(dev_priv);
1654*4882a593Smuzhiyun 	intel_dump_cdclk_config(&dev_priv->cdclk.hw, "Current CDCLK");
1655*4882a593Smuzhiyun 
1656*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.vco == 0 ||
1657*4882a593Smuzhiyun 	    dev_priv->cdclk.hw.cdclk == dev_priv->cdclk.hw.bypass)
1658*4882a593Smuzhiyun 		goto sanitize;
1659*4882a593Smuzhiyun 
1660*4882a593Smuzhiyun 	/* DPLL okay; verify the cdclock
1661*4882a593Smuzhiyun 	 *
1662*4882a593Smuzhiyun 	 * Some BIOS versions leave an incorrect decimal frequency value and
1663*4882a593Smuzhiyun 	 * set reserved MBZ bits in CDCLK_CTL at least during exiting from S4,
1664*4882a593Smuzhiyun 	 * so sanitize this register.
1665*4882a593Smuzhiyun 	 */
1666*4882a593Smuzhiyun 	cdctl = intel_de_read(dev_priv, CDCLK_CTL);
1667*4882a593Smuzhiyun 	/*
1668*4882a593Smuzhiyun 	 * Let's ignore the pipe field, since BIOS could have configured the
1669*4882a593Smuzhiyun 	 * dividers both synching to an active pipe, or asynchronously
1670*4882a593Smuzhiyun 	 * (PIPE_NONE).
1671*4882a593Smuzhiyun 	 */
1672*4882a593Smuzhiyun 	cdctl &= ~bxt_cdclk_cd2x_pipe(dev_priv, INVALID_PIPE);
1673*4882a593Smuzhiyun 
1674*4882a593Smuzhiyun 	/* Make sure this is a legal cdclk value for the platform */
1675*4882a593Smuzhiyun 	cdclk = bxt_calc_cdclk(dev_priv, dev_priv->cdclk.hw.cdclk);
1676*4882a593Smuzhiyun 	if (cdclk != dev_priv->cdclk.hw.cdclk)
1677*4882a593Smuzhiyun 		goto sanitize;
1678*4882a593Smuzhiyun 
1679*4882a593Smuzhiyun 	/* Make sure the VCO is correct for the cdclk */
1680*4882a593Smuzhiyun 	vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
1681*4882a593Smuzhiyun 	if (vco != dev_priv->cdclk.hw.vco)
1682*4882a593Smuzhiyun 		goto sanitize;
1683*4882a593Smuzhiyun 
1684*4882a593Smuzhiyun 	expected = skl_cdclk_decimal(cdclk);
1685*4882a593Smuzhiyun 
1686*4882a593Smuzhiyun 	/* Figure out what CD2X divider we should be using for this cdclk */
1687*4882a593Smuzhiyun 	switch (DIV_ROUND_CLOSEST(dev_priv->cdclk.hw.vco,
1688*4882a593Smuzhiyun 				  dev_priv->cdclk.hw.cdclk)) {
1689*4882a593Smuzhiyun 	case 2:
1690*4882a593Smuzhiyun 		expected |= BXT_CDCLK_CD2X_DIV_SEL_1;
1691*4882a593Smuzhiyun 		break;
1692*4882a593Smuzhiyun 	case 3:
1693*4882a593Smuzhiyun 		expected |= BXT_CDCLK_CD2X_DIV_SEL_1_5;
1694*4882a593Smuzhiyun 		break;
1695*4882a593Smuzhiyun 	case 4:
1696*4882a593Smuzhiyun 		expected |= BXT_CDCLK_CD2X_DIV_SEL_2;
1697*4882a593Smuzhiyun 		break;
1698*4882a593Smuzhiyun 	case 8:
1699*4882a593Smuzhiyun 		expected |= BXT_CDCLK_CD2X_DIV_SEL_4;
1700*4882a593Smuzhiyun 		break;
1701*4882a593Smuzhiyun 	default:
1702*4882a593Smuzhiyun 		goto sanitize;
1703*4882a593Smuzhiyun 	}
1704*4882a593Smuzhiyun 
1705*4882a593Smuzhiyun 	/*
1706*4882a593Smuzhiyun 	 * Disable SSA Precharge when CD clock frequency < 500 MHz,
1707*4882a593Smuzhiyun 	 * enable otherwise.
1708*4882a593Smuzhiyun 	 */
1709*4882a593Smuzhiyun 	if (IS_GEN9_LP(dev_priv) && dev_priv->cdclk.hw.cdclk >= 500000)
1710*4882a593Smuzhiyun 		expected |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	if (cdctl == expected)
1713*4882a593Smuzhiyun 		/* All well; nothing to sanitize */
1714*4882a593Smuzhiyun 		return;
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun sanitize:
1717*4882a593Smuzhiyun 	drm_dbg_kms(&dev_priv->drm, "Sanitizing cdclk programmed by pre-os\n");
1718*4882a593Smuzhiyun 
1719*4882a593Smuzhiyun 	/* force cdclk programming */
1720*4882a593Smuzhiyun 	dev_priv->cdclk.hw.cdclk = 0;
1721*4882a593Smuzhiyun 
1722*4882a593Smuzhiyun 	/* force full PLL disable + enable */
1723*4882a593Smuzhiyun 	dev_priv->cdclk.hw.vco = -1;
1724*4882a593Smuzhiyun }
1725*4882a593Smuzhiyun 
bxt_cdclk_init_hw(struct drm_i915_private * dev_priv)1726*4882a593Smuzhiyun static void bxt_cdclk_init_hw(struct drm_i915_private *dev_priv)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun 	struct intel_cdclk_config cdclk_config;
1729*4882a593Smuzhiyun 
1730*4882a593Smuzhiyun 	bxt_sanitize_cdclk(dev_priv);
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun 	if (dev_priv->cdclk.hw.cdclk != 0 &&
1733*4882a593Smuzhiyun 	    dev_priv->cdclk.hw.vco != 0)
1734*4882a593Smuzhiyun 		return;
1735*4882a593Smuzhiyun 
1736*4882a593Smuzhiyun 	cdclk_config = dev_priv->cdclk.hw;
1737*4882a593Smuzhiyun 
1738*4882a593Smuzhiyun 	/*
1739*4882a593Smuzhiyun 	 * FIXME:
1740*4882a593Smuzhiyun 	 * - The initial CDCLK needs to be read from VBT.
1741*4882a593Smuzhiyun 	 *   Need to make this change after VBT has changes for BXT.
1742*4882a593Smuzhiyun 	 */
1743*4882a593Smuzhiyun 	cdclk_config.cdclk = bxt_calc_cdclk(dev_priv, 0);
1744*4882a593Smuzhiyun 	cdclk_config.vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk_config.cdclk);
1745*4882a593Smuzhiyun 	cdclk_config.voltage_level =
1746*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level(cdclk_config.cdclk);
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
1749*4882a593Smuzhiyun }
1750*4882a593Smuzhiyun 
bxt_cdclk_uninit_hw(struct drm_i915_private * dev_priv)1751*4882a593Smuzhiyun static void bxt_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
1752*4882a593Smuzhiyun {
1753*4882a593Smuzhiyun 	struct intel_cdclk_config cdclk_config = dev_priv->cdclk.hw;
1754*4882a593Smuzhiyun 
1755*4882a593Smuzhiyun 	cdclk_config.cdclk = cdclk_config.bypass;
1756*4882a593Smuzhiyun 	cdclk_config.vco = 0;
1757*4882a593Smuzhiyun 	cdclk_config.voltage_level =
1758*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level(cdclk_config.cdclk);
1759*4882a593Smuzhiyun 
1760*4882a593Smuzhiyun 	bxt_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
1761*4882a593Smuzhiyun }
1762*4882a593Smuzhiyun 
1763*4882a593Smuzhiyun /**
1764*4882a593Smuzhiyun  * intel_cdclk_init_hw - Initialize CDCLK hardware
1765*4882a593Smuzhiyun  * @i915: i915 device
1766*4882a593Smuzhiyun  *
1767*4882a593Smuzhiyun  * Initialize CDCLK. This consists mainly of initializing dev_priv->cdclk.hw and
1768*4882a593Smuzhiyun  * sanitizing the state of the hardware if needed. This is generally done only
1769*4882a593Smuzhiyun  * during the display core initialization sequence, after which the DMC will
1770*4882a593Smuzhiyun  * take care of turning CDCLK off/on as needed.
1771*4882a593Smuzhiyun  */
intel_cdclk_init_hw(struct drm_i915_private * i915)1772*4882a593Smuzhiyun void intel_cdclk_init_hw(struct drm_i915_private *i915)
1773*4882a593Smuzhiyun {
1774*4882a593Smuzhiyun 	if (IS_GEN9_LP(i915) || INTEL_GEN(i915) >= 10)
1775*4882a593Smuzhiyun 		bxt_cdclk_init_hw(i915);
1776*4882a593Smuzhiyun 	else if (IS_GEN9_BC(i915))
1777*4882a593Smuzhiyun 		skl_cdclk_init_hw(i915);
1778*4882a593Smuzhiyun }
1779*4882a593Smuzhiyun 
1780*4882a593Smuzhiyun /**
1781*4882a593Smuzhiyun  * intel_cdclk_uninit_hw - Uninitialize CDCLK hardware
1782*4882a593Smuzhiyun  * @i915: i915 device
1783*4882a593Smuzhiyun  *
1784*4882a593Smuzhiyun  * Uninitialize CDCLK. This is done only during the display core
1785*4882a593Smuzhiyun  * uninitialization sequence.
1786*4882a593Smuzhiyun  */
intel_cdclk_uninit_hw(struct drm_i915_private * i915)1787*4882a593Smuzhiyun void intel_cdclk_uninit_hw(struct drm_i915_private *i915)
1788*4882a593Smuzhiyun {
1789*4882a593Smuzhiyun 	if (INTEL_GEN(i915) >= 10 || IS_GEN9_LP(i915))
1790*4882a593Smuzhiyun 		bxt_cdclk_uninit_hw(i915);
1791*4882a593Smuzhiyun 	else if (IS_GEN9_BC(i915))
1792*4882a593Smuzhiyun 		skl_cdclk_uninit_hw(i915);
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun 
1795*4882a593Smuzhiyun /**
1796*4882a593Smuzhiyun  * intel_cdclk_needs_modeset - Determine if changong between the CDCLK
1797*4882a593Smuzhiyun  *                             configurations requires a modeset on all pipes
1798*4882a593Smuzhiyun  * @a: first CDCLK configuration
1799*4882a593Smuzhiyun  * @b: second CDCLK configuration
1800*4882a593Smuzhiyun  *
1801*4882a593Smuzhiyun  * Returns:
1802*4882a593Smuzhiyun  * True if changing between the two CDCLK configurations
1803*4882a593Smuzhiyun  * requires all pipes to be off, false if not.
1804*4882a593Smuzhiyun  */
intel_cdclk_needs_modeset(const struct intel_cdclk_config * a,const struct intel_cdclk_config * b)1805*4882a593Smuzhiyun bool intel_cdclk_needs_modeset(const struct intel_cdclk_config *a,
1806*4882a593Smuzhiyun 			       const struct intel_cdclk_config *b)
1807*4882a593Smuzhiyun {
1808*4882a593Smuzhiyun 	return a->cdclk != b->cdclk ||
1809*4882a593Smuzhiyun 		a->vco != b->vco ||
1810*4882a593Smuzhiyun 		a->ref != b->ref;
1811*4882a593Smuzhiyun }
1812*4882a593Smuzhiyun 
1813*4882a593Smuzhiyun /**
1814*4882a593Smuzhiyun  * intel_cdclk_can_cd2x_update - Determine if changing between the two CDCLK
1815*4882a593Smuzhiyun  *                               configurations requires only a cd2x divider update
1816*4882a593Smuzhiyun  * @dev_priv: i915 device
1817*4882a593Smuzhiyun  * @a: first CDCLK configuration
1818*4882a593Smuzhiyun  * @b: second CDCLK configuration
1819*4882a593Smuzhiyun  *
1820*4882a593Smuzhiyun  * Returns:
1821*4882a593Smuzhiyun  * True if changing between the two CDCLK configurations
1822*4882a593Smuzhiyun  * can be done with just a cd2x divider update, false if not.
1823*4882a593Smuzhiyun  */
intel_cdclk_can_cd2x_update(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * a,const struct intel_cdclk_config * b)1824*4882a593Smuzhiyun static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
1825*4882a593Smuzhiyun 					const struct intel_cdclk_config *a,
1826*4882a593Smuzhiyun 					const struct intel_cdclk_config *b)
1827*4882a593Smuzhiyun {
1828*4882a593Smuzhiyun 	/* Older hw doesn't have the capability */
1829*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) < 10 && !IS_GEN9_LP(dev_priv))
1830*4882a593Smuzhiyun 		return false;
1831*4882a593Smuzhiyun 
1832*4882a593Smuzhiyun 	return a->cdclk != b->cdclk &&
1833*4882a593Smuzhiyun 		a->vco == b->vco &&
1834*4882a593Smuzhiyun 		a->ref == b->ref;
1835*4882a593Smuzhiyun }
1836*4882a593Smuzhiyun 
1837*4882a593Smuzhiyun /**
1838*4882a593Smuzhiyun  * intel_cdclk_changed - Determine if two CDCLK configurations are different
1839*4882a593Smuzhiyun  * @a: first CDCLK configuration
1840*4882a593Smuzhiyun  * @b: second CDCLK configuration
1841*4882a593Smuzhiyun  *
1842*4882a593Smuzhiyun  * Returns:
1843*4882a593Smuzhiyun  * True if the CDCLK configurations don't match, false if they do.
1844*4882a593Smuzhiyun  */
intel_cdclk_changed(const struct intel_cdclk_config * a,const struct intel_cdclk_config * b)1845*4882a593Smuzhiyun static bool intel_cdclk_changed(const struct intel_cdclk_config *a,
1846*4882a593Smuzhiyun 				const struct intel_cdclk_config *b)
1847*4882a593Smuzhiyun {
1848*4882a593Smuzhiyun 	return intel_cdclk_needs_modeset(a, b) ||
1849*4882a593Smuzhiyun 		a->voltage_level != b->voltage_level;
1850*4882a593Smuzhiyun }
1851*4882a593Smuzhiyun 
intel_dump_cdclk_config(const struct intel_cdclk_config * cdclk_config,const char * context)1852*4882a593Smuzhiyun void intel_dump_cdclk_config(const struct intel_cdclk_config *cdclk_config,
1853*4882a593Smuzhiyun 			     const char *context)
1854*4882a593Smuzhiyun {
1855*4882a593Smuzhiyun 	DRM_DEBUG_DRIVER("%s %d kHz, VCO %d kHz, ref %d kHz, bypass %d kHz, voltage level %d\n",
1856*4882a593Smuzhiyun 			 context, cdclk_config->cdclk, cdclk_config->vco,
1857*4882a593Smuzhiyun 			 cdclk_config->ref, cdclk_config->bypass,
1858*4882a593Smuzhiyun 			 cdclk_config->voltage_level);
1859*4882a593Smuzhiyun }
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun /**
1862*4882a593Smuzhiyun  * intel_set_cdclk - Push the CDCLK configuration to the hardware
1863*4882a593Smuzhiyun  * @dev_priv: i915 device
1864*4882a593Smuzhiyun  * @cdclk_config: new CDCLK configuration
1865*4882a593Smuzhiyun  * @pipe: pipe with which to synchronize the update
1866*4882a593Smuzhiyun  *
1867*4882a593Smuzhiyun  * Program the hardware based on the passed in CDCLK state,
1868*4882a593Smuzhiyun  * if necessary.
1869*4882a593Smuzhiyun  */
intel_set_cdclk(struct drm_i915_private * dev_priv,const struct intel_cdclk_config * cdclk_config,enum pipe pipe)1870*4882a593Smuzhiyun static void intel_set_cdclk(struct drm_i915_private *dev_priv,
1871*4882a593Smuzhiyun 			    const struct intel_cdclk_config *cdclk_config,
1872*4882a593Smuzhiyun 			    enum pipe pipe)
1873*4882a593Smuzhiyun {
1874*4882a593Smuzhiyun 	struct intel_encoder *encoder;
1875*4882a593Smuzhiyun 
1876*4882a593Smuzhiyun 	if (!intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config))
1877*4882a593Smuzhiyun 		return;
1878*4882a593Smuzhiyun 
1879*4882a593Smuzhiyun 	if (drm_WARN_ON_ONCE(&dev_priv->drm, !dev_priv->display.set_cdclk))
1880*4882a593Smuzhiyun 		return;
1881*4882a593Smuzhiyun 
1882*4882a593Smuzhiyun 	intel_dump_cdclk_config(cdclk_config, "Changing CDCLK to");
1883*4882a593Smuzhiyun 
1884*4882a593Smuzhiyun 	/*
1885*4882a593Smuzhiyun 	 * Lock aux/gmbus while we change cdclk in case those
1886*4882a593Smuzhiyun 	 * functions use cdclk. Not all platforms/ports do,
1887*4882a593Smuzhiyun 	 * but we'll lock them all for simplicity.
1888*4882a593Smuzhiyun 	 */
1889*4882a593Smuzhiyun 	mutex_lock(&dev_priv->gmbus_mutex);
1890*4882a593Smuzhiyun 	for_each_intel_dp(&dev_priv->drm, encoder) {
1891*4882a593Smuzhiyun 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1892*4882a593Smuzhiyun 
1893*4882a593Smuzhiyun 		mutex_lock_nest_lock(&intel_dp->aux.hw_mutex,
1894*4882a593Smuzhiyun 				     &dev_priv->gmbus_mutex);
1895*4882a593Smuzhiyun 	}
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 	dev_priv->display.set_cdclk(dev_priv, cdclk_config, pipe);
1898*4882a593Smuzhiyun 
1899*4882a593Smuzhiyun 	for_each_intel_dp(&dev_priv->drm, encoder) {
1900*4882a593Smuzhiyun 		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1901*4882a593Smuzhiyun 
1902*4882a593Smuzhiyun 		mutex_unlock(&intel_dp->aux.hw_mutex);
1903*4882a593Smuzhiyun 	}
1904*4882a593Smuzhiyun 	mutex_unlock(&dev_priv->gmbus_mutex);
1905*4882a593Smuzhiyun 
1906*4882a593Smuzhiyun 	if (drm_WARN(&dev_priv->drm,
1907*4882a593Smuzhiyun 		     intel_cdclk_changed(&dev_priv->cdclk.hw, cdclk_config),
1908*4882a593Smuzhiyun 		     "cdclk state doesn't match!\n")) {
1909*4882a593Smuzhiyun 		intel_dump_cdclk_config(&dev_priv->cdclk.hw, "[hw state]");
1910*4882a593Smuzhiyun 		intel_dump_cdclk_config(cdclk_config, "[sw state]");
1911*4882a593Smuzhiyun 	}
1912*4882a593Smuzhiyun }
1913*4882a593Smuzhiyun 
1914*4882a593Smuzhiyun /**
1915*4882a593Smuzhiyun  * intel_set_cdclk_pre_plane_update - Push the CDCLK state to the hardware
1916*4882a593Smuzhiyun  * @state: intel atomic state
1917*4882a593Smuzhiyun  *
1918*4882a593Smuzhiyun  * Program the hardware before updating the HW plane state based on the
1919*4882a593Smuzhiyun  * new CDCLK state, if necessary.
1920*4882a593Smuzhiyun  */
1921*4882a593Smuzhiyun void
intel_set_cdclk_pre_plane_update(struct intel_atomic_state * state)1922*4882a593Smuzhiyun intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
1923*4882a593Smuzhiyun {
1924*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1925*4882a593Smuzhiyun 	const struct intel_cdclk_state *old_cdclk_state =
1926*4882a593Smuzhiyun 		intel_atomic_get_old_cdclk_state(state);
1927*4882a593Smuzhiyun 	const struct intel_cdclk_state *new_cdclk_state =
1928*4882a593Smuzhiyun 		intel_atomic_get_new_cdclk_state(state);
1929*4882a593Smuzhiyun 	enum pipe pipe = new_cdclk_state->pipe;
1930*4882a593Smuzhiyun 
1931*4882a593Smuzhiyun 	if (!intel_cdclk_changed(&old_cdclk_state->actual,
1932*4882a593Smuzhiyun 				 &new_cdclk_state->actual))
1933*4882a593Smuzhiyun 		return;
1934*4882a593Smuzhiyun 
1935*4882a593Smuzhiyun 	if (pipe == INVALID_PIPE ||
1936*4882a593Smuzhiyun 	    old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
1937*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm, !new_cdclk_state->base.changed);
1938*4882a593Smuzhiyun 
1939*4882a593Smuzhiyun 		intel_set_cdclk(dev_priv, &new_cdclk_state->actual, pipe);
1940*4882a593Smuzhiyun 	}
1941*4882a593Smuzhiyun }
1942*4882a593Smuzhiyun 
1943*4882a593Smuzhiyun /**
1944*4882a593Smuzhiyun  * intel_set_cdclk_post_plane_update - Push the CDCLK state to the hardware
1945*4882a593Smuzhiyun  * @state: intel atomic state
1946*4882a593Smuzhiyun  *
1947*4882a593Smuzhiyun  * Program the hardware after updating the HW plane state based on the
1948*4882a593Smuzhiyun  * new CDCLK state, if necessary.
1949*4882a593Smuzhiyun  */
1950*4882a593Smuzhiyun void
intel_set_cdclk_post_plane_update(struct intel_atomic_state * state)1951*4882a593Smuzhiyun intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
1952*4882a593Smuzhiyun {
1953*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
1954*4882a593Smuzhiyun 	const struct intel_cdclk_state *old_cdclk_state =
1955*4882a593Smuzhiyun 		intel_atomic_get_old_cdclk_state(state);
1956*4882a593Smuzhiyun 	const struct intel_cdclk_state *new_cdclk_state =
1957*4882a593Smuzhiyun 		intel_atomic_get_new_cdclk_state(state);
1958*4882a593Smuzhiyun 	enum pipe pipe = new_cdclk_state->pipe;
1959*4882a593Smuzhiyun 
1960*4882a593Smuzhiyun 	if (!intel_cdclk_changed(&old_cdclk_state->actual,
1961*4882a593Smuzhiyun 				 &new_cdclk_state->actual))
1962*4882a593Smuzhiyun 		return;
1963*4882a593Smuzhiyun 
1964*4882a593Smuzhiyun 	if (pipe != INVALID_PIPE &&
1965*4882a593Smuzhiyun 	    old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) {
1966*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm, !new_cdclk_state->base.changed);
1967*4882a593Smuzhiyun 
1968*4882a593Smuzhiyun 		intel_set_cdclk(dev_priv, &new_cdclk_state->actual, pipe);
1969*4882a593Smuzhiyun 	}
1970*4882a593Smuzhiyun }
1971*4882a593Smuzhiyun 
intel_pixel_rate_to_cdclk(const struct intel_crtc_state * crtc_state)1972*4882a593Smuzhiyun static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
1973*4882a593Smuzhiyun {
1974*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
1975*4882a593Smuzhiyun 	int pixel_rate = crtc_state->pixel_rate;
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1978*4882a593Smuzhiyun 		return DIV_ROUND_UP(pixel_rate, 2);
1979*4882a593Smuzhiyun 	else if (IS_GEN(dev_priv, 9) ||
1980*4882a593Smuzhiyun 		 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
1981*4882a593Smuzhiyun 		return pixel_rate;
1982*4882a593Smuzhiyun 	else if (IS_CHERRYVIEW(dev_priv))
1983*4882a593Smuzhiyun 		return DIV_ROUND_UP(pixel_rate * 100, 95);
1984*4882a593Smuzhiyun 	else if (crtc_state->double_wide)
1985*4882a593Smuzhiyun 		return DIV_ROUND_UP(pixel_rate * 100, 90 * 2);
1986*4882a593Smuzhiyun 	else
1987*4882a593Smuzhiyun 		return DIV_ROUND_UP(pixel_rate * 100, 90);
1988*4882a593Smuzhiyun }
1989*4882a593Smuzhiyun 
intel_planes_min_cdclk(const struct intel_crtc_state * crtc_state)1990*4882a593Smuzhiyun static int intel_planes_min_cdclk(const struct intel_crtc_state *crtc_state)
1991*4882a593Smuzhiyun {
1992*4882a593Smuzhiyun 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1993*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1994*4882a593Smuzhiyun 	struct intel_plane *plane;
1995*4882a593Smuzhiyun 	int min_cdclk = 0;
1996*4882a593Smuzhiyun 
1997*4882a593Smuzhiyun 	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane)
1998*4882a593Smuzhiyun 		min_cdclk = max(crtc_state->min_cdclk[plane->id], min_cdclk);
1999*4882a593Smuzhiyun 
2000*4882a593Smuzhiyun 	return min_cdclk;
2001*4882a593Smuzhiyun }
2002*4882a593Smuzhiyun 
intel_crtc_compute_min_cdclk(const struct intel_crtc_state * crtc_state)2003*4882a593Smuzhiyun int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
2004*4882a593Smuzhiyun {
2005*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv =
2006*4882a593Smuzhiyun 		to_i915(crtc_state->uapi.crtc->dev);
2007*4882a593Smuzhiyun 	int min_cdclk;
2008*4882a593Smuzhiyun 
2009*4882a593Smuzhiyun 	if (!crtc_state->hw.enable)
2010*4882a593Smuzhiyun 		return 0;
2011*4882a593Smuzhiyun 
2012*4882a593Smuzhiyun 	min_cdclk = intel_pixel_rate_to_cdclk(crtc_state);
2013*4882a593Smuzhiyun 
2014*4882a593Smuzhiyun 	/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
2015*4882a593Smuzhiyun 	if (IS_BROADWELL(dev_priv) && hsw_crtc_state_ips_capable(crtc_state))
2016*4882a593Smuzhiyun 		min_cdclk = DIV_ROUND_UP(min_cdclk * 100, 95);
2017*4882a593Smuzhiyun 
2018*4882a593Smuzhiyun 	/* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,
2019*4882a593Smuzhiyun 	 * audio enabled, port width x4, and link rate HBR2 (5.4 GHz), or else
2020*4882a593Smuzhiyun 	 * there may be audio corruption or screen corruption." This cdclk
2021*4882a593Smuzhiyun 	 * restriction for GLK is 316.8 MHz.
2022*4882a593Smuzhiyun 	 */
2023*4882a593Smuzhiyun 	if (intel_crtc_has_dp_encoder(crtc_state) &&
2024*4882a593Smuzhiyun 	    crtc_state->has_audio &&
2025*4882a593Smuzhiyun 	    crtc_state->port_clock >= 540000 &&
2026*4882a593Smuzhiyun 	    crtc_state->lane_count == 4) {
2027*4882a593Smuzhiyun 		if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) {
2028*4882a593Smuzhiyun 			/* Display WA #1145: glk,cnl */
2029*4882a593Smuzhiyun 			min_cdclk = max(316800, min_cdclk);
2030*4882a593Smuzhiyun 		} else if (IS_GEN(dev_priv, 9) || IS_BROADWELL(dev_priv)) {
2031*4882a593Smuzhiyun 			/* Display WA #1144: skl,bxt */
2032*4882a593Smuzhiyun 			min_cdclk = max(432000, min_cdclk);
2033*4882a593Smuzhiyun 		}
2034*4882a593Smuzhiyun 	}
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun 	/*
2037*4882a593Smuzhiyun 	 * According to BSpec, "The CD clock frequency must be at least twice
2038*4882a593Smuzhiyun 	 * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
2039*4882a593Smuzhiyun 	 */
2040*4882a593Smuzhiyun 	if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
2041*4882a593Smuzhiyun 		min_cdclk = max(2 * 96000, min_cdclk);
2042*4882a593Smuzhiyun 
2043*4882a593Smuzhiyun 	/*
2044*4882a593Smuzhiyun 	 * "For DP audio configuration, cdclk frequency shall be set to
2045*4882a593Smuzhiyun 	 *  meet the following requirements:
2046*4882a593Smuzhiyun 	 *  DP Link Frequency(MHz) | Cdclk frequency(MHz)
2047*4882a593Smuzhiyun 	 *  270                    | 320 or higher
2048*4882a593Smuzhiyun 	 *  162                    | 200 or higher"
2049*4882a593Smuzhiyun 	 */
2050*4882a593Smuzhiyun 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
2051*4882a593Smuzhiyun 	    intel_crtc_has_dp_encoder(crtc_state) && crtc_state->has_audio)
2052*4882a593Smuzhiyun 		min_cdclk = max(crtc_state->port_clock, min_cdclk);
2053*4882a593Smuzhiyun 
2054*4882a593Smuzhiyun 	/*
2055*4882a593Smuzhiyun 	 * On Valleyview some DSI panels lose (v|h)sync when the clock is lower
2056*4882a593Smuzhiyun 	 * than 320000KHz.
2057*4882a593Smuzhiyun 	 */
2058*4882a593Smuzhiyun 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&
2059*4882a593Smuzhiyun 	    IS_VALLEYVIEW(dev_priv))
2060*4882a593Smuzhiyun 		min_cdclk = max(320000, min_cdclk);
2061*4882a593Smuzhiyun 
2062*4882a593Smuzhiyun 	/*
2063*4882a593Smuzhiyun 	 * On Geminilake once the CDCLK gets as low as 79200
2064*4882a593Smuzhiyun 	 * picture gets unstable, despite that values are
2065*4882a593Smuzhiyun 	 * correct for DSI PLL and DE PLL.
2066*4882a593Smuzhiyun 	 */
2067*4882a593Smuzhiyun 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) &&
2068*4882a593Smuzhiyun 	    IS_GEMINILAKE(dev_priv))
2069*4882a593Smuzhiyun 		min_cdclk = max(158400, min_cdclk);
2070*4882a593Smuzhiyun 
2071*4882a593Smuzhiyun 	/* Account for additional needs from the planes */
2072*4882a593Smuzhiyun 	min_cdclk = max(intel_planes_min_cdclk(crtc_state), min_cdclk);
2073*4882a593Smuzhiyun 
2074*4882a593Smuzhiyun 	/*
2075*4882a593Smuzhiyun 	 * HACK. Currently for TGL platforms we calculate
2076*4882a593Smuzhiyun 	 * min_cdclk initially based on pixel_rate divided
2077*4882a593Smuzhiyun 	 * by 2, accounting for also plane requirements,
2078*4882a593Smuzhiyun 	 * however in some cases the lowest possible CDCLK
2079*4882a593Smuzhiyun 	 * doesn't work and causing the underruns.
2080*4882a593Smuzhiyun 	 * Explicitly stating here that this seems to be currently
2081*4882a593Smuzhiyun 	 * rather a Hack, than final solution.
2082*4882a593Smuzhiyun 	 */
2083*4882a593Smuzhiyun 	if (IS_TIGERLAKE(dev_priv)) {
2084*4882a593Smuzhiyun 		/*
2085*4882a593Smuzhiyun 		 * Clamp to max_cdclk_freq in case pixel rate is higher,
2086*4882a593Smuzhiyun 		 * in order not to break an 8K, but still leave W/A at place.
2087*4882a593Smuzhiyun 		 */
2088*4882a593Smuzhiyun 		min_cdclk = max_t(int, min_cdclk,
2089*4882a593Smuzhiyun 				  min_t(int, crtc_state->pixel_rate,
2090*4882a593Smuzhiyun 					dev_priv->max_cdclk_freq));
2091*4882a593Smuzhiyun 	}
2092*4882a593Smuzhiyun 
2093*4882a593Smuzhiyun 	if (min_cdclk > dev_priv->max_cdclk_freq) {
2094*4882a593Smuzhiyun 		drm_dbg_kms(&dev_priv->drm,
2095*4882a593Smuzhiyun 			    "required cdclk (%d kHz) exceeds max (%d kHz)\n",
2096*4882a593Smuzhiyun 			    min_cdclk, dev_priv->max_cdclk_freq);
2097*4882a593Smuzhiyun 		return -EINVAL;
2098*4882a593Smuzhiyun 	}
2099*4882a593Smuzhiyun 
2100*4882a593Smuzhiyun 	return min_cdclk;
2101*4882a593Smuzhiyun }
2102*4882a593Smuzhiyun 
intel_compute_min_cdclk(struct intel_cdclk_state * cdclk_state)2103*4882a593Smuzhiyun static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
2104*4882a593Smuzhiyun {
2105*4882a593Smuzhiyun 	struct intel_atomic_state *state = cdclk_state->base.state;
2106*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2107*4882a593Smuzhiyun 	struct intel_bw_state *bw_state = NULL;
2108*4882a593Smuzhiyun 	struct intel_crtc *crtc;
2109*4882a593Smuzhiyun 	struct intel_crtc_state *crtc_state;
2110*4882a593Smuzhiyun 	int min_cdclk, i;
2111*4882a593Smuzhiyun 	enum pipe pipe;
2112*4882a593Smuzhiyun 
2113*4882a593Smuzhiyun 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
2114*4882a593Smuzhiyun 		int ret;
2115*4882a593Smuzhiyun 
2116*4882a593Smuzhiyun 		min_cdclk = intel_crtc_compute_min_cdclk(crtc_state);
2117*4882a593Smuzhiyun 		if (min_cdclk < 0)
2118*4882a593Smuzhiyun 			return min_cdclk;
2119*4882a593Smuzhiyun 
2120*4882a593Smuzhiyun 		bw_state = intel_atomic_get_bw_state(state);
2121*4882a593Smuzhiyun 		if (IS_ERR(bw_state))
2122*4882a593Smuzhiyun 			return PTR_ERR(bw_state);
2123*4882a593Smuzhiyun 
2124*4882a593Smuzhiyun 		if (cdclk_state->min_cdclk[i] == min_cdclk)
2125*4882a593Smuzhiyun 			continue;
2126*4882a593Smuzhiyun 
2127*4882a593Smuzhiyun 		cdclk_state->min_cdclk[i] = min_cdclk;
2128*4882a593Smuzhiyun 
2129*4882a593Smuzhiyun 		ret = intel_atomic_lock_global_state(&cdclk_state->base);
2130*4882a593Smuzhiyun 		if (ret)
2131*4882a593Smuzhiyun 			return ret;
2132*4882a593Smuzhiyun 	}
2133*4882a593Smuzhiyun 
2134*4882a593Smuzhiyun 	min_cdclk = cdclk_state->force_min_cdclk;
2135*4882a593Smuzhiyun 	for_each_pipe(dev_priv, pipe) {
2136*4882a593Smuzhiyun 		min_cdclk = max(cdclk_state->min_cdclk[pipe], min_cdclk);
2137*4882a593Smuzhiyun 
2138*4882a593Smuzhiyun 		if (!bw_state)
2139*4882a593Smuzhiyun 			continue;
2140*4882a593Smuzhiyun 
2141*4882a593Smuzhiyun 		min_cdclk = max(bw_state->min_cdclk, min_cdclk);
2142*4882a593Smuzhiyun 	}
2143*4882a593Smuzhiyun 
2144*4882a593Smuzhiyun 	return min_cdclk;
2145*4882a593Smuzhiyun }
2146*4882a593Smuzhiyun 
2147*4882a593Smuzhiyun /*
2148*4882a593Smuzhiyun  * Account for port clock min voltage level requirements.
2149*4882a593Smuzhiyun  * This only really does something on CNL+ but can be
2150*4882a593Smuzhiyun  * called on earlier platforms as well.
2151*4882a593Smuzhiyun  *
2152*4882a593Smuzhiyun  * Note that this functions assumes that 0 is
2153*4882a593Smuzhiyun  * the lowest voltage value, and higher values
2154*4882a593Smuzhiyun  * correspond to increasingly higher voltages.
2155*4882a593Smuzhiyun  *
2156*4882a593Smuzhiyun  * Should that relationship no longer hold on
2157*4882a593Smuzhiyun  * future platforms this code will need to be
2158*4882a593Smuzhiyun  * adjusted.
2159*4882a593Smuzhiyun  */
bxt_compute_min_voltage_level(struct intel_cdclk_state * cdclk_state)2160*4882a593Smuzhiyun static int bxt_compute_min_voltage_level(struct intel_cdclk_state *cdclk_state)
2161*4882a593Smuzhiyun {
2162*4882a593Smuzhiyun 	struct intel_atomic_state *state = cdclk_state->base.state;
2163*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2164*4882a593Smuzhiyun 	struct intel_crtc *crtc;
2165*4882a593Smuzhiyun 	struct intel_crtc_state *crtc_state;
2166*4882a593Smuzhiyun 	u8 min_voltage_level;
2167*4882a593Smuzhiyun 	int i;
2168*4882a593Smuzhiyun 	enum pipe pipe;
2169*4882a593Smuzhiyun 
2170*4882a593Smuzhiyun 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
2171*4882a593Smuzhiyun 		int ret;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 		if (crtc_state->hw.enable)
2174*4882a593Smuzhiyun 			min_voltage_level = crtc_state->min_voltage_level;
2175*4882a593Smuzhiyun 		else
2176*4882a593Smuzhiyun 			min_voltage_level = 0;
2177*4882a593Smuzhiyun 
2178*4882a593Smuzhiyun 		if (cdclk_state->min_voltage_level[i] == min_voltage_level)
2179*4882a593Smuzhiyun 			continue;
2180*4882a593Smuzhiyun 
2181*4882a593Smuzhiyun 		cdclk_state->min_voltage_level[i] = min_voltage_level;
2182*4882a593Smuzhiyun 
2183*4882a593Smuzhiyun 		ret = intel_atomic_lock_global_state(&cdclk_state->base);
2184*4882a593Smuzhiyun 		if (ret)
2185*4882a593Smuzhiyun 			return ret;
2186*4882a593Smuzhiyun 	}
2187*4882a593Smuzhiyun 
2188*4882a593Smuzhiyun 	min_voltage_level = 0;
2189*4882a593Smuzhiyun 	for_each_pipe(dev_priv, pipe)
2190*4882a593Smuzhiyun 		min_voltage_level = max(cdclk_state->min_voltage_level[pipe],
2191*4882a593Smuzhiyun 					min_voltage_level);
2192*4882a593Smuzhiyun 
2193*4882a593Smuzhiyun 	return min_voltage_level;
2194*4882a593Smuzhiyun }
2195*4882a593Smuzhiyun 
vlv_modeset_calc_cdclk(struct intel_cdclk_state * cdclk_state)2196*4882a593Smuzhiyun static int vlv_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
2197*4882a593Smuzhiyun {
2198*4882a593Smuzhiyun 	struct intel_atomic_state *state = cdclk_state->base.state;
2199*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2200*4882a593Smuzhiyun 	int min_cdclk, cdclk;
2201*4882a593Smuzhiyun 
2202*4882a593Smuzhiyun 	min_cdclk = intel_compute_min_cdclk(cdclk_state);
2203*4882a593Smuzhiyun 	if (min_cdclk < 0)
2204*4882a593Smuzhiyun 		return min_cdclk;
2205*4882a593Smuzhiyun 
2206*4882a593Smuzhiyun 	cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
2207*4882a593Smuzhiyun 
2208*4882a593Smuzhiyun 	cdclk_state->logical.cdclk = cdclk;
2209*4882a593Smuzhiyun 	cdclk_state->logical.voltage_level =
2210*4882a593Smuzhiyun 		vlv_calc_voltage_level(dev_priv, cdclk);
2211*4882a593Smuzhiyun 
2212*4882a593Smuzhiyun 	if (!cdclk_state->active_pipes) {
2213*4882a593Smuzhiyun 		cdclk = vlv_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);
2214*4882a593Smuzhiyun 
2215*4882a593Smuzhiyun 		cdclk_state->actual.cdclk = cdclk;
2216*4882a593Smuzhiyun 		cdclk_state->actual.voltage_level =
2217*4882a593Smuzhiyun 			vlv_calc_voltage_level(dev_priv, cdclk);
2218*4882a593Smuzhiyun 	} else {
2219*4882a593Smuzhiyun 		cdclk_state->actual = cdclk_state->logical;
2220*4882a593Smuzhiyun 	}
2221*4882a593Smuzhiyun 
2222*4882a593Smuzhiyun 	return 0;
2223*4882a593Smuzhiyun }
2224*4882a593Smuzhiyun 
bdw_modeset_calc_cdclk(struct intel_cdclk_state * cdclk_state)2225*4882a593Smuzhiyun static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
2226*4882a593Smuzhiyun {
2227*4882a593Smuzhiyun 	int min_cdclk, cdclk;
2228*4882a593Smuzhiyun 
2229*4882a593Smuzhiyun 	min_cdclk = intel_compute_min_cdclk(cdclk_state);
2230*4882a593Smuzhiyun 	if (min_cdclk < 0)
2231*4882a593Smuzhiyun 		return min_cdclk;
2232*4882a593Smuzhiyun 
2233*4882a593Smuzhiyun 	/*
2234*4882a593Smuzhiyun 	 * FIXME should also account for plane ratio
2235*4882a593Smuzhiyun 	 * once 64bpp pixel formats are supported.
2236*4882a593Smuzhiyun 	 */
2237*4882a593Smuzhiyun 	cdclk = bdw_calc_cdclk(min_cdclk);
2238*4882a593Smuzhiyun 
2239*4882a593Smuzhiyun 	cdclk_state->logical.cdclk = cdclk;
2240*4882a593Smuzhiyun 	cdclk_state->logical.voltage_level =
2241*4882a593Smuzhiyun 		bdw_calc_voltage_level(cdclk);
2242*4882a593Smuzhiyun 
2243*4882a593Smuzhiyun 	if (!cdclk_state->active_pipes) {
2244*4882a593Smuzhiyun 		cdclk = bdw_calc_cdclk(cdclk_state->force_min_cdclk);
2245*4882a593Smuzhiyun 
2246*4882a593Smuzhiyun 		cdclk_state->actual.cdclk = cdclk;
2247*4882a593Smuzhiyun 		cdclk_state->actual.voltage_level =
2248*4882a593Smuzhiyun 			bdw_calc_voltage_level(cdclk);
2249*4882a593Smuzhiyun 	} else {
2250*4882a593Smuzhiyun 		cdclk_state->actual = cdclk_state->logical;
2251*4882a593Smuzhiyun 	}
2252*4882a593Smuzhiyun 
2253*4882a593Smuzhiyun 	return 0;
2254*4882a593Smuzhiyun }
2255*4882a593Smuzhiyun 
skl_dpll0_vco(struct intel_cdclk_state * cdclk_state)2256*4882a593Smuzhiyun static int skl_dpll0_vco(struct intel_cdclk_state *cdclk_state)
2257*4882a593Smuzhiyun {
2258*4882a593Smuzhiyun 	struct intel_atomic_state *state = cdclk_state->base.state;
2259*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2260*4882a593Smuzhiyun 	struct intel_crtc *crtc;
2261*4882a593Smuzhiyun 	struct intel_crtc_state *crtc_state;
2262*4882a593Smuzhiyun 	int vco, i;
2263*4882a593Smuzhiyun 
2264*4882a593Smuzhiyun 	vco = cdclk_state->logical.vco;
2265*4882a593Smuzhiyun 	if (!vco)
2266*4882a593Smuzhiyun 		vco = dev_priv->skl_preferred_vco_freq;
2267*4882a593Smuzhiyun 
2268*4882a593Smuzhiyun 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
2269*4882a593Smuzhiyun 		if (!crtc_state->hw.enable)
2270*4882a593Smuzhiyun 			continue;
2271*4882a593Smuzhiyun 
2272*4882a593Smuzhiyun 		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
2273*4882a593Smuzhiyun 			continue;
2274*4882a593Smuzhiyun 
2275*4882a593Smuzhiyun 		/*
2276*4882a593Smuzhiyun 		 * DPLL0 VCO may need to be adjusted to get the correct
2277*4882a593Smuzhiyun 		 * clock for eDP. This will affect cdclk as well.
2278*4882a593Smuzhiyun 		 */
2279*4882a593Smuzhiyun 		switch (crtc_state->port_clock / 2) {
2280*4882a593Smuzhiyun 		case 108000:
2281*4882a593Smuzhiyun 		case 216000:
2282*4882a593Smuzhiyun 			vco = 8640000;
2283*4882a593Smuzhiyun 			break;
2284*4882a593Smuzhiyun 		default:
2285*4882a593Smuzhiyun 			vco = 8100000;
2286*4882a593Smuzhiyun 			break;
2287*4882a593Smuzhiyun 		}
2288*4882a593Smuzhiyun 	}
2289*4882a593Smuzhiyun 
2290*4882a593Smuzhiyun 	return vco;
2291*4882a593Smuzhiyun }
2292*4882a593Smuzhiyun 
skl_modeset_calc_cdclk(struct intel_cdclk_state * cdclk_state)2293*4882a593Smuzhiyun static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
2294*4882a593Smuzhiyun {
2295*4882a593Smuzhiyun 	int min_cdclk, cdclk, vco;
2296*4882a593Smuzhiyun 
2297*4882a593Smuzhiyun 	min_cdclk = intel_compute_min_cdclk(cdclk_state);
2298*4882a593Smuzhiyun 	if (min_cdclk < 0)
2299*4882a593Smuzhiyun 		return min_cdclk;
2300*4882a593Smuzhiyun 
2301*4882a593Smuzhiyun 	vco = skl_dpll0_vco(cdclk_state);
2302*4882a593Smuzhiyun 
2303*4882a593Smuzhiyun 	/*
2304*4882a593Smuzhiyun 	 * FIXME should also account for plane ratio
2305*4882a593Smuzhiyun 	 * once 64bpp pixel formats are supported.
2306*4882a593Smuzhiyun 	 */
2307*4882a593Smuzhiyun 	cdclk = skl_calc_cdclk(min_cdclk, vco);
2308*4882a593Smuzhiyun 
2309*4882a593Smuzhiyun 	cdclk_state->logical.vco = vco;
2310*4882a593Smuzhiyun 	cdclk_state->logical.cdclk = cdclk;
2311*4882a593Smuzhiyun 	cdclk_state->logical.voltage_level =
2312*4882a593Smuzhiyun 		skl_calc_voltage_level(cdclk);
2313*4882a593Smuzhiyun 
2314*4882a593Smuzhiyun 	if (!cdclk_state->active_pipes) {
2315*4882a593Smuzhiyun 		cdclk = skl_calc_cdclk(cdclk_state->force_min_cdclk, vco);
2316*4882a593Smuzhiyun 
2317*4882a593Smuzhiyun 		cdclk_state->actual.vco = vco;
2318*4882a593Smuzhiyun 		cdclk_state->actual.cdclk = cdclk;
2319*4882a593Smuzhiyun 		cdclk_state->actual.voltage_level =
2320*4882a593Smuzhiyun 			skl_calc_voltage_level(cdclk);
2321*4882a593Smuzhiyun 	} else {
2322*4882a593Smuzhiyun 		cdclk_state->actual = cdclk_state->logical;
2323*4882a593Smuzhiyun 	}
2324*4882a593Smuzhiyun 
2325*4882a593Smuzhiyun 	return 0;
2326*4882a593Smuzhiyun }
2327*4882a593Smuzhiyun 
bxt_modeset_calc_cdclk(struct intel_cdclk_state * cdclk_state)2328*4882a593Smuzhiyun static int bxt_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
2329*4882a593Smuzhiyun {
2330*4882a593Smuzhiyun 	struct intel_atomic_state *state = cdclk_state->base.state;
2331*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2332*4882a593Smuzhiyun 	int min_cdclk, min_voltage_level, cdclk, vco;
2333*4882a593Smuzhiyun 
2334*4882a593Smuzhiyun 	min_cdclk = intel_compute_min_cdclk(cdclk_state);
2335*4882a593Smuzhiyun 	if (min_cdclk < 0)
2336*4882a593Smuzhiyun 		return min_cdclk;
2337*4882a593Smuzhiyun 
2338*4882a593Smuzhiyun 	min_voltage_level = bxt_compute_min_voltage_level(cdclk_state);
2339*4882a593Smuzhiyun 	if (min_voltage_level < 0)
2340*4882a593Smuzhiyun 		return min_voltage_level;
2341*4882a593Smuzhiyun 
2342*4882a593Smuzhiyun 	cdclk = bxt_calc_cdclk(dev_priv, min_cdclk);
2343*4882a593Smuzhiyun 	vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
2344*4882a593Smuzhiyun 
2345*4882a593Smuzhiyun 	cdclk_state->logical.vco = vco;
2346*4882a593Smuzhiyun 	cdclk_state->logical.cdclk = cdclk;
2347*4882a593Smuzhiyun 	cdclk_state->logical.voltage_level =
2348*4882a593Smuzhiyun 		max_t(int, min_voltage_level,
2349*4882a593Smuzhiyun 		      dev_priv->display.calc_voltage_level(cdclk));
2350*4882a593Smuzhiyun 
2351*4882a593Smuzhiyun 	if (!cdclk_state->active_pipes) {
2352*4882a593Smuzhiyun 		cdclk = bxt_calc_cdclk(dev_priv, cdclk_state->force_min_cdclk);
2353*4882a593Smuzhiyun 		vco = bxt_calc_cdclk_pll_vco(dev_priv, cdclk);
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 		cdclk_state->actual.vco = vco;
2356*4882a593Smuzhiyun 		cdclk_state->actual.cdclk = cdclk;
2357*4882a593Smuzhiyun 		cdclk_state->actual.voltage_level =
2358*4882a593Smuzhiyun 			dev_priv->display.calc_voltage_level(cdclk);
2359*4882a593Smuzhiyun 	} else {
2360*4882a593Smuzhiyun 		cdclk_state->actual = cdclk_state->logical;
2361*4882a593Smuzhiyun 	}
2362*4882a593Smuzhiyun 
2363*4882a593Smuzhiyun 	return 0;
2364*4882a593Smuzhiyun }
2365*4882a593Smuzhiyun 
intel_modeset_all_pipes(struct intel_atomic_state * state)2366*4882a593Smuzhiyun static int intel_modeset_all_pipes(struct intel_atomic_state *state)
2367*4882a593Smuzhiyun {
2368*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2369*4882a593Smuzhiyun 	struct intel_crtc *crtc;
2370*4882a593Smuzhiyun 
2371*4882a593Smuzhiyun 	/*
2372*4882a593Smuzhiyun 	 * Add all pipes to the state, and force
2373*4882a593Smuzhiyun 	 * a modeset on all the active ones.
2374*4882a593Smuzhiyun 	 */
2375*4882a593Smuzhiyun 	for_each_intel_crtc(&dev_priv->drm, crtc) {
2376*4882a593Smuzhiyun 		struct intel_crtc_state *crtc_state;
2377*4882a593Smuzhiyun 		int ret;
2378*4882a593Smuzhiyun 
2379*4882a593Smuzhiyun 		crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
2380*4882a593Smuzhiyun 		if (IS_ERR(crtc_state))
2381*4882a593Smuzhiyun 			return PTR_ERR(crtc_state);
2382*4882a593Smuzhiyun 
2383*4882a593Smuzhiyun 		if (!crtc_state->hw.active ||
2384*4882a593Smuzhiyun 		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
2385*4882a593Smuzhiyun 			continue;
2386*4882a593Smuzhiyun 
2387*4882a593Smuzhiyun 		crtc_state->uapi.mode_changed = true;
2388*4882a593Smuzhiyun 
2389*4882a593Smuzhiyun 		ret = drm_atomic_add_affected_connectors(&state->base,
2390*4882a593Smuzhiyun 							 &crtc->base);
2391*4882a593Smuzhiyun 		if (ret)
2392*4882a593Smuzhiyun 			return ret;
2393*4882a593Smuzhiyun 
2394*4882a593Smuzhiyun 		ret = drm_atomic_add_affected_planes(&state->base,
2395*4882a593Smuzhiyun 						     &crtc->base);
2396*4882a593Smuzhiyun 		if (ret)
2397*4882a593Smuzhiyun 			return ret;
2398*4882a593Smuzhiyun 
2399*4882a593Smuzhiyun 		crtc_state->update_planes |= crtc_state->active_planes;
2400*4882a593Smuzhiyun 	}
2401*4882a593Smuzhiyun 
2402*4882a593Smuzhiyun 	return 0;
2403*4882a593Smuzhiyun }
2404*4882a593Smuzhiyun 
fixed_modeset_calc_cdclk(struct intel_cdclk_state * cdclk_state)2405*4882a593Smuzhiyun static int fixed_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
2406*4882a593Smuzhiyun {
2407*4882a593Smuzhiyun 	int min_cdclk;
2408*4882a593Smuzhiyun 
2409*4882a593Smuzhiyun 	/*
2410*4882a593Smuzhiyun 	 * We can't change the cdclk frequency, but we still want to
2411*4882a593Smuzhiyun 	 * check that the required minimum frequency doesn't exceed
2412*4882a593Smuzhiyun 	 * the actual cdclk frequency.
2413*4882a593Smuzhiyun 	 */
2414*4882a593Smuzhiyun 	min_cdclk = intel_compute_min_cdclk(cdclk_state);
2415*4882a593Smuzhiyun 	if (min_cdclk < 0)
2416*4882a593Smuzhiyun 		return min_cdclk;
2417*4882a593Smuzhiyun 
2418*4882a593Smuzhiyun 	return 0;
2419*4882a593Smuzhiyun }
2420*4882a593Smuzhiyun 
intel_cdclk_duplicate_state(struct intel_global_obj * obj)2421*4882a593Smuzhiyun static struct intel_global_state *intel_cdclk_duplicate_state(struct intel_global_obj *obj)
2422*4882a593Smuzhiyun {
2423*4882a593Smuzhiyun 	struct intel_cdclk_state *cdclk_state;
2424*4882a593Smuzhiyun 
2425*4882a593Smuzhiyun 	cdclk_state = kmemdup(obj->state, sizeof(*cdclk_state), GFP_KERNEL);
2426*4882a593Smuzhiyun 	if (!cdclk_state)
2427*4882a593Smuzhiyun 		return NULL;
2428*4882a593Smuzhiyun 
2429*4882a593Smuzhiyun 	cdclk_state->pipe = INVALID_PIPE;
2430*4882a593Smuzhiyun 
2431*4882a593Smuzhiyun 	return &cdclk_state->base;
2432*4882a593Smuzhiyun }
2433*4882a593Smuzhiyun 
intel_cdclk_destroy_state(struct intel_global_obj * obj,struct intel_global_state * state)2434*4882a593Smuzhiyun static void intel_cdclk_destroy_state(struct intel_global_obj *obj,
2435*4882a593Smuzhiyun 				      struct intel_global_state *state)
2436*4882a593Smuzhiyun {
2437*4882a593Smuzhiyun 	kfree(state);
2438*4882a593Smuzhiyun }
2439*4882a593Smuzhiyun 
2440*4882a593Smuzhiyun static const struct intel_global_state_funcs intel_cdclk_funcs = {
2441*4882a593Smuzhiyun 	.atomic_duplicate_state = intel_cdclk_duplicate_state,
2442*4882a593Smuzhiyun 	.atomic_destroy_state = intel_cdclk_destroy_state,
2443*4882a593Smuzhiyun };
2444*4882a593Smuzhiyun 
2445*4882a593Smuzhiyun struct intel_cdclk_state *
intel_atomic_get_cdclk_state(struct intel_atomic_state * state)2446*4882a593Smuzhiyun intel_atomic_get_cdclk_state(struct intel_atomic_state *state)
2447*4882a593Smuzhiyun {
2448*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2449*4882a593Smuzhiyun 	struct intel_global_state *cdclk_state;
2450*4882a593Smuzhiyun 
2451*4882a593Smuzhiyun 	cdclk_state = intel_atomic_get_global_obj_state(state, &dev_priv->cdclk.obj);
2452*4882a593Smuzhiyun 	if (IS_ERR(cdclk_state))
2453*4882a593Smuzhiyun 		return ERR_CAST(cdclk_state);
2454*4882a593Smuzhiyun 
2455*4882a593Smuzhiyun 	return to_intel_cdclk_state(cdclk_state);
2456*4882a593Smuzhiyun }
2457*4882a593Smuzhiyun 
intel_cdclk_init(struct drm_i915_private * dev_priv)2458*4882a593Smuzhiyun int intel_cdclk_init(struct drm_i915_private *dev_priv)
2459*4882a593Smuzhiyun {
2460*4882a593Smuzhiyun 	struct intel_cdclk_state *cdclk_state;
2461*4882a593Smuzhiyun 
2462*4882a593Smuzhiyun 	cdclk_state = kzalloc(sizeof(*cdclk_state), GFP_KERNEL);
2463*4882a593Smuzhiyun 	if (!cdclk_state)
2464*4882a593Smuzhiyun 		return -ENOMEM;
2465*4882a593Smuzhiyun 
2466*4882a593Smuzhiyun 	intel_atomic_global_obj_init(dev_priv, &dev_priv->cdclk.obj,
2467*4882a593Smuzhiyun 				     &cdclk_state->base, &intel_cdclk_funcs);
2468*4882a593Smuzhiyun 
2469*4882a593Smuzhiyun 	return 0;
2470*4882a593Smuzhiyun }
2471*4882a593Smuzhiyun 
intel_modeset_calc_cdclk(struct intel_atomic_state * state)2472*4882a593Smuzhiyun int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
2473*4882a593Smuzhiyun {
2474*4882a593Smuzhiyun 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
2475*4882a593Smuzhiyun 	const struct intel_cdclk_state *old_cdclk_state;
2476*4882a593Smuzhiyun 	struct intel_cdclk_state *new_cdclk_state;
2477*4882a593Smuzhiyun 	enum pipe pipe;
2478*4882a593Smuzhiyun 	int ret;
2479*4882a593Smuzhiyun 
2480*4882a593Smuzhiyun 	new_cdclk_state = intel_atomic_get_cdclk_state(state);
2481*4882a593Smuzhiyun 	if (IS_ERR(new_cdclk_state))
2482*4882a593Smuzhiyun 		return PTR_ERR(new_cdclk_state);
2483*4882a593Smuzhiyun 
2484*4882a593Smuzhiyun 	old_cdclk_state = intel_atomic_get_old_cdclk_state(state);
2485*4882a593Smuzhiyun 
2486*4882a593Smuzhiyun 	new_cdclk_state->active_pipes =
2487*4882a593Smuzhiyun 		intel_calc_active_pipes(state, old_cdclk_state->active_pipes);
2488*4882a593Smuzhiyun 
2489*4882a593Smuzhiyun 	ret = dev_priv->display.modeset_calc_cdclk(new_cdclk_state);
2490*4882a593Smuzhiyun 	if (ret)
2491*4882a593Smuzhiyun 		return ret;
2492*4882a593Smuzhiyun 
2493*4882a593Smuzhiyun 	if (intel_cdclk_changed(&old_cdclk_state->actual,
2494*4882a593Smuzhiyun 				&new_cdclk_state->actual)) {
2495*4882a593Smuzhiyun 		/*
2496*4882a593Smuzhiyun 		 * Also serialize commits across all crtcs
2497*4882a593Smuzhiyun 		 * if the actual hw needs to be poked.
2498*4882a593Smuzhiyun 		 */
2499*4882a593Smuzhiyun 		ret = intel_atomic_serialize_global_state(&new_cdclk_state->base);
2500*4882a593Smuzhiyun 		if (ret)
2501*4882a593Smuzhiyun 			return ret;
2502*4882a593Smuzhiyun 	} else if (old_cdclk_state->active_pipes != new_cdclk_state->active_pipes ||
2503*4882a593Smuzhiyun 		   old_cdclk_state->force_min_cdclk != new_cdclk_state->force_min_cdclk ||
2504*4882a593Smuzhiyun 		   intel_cdclk_changed(&old_cdclk_state->logical,
2505*4882a593Smuzhiyun 				       &new_cdclk_state->logical)) {
2506*4882a593Smuzhiyun 		ret = intel_atomic_lock_global_state(&new_cdclk_state->base);
2507*4882a593Smuzhiyun 		if (ret)
2508*4882a593Smuzhiyun 			return ret;
2509*4882a593Smuzhiyun 	} else {
2510*4882a593Smuzhiyun 		return 0;
2511*4882a593Smuzhiyun 	}
2512*4882a593Smuzhiyun 
2513*4882a593Smuzhiyun 	if (is_power_of_2(new_cdclk_state->active_pipes) &&
2514*4882a593Smuzhiyun 	    intel_cdclk_can_cd2x_update(dev_priv,
2515*4882a593Smuzhiyun 					&old_cdclk_state->actual,
2516*4882a593Smuzhiyun 					&new_cdclk_state->actual)) {
2517*4882a593Smuzhiyun 		struct intel_crtc *crtc;
2518*4882a593Smuzhiyun 		struct intel_crtc_state *crtc_state;
2519*4882a593Smuzhiyun 
2520*4882a593Smuzhiyun 		pipe = ilog2(new_cdclk_state->active_pipes);
2521*4882a593Smuzhiyun 		crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
2522*4882a593Smuzhiyun 
2523*4882a593Smuzhiyun 		crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
2524*4882a593Smuzhiyun 		if (IS_ERR(crtc_state))
2525*4882a593Smuzhiyun 			return PTR_ERR(crtc_state);
2526*4882a593Smuzhiyun 
2527*4882a593Smuzhiyun 		if (drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
2528*4882a593Smuzhiyun 			pipe = INVALID_PIPE;
2529*4882a593Smuzhiyun 	} else {
2530*4882a593Smuzhiyun 		pipe = INVALID_PIPE;
2531*4882a593Smuzhiyun 	}
2532*4882a593Smuzhiyun 
2533*4882a593Smuzhiyun 	if (pipe != INVALID_PIPE) {
2534*4882a593Smuzhiyun 		new_cdclk_state->pipe = pipe;
2535*4882a593Smuzhiyun 
2536*4882a593Smuzhiyun 		drm_dbg_kms(&dev_priv->drm,
2537*4882a593Smuzhiyun 			    "Can change cdclk with pipe %c active\n",
2538*4882a593Smuzhiyun 			    pipe_name(pipe));
2539*4882a593Smuzhiyun 	} else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
2540*4882a593Smuzhiyun 					     &new_cdclk_state->actual)) {
2541*4882a593Smuzhiyun 		/* All pipes must be switched off while we change the cdclk. */
2542*4882a593Smuzhiyun 		ret = intel_modeset_all_pipes(state);
2543*4882a593Smuzhiyun 		if (ret)
2544*4882a593Smuzhiyun 			return ret;
2545*4882a593Smuzhiyun 
2546*4882a593Smuzhiyun 		new_cdclk_state->pipe = INVALID_PIPE;
2547*4882a593Smuzhiyun 
2548*4882a593Smuzhiyun 		drm_dbg_kms(&dev_priv->drm,
2549*4882a593Smuzhiyun 			    "Modeset required for cdclk change\n");
2550*4882a593Smuzhiyun 	}
2551*4882a593Smuzhiyun 
2552*4882a593Smuzhiyun 	drm_dbg_kms(&dev_priv->drm,
2553*4882a593Smuzhiyun 		    "New cdclk calculated to be logical %u kHz, actual %u kHz\n",
2554*4882a593Smuzhiyun 		    new_cdclk_state->logical.cdclk,
2555*4882a593Smuzhiyun 		    new_cdclk_state->actual.cdclk);
2556*4882a593Smuzhiyun 	drm_dbg_kms(&dev_priv->drm,
2557*4882a593Smuzhiyun 		    "New voltage level calculated to be logical %u, actual %u\n",
2558*4882a593Smuzhiyun 		    new_cdclk_state->logical.voltage_level,
2559*4882a593Smuzhiyun 		    new_cdclk_state->actual.voltage_level);
2560*4882a593Smuzhiyun 
2561*4882a593Smuzhiyun 	return 0;
2562*4882a593Smuzhiyun }
2563*4882a593Smuzhiyun 
intel_compute_max_dotclk(struct drm_i915_private * dev_priv)2564*4882a593Smuzhiyun static int intel_compute_max_dotclk(struct drm_i915_private *dev_priv)
2565*4882a593Smuzhiyun {
2566*4882a593Smuzhiyun 	int max_cdclk_freq = dev_priv->max_cdclk_freq;
2567*4882a593Smuzhiyun 
2568*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2569*4882a593Smuzhiyun 		return 2 * max_cdclk_freq;
2570*4882a593Smuzhiyun 	else if (IS_GEN(dev_priv, 9) ||
2571*4882a593Smuzhiyun 		 IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
2572*4882a593Smuzhiyun 		return max_cdclk_freq;
2573*4882a593Smuzhiyun 	else if (IS_CHERRYVIEW(dev_priv))
2574*4882a593Smuzhiyun 		return max_cdclk_freq*95/100;
2575*4882a593Smuzhiyun 	else if (INTEL_GEN(dev_priv) < 4)
2576*4882a593Smuzhiyun 		return 2*max_cdclk_freq*90/100;
2577*4882a593Smuzhiyun 	else
2578*4882a593Smuzhiyun 		return max_cdclk_freq*90/100;
2579*4882a593Smuzhiyun }
2580*4882a593Smuzhiyun 
2581*4882a593Smuzhiyun /**
2582*4882a593Smuzhiyun  * intel_update_max_cdclk - Determine the maximum support CDCLK frequency
2583*4882a593Smuzhiyun  * @dev_priv: i915 device
2584*4882a593Smuzhiyun  *
2585*4882a593Smuzhiyun  * Determine the maximum CDCLK frequency the platform supports, and also
2586*4882a593Smuzhiyun  * derive the maximum dot clock frequency the maximum CDCLK frequency
2587*4882a593Smuzhiyun  * allows.
2588*4882a593Smuzhiyun  */
intel_update_max_cdclk(struct drm_i915_private * dev_priv)2589*4882a593Smuzhiyun void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
2590*4882a593Smuzhiyun {
2591*4882a593Smuzhiyun 	if (IS_ELKHARTLAKE(dev_priv)) {
2592*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.ref == 24000)
2593*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 552000;
2594*4882a593Smuzhiyun 		else
2595*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 556800;
2596*4882a593Smuzhiyun 	} else if (INTEL_GEN(dev_priv) >= 11) {
2597*4882a593Smuzhiyun 		if (dev_priv->cdclk.hw.ref == 24000)
2598*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 648000;
2599*4882a593Smuzhiyun 		else
2600*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 652800;
2601*4882a593Smuzhiyun 	} else if (IS_CANNONLAKE(dev_priv)) {
2602*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = 528000;
2603*4882a593Smuzhiyun 	} else if (IS_GEN9_BC(dev_priv)) {
2604*4882a593Smuzhiyun 		u32 limit = intel_de_read(dev_priv, SKL_DFSM) & SKL_DFSM_CDCLK_LIMIT_MASK;
2605*4882a593Smuzhiyun 		int max_cdclk, vco;
2606*4882a593Smuzhiyun 
2607*4882a593Smuzhiyun 		vco = dev_priv->skl_preferred_vco_freq;
2608*4882a593Smuzhiyun 		drm_WARN_ON(&dev_priv->drm, vco != 8100000 && vco != 8640000);
2609*4882a593Smuzhiyun 
2610*4882a593Smuzhiyun 		/*
2611*4882a593Smuzhiyun 		 * Use the lower (vco 8640) cdclk values as a
2612*4882a593Smuzhiyun 		 * first guess. skl_calc_cdclk() will correct it
2613*4882a593Smuzhiyun 		 * if the preferred vco is 8100 instead.
2614*4882a593Smuzhiyun 		 */
2615*4882a593Smuzhiyun 		if (limit == SKL_DFSM_CDCLK_LIMIT_675)
2616*4882a593Smuzhiyun 			max_cdclk = 617143;
2617*4882a593Smuzhiyun 		else if (limit == SKL_DFSM_CDCLK_LIMIT_540)
2618*4882a593Smuzhiyun 			max_cdclk = 540000;
2619*4882a593Smuzhiyun 		else if (limit == SKL_DFSM_CDCLK_LIMIT_450)
2620*4882a593Smuzhiyun 			max_cdclk = 432000;
2621*4882a593Smuzhiyun 		else
2622*4882a593Smuzhiyun 			max_cdclk = 308571;
2623*4882a593Smuzhiyun 
2624*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = skl_calc_cdclk(max_cdclk, vco);
2625*4882a593Smuzhiyun 	} else if (IS_GEMINILAKE(dev_priv)) {
2626*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = 316800;
2627*4882a593Smuzhiyun 	} else if (IS_BROXTON(dev_priv)) {
2628*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = 624000;
2629*4882a593Smuzhiyun 	} else if (IS_BROADWELL(dev_priv))  {
2630*4882a593Smuzhiyun 		/*
2631*4882a593Smuzhiyun 		 * FIXME with extra cooling we can allow
2632*4882a593Smuzhiyun 		 * 540 MHz for ULX and 675 Mhz for ULT.
2633*4882a593Smuzhiyun 		 * How can we know if extra cooling is
2634*4882a593Smuzhiyun 		 * available? PCI ID, VTB, something else?
2635*4882a593Smuzhiyun 		 */
2636*4882a593Smuzhiyun 		if (intel_de_read(dev_priv, FUSE_STRAP) & HSW_CDCLK_LIMIT)
2637*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 450000;
2638*4882a593Smuzhiyun 		else if (IS_BDW_ULX(dev_priv))
2639*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 450000;
2640*4882a593Smuzhiyun 		else if (IS_BDW_ULT(dev_priv))
2641*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 540000;
2642*4882a593Smuzhiyun 		else
2643*4882a593Smuzhiyun 			dev_priv->max_cdclk_freq = 675000;
2644*4882a593Smuzhiyun 	} else if (IS_CHERRYVIEW(dev_priv)) {
2645*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = 320000;
2646*4882a593Smuzhiyun 	} else if (IS_VALLEYVIEW(dev_priv)) {
2647*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = 400000;
2648*4882a593Smuzhiyun 	} else {
2649*4882a593Smuzhiyun 		/* otherwise assume cdclk is fixed */
2650*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq = dev_priv->cdclk.hw.cdclk;
2651*4882a593Smuzhiyun 	}
2652*4882a593Smuzhiyun 
2653*4882a593Smuzhiyun 	dev_priv->max_dotclk_freq = intel_compute_max_dotclk(dev_priv);
2654*4882a593Smuzhiyun 
2655*4882a593Smuzhiyun 	drm_dbg(&dev_priv->drm, "Max CD clock rate: %d kHz\n",
2656*4882a593Smuzhiyun 		dev_priv->max_cdclk_freq);
2657*4882a593Smuzhiyun 
2658*4882a593Smuzhiyun 	drm_dbg(&dev_priv->drm, "Max dotclock rate: %d kHz\n",
2659*4882a593Smuzhiyun 		dev_priv->max_dotclk_freq);
2660*4882a593Smuzhiyun }
2661*4882a593Smuzhiyun 
2662*4882a593Smuzhiyun /**
2663*4882a593Smuzhiyun  * intel_update_cdclk - Determine the current CDCLK frequency
2664*4882a593Smuzhiyun  * @dev_priv: i915 device
2665*4882a593Smuzhiyun  *
2666*4882a593Smuzhiyun  * Determine the current CDCLK frequency.
2667*4882a593Smuzhiyun  */
intel_update_cdclk(struct drm_i915_private * dev_priv)2668*4882a593Smuzhiyun void intel_update_cdclk(struct drm_i915_private *dev_priv)
2669*4882a593Smuzhiyun {
2670*4882a593Smuzhiyun 	dev_priv->display.get_cdclk(dev_priv, &dev_priv->cdclk.hw);
2671*4882a593Smuzhiyun 
2672*4882a593Smuzhiyun 	/*
2673*4882a593Smuzhiyun 	 * 9:0 CMBUS [sic] CDCLK frequency (cdfreq):
2674*4882a593Smuzhiyun 	 * Programmng [sic] note: bit[9:2] should be programmed to the number
2675*4882a593Smuzhiyun 	 * of cdclk that generates 4MHz reference clock freq which is used to
2676*4882a593Smuzhiyun 	 * generate GMBus clock. This will vary with the cdclk freq.
2677*4882a593Smuzhiyun 	 */
2678*4882a593Smuzhiyun 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
2679*4882a593Smuzhiyun 		intel_de_write(dev_priv, GMBUSFREQ_VLV,
2680*4882a593Smuzhiyun 			       DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
2681*4882a593Smuzhiyun }
2682*4882a593Smuzhiyun 
cnp_rawclk(struct drm_i915_private * dev_priv)2683*4882a593Smuzhiyun static int cnp_rawclk(struct drm_i915_private *dev_priv)
2684*4882a593Smuzhiyun {
2685*4882a593Smuzhiyun 	u32 rawclk;
2686*4882a593Smuzhiyun 	int divider, fraction;
2687*4882a593Smuzhiyun 
2688*4882a593Smuzhiyun 	if (intel_de_read(dev_priv, SFUSE_STRAP) & SFUSE_STRAP_RAW_FREQUENCY) {
2689*4882a593Smuzhiyun 		/* 24 MHz */
2690*4882a593Smuzhiyun 		divider = 24000;
2691*4882a593Smuzhiyun 		fraction = 0;
2692*4882a593Smuzhiyun 	} else {
2693*4882a593Smuzhiyun 		/* 19.2 MHz */
2694*4882a593Smuzhiyun 		divider = 19000;
2695*4882a593Smuzhiyun 		fraction = 200;
2696*4882a593Smuzhiyun 	}
2697*4882a593Smuzhiyun 
2698*4882a593Smuzhiyun 	rawclk = CNP_RAWCLK_DIV(divider / 1000);
2699*4882a593Smuzhiyun 	if (fraction) {
2700*4882a593Smuzhiyun 		int numerator = 1;
2701*4882a593Smuzhiyun 
2702*4882a593Smuzhiyun 		rawclk |= CNP_RAWCLK_DEN(DIV_ROUND_CLOSEST(numerator * 1000,
2703*4882a593Smuzhiyun 							   fraction) - 1);
2704*4882a593Smuzhiyun 		if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
2705*4882a593Smuzhiyun 			rawclk |= ICP_RAWCLK_NUM(numerator);
2706*4882a593Smuzhiyun 	}
2707*4882a593Smuzhiyun 
2708*4882a593Smuzhiyun 	intel_de_write(dev_priv, PCH_RAWCLK_FREQ, rawclk);
2709*4882a593Smuzhiyun 	return divider + fraction;
2710*4882a593Smuzhiyun }
2711*4882a593Smuzhiyun 
pch_rawclk(struct drm_i915_private * dev_priv)2712*4882a593Smuzhiyun static int pch_rawclk(struct drm_i915_private *dev_priv)
2713*4882a593Smuzhiyun {
2714*4882a593Smuzhiyun 	return (intel_de_read(dev_priv, PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK) * 1000;
2715*4882a593Smuzhiyun }
2716*4882a593Smuzhiyun 
vlv_hrawclk(struct drm_i915_private * dev_priv)2717*4882a593Smuzhiyun static int vlv_hrawclk(struct drm_i915_private *dev_priv)
2718*4882a593Smuzhiyun {
2719*4882a593Smuzhiyun 	/* RAWCLK_FREQ_VLV register updated from power well code */
2720*4882a593Smuzhiyun 	return vlv_get_cck_clock_hpll(dev_priv, "hrawclk",
2721*4882a593Smuzhiyun 				      CCK_DISPLAY_REF_CLOCK_CONTROL);
2722*4882a593Smuzhiyun }
2723*4882a593Smuzhiyun 
i9xx_hrawclk(struct drm_i915_private * dev_priv)2724*4882a593Smuzhiyun static int i9xx_hrawclk(struct drm_i915_private *dev_priv)
2725*4882a593Smuzhiyun {
2726*4882a593Smuzhiyun 	u32 clkcfg;
2727*4882a593Smuzhiyun 
2728*4882a593Smuzhiyun 	/*
2729*4882a593Smuzhiyun 	 * hrawclock is 1/4 the FSB frequency
2730*4882a593Smuzhiyun 	 *
2731*4882a593Smuzhiyun 	 * Note that this only reads the state of the FSB
2732*4882a593Smuzhiyun 	 * straps, not the actual FSB frequency. Some BIOSen
2733*4882a593Smuzhiyun 	 * let you configure each independently. Ideally we'd
2734*4882a593Smuzhiyun 	 * read out the actual FSB frequency but sadly we
2735*4882a593Smuzhiyun 	 * don't know which registers have that information,
2736*4882a593Smuzhiyun 	 * and all the relevant docs have gone to bit heaven :(
2737*4882a593Smuzhiyun 	 */
2738*4882a593Smuzhiyun 	clkcfg = intel_de_read(dev_priv, CLKCFG) & CLKCFG_FSB_MASK;
2739*4882a593Smuzhiyun 
2740*4882a593Smuzhiyun 	if (IS_MOBILE(dev_priv)) {
2741*4882a593Smuzhiyun 		switch (clkcfg) {
2742*4882a593Smuzhiyun 		case CLKCFG_FSB_400:
2743*4882a593Smuzhiyun 			return 100000;
2744*4882a593Smuzhiyun 		case CLKCFG_FSB_533:
2745*4882a593Smuzhiyun 			return 133333;
2746*4882a593Smuzhiyun 		case CLKCFG_FSB_667:
2747*4882a593Smuzhiyun 			return 166667;
2748*4882a593Smuzhiyun 		case CLKCFG_FSB_800:
2749*4882a593Smuzhiyun 			return 200000;
2750*4882a593Smuzhiyun 		case CLKCFG_FSB_1067:
2751*4882a593Smuzhiyun 			return 266667;
2752*4882a593Smuzhiyun 		case CLKCFG_FSB_1333:
2753*4882a593Smuzhiyun 			return 333333;
2754*4882a593Smuzhiyun 		default:
2755*4882a593Smuzhiyun 			MISSING_CASE(clkcfg);
2756*4882a593Smuzhiyun 			return 133333;
2757*4882a593Smuzhiyun 		}
2758*4882a593Smuzhiyun 	} else {
2759*4882a593Smuzhiyun 		switch (clkcfg) {
2760*4882a593Smuzhiyun 		case CLKCFG_FSB_400_ALT:
2761*4882a593Smuzhiyun 			return 100000;
2762*4882a593Smuzhiyun 		case CLKCFG_FSB_533:
2763*4882a593Smuzhiyun 			return 133333;
2764*4882a593Smuzhiyun 		case CLKCFG_FSB_667:
2765*4882a593Smuzhiyun 			return 166667;
2766*4882a593Smuzhiyun 		case CLKCFG_FSB_800:
2767*4882a593Smuzhiyun 			return 200000;
2768*4882a593Smuzhiyun 		case CLKCFG_FSB_1067_ALT:
2769*4882a593Smuzhiyun 			return 266667;
2770*4882a593Smuzhiyun 		case CLKCFG_FSB_1333_ALT:
2771*4882a593Smuzhiyun 			return 333333;
2772*4882a593Smuzhiyun 		case CLKCFG_FSB_1600_ALT:
2773*4882a593Smuzhiyun 			return 400000;
2774*4882a593Smuzhiyun 		default:
2775*4882a593Smuzhiyun 			return 133333;
2776*4882a593Smuzhiyun 		}
2777*4882a593Smuzhiyun 	}
2778*4882a593Smuzhiyun }
2779*4882a593Smuzhiyun 
2780*4882a593Smuzhiyun /**
2781*4882a593Smuzhiyun  * intel_read_rawclk - Determine the current RAWCLK frequency
2782*4882a593Smuzhiyun  * @dev_priv: i915 device
2783*4882a593Smuzhiyun  *
2784*4882a593Smuzhiyun  * Determine the current RAWCLK frequency. RAWCLK is a fixed
2785*4882a593Smuzhiyun  * frequency clock so this needs to done only once.
2786*4882a593Smuzhiyun  */
intel_read_rawclk(struct drm_i915_private * dev_priv)2787*4882a593Smuzhiyun u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
2788*4882a593Smuzhiyun {
2789*4882a593Smuzhiyun 	u32 freq;
2790*4882a593Smuzhiyun 
2791*4882a593Smuzhiyun 	if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP)
2792*4882a593Smuzhiyun 		freq = cnp_rawclk(dev_priv);
2793*4882a593Smuzhiyun 	else if (HAS_PCH_SPLIT(dev_priv))
2794*4882a593Smuzhiyun 		freq = pch_rawclk(dev_priv);
2795*4882a593Smuzhiyun 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
2796*4882a593Smuzhiyun 		freq = vlv_hrawclk(dev_priv);
2797*4882a593Smuzhiyun 	else if (INTEL_GEN(dev_priv) >= 3)
2798*4882a593Smuzhiyun 		freq = i9xx_hrawclk(dev_priv);
2799*4882a593Smuzhiyun 	else
2800*4882a593Smuzhiyun 		/* no rawclk on other platforms, or no need to know it */
2801*4882a593Smuzhiyun 		return 0;
2802*4882a593Smuzhiyun 
2803*4882a593Smuzhiyun 	return freq;
2804*4882a593Smuzhiyun }
2805*4882a593Smuzhiyun 
2806*4882a593Smuzhiyun /**
2807*4882a593Smuzhiyun  * intel_init_cdclk_hooks - Initialize CDCLK related modesetting hooks
2808*4882a593Smuzhiyun  * @dev_priv: i915 device
2809*4882a593Smuzhiyun  */
intel_init_cdclk_hooks(struct drm_i915_private * dev_priv)2810*4882a593Smuzhiyun void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
2811*4882a593Smuzhiyun {
2812*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 12) {
2813*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bxt_set_cdclk;
2814*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2815*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
2816*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
2817*4882a593Smuzhiyun 		dev_priv->cdclk.table = icl_cdclk_table;
2818*4882a593Smuzhiyun 	} else if (IS_ELKHARTLAKE(dev_priv)) {
2819*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bxt_set_cdclk;
2820*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2821*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
2822*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level = ehl_calc_voltage_level;
2823*4882a593Smuzhiyun 		dev_priv->cdclk.table = icl_cdclk_table;
2824*4882a593Smuzhiyun 	} else if (INTEL_GEN(dev_priv) >= 11) {
2825*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bxt_set_cdclk;
2826*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2827*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
2828*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level = icl_calc_voltage_level;
2829*4882a593Smuzhiyun 		dev_priv->cdclk.table = icl_cdclk_table;
2830*4882a593Smuzhiyun 	} else if (IS_CANNONLAKE(dev_priv)) {
2831*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2832*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bxt_set_cdclk;
2833*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
2834*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level = cnl_calc_voltage_level;
2835*4882a593Smuzhiyun 		dev_priv->cdclk.table = cnl_cdclk_table;
2836*4882a593Smuzhiyun 	} else if (IS_GEN9_LP(dev_priv)) {
2837*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2838*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bxt_set_cdclk;
2839*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
2840*4882a593Smuzhiyun 		dev_priv->display.calc_voltage_level = bxt_calc_voltage_level;
2841*4882a593Smuzhiyun 		if (IS_GEMINILAKE(dev_priv))
2842*4882a593Smuzhiyun 			dev_priv->cdclk.table = glk_cdclk_table;
2843*4882a593Smuzhiyun 		else
2844*4882a593Smuzhiyun 			dev_priv->cdclk.table = bxt_cdclk_table;
2845*4882a593Smuzhiyun 	} else if (IS_GEN9_BC(dev_priv)) {
2846*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
2847*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = skl_set_cdclk;
2848*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = skl_modeset_calc_cdclk;
2849*4882a593Smuzhiyun 	} else if (IS_BROADWELL(dev_priv)) {
2850*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
2851*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = bdw_set_cdclk;
2852*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = bdw_modeset_calc_cdclk;
2853*4882a593Smuzhiyun 	} else if (IS_CHERRYVIEW(dev_priv)) {
2854*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
2855*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = chv_set_cdclk;
2856*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk;
2857*4882a593Smuzhiyun 	} else if (IS_VALLEYVIEW(dev_priv)) {
2858*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
2859*4882a593Smuzhiyun 		dev_priv->display.set_cdclk = vlv_set_cdclk;
2860*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = vlv_modeset_calc_cdclk;
2861*4882a593Smuzhiyun 	} else {
2862*4882a593Smuzhiyun 		dev_priv->display.bw_calc_min_cdclk = intel_bw_calc_min_cdclk;
2863*4882a593Smuzhiyun 		dev_priv->display.modeset_calc_cdclk = fixed_modeset_calc_cdclk;
2864*4882a593Smuzhiyun 	}
2865*4882a593Smuzhiyun 
2866*4882a593Smuzhiyun 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEN9_LP(dev_priv))
2867*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = bxt_get_cdclk;
2868*4882a593Smuzhiyun 	else if (IS_GEN9_BC(dev_priv))
2869*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = skl_get_cdclk;
2870*4882a593Smuzhiyun 	else if (IS_BROADWELL(dev_priv))
2871*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = bdw_get_cdclk;
2872*4882a593Smuzhiyun 	else if (IS_HASWELL(dev_priv))
2873*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = hsw_get_cdclk;
2874*4882a593Smuzhiyun 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
2875*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = vlv_get_cdclk;
2876*4882a593Smuzhiyun 	else if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
2877*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk;
2878*4882a593Smuzhiyun 	else if (IS_GEN(dev_priv, 5))
2879*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_450mhz_get_cdclk;
2880*4882a593Smuzhiyun 	else if (IS_GM45(dev_priv))
2881*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = gm45_get_cdclk;
2882*4882a593Smuzhiyun 	else if (IS_G45(dev_priv))
2883*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = g33_get_cdclk;
2884*4882a593Smuzhiyun 	else if (IS_I965GM(dev_priv))
2885*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = i965gm_get_cdclk;
2886*4882a593Smuzhiyun 	else if (IS_I965G(dev_priv))
2887*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk;
2888*4882a593Smuzhiyun 	else if (IS_PINEVIEW(dev_priv))
2889*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = pnv_get_cdclk;
2890*4882a593Smuzhiyun 	else if (IS_G33(dev_priv))
2891*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = g33_get_cdclk;
2892*4882a593Smuzhiyun 	else if (IS_I945GM(dev_priv))
2893*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = i945gm_get_cdclk;
2894*4882a593Smuzhiyun 	else if (IS_I945G(dev_priv))
2895*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_400mhz_get_cdclk;
2896*4882a593Smuzhiyun 	else if (IS_I915GM(dev_priv))
2897*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = i915gm_get_cdclk;
2898*4882a593Smuzhiyun 	else if (IS_I915G(dev_priv))
2899*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_333mhz_get_cdclk;
2900*4882a593Smuzhiyun 	else if (IS_I865G(dev_priv))
2901*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_266mhz_get_cdclk;
2902*4882a593Smuzhiyun 	else if (IS_I85X(dev_priv))
2903*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = i85x_get_cdclk;
2904*4882a593Smuzhiyun 	else if (IS_I845G(dev_priv))
2905*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_200mhz_get_cdclk;
2906*4882a593Smuzhiyun 	else if (IS_I830(dev_priv))
2907*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk;
2908*4882a593Smuzhiyun 
2909*4882a593Smuzhiyun 	if (drm_WARN(&dev_priv->drm, !dev_priv->display.get_cdclk,
2910*4882a593Smuzhiyun 		     "Unknown platform. Assuming 133 MHz CDCLK\n"))
2911*4882a593Smuzhiyun 		dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk;
2912*4882a593Smuzhiyun }
2913