xref: /openbmc/linux/drivers/gpu/drm/meson/meson_vclk.c (revision 2f4c95dc)
1 /*
2  * Copyright (C) 2016 BayLibre, SAS
3  * Author: Neil Armstrong <narmstrong@baylibre.com>
4  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <drm/drmP.h>
23 #include "meson_drv.h"
24 #include "meson_vclk.h"
25 
26 /*
27  * VCLK is the "Pixel Clock" frequency generator from a dedicated PLL.
28  * We handle the following encodings :
29  * - CVBS 27MHz generator via the VCLK2 to the VENCI and VDAC blocks
30  * - HDMI Pixel Clocks generation
31  * What is missing :
32  * - Genenate Pixel clocks for 2K/4K 10bit formats
33  *
34  * Clock generator scheme :
35  *  __________   _________            _____
36  * |          | |         |          |     |--ENCI
37  * | HDMI PLL |-| PLL_DIV |--- VCLK--|     |--ENCL
38  * |__________| |_________| \        | MUX |--ENCP
39  *                           --VCLK2-|     |--VDAC
40  *                                   |_____|--HDMI-TX
41  *
42  * Final clocks can take input for either VCLK or VCLK2, but
43  * VCLK is the preferred path for HDMI clocking and VCLK2 is the
44  * preferred path for CVBS VDAC clocking.
45  *
46  * VCLK and VCLK2 have fixed divided clocks paths for /1, /2, /4, /6 or /12.
47  *
48  * The PLL_DIV can achieve an additional fractional dividing like
49  * 1.5, 3.5, 3.75... to generate special 2K and 4K 10bit clocks.
50  */
51 
52 /* HHI Registers */
53 #define HHI_VID_PLL_CLK_DIV	0x1a0 /* 0x68 offset in data sheet */
54 #define VID_PLL_EN		BIT(19)
55 #define VID_PLL_BYPASS		BIT(18)
56 #define VID_PLL_PRESET		BIT(15)
57 #define HHI_VIID_CLK_DIV	0x128 /* 0x4a offset in data sheet */
58 #define VCLK2_DIV_MASK		0xff
59 #define VCLK2_DIV_EN		BIT(16)
60 #define VCLK2_DIV_RESET		BIT(17)
61 #define CTS_VDAC_SEL_MASK	(0xf << 28)
62 #define CTS_VDAC_SEL_SHIFT	28
63 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
64 #define VCLK2_EN		BIT(19)
65 #define VCLK2_SEL_MASK		(0x7 << 16)
66 #define VCLK2_SEL_SHIFT		16
67 #define VCLK2_SOFT_RESET	BIT(15)
68 #define VCLK2_DIV1_EN		BIT(0)
69 #define HHI_VID_CLK_DIV		0x164 /* 0x59 offset in data sheet */
70 #define VCLK_DIV_MASK		0xff
71 #define VCLK_DIV_EN		BIT(16)
72 #define VCLK_DIV_RESET		BIT(17)
73 #define CTS_ENCP_SEL_MASK	(0xf << 24)
74 #define CTS_ENCP_SEL_SHIFT	24
75 #define CTS_ENCI_SEL_MASK	(0xf << 28)
76 #define CTS_ENCI_SEL_SHIFT	28
77 #define HHI_VID_CLK_CNTL	0x17c /* 0x5f offset in data sheet */
78 #define VCLK_EN			BIT(19)
79 #define VCLK_SEL_MASK		(0x7 << 16)
80 #define VCLK_SEL_SHIFT		16
81 #define VCLK_SOFT_RESET		BIT(15)
82 #define VCLK_DIV1_EN		BIT(0)
83 #define VCLK_DIV2_EN		BIT(1)
84 #define VCLK_DIV4_EN		BIT(2)
85 #define VCLK_DIV6_EN		BIT(3)
86 #define VCLK_DIV12_EN		BIT(4)
87 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
88 #define CTS_ENCI_EN		BIT(0)
89 #define CTS_ENCP_EN		BIT(2)
90 #define CTS_VDAC_EN		BIT(4)
91 #define HDMI_TX_PIXEL_EN	BIT(5)
92 #define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 offset in data sheet */
93 #define HDMI_TX_PIXEL_SEL_MASK	(0xf << 16)
94 #define HDMI_TX_PIXEL_SEL_SHIFT	16
95 #define CTS_HDMI_SYS_SEL_MASK	(0x7 << 9)
96 #define CTS_HDMI_SYS_DIV_MASK	(0x7f)
97 #define CTS_HDMI_SYS_EN		BIT(8)
98 
99 #define HHI_VDAC_CNTL0		0x2F4 /* 0xbd offset in data sheet */
100 #define HHI_VDAC_CNTL1		0x2F8 /* 0xbe offset in data sheet */
101 
102 #define HHI_HDMI_PLL_CNTL	0x320 /* 0xc8 offset in data sheet */
103 #define HHI_HDMI_PLL_CNTL2	0x324 /* 0xc9 offset in data sheet */
104 #define HHI_HDMI_PLL_CNTL3	0x328 /* 0xca offset in data sheet */
105 #define HHI_HDMI_PLL_CNTL4	0x32C /* 0xcb offset in data sheet */
106 #define HHI_HDMI_PLL_CNTL5	0x330 /* 0xcc offset in data sheet */
107 #define HHI_HDMI_PLL_CNTL6	0x334 /* 0xcd offset in data sheet */
108 
109 #define HDMI_PLL_RESET		BIT(28)
110 #define HDMI_PLL_LOCK		BIT(31)
111 
112 /* VID PLL Dividers */
113 enum {
114 	VID_PLL_DIV_1 = 0,
115 	VID_PLL_DIV_2,
116 	VID_PLL_DIV_2p5,
117 	VID_PLL_DIV_3,
118 	VID_PLL_DIV_3p5,
119 	VID_PLL_DIV_3p75,
120 	VID_PLL_DIV_4,
121 	VID_PLL_DIV_5,
122 	VID_PLL_DIV_6,
123 	VID_PLL_DIV_6p25,
124 	VID_PLL_DIV_7,
125 	VID_PLL_DIV_7p5,
126 	VID_PLL_DIV_12,
127 	VID_PLL_DIV_14,
128 	VID_PLL_DIV_15,
129 };
130 
131 void meson_vid_pll_set(struct meson_drm *priv, unsigned int div)
132 {
133 	unsigned int shift_val = 0;
134 	unsigned int shift_sel = 0;
135 
136 	/* Disable vid_pll output clock */
137 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
138 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
139 
140 	switch (div) {
141 	case VID_PLL_DIV_2:
142 		shift_val = 0x0aaa;
143 		shift_sel = 0;
144 		break;
145 	case VID_PLL_DIV_2p5:
146 		shift_val = 0x5294;
147 		shift_sel = 2;
148 		break;
149 	case VID_PLL_DIV_3:
150 		shift_val = 0x0db6;
151 		shift_sel = 0;
152 		break;
153 	case VID_PLL_DIV_3p5:
154 		shift_val = 0x36cc;
155 		shift_sel = 1;
156 		break;
157 	case VID_PLL_DIV_3p75:
158 		shift_val = 0x6666;
159 		shift_sel = 2;
160 		break;
161 	case VID_PLL_DIV_4:
162 		shift_val = 0x0ccc;
163 		shift_sel = 0;
164 		break;
165 	case VID_PLL_DIV_5:
166 		shift_val = 0x739c;
167 		shift_sel = 2;
168 		break;
169 	case VID_PLL_DIV_6:
170 		shift_val = 0x0e38;
171 		shift_sel = 0;
172 		break;
173 	case VID_PLL_DIV_6p25:
174 		shift_val = 0x0000;
175 		shift_sel = 3;
176 		break;
177 	case VID_PLL_DIV_7:
178 		shift_val = 0x3c78;
179 		shift_sel = 1;
180 		break;
181 	case VID_PLL_DIV_7p5:
182 		shift_val = 0x78f0;
183 		shift_sel = 2;
184 		break;
185 	case VID_PLL_DIV_12:
186 		shift_val = 0x0fc0;
187 		shift_sel = 0;
188 		break;
189 	case VID_PLL_DIV_14:
190 		shift_val = 0x3f80;
191 		shift_sel = 1;
192 		break;
193 	case VID_PLL_DIV_15:
194 		shift_val = 0x7f80;
195 		shift_sel = 2;
196 		break;
197 	}
198 
199 	if (div == VID_PLL_DIV_1)
200 		/* Enable vid_pll bypass to HDMI pll */
201 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
202 				   VID_PLL_BYPASS, VID_PLL_BYPASS);
203 	else {
204 		/* Disable Bypass */
205 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
206 				   VID_PLL_BYPASS, 0);
207 		/* Clear sel */
208 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
209 				   3 << 16, 0);
210 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
211 				   VID_PLL_PRESET, 0);
212 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
213 				   0x7fff, 0);
214 
215 		/* Setup sel and val */
216 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
217 				   3 << 16, shift_sel << 16);
218 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
219 				   VID_PLL_PRESET, VID_PLL_PRESET);
220 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
221 				   0x7fff, shift_val);
222 
223 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
224 				   VID_PLL_PRESET, 0);
225 	}
226 
227 	/* Enable the vid_pll output clock */
228 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
229 				VID_PLL_EN, VID_PLL_EN);
230 }
231 
232 /*
233  * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
234  *
235  * TOFIX: Refactor into table to also handle HDMI frequency and paths
236  */
237 static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
238 {
239 	unsigned int val;
240 
241 	/* Setup PLL to output 1.485GHz */
242 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
243 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
244 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
245 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
246 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
247 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
248 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
249 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
250 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
251 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
252 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
253 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
254 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
255 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
256 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
257 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
258 
259 		/* Reset PLL */
260 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
261 					HDMI_PLL_RESET, HDMI_PLL_RESET);
262 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
263 					HDMI_PLL_RESET, 0);
264 	}
265 
266 	/* Poll for lock bit */
267 	regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
268 				 (val & HDMI_PLL_LOCK), 10, 0);
269 
270 	/* Disable VCLK2 */
271 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
272 
273 	/* Setup vid_pll to /1 */
274 	meson_vid_pll_set(priv, VID_PLL_DIV_1);
275 
276 	/* Setup the VCLK2 divider value to achieve 27MHz */
277 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
278 				VCLK2_DIV_MASK, (55 - 1));
279 
280 	/* select vid_pll for vclk2 */
281 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
282 				VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
283 	/* enable vclk2 gate */
284 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
285 
286 	/* select vclk_div1 for enci */
287 	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
288 				CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
289 	/* select vclk_div1 for vdac */
290 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
291 				CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
292 
293 	/* release vclk2_div_reset and enable vclk2_div */
294 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
295 				VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
296 
297 	/* enable vclk2_div1 gate */
298 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
299 				VCLK2_DIV1_EN, VCLK2_DIV1_EN);
300 
301 	/* reset vclk2 */
302 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
303 				VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
304 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
305 				VCLK2_SOFT_RESET, 0);
306 
307 	/* enable enci_clk */
308 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
309 				CTS_ENCI_EN, CTS_ENCI_EN);
310 	/* enable vdac_clk */
311 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
312 				CTS_VDAC_EN, CTS_VDAC_EN);
313 }
314 
315 
316 /* PLL	O1 O2 O3 VP DV     EN TX */
317 /* 4320 /4 /4 /1 /5 /1  => /2 /2 */
318 #define MESON_VCLK_HDMI_ENCI_54000	1
319 /* 4320 /4 /4 /1 /5 /1  => /1 /2 */
320 #define MESON_VCLK_HDMI_DDR_54000	2
321 /* 2970 /4 /1 /1 /5 /1  => /1 /2 */
322 #define MESON_VCLK_HDMI_DDR_148500	3
323 /* 2970 /2 /2 /2 /5 /1  => /1 /1 */
324 #define MESON_VCLK_HDMI_74250		4
325 /* 2970 /1 /2 /2 /5 /1  => /1 /1 */
326 #define MESON_VCLK_HDMI_148500		5
327 /* 2970 /1 /1 /1 /5 /2  => /1 /1 */
328 #define MESON_VCLK_HDMI_297000		6
329 /* 5940 /1 /1 /2 /5 /1  => /1 /1 */
330 #define MESON_VCLK_HDMI_594000		7
331 
332 struct meson_vclk_params {
333 	unsigned int pll_base_freq;
334 	unsigned int pll_od1;
335 	unsigned int pll_od2;
336 	unsigned int pll_od3;
337 	unsigned int vid_pll_div;
338 	unsigned int vclk_div;
339 } params[] = {
340 	[MESON_VCLK_HDMI_ENCI_54000] = {
341 		.pll_base_freq = 4320000,
342 		.pll_od1 = 4,
343 		.pll_od2 = 4,
344 		.pll_od3 = 1,
345 		.vid_pll_div = VID_PLL_DIV_5,
346 		.vclk_div = 1,
347 	},
348 	[MESON_VCLK_HDMI_DDR_54000] = {
349 		.pll_base_freq = 4320000,
350 		.pll_od1 = 4,
351 		.pll_od2 = 4,
352 		.pll_od3 = 1,
353 		.vid_pll_div = VID_PLL_DIV_5,
354 		.vclk_div = 1,
355 	},
356 	[MESON_VCLK_HDMI_DDR_148500] = {
357 		.pll_base_freq = 2970000,
358 		.pll_od1 = 4,
359 		.pll_od2 = 1,
360 		.pll_od3 = 1,
361 		.vid_pll_div = VID_PLL_DIV_5,
362 		.vclk_div = 1,
363 	},
364 	[MESON_VCLK_HDMI_74250] = {
365 		.pll_base_freq = 2970000,
366 		.pll_od1 = 2,
367 		.pll_od2 = 2,
368 		.pll_od3 = 2,
369 		.vid_pll_div = VID_PLL_DIV_5,
370 		.vclk_div = 1,
371 	},
372 	[MESON_VCLK_HDMI_148500] = {
373 		.pll_base_freq = 2970000,
374 		.pll_od1 = 1,
375 		.pll_od2 = 2,
376 		.pll_od3 = 2,
377 		.vid_pll_div = VID_PLL_DIV_5,
378 		.vclk_div = 1,
379 	},
380 	[MESON_VCLK_HDMI_297000] = {
381 		.pll_base_freq = 2970000,
382 		.pll_od1 = 1,
383 		.pll_od2 = 1,
384 		.pll_od3 = 1,
385 		.vid_pll_div = VID_PLL_DIV_5,
386 		.vclk_div = 2,
387 	},
388 	[MESON_VCLK_HDMI_594000] = {
389 		.pll_base_freq = 5940000,
390 		.pll_od1 = 1,
391 		.pll_od2 = 1,
392 		.pll_od3 = 2,
393 		.vid_pll_div = VID_PLL_DIV_5,
394 		.vclk_div = 1,
395 	},
396 };
397 
398 static inline unsigned int pll_od_to_reg(unsigned int od)
399 {
400 	switch (od) {
401 	case 1:
402 		return 0;
403 	case 2:
404 		return 1;
405 	case 4:
406 		return 2;
407 	case 8:
408 		return 3;
409 	}
410 
411 	/* Invalid */
412 	return 0;
413 }
414 
415 void meson_hdmi_pll_set(struct meson_drm *priv,
416 			unsigned int base,
417 			unsigned int od1,
418 			unsigned int od2,
419 			unsigned int od3)
420 {
421 	unsigned int val;
422 
423 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
424 		switch (base) {
425 		case 2970000:
426 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
427 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
428 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
429 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
430 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
431 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
432 
433 			/* Enable and unreset */
434 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
435 						0x7 << 28, 0x4 << 28);
436 
437 			/* Poll for lock bit */
438 			regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
439 					val, (val & HDMI_PLL_LOCK), 10, 0);
440 
441 			/* div_frac */
442 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
443 						0xFFFF,  0x4e00);
444 			break;
445 
446 		case 4320000:
447 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800025a);
448 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00000000);
449 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
450 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
451 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
452 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
453 
454 			/* unreset */
455 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
456 						BIT(28), 0);
457 
458 			/* Poll for lock bit */
459 			regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
460 					val, (val & HDMI_PLL_LOCK), 10, 0);
461 			break;
462 
463 		case 5940000:
464 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800027b);
465 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
466 						0xFFFF,  0x4c00);
467 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x135c5091);
468 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
469 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
470 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
471 
472 			/* unreset */
473 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
474 						BIT(28), 0);
475 
476 			/* Poll for lock bit */
477 			regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
478 					val, (val & HDMI_PLL_LOCK), 10, 0);
479 			break;
480 		};
481 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
482 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
483 		switch (base) {
484 		case 2970000:
485 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
486 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
487 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
488 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
489 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
490 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
491 			break;
492 
493 		case 4320000:
494 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002b4);
495 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000);
496 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
497 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
498 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
499 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
500 			break;
501 
502 		case 5940000:
503 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x400002f7);
504 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb200);
505 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
506 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
507 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
508 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
509 			break;
510 
511 		};
512 
513 		/* Reset PLL */
514 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
515 					HDMI_PLL_RESET, HDMI_PLL_RESET);
516 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
517 					HDMI_PLL_RESET, 0);
518 
519 		/* Poll for lock bit */
520 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
521 				(val & HDMI_PLL_LOCK), 10, 0);
522 	};
523 
524 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
525 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
526 				   3 << 16, pll_od_to_reg(od1) << 16);
527 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
528 		 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
529 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
530 				   3 << 21, pll_od_to_reg(od1) << 21);
531 
532 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
533 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
534 				   3 << 22, pll_od_to_reg(od2) << 22);
535 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
536 		 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
537 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
538 				   3 << 23, pll_od_to_reg(od2) << 23);
539 
540 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
541 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
542 				   3 << 18, pll_od_to_reg(od3) << 18);
543 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
544 		 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
545 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
546 				   3 << 19, pll_od_to_reg(od3) << 19);
547 }
548 
549 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
550 		      unsigned int vclk_freq, unsigned int venc_freq,
551 		      unsigned int dac_freq, bool hdmi_use_enci)
552 {
553 	unsigned int freq;
554 	unsigned int hdmi_tx_div;
555 	unsigned int venc_div;
556 
557 	if (target == MESON_VCLK_TARGET_CVBS) {
558 		meson_venci_cvbs_clock_config(priv);
559 		return;
560 	}
561 
562 	hdmi_tx_div = vclk_freq / dac_freq;
563 
564 	if (hdmi_tx_div == 0) {
565 		pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
566 				dac_freq);
567 		return;
568 	}
569 
570 	venc_div = vclk_freq / venc_freq;
571 
572 	if (venc_div == 0) {
573 		pr_err("Fatal Error, invalid HDMI venc freq %d\n",
574 				venc_freq);
575 		return;
576 	}
577 
578 	switch (vclk_freq) {
579 	case 54000:
580 		if (hdmi_use_enci)
581 			freq = MESON_VCLK_HDMI_ENCI_54000;
582 		else
583 			freq = MESON_VCLK_HDMI_DDR_54000;
584 		break;
585 	case 74250:
586 		freq = MESON_VCLK_HDMI_74250;
587 		break;
588 	case 148500:
589 		if (dac_freq != 148500)
590 			freq = MESON_VCLK_HDMI_DDR_148500;
591 		else
592 			freq = MESON_VCLK_HDMI_148500;
593 		break;
594 	case 297000:
595 		freq = MESON_VCLK_HDMI_297000;
596 		break;
597 	case 594000:
598 		freq = MESON_VCLK_HDMI_594000;
599 		break;
600 	default:
601 		pr_err("Fatal Error, invalid HDMI vclk freq %d\n",
602 			vclk_freq);
603 		return;
604 	}
605 
606 	/* Set HDMI-TX sys clock */
607 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
608 			   CTS_HDMI_SYS_SEL_MASK, 0);
609 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
610 			   CTS_HDMI_SYS_DIV_MASK, 0);
611 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
612 			   CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
613 
614 	/* Set HDMI PLL rate */
615 	meson_hdmi_pll_set(priv, params[freq].pll_base_freq,
616 			   params[freq].pll_od1,
617 			   params[freq].pll_od2,
618 			   params[freq].pll_od3);
619 
620 	/* Setup vid_pll divider */
621 	meson_vid_pll_set(priv, params[freq].vid_pll_div);
622 
623 	/* Set VCLK div */
624 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
625 			   VCLK_SEL_MASK, 0);
626 	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
627 			   VCLK_DIV_MASK, params[freq].vclk_div - 1);
628 
629 	/* Set HDMI-TX source */
630 	switch (hdmi_tx_div) {
631 	case 1:
632 		/* enable vclk_div1 gate */
633 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
634 				   VCLK_DIV1_EN, VCLK_DIV1_EN);
635 
636 		/* select vclk_div1 for HDMI-TX */
637 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
638 				   HDMI_TX_PIXEL_SEL_MASK, 0);
639 		break;
640 	case 2:
641 		/* enable vclk_div2 gate */
642 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
643 				   VCLK_DIV2_EN, VCLK_DIV2_EN);
644 
645 		/* select vclk_div2 for HDMI-TX */
646 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
647 			HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
648 		break;
649 	case 4:
650 		/* enable vclk_div4 gate */
651 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
652 				   VCLK_DIV4_EN, VCLK_DIV4_EN);
653 
654 		/* select vclk_div4 for HDMI-TX */
655 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
656 			HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
657 		break;
658 	case 6:
659 		/* enable vclk_div6 gate */
660 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
661 				   VCLK_DIV6_EN, VCLK_DIV6_EN);
662 
663 		/* select vclk_div6 for HDMI-TX */
664 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
665 			HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
666 		break;
667 	case 12:
668 		/* enable vclk_div12 gate */
669 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
670 				   VCLK_DIV12_EN, VCLK_DIV12_EN);
671 
672 		/* select vclk_div12 for HDMI-TX */
673 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
674 			HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
675 		break;
676 	}
677 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
678 				   HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
679 
680 	/* Set ENCI/ENCP Source */
681 	switch (venc_div) {
682 	case 1:
683 		/* enable vclk_div1 gate */
684 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
685 				   VCLK_DIV1_EN, VCLK_DIV1_EN);
686 
687 		if (hdmi_use_enci)
688 			/* select vclk_div1 for enci */
689 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
690 					   CTS_ENCI_SEL_MASK, 0);
691 		else
692 			/* select vclk_div1 for encp */
693 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
694 					   CTS_ENCP_SEL_MASK, 0);
695 		break;
696 	case 2:
697 		/* enable vclk_div2 gate */
698 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
699 				   VCLK_DIV2_EN, VCLK_DIV2_EN);
700 
701 		if (hdmi_use_enci)
702 			/* select vclk_div2 for enci */
703 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
704 				CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
705 		else
706 			/* select vclk_div2 for encp */
707 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
708 				CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
709 		break;
710 	case 4:
711 		/* enable vclk_div4 gate */
712 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
713 				   VCLK_DIV4_EN, VCLK_DIV4_EN);
714 
715 		if (hdmi_use_enci)
716 			/* select vclk_div4 for enci */
717 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
718 				CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
719 		else
720 			/* select vclk_div4 for encp */
721 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
722 				CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
723 		break;
724 	case 6:
725 		/* enable vclk_div6 gate */
726 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
727 				   VCLK_DIV6_EN, VCLK_DIV6_EN);
728 
729 		if (hdmi_use_enci)
730 			/* select vclk_div6 for enci */
731 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
732 				CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
733 		else
734 			/* select vclk_div6 for encp */
735 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
736 				CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
737 		break;
738 	case 12:
739 		/* enable vclk_div12 gate */
740 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
741 				   VCLK_DIV12_EN, VCLK_DIV12_EN);
742 
743 		if (hdmi_use_enci)
744 			/* select vclk_div12 for enci */
745 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
746 				CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
747 		else
748 			/* select vclk_div12 for encp */
749 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
750 				CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
751 		break;
752 	}
753 
754 	if (hdmi_use_enci)
755 		/* Enable ENCI clock gate */
756 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
757 				   CTS_ENCI_EN, CTS_ENCI_EN);
758 	else
759 		/* Enable ENCP clock gate */
760 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
761 				   CTS_ENCP_EN, CTS_ENCP_EN);
762 
763 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
764 }
765 EXPORT_SYMBOL_GPL(meson_vclk_setup);
766