xref: /openbmc/linux/drivers/gpu/drm/meson/meson_vclk.c (revision 151f4e2b)
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 #define HHI_HDMI_PLL_CNTL7	0x338 /* 0xce offset in data sheet */
117 
118 #define HDMI_PLL_RESET		BIT(28)
119 #define HDMI_PLL_RESET_G12A	BIT(29)
120 #define HDMI_PLL_LOCK		BIT(31)
121 #define HDMI_PLL_LOCK_G12A	(3 << 30)
122 
123 #define FREQ_1000_1001(_freq)	DIV_ROUND_CLOSEST(_freq * 1000, 1001)
124 
125 /* VID PLL Dividers */
126 enum {
127 	VID_PLL_DIV_1 = 0,
128 	VID_PLL_DIV_2,
129 	VID_PLL_DIV_2p5,
130 	VID_PLL_DIV_3,
131 	VID_PLL_DIV_3p5,
132 	VID_PLL_DIV_3p75,
133 	VID_PLL_DIV_4,
134 	VID_PLL_DIV_5,
135 	VID_PLL_DIV_6,
136 	VID_PLL_DIV_6p25,
137 	VID_PLL_DIV_7,
138 	VID_PLL_DIV_7p5,
139 	VID_PLL_DIV_12,
140 	VID_PLL_DIV_14,
141 	VID_PLL_DIV_15,
142 };
143 
144 void meson_vid_pll_set(struct meson_drm *priv, unsigned int div)
145 {
146 	unsigned int shift_val = 0;
147 	unsigned int shift_sel = 0;
148 
149 	/* Disable vid_pll output clock */
150 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
151 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
152 
153 	switch (div) {
154 	case VID_PLL_DIV_2:
155 		shift_val = 0x0aaa;
156 		shift_sel = 0;
157 		break;
158 	case VID_PLL_DIV_2p5:
159 		shift_val = 0x5294;
160 		shift_sel = 2;
161 		break;
162 	case VID_PLL_DIV_3:
163 		shift_val = 0x0db6;
164 		shift_sel = 0;
165 		break;
166 	case VID_PLL_DIV_3p5:
167 		shift_val = 0x36cc;
168 		shift_sel = 1;
169 		break;
170 	case VID_PLL_DIV_3p75:
171 		shift_val = 0x6666;
172 		shift_sel = 2;
173 		break;
174 	case VID_PLL_DIV_4:
175 		shift_val = 0x0ccc;
176 		shift_sel = 0;
177 		break;
178 	case VID_PLL_DIV_5:
179 		shift_val = 0x739c;
180 		shift_sel = 2;
181 		break;
182 	case VID_PLL_DIV_6:
183 		shift_val = 0x0e38;
184 		shift_sel = 0;
185 		break;
186 	case VID_PLL_DIV_6p25:
187 		shift_val = 0x0000;
188 		shift_sel = 3;
189 		break;
190 	case VID_PLL_DIV_7:
191 		shift_val = 0x3c78;
192 		shift_sel = 1;
193 		break;
194 	case VID_PLL_DIV_7p5:
195 		shift_val = 0x78f0;
196 		shift_sel = 2;
197 		break;
198 	case VID_PLL_DIV_12:
199 		shift_val = 0x0fc0;
200 		shift_sel = 0;
201 		break;
202 	case VID_PLL_DIV_14:
203 		shift_val = 0x3f80;
204 		shift_sel = 1;
205 		break;
206 	case VID_PLL_DIV_15:
207 		shift_val = 0x7f80;
208 		shift_sel = 2;
209 		break;
210 	}
211 
212 	if (div == VID_PLL_DIV_1)
213 		/* Enable vid_pll bypass to HDMI pll */
214 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
215 				   VID_PLL_BYPASS, VID_PLL_BYPASS);
216 	else {
217 		/* Disable Bypass */
218 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
219 				   VID_PLL_BYPASS, 0);
220 		/* Clear sel */
221 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
222 				   3 << 16, 0);
223 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
224 				   VID_PLL_PRESET, 0);
225 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
226 				   0x7fff, 0);
227 
228 		/* Setup sel and val */
229 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
230 				   3 << 16, shift_sel << 16);
231 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
232 				   VID_PLL_PRESET, VID_PLL_PRESET);
233 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
234 				   0x7fff, shift_val);
235 
236 		regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
237 				   VID_PLL_PRESET, 0);
238 	}
239 
240 	/* Enable the vid_pll output clock */
241 	regmap_update_bits(priv->hhi, HHI_VID_PLL_CLK_DIV,
242 				VID_PLL_EN, VID_PLL_EN);
243 }
244 
245 /*
246  * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
247  *
248  * TOFIX: Refactor into table to also handle HDMI frequency and paths
249  */
250 static void meson_venci_cvbs_clock_config(struct meson_drm *priv)
251 {
252 	unsigned int val;
253 
254 	/* Setup PLL to output 1.485GHz */
255 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
256 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x5800023d);
257 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00404e00);
258 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
259 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
260 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
261 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
262 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4800023d);
263 
264 		/* Poll for lock bit */
265 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
266 					 (val & HDMI_PLL_LOCK), 10, 0);
267 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
268 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
269 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x4000027b);
270 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb300);
271 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0xa6212844);
272 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
273 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
274 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
275 
276 		/* Reset PLL */
277 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
278 					HDMI_PLL_RESET, HDMI_PLL_RESET);
279 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
280 					HDMI_PLL_RESET, 0);
281 
282 		/* Poll for lock bit */
283 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
284 					 (val & HDMI_PLL_LOCK), 10, 0);
285 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
286 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
287 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x00010000);
288 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
289 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x6a28dc00);
290 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290);
291 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
292 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x56540000);
293 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x3a0504f7);
294 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x1a0504f7);
295 
296 		/* Poll for lock bit */
297 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
298 			((val & HDMI_PLL_LOCK_G12A) == HDMI_PLL_LOCK_G12A),
299 			10, 0);
300 	}
301 
302 	/* Disable VCLK2 */
303 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
304 
305 	/* Setup vid_pll to /1 */
306 	meson_vid_pll_set(priv, VID_PLL_DIV_1);
307 
308 	/* Setup the VCLK2 divider value to achieve 27MHz */
309 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
310 				VCLK2_DIV_MASK, (55 - 1));
311 
312 	/* select vid_pll for vclk2 */
313 	if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
314 		regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
315 					VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
316 	else
317 		regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
318 					VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
319 
320 	/* enable vclk2 gate */
321 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
322 
323 	/* select vclk_div1 for enci */
324 	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
325 				CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
326 	/* select vclk_div1 for vdac */
327 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
328 				CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
329 
330 	/* release vclk2_div_reset and enable vclk2_div */
331 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
332 				VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
333 
334 	/* enable vclk2_div1 gate */
335 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
336 				VCLK2_DIV1_EN, VCLK2_DIV1_EN);
337 
338 	/* reset vclk2 */
339 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
340 				VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
341 	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
342 				VCLK2_SOFT_RESET, 0);
343 
344 	/* enable enci_clk */
345 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
346 				CTS_ENCI_EN, CTS_ENCI_EN);
347 	/* enable vdac_clk */
348 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
349 				CTS_VDAC_EN, CTS_VDAC_EN);
350 }
351 
352 enum {
353 /* PLL	O1 O2 O3 VP DV     EN TX */
354 /* 4320 /4 /4 /1 /5 /1  => /2 /2 */
355 	MESON_VCLK_HDMI_ENCI_54000 = 0,
356 /* 4320 /4 /4 /1 /5 /1  => /1 /2 */
357 	MESON_VCLK_HDMI_DDR_54000,
358 /* 2970 /4 /1 /1 /5 /1  => /1 /2 */
359 	MESON_VCLK_HDMI_DDR_148500,
360 /* 2970 /2 /2 /2 /5 /1  => /1 /1 */
361 	MESON_VCLK_HDMI_74250,
362 /* 2970 /1 /2 /2 /5 /1  => /1 /1 */
363 	MESON_VCLK_HDMI_148500,
364 /* 2970 /1 /1 /1 /5 /2  => /1 /1 */
365 	MESON_VCLK_HDMI_297000,
366 /* 5940 /1 /1 /2 /5 /1  => /1 /1 */
367 	MESON_VCLK_HDMI_594000
368 };
369 
370 struct meson_vclk_params {
371 	unsigned int pixel_freq;
372 	unsigned int pll_base_freq;
373 	unsigned int pll_od1;
374 	unsigned int pll_od2;
375 	unsigned int pll_od3;
376 	unsigned int vid_pll_div;
377 	unsigned int vclk_div;
378 } params[] = {
379 	[MESON_VCLK_HDMI_ENCI_54000] = {
380 		.pixel_freq = 54000,
381 		.pll_base_freq = 4320000,
382 		.pll_od1 = 4,
383 		.pll_od2 = 4,
384 		.pll_od3 = 1,
385 		.vid_pll_div = VID_PLL_DIV_5,
386 		.vclk_div = 1,
387 	},
388 	[MESON_VCLK_HDMI_DDR_54000] = {
389 		.pixel_freq = 54000,
390 		.pll_base_freq = 4320000,
391 		.pll_od1 = 4,
392 		.pll_od2 = 4,
393 		.pll_od3 = 1,
394 		.vid_pll_div = VID_PLL_DIV_5,
395 		.vclk_div = 1,
396 	},
397 	[MESON_VCLK_HDMI_DDR_148500] = {
398 		.pixel_freq = 148500,
399 		.pll_base_freq = 2970000,
400 		.pll_od1 = 4,
401 		.pll_od2 = 1,
402 		.pll_od3 = 1,
403 		.vid_pll_div = VID_PLL_DIV_5,
404 		.vclk_div = 1,
405 	},
406 	[MESON_VCLK_HDMI_74250] = {
407 		.pixel_freq = 74250,
408 		.pll_base_freq = 2970000,
409 		.pll_od1 = 2,
410 		.pll_od2 = 2,
411 		.pll_od3 = 2,
412 		.vid_pll_div = VID_PLL_DIV_5,
413 		.vclk_div = 1,
414 	},
415 	[MESON_VCLK_HDMI_148500] = {
416 		.pixel_freq = 148500,
417 		.pll_base_freq = 2970000,
418 		.pll_od1 = 1,
419 		.pll_od2 = 2,
420 		.pll_od3 = 2,
421 		.vid_pll_div = VID_PLL_DIV_5,
422 		.vclk_div = 1,
423 	},
424 	[MESON_VCLK_HDMI_297000] = {
425 		.pixel_freq = 297000,
426 		.pll_base_freq = 5940000,
427 		.pll_od1 = 2,
428 		.pll_od2 = 1,
429 		.pll_od3 = 1,
430 		.vid_pll_div = VID_PLL_DIV_5,
431 		.vclk_div = 2,
432 	},
433 	[MESON_VCLK_HDMI_594000] = {
434 		.pixel_freq = 594000,
435 		.pll_base_freq = 5940000,
436 		.pll_od1 = 1,
437 		.pll_od2 = 1,
438 		.pll_od3 = 2,
439 		.vid_pll_div = VID_PLL_DIV_5,
440 		.vclk_div = 1,
441 	},
442 	{ /* sentinel */ },
443 };
444 
445 static inline unsigned int pll_od_to_reg(unsigned int od)
446 {
447 	switch (od) {
448 	case 1:
449 		return 0;
450 	case 2:
451 		return 1;
452 	case 4:
453 		return 2;
454 	case 8:
455 		return 3;
456 	}
457 
458 	/* Invalid */
459 	return 0;
460 }
461 
462 void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
463 			       unsigned int frac, unsigned int od1,
464 			       unsigned int od2, unsigned int od3)
465 {
466 	unsigned int val;
467 
468 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
469 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x58000200 | m);
470 		if (frac)
471 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
472 				     0x00004000 | frac);
473 		else
474 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2,
475 				     0x00000000);
476 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
477 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x801da72c);
478 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x71486980);
479 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x00000e55);
480 
481 		/* Enable and unreset */
482 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
483 				   0x7 << 28, 0x4 << 28);
484 
485 		/* Poll for lock bit */
486 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
487 					 val, (val & HDMI_PLL_LOCK), 10, 0);
488 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
489 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
490 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x40000200 | m);
491 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
492 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x860f30c4);
493 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
494 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x001fa729);
495 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x01a31500);
496 
497 		/* Reset PLL */
498 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
499 				HDMI_PLL_RESET, HDMI_PLL_RESET);
500 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
501 				HDMI_PLL_RESET, 0);
502 
503 		/* Poll for lock bit */
504 		regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL, val,
505 				(val & HDMI_PLL_LOCK), 10, 0);
506 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
507 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
508 
509 		/* Enable and reset */
510 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
511 				   0x3 << 28, 0x3 << 28);
512 
513 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL2, frac);
514 		regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL3, 0x00000000);
515 
516 		/* G12A HDMI PLL Needs specific parameters for 5.4GHz */
517 		if (m >= 0xf7) {
518 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0xea68dc00);
519 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290);
520 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
521 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000);
522 		} else {
523 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0x0a691c00);
524 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x33771290);
525 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39270000);
526 			regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x50540000);
527 		}
528 
529 		do {
530 			/* Reset PLL */
531 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
532 					HDMI_PLL_RESET_G12A, HDMI_PLL_RESET_G12A);
533 
534 			/* UN-Reset PLL */
535 			regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
536 					HDMI_PLL_RESET_G12A, 0);
537 
538 			/* Poll for lock bits */
539 			if (!regmap_read_poll_timeout(priv->hhi,
540 						      HHI_HDMI_PLL_CNTL, val,
541 						      ((val & HDMI_PLL_LOCK_G12A)
542 						        == HDMI_PLL_LOCK_G12A),
543 						      10, 100))
544 				break;
545 		} while(1);
546 	}
547 
548 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
549 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
550 				3 << 16, pll_od_to_reg(od1) << 16);
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 << 21, pll_od_to_reg(od1) << 21);
555 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
556 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
557 				3 << 16, pll_od_to_reg(od1) << 16);
558 
559 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
560 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
561 				3 << 22, pll_od_to_reg(od2) << 22);
562 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
563 		 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
564 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
565 				3 << 23, pll_od_to_reg(od2) << 23);
566 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
567 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
568 				3 << 18, pll_od_to_reg(od2) << 18);
569 
570 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
571 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL2,
572 				3 << 18, pll_od_to_reg(od3) << 18);
573 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
574 		 meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu"))
575 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL3,
576 				3 << 19, pll_od_to_reg(od3) << 19);
577 	else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
578 		regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
579 				3 << 20, pll_od_to_reg(od3) << 20);
580 }
581 
582 #define XTAL_FREQ 24000
583 
584 static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
585 					 unsigned int pll_freq)
586 {
587 	/* The GXBB PLL has a /2 pre-multiplier */
588 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu"))
589 		pll_freq /= 2;
590 
591 	return pll_freq / XTAL_FREQ;
592 }
593 
594 #define HDMI_FRAC_MAX_GXBB	4096
595 #define HDMI_FRAC_MAX_GXL	1024
596 #define HDMI_FRAC_MAX_G12A	131072
597 
598 static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv,
599 					    unsigned int m,
600 					    unsigned int pll_freq)
601 {
602 	unsigned int parent_freq = XTAL_FREQ;
603 	unsigned int frac_max = HDMI_FRAC_MAX_GXL;
604 	unsigned int frac_m;
605 	unsigned int frac;
606 
607 	/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
608 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
609 		frac_max = HDMI_FRAC_MAX_GXBB;
610 		parent_freq *= 2;
611 	}
612 
613 	if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
614 		frac_max = HDMI_FRAC_MAX_G12A;
615 
616 	/* We can have a perfect match !*/
617 	if (pll_freq / m == parent_freq &&
618 	    pll_freq % m == 0)
619 		return 0;
620 
621 	frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
622 	frac_m = m * frac_max;
623 	if (frac_m > frac)
624 		return frac_max;
625 	frac -= frac_m;
626 
627 	return min((u16)frac, (u16)(frac_max - 1));
628 }
629 
630 static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
631 					   unsigned int m,
632 					   unsigned int frac)
633 {
634 	if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
635 		/* Empiric supported min/max dividers */
636 		if (m < 53 || m > 123)
637 			return false;
638 		if (frac >= HDMI_FRAC_MAX_GXBB)
639 			return false;
640 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
641 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu") ||
642 		   meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
643 		/* Empiric supported min/max dividers */
644 		if (m < 106 || m > 247)
645 			return false;
646 		if (frac >= HDMI_FRAC_MAX_GXL)
647 			return false;
648 	}
649 
650 	return true;
651 }
652 
653 static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
654 				       unsigned int freq,
655 				       unsigned int *m,
656 				       unsigned int *frac,
657 				       unsigned int *od)
658 {
659 	/* Cycle from /16 to /2 */
660 	for (*od = 16 ; *od > 1 ; *od >>= 1) {
661 		*m = meson_hdmi_pll_get_m(priv, freq * *od);
662 		if (!*m)
663 			continue;
664 		*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
665 
666 		DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n",
667 				 freq, *m, *frac, *od);
668 
669 		if (meson_hdmi_pll_validate_params(priv, *m, *frac))
670 			return true;
671 	}
672 
673 	return false;
674 }
675 
676 /* pll_freq is the frequency after the OD dividers */
677 enum drm_mode_status
678 meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq)
679 {
680 	unsigned int od, m, frac;
681 
682 	/* In DMT mode, path after PLL is always /10 */
683 	freq *= 10;
684 
685 	if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
686 		return MODE_OK;
687 
688 	return MODE_CLOCK_RANGE;
689 }
690 EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
691 
692 /* pll_freq is the frequency after the OD dividers */
693 static void meson_hdmi_pll_generic_set(struct meson_drm *priv,
694 				       unsigned int pll_freq)
695 {
696 	unsigned int od, m, frac, od1, od2, od3;
697 
698 	if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
699 		od3 = 1;
700 		if (od < 4) {
701 			od1 = 2;
702 			od2 = 1;
703 		} else {
704 			od2 = od / 4;
705 			od1 = od / od2;
706 		}
707 
708 		DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
709 				 pll_freq, m, frac, od1, od2, od3);
710 
711 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
712 
713 		return;
714 	}
715 
716 	DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n",
717 		  pll_freq);
718 }
719 
720 enum drm_mode_status
721 meson_vclk_vic_supported_freq(unsigned int freq)
722 {
723 	int i;
724 
725 	DRM_DEBUG_DRIVER("freq = %d\n", freq);
726 
727 	for (i = 0 ; params[i].pixel_freq ; ++i) {
728 		DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n",
729 				 i, params[i].pixel_freq,
730 				 FREQ_1000_1001(params[i].pixel_freq));
731 		/* Match strict frequency */
732 		if (freq == params[i].pixel_freq)
733 			return MODE_OK;
734 		/* Match 1000/1001 variant */
735 		if (freq == FREQ_1000_1001(params[i].pixel_freq))
736 			return MODE_OK;
737 	}
738 
739 	return MODE_CLOCK_RANGE;
740 }
741 EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
742 
743 static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
744 			   unsigned int od1, unsigned int od2, unsigned int od3,
745 			   unsigned int vid_pll_div, unsigned int vclk_div,
746 			   unsigned int hdmi_tx_div, unsigned int venc_div,
747 			   bool hdmi_use_enci, bool vic_alternate_clock)
748 {
749 	unsigned int m = 0, frac = 0;
750 
751 	/* Set HDMI-TX sys clock */
752 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
753 			   CTS_HDMI_SYS_SEL_MASK, 0);
754 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
755 			   CTS_HDMI_SYS_DIV_MASK, 0);
756 	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
757 			   CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
758 
759 	/* Set HDMI PLL rate */
760 	if (!od1 && !od2 && !od3) {
761 		meson_hdmi_pll_generic_set(priv, pll_base_freq);
762 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
763 		switch (pll_base_freq) {
764 		case 2970000:
765 			m = 0x3d;
766 			frac = vic_alternate_clock ? 0xd02 : 0xe00;
767 			break;
768 		case 4320000:
769 			m = vic_alternate_clock ? 0x59 : 0x5a;
770 			frac = vic_alternate_clock ? 0xe8f : 0;
771 			break;
772 		case 5940000:
773 			m = 0x7b;
774 			frac = vic_alternate_clock ? 0xa05 : 0xc00;
775 			break;
776 		}
777 
778 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
779 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
780 		   meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
781 		switch (pll_base_freq) {
782 		case 2970000:
783 			m = 0x7b;
784 			frac = vic_alternate_clock ? 0x281 : 0x300;
785 			break;
786 		case 4320000:
787 			m = vic_alternate_clock ? 0xb3 : 0xb4;
788 			frac = vic_alternate_clock ? 0x347 : 0;
789 			break;
790 		case 5940000:
791 			m = 0xf7;
792 			frac = vic_alternate_clock ? 0x102 : 0x200;
793 			break;
794 		}
795 
796 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
797 	} else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
798 		switch (pll_base_freq) {
799 		case 2970000:
800 			m = 0x7b;
801 			frac = vic_alternate_clock ? 0x140b4 : 0x18000;
802 			break;
803 		case 4320000:
804 			m = vic_alternate_clock ? 0xb3 : 0xb4;
805 			frac = vic_alternate_clock ? 0x1a3ee : 0;
806 			break;
807 		case 5940000:
808 			m = 0xf7;
809 			frac = vic_alternate_clock ? 0x8148 : 0x10000;
810 			break;
811 		}
812 
813 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
814 	}
815 
816 	/* Setup vid_pll divider */
817 	meson_vid_pll_set(priv, vid_pll_div);
818 
819 	/* Set VCLK div */
820 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
821 			   VCLK_SEL_MASK, 0);
822 	regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
823 			   VCLK_DIV_MASK, vclk_div - 1);
824 
825 	/* Set HDMI-TX source */
826 	switch (hdmi_tx_div) {
827 	case 1:
828 		/* enable vclk_div1 gate */
829 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
830 				   VCLK_DIV1_EN, VCLK_DIV1_EN);
831 
832 		/* select vclk_div1 for HDMI-TX */
833 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
834 				   HDMI_TX_PIXEL_SEL_MASK, 0);
835 		break;
836 	case 2:
837 		/* enable vclk_div2 gate */
838 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
839 				   VCLK_DIV2_EN, VCLK_DIV2_EN);
840 
841 		/* select vclk_div2 for HDMI-TX */
842 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
843 			HDMI_TX_PIXEL_SEL_MASK, 1 << HDMI_TX_PIXEL_SEL_SHIFT);
844 		break;
845 	case 4:
846 		/* enable vclk_div4 gate */
847 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
848 				   VCLK_DIV4_EN, VCLK_DIV4_EN);
849 
850 		/* select vclk_div4 for HDMI-TX */
851 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
852 			HDMI_TX_PIXEL_SEL_MASK, 2 << HDMI_TX_PIXEL_SEL_SHIFT);
853 		break;
854 	case 6:
855 		/* enable vclk_div6 gate */
856 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
857 				   VCLK_DIV6_EN, VCLK_DIV6_EN);
858 
859 		/* select vclk_div6 for HDMI-TX */
860 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
861 			HDMI_TX_PIXEL_SEL_MASK, 3 << HDMI_TX_PIXEL_SEL_SHIFT);
862 		break;
863 	case 12:
864 		/* enable vclk_div12 gate */
865 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
866 				   VCLK_DIV12_EN, VCLK_DIV12_EN);
867 
868 		/* select vclk_div12 for HDMI-TX */
869 		regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL,
870 			HDMI_TX_PIXEL_SEL_MASK, 4 << HDMI_TX_PIXEL_SEL_SHIFT);
871 		break;
872 	}
873 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
874 				   HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
875 
876 	/* Set ENCI/ENCP Source */
877 	switch (venc_div) {
878 	case 1:
879 		/* enable vclk_div1 gate */
880 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
881 				   VCLK_DIV1_EN, VCLK_DIV1_EN);
882 
883 		if (hdmi_use_enci)
884 			/* select vclk_div1 for enci */
885 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
886 					   CTS_ENCI_SEL_MASK, 0);
887 		else
888 			/* select vclk_div1 for encp */
889 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
890 					   CTS_ENCP_SEL_MASK, 0);
891 		break;
892 	case 2:
893 		/* enable vclk_div2 gate */
894 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
895 				   VCLK_DIV2_EN, VCLK_DIV2_EN);
896 
897 		if (hdmi_use_enci)
898 			/* select vclk_div2 for enci */
899 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
900 				CTS_ENCI_SEL_MASK, 1 << CTS_ENCI_SEL_SHIFT);
901 		else
902 			/* select vclk_div2 for encp */
903 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
904 				CTS_ENCP_SEL_MASK, 1 << CTS_ENCP_SEL_SHIFT);
905 		break;
906 	case 4:
907 		/* enable vclk_div4 gate */
908 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
909 				   VCLK_DIV4_EN, VCLK_DIV4_EN);
910 
911 		if (hdmi_use_enci)
912 			/* select vclk_div4 for enci */
913 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
914 				CTS_ENCI_SEL_MASK, 2 << CTS_ENCI_SEL_SHIFT);
915 		else
916 			/* select vclk_div4 for encp */
917 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
918 				CTS_ENCP_SEL_MASK, 2 << CTS_ENCP_SEL_SHIFT);
919 		break;
920 	case 6:
921 		/* enable vclk_div6 gate */
922 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
923 				   VCLK_DIV6_EN, VCLK_DIV6_EN);
924 
925 		if (hdmi_use_enci)
926 			/* select vclk_div6 for enci */
927 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
928 				CTS_ENCI_SEL_MASK, 3 << CTS_ENCI_SEL_SHIFT);
929 		else
930 			/* select vclk_div6 for encp */
931 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
932 				CTS_ENCP_SEL_MASK, 3 << CTS_ENCP_SEL_SHIFT);
933 		break;
934 	case 12:
935 		/* enable vclk_div12 gate */
936 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL,
937 				   VCLK_DIV12_EN, VCLK_DIV12_EN);
938 
939 		if (hdmi_use_enci)
940 			/* select vclk_div12 for enci */
941 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
942 				CTS_ENCI_SEL_MASK, 4 << CTS_ENCI_SEL_SHIFT);
943 		else
944 			/* select vclk_div12 for encp */
945 			regmap_update_bits(priv->hhi, HHI_VID_CLK_DIV,
946 				CTS_ENCP_SEL_MASK, 4 << CTS_ENCP_SEL_SHIFT);
947 		break;
948 	}
949 
950 	if (hdmi_use_enci)
951 		/* Enable ENCI clock gate */
952 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
953 				   CTS_ENCI_EN, CTS_ENCI_EN);
954 	else
955 		/* Enable ENCP clock gate */
956 		regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2,
957 				   CTS_ENCP_EN, CTS_ENCP_EN);
958 
959 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
960 }
961 
962 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
963 		      unsigned int vclk_freq, unsigned int venc_freq,
964 		      unsigned int dac_freq, bool hdmi_use_enci)
965 {
966 	bool vic_alternate_clock = false;
967 	unsigned int freq;
968 	unsigned int hdmi_tx_div;
969 	unsigned int venc_div;
970 
971 	if (target == MESON_VCLK_TARGET_CVBS) {
972 		meson_venci_cvbs_clock_config(priv);
973 		return;
974 	} else if (target == MESON_VCLK_TARGET_DMT) {
975 		/* The DMT clock path is fixed after the PLL:
976 		 * - automatic PLL freq + OD management
977 		 * - vid_pll_div = VID_PLL_DIV_5
978 		 * - vclk_div = 2
979 		 * - hdmi_tx_div = 1
980 		 * - venc_div = 1
981 		 * - encp encoder
982 		 */
983 		meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
984 			       VID_PLL_DIV_5, 2, 1, 1, false, false);
985 		return;
986 	}
987 
988 	hdmi_tx_div = vclk_freq / dac_freq;
989 
990 	if (hdmi_tx_div == 0) {
991 		pr_err("Fatal Error, invalid HDMI-TX freq %d\n",
992 		       dac_freq);
993 		return;
994 	}
995 
996 	venc_div = vclk_freq / venc_freq;
997 
998 	if (venc_div == 0) {
999 		pr_err("Fatal Error, invalid HDMI venc freq %d\n",
1000 		       venc_freq);
1001 		return;
1002 	}
1003 
1004 	for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
1005 		if (vclk_freq == params[freq].pixel_freq ||
1006 		    vclk_freq == FREQ_1000_1001(params[freq].pixel_freq)) {
1007 			if (vclk_freq != params[freq].pixel_freq)
1008 				vic_alternate_clock = true;
1009 			else
1010 				vic_alternate_clock = false;
1011 
1012 			if (freq == MESON_VCLK_HDMI_ENCI_54000 &&
1013 			    !hdmi_use_enci)
1014 				continue;
1015 
1016 			if (freq == MESON_VCLK_HDMI_DDR_54000 &&
1017 			    hdmi_use_enci)
1018 				continue;
1019 
1020 			if (freq == MESON_VCLK_HDMI_DDR_148500 &&
1021 			    dac_freq == vclk_freq)
1022 				continue;
1023 
1024 			if (freq == MESON_VCLK_HDMI_148500 &&
1025 			    dac_freq != vclk_freq)
1026 				continue;
1027 			break;
1028 		}
1029 	}
1030 
1031 	if (!params[freq].pixel_freq) {
1032 		pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq);
1033 		return;
1034 	}
1035 
1036 	meson_vclk_set(priv, params[freq].pll_base_freq,
1037 		       params[freq].pll_od1, params[freq].pll_od2,
1038 		       params[freq].pll_od3, params[freq].vid_pll_div,
1039 		       params[freq].vclk_div, hdmi_tx_div, venc_div,
1040 		       hdmi_use_enci, vic_alternate_clock);
1041 }
1042 EXPORT_SYMBOL_GPL(meson_vclk_setup);
1043