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