1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Amlogic Meson Video Processing Unit driver
4  *
5  * Copyright (c) 2018 BayLibre, SAS.
6  * Author: Neil Armstrong <narmstrong@baylibre.com>
7  */
8 
9 #include <edid.h>
10 #include "meson_vpu.h"
11 #include <linux/iopoll.h>
12 #include <linux/math64.h>
13 
14 #define writel_bits(mask, val, addr) \
15 	writel((readl(addr) & ~(mask)) | (val), addr)
16 
17 enum {
18 	MESON_VCLK_TARGET_CVBS = 0,
19 	MESON_VCLK_TARGET_HDMI = 1,
20 	MESON_VCLK_TARGET_DMT = 2,
21 };
22 
23 /* HHI Registers */
24 #define HHI_VID_PLL_CLK_DIV	0x1a0 /* 0x68 offset in data sheet */
25 #define VID_PLL_EN		BIT(19)
26 #define VID_PLL_BYPASS		BIT(18)
27 #define VID_PLL_PRESET		BIT(15)
28 #define HHI_VIID_CLK_DIV	0x128 /* 0x4a offset in data sheet */
29 #define VCLK2_DIV_MASK		0xff
30 #define VCLK2_DIV_EN		BIT(16)
31 #define VCLK2_DIV_RESET		BIT(17)
32 #define CTS_VDAC_SEL_MASK	(0xf << 28)
33 #define CTS_VDAC_SEL_SHIFT	28
34 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
35 #define VCLK2_EN		BIT(19)
36 #define VCLK2_SEL_MASK		(0x7 << 16)
37 #define VCLK2_SEL_SHIFT		16
38 #define VCLK2_SOFT_RESET	BIT(15)
39 #define VCLK2_DIV1_EN		BIT(0)
40 #define HHI_VID_CLK_DIV		0x164 /* 0x59 offset in data sheet */
41 #define VCLK_DIV_MASK		0xff
42 #define VCLK_DIV_EN		BIT(16)
43 #define VCLK_DIV_RESET		BIT(17)
44 #define CTS_ENCP_SEL_MASK	(0xf << 24)
45 #define CTS_ENCP_SEL_SHIFT	24
46 #define CTS_ENCI_SEL_MASK	(0xf << 28)
47 #define CTS_ENCI_SEL_SHIFT	28
48 #define HHI_VID_CLK_CNTL	0x17c /* 0x5f offset in data sheet */
49 #define VCLK_EN			BIT(19)
50 #define VCLK_SEL_MASK		(0x7 << 16)
51 #define VCLK_SEL_SHIFT		16
52 #define VCLK_SOFT_RESET		BIT(15)
53 #define VCLK_DIV1_EN		BIT(0)
54 #define VCLK_DIV2_EN		BIT(1)
55 #define VCLK_DIV4_EN		BIT(2)
56 #define VCLK_DIV6_EN		BIT(3)
57 #define VCLK_DIV12_EN		BIT(4)
58 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
59 #define CTS_ENCI_EN		BIT(0)
60 #define CTS_ENCP_EN		BIT(2)
61 #define CTS_VDAC_EN		BIT(4)
62 #define HDMI_TX_PIXEL_EN	BIT(5)
63 #define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 offset in data sheet */
64 #define HDMI_TX_PIXEL_SEL_MASK	(0xf << 16)
65 #define HDMI_TX_PIXEL_SEL_SHIFT	16
66 #define CTS_HDMI_SYS_SEL_MASK	(0x7 << 9)
67 #define CTS_HDMI_SYS_DIV_MASK	(0x7f)
68 #define CTS_HDMI_SYS_EN		BIT(8)
69 
70 #define HHI_HDMI_PLL_CNTL	0x320 /* 0xc8 offset in data sheet */
71 #define HHI_HDMI_PLL_CNTL2	0x324 /* 0xc9 offset in data sheet */
72 #define HHI_HDMI_PLL_CNTL3	0x328 /* 0xca offset in data sheet */
73 #define HHI_HDMI_PLL_CNTL4	0x32C /* 0xcb offset in data sheet */
74 #define HHI_HDMI_PLL_CNTL5	0x330 /* 0xcc offset in data sheet */
75 #define HHI_HDMI_PLL_CNTL6	0x334 /* 0xcd offset in data sheet */
76 
77 #define HDMI_PLL_RESET		BIT(28)
78 #define HDMI_PLL_LOCK		BIT(31)
79 
80 /* VID PLL Dividers */
81 enum {
82 	VID_PLL_DIV_1 = 0,
83 	VID_PLL_DIV_2,
84 	VID_PLL_DIV_2p5,
85 	VID_PLL_DIV_3,
86 	VID_PLL_DIV_3p5,
87 	VID_PLL_DIV_3p75,
88 	VID_PLL_DIV_4,
89 	VID_PLL_DIV_5,
90 	VID_PLL_DIV_6,
91 	VID_PLL_DIV_6p25,
92 	VID_PLL_DIV_7,
93 	VID_PLL_DIV_7p5,
94 	VID_PLL_DIV_12,
95 	VID_PLL_DIV_14,
96 	VID_PLL_DIV_15,
97 };
98 
meson_vid_pll_set(struct meson_vpu_priv * priv,unsigned int div)99 void meson_vid_pll_set(struct meson_vpu_priv *priv, unsigned int div)
100 {
101 	unsigned int shift_val = 0;
102 	unsigned int shift_sel = 0;
103 
104 	/* Disable vid_pll output clock */
105 	hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_EN, 0);
106 	hhi_update_bits(HHI_VID_PLL_CLK_DIV, VID_PLL_PRESET, 0);
107 
108 	switch (div) {
109 	case VID_PLL_DIV_2:
110 		shift_val = 0x0aaa;
111 		shift_sel = 0;
112 		break;
113 	case VID_PLL_DIV_2p5:
114 		shift_val = 0x5294;
115 		shift_sel = 2;
116 		break;
117 	case VID_PLL_DIV_3:
118 		shift_val = 0x0db6;
119 		shift_sel = 0;
120 		break;
121 	case VID_PLL_DIV_3p5:
122 		shift_val = 0x36cc;
123 		shift_sel = 1;
124 		break;
125 	case VID_PLL_DIV_3p75:
126 		shift_val = 0x6666;
127 		shift_sel = 2;
128 		break;
129 	case VID_PLL_DIV_4:
130 		shift_val = 0x0ccc;
131 		shift_sel = 0;
132 		break;
133 	case VID_PLL_DIV_5:
134 		shift_val = 0x739c;
135 		shift_sel = 2;
136 		break;
137 	case VID_PLL_DIV_6:
138 		shift_val = 0x0e38;
139 		shift_sel = 0;
140 		break;
141 	case VID_PLL_DIV_6p25:
142 		shift_val = 0x0000;
143 		shift_sel = 3;
144 		break;
145 	case VID_PLL_DIV_7:
146 		shift_val = 0x3c78;
147 		shift_sel = 1;
148 		break;
149 	case VID_PLL_DIV_7p5:
150 		shift_val = 0x78f0;
151 		shift_sel = 2;
152 		break;
153 	case VID_PLL_DIV_12:
154 		shift_val = 0x0fc0;
155 		shift_sel = 0;
156 		break;
157 	case VID_PLL_DIV_14:
158 		shift_val = 0x3f80;
159 		shift_sel = 1;
160 		break;
161 	case VID_PLL_DIV_15:
162 		shift_val = 0x7f80;
163 		shift_sel = 2;
164 		break;
165 	}
166 
167 	if (div == VID_PLL_DIV_1) {
168 		/* Enable vid_pll bypass to HDMI pll */
169 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
170 				VID_PLL_BYPASS, VID_PLL_BYPASS);
171 	} else {
172 		/* Disable Bypass */
173 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
174 				VID_PLL_BYPASS, 0);
175 		/* Clear sel */
176 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
177 				3 << 16, 0);
178 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
179 				VID_PLL_PRESET, 0);
180 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
181 				0x7fff, 0);
182 
183 		/* Setup sel and val */
184 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
185 				3 << 16, shift_sel << 16);
186 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
187 				VID_PLL_PRESET, VID_PLL_PRESET);
188 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
189 				0x7fff, shift_val);
190 
191 		hhi_update_bits(HHI_VID_PLL_CLK_DIV,
192 				VID_PLL_PRESET, 0);
193 	}
194 
195 	/* Enable the vid_pll output clock */
196 	hhi_update_bits(HHI_VID_PLL_CLK_DIV,
197 			VID_PLL_EN, VID_PLL_EN);
198 }
199 
200 /*
201  * Setup VCLK2 for 27MHz, and enable clocks for ENCI and VDAC
202  *
203  * TOFIX: Refactor into table to also handle HDMI frequency and paths
204  */
meson_venci_cvbs_clock_config(struct meson_vpu_priv * priv)205 static void meson_venci_cvbs_clock_config(struct meson_vpu_priv *priv)
206 {
207 	unsigned int val;
208 
209 	debug("%s:%d\n", __func__, __LINE__);
210 
211 	/* Setup PLL to output 1.485GHz */
212 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
213 		hhi_write(HHI_HDMI_PLL_CNTL, 0x5800023d);
214 		hhi_write(HHI_HDMI_PLL_CNTL2, 0x00404e00);
215 		hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
216 		hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
217 		hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
218 		hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
219 		hhi_write(HHI_HDMI_PLL_CNTL, 0x4800023d);
220 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
221 		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
222 		hhi_write(HHI_HDMI_PLL_CNTL, 0x4000027b);
223 		hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb300);
224 		hhi_write(HHI_HDMI_PLL_CNTL3, 0xa6212844);
225 		hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c4d000c);
226 		hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
227 		hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
228 
229 		/* Reset PLL */
230 		hhi_update_bits(HHI_HDMI_PLL_CNTL,
231 				HDMI_PLL_RESET, HDMI_PLL_RESET);
232 		hhi_update_bits(HHI_HDMI_PLL_CNTL,
233 				HDMI_PLL_RESET, 0);
234 	}
235 
236 	debug("%s:%d\n", __func__, __LINE__);
237 
238 	/* Poll for lock bit */
239 	readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
240 			   (val & HDMI_PLL_LOCK), 10);
241 
242 	/* Disable VCLK2 */
243 	hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
244 
245 	/* Setup vid_pll to /1 */
246 	meson_vid_pll_set(priv, VID_PLL_DIV_1);
247 
248 	/* Setup the VCLK2 divider value to achieve 27MHz */
249 	hhi_update_bits(HHI_VIID_CLK_DIV,
250 			VCLK2_DIV_MASK, (55 - 1));
251 
252 	/* select vid_pll for vclk2 */
253 	hhi_update_bits(HHI_VIID_CLK_CNTL,
254 			VCLK2_SEL_MASK, (4 << VCLK2_SEL_SHIFT));
255 	/* enable vclk2 gate */
256 	hhi_update_bits(HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
257 
258 	/* select vclk_div1 for enci */
259 	hhi_update_bits(HHI_VID_CLK_DIV,
260 			CTS_ENCI_SEL_MASK, (8 << CTS_ENCI_SEL_SHIFT));
261 	/* select vclk_div1 for vdac */
262 	hhi_update_bits(HHI_VIID_CLK_DIV,
263 			CTS_VDAC_SEL_MASK, (8 << CTS_VDAC_SEL_SHIFT));
264 
265 	/* release vclk2_div_reset and enable vclk2_div */
266 	hhi_update_bits(HHI_VIID_CLK_DIV,
267 			VCLK2_DIV_EN | VCLK2_DIV_RESET, VCLK2_DIV_EN);
268 
269 	/* enable vclk2_div1 gate */
270 	hhi_update_bits(HHI_VIID_CLK_CNTL,
271 			VCLK2_DIV1_EN, VCLK2_DIV1_EN);
272 
273 	/* reset vclk2 */
274 	hhi_update_bits(HHI_VIID_CLK_CNTL,
275 			VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
276 	hhi_update_bits(HHI_VIID_CLK_CNTL,
277 			VCLK2_SOFT_RESET, 0);
278 
279 	/* enable enci_clk */
280 	hhi_update_bits(HHI_VID_CLK_CNTL2,
281 			CTS_ENCI_EN, CTS_ENCI_EN);
282 	/* enable vdac_clk */
283 	hhi_update_bits(HHI_VID_CLK_CNTL2,
284 			CTS_VDAC_EN, CTS_VDAC_EN);
285 
286 	debug("%s:%d\n", __func__, __LINE__);
287 }
288 
289 enum {
290 /* PLL	O1 O2 O3 VP DV     EN TX */
291 /* 4320 /4 /4 /1 /5 /1  => /2 /2 */
292 	MESON_VCLK_HDMI_ENCI_54000 = 1,
293 /* 4320 /4 /4 /1 /5 /1  => /1 /2 */
294 	MESON_VCLK_HDMI_DDR_54000,
295 /* 2970 /4 /1 /1 /5 /1  => /1 /2 */
296 	MESON_VCLK_HDMI_DDR_148500,
297 /* 2970 /2 /2 /2 /5 /1  => /1 /1 */
298 	MESON_VCLK_HDMI_74250,
299 /* 2970 /1 /2 /2 /5 /1  => /1 /1 */
300 	MESON_VCLK_HDMI_148500,
301 /* 2970 /1 /1 /1 /5 /2  => /1 /1 */
302 	MESON_VCLK_HDMI_297000,
303 /* 5940 /1 /1 /2 /5 /1  => /1 /1 */
304 	MESON_VCLK_HDMI_594000
305 };
306 
307 struct meson_vclk_params {
308 	unsigned int pll_base_freq;
309 	unsigned int pll_od1;
310 	unsigned int pll_od2;
311 	unsigned int pll_od3;
312 	unsigned int vid_pll_div;
313 	unsigned int vclk_div;
314 } params[] = {
315 	[MESON_VCLK_HDMI_ENCI_54000] = {
316 		.pll_base_freq = 4320000,
317 		.pll_od1 = 4,
318 		.pll_od2 = 4,
319 		.pll_od3 = 1,
320 		.vid_pll_div = VID_PLL_DIV_5,
321 		.vclk_div = 1,
322 	},
323 	[MESON_VCLK_HDMI_DDR_54000] = {
324 		.pll_base_freq = 4320000,
325 		.pll_od1 = 4,
326 		.pll_od2 = 4,
327 		.pll_od3 = 1,
328 		.vid_pll_div = VID_PLL_DIV_5,
329 		.vclk_div = 1,
330 	},
331 	[MESON_VCLK_HDMI_DDR_148500] = {
332 		.pll_base_freq = 2970000,
333 		.pll_od1 = 4,
334 		.pll_od2 = 1,
335 		.pll_od3 = 1,
336 		.vid_pll_div = VID_PLL_DIV_5,
337 		.vclk_div = 1,
338 	},
339 	[MESON_VCLK_HDMI_74250] = {
340 		.pll_base_freq = 2970000,
341 		.pll_od1 = 2,
342 		.pll_od2 = 2,
343 		.pll_od3 = 2,
344 		.vid_pll_div = VID_PLL_DIV_5,
345 		.vclk_div = 1,
346 	},
347 	[MESON_VCLK_HDMI_148500] = {
348 		.pll_base_freq = 2970000,
349 		.pll_od1 = 1,
350 		.pll_od2 = 2,
351 		.pll_od3 = 2,
352 		.vid_pll_div = VID_PLL_DIV_5,
353 		.vclk_div = 1,
354 	},
355 	[MESON_VCLK_HDMI_297000] = {
356 		.pll_base_freq = 2970000,
357 		.pll_od1 = 1,
358 		.pll_od2 = 1,
359 		.pll_od3 = 1,
360 		.vid_pll_div = VID_PLL_DIV_5,
361 		.vclk_div = 2,
362 	},
363 	[MESON_VCLK_HDMI_594000] = {
364 		.pll_base_freq = 5940000,
365 		.pll_od1 = 1,
366 		.pll_od2 = 1,
367 		.pll_od3 = 2,
368 		.vid_pll_div = VID_PLL_DIV_5,
369 		.vclk_div = 1,
370 	},
371 };
372 
pll_od_to_reg(unsigned int od)373 static inline unsigned int pll_od_to_reg(unsigned int od)
374 {
375 	switch (od) {
376 	case 1:
377 		return 0;
378 	case 2:
379 		return 1;
380 	case 4:
381 		return 2;
382 	case 8:
383 		return 3;
384 	}
385 
386 	/* Invalid */
387 	return 0;
388 }
389 
meson_hdmi_pll_set_params(struct meson_vpu_priv * priv,unsigned int m,unsigned int frac,unsigned int od1,unsigned int od2,unsigned int od3)390 void meson_hdmi_pll_set_params(struct meson_vpu_priv *priv, unsigned int m,
391 			       unsigned int frac, unsigned int od1,
392 			       unsigned int od2, unsigned int od3)
393 {
394 	unsigned int val;
395 
396 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
397 		hhi_write(HHI_HDMI_PLL_CNTL, 0x58000200 | m);
398 		if (frac)
399 			hhi_write(HHI_HDMI_PLL_CNTL2,
400 				  0x00004000 | frac);
401 		else
402 			hhi_write(HHI_HDMI_PLL_CNTL2,
403 				  0x00000000);
404 		hhi_write(HHI_HDMI_PLL_CNTL3, 0x0d5c5091);
405 		hhi_write(HHI_HDMI_PLL_CNTL4, 0x801da72c);
406 		hhi_write(HHI_HDMI_PLL_CNTL5, 0x71486980);
407 		hhi_write(HHI_HDMI_PLL_CNTL6, 0x00000e55);
408 
409 		/* Enable and unreset */
410 		hhi_update_bits(HHI_HDMI_PLL_CNTL,
411 				0x7 << 28, 0x4 << 28);
412 
413 		/* Poll for lock bit */
414 		readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
415 				   (val & HDMI_PLL_LOCK), 10);
416 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
417 		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
418 		hhi_write(HHI_HDMI_PLL_CNTL, 0x40000200 | m);
419 		hhi_write(HHI_HDMI_PLL_CNTL2, 0x800cb000 | frac);
420 		hhi_write(HHI_HDMI_PLL_CNTL3, 0x860f30c4);
421 		hhi_write(HHI_HDMI_PLL_CNTL4, 0x0c8e0000);
422 		hhi_write(HHI_HDMI_PLL_CNTL5, 0x001fa729);
423 		hhi_write(HHI_HDMI_PLL_CNTL6, 0x01a31500);
424 
425 		/* Reset PLL */
426 		hhi_update_bits(HHI_HDMI_PLL_CNTL,
427 				HDMI_PLL_RESET, HDMI_PLL_RESET);
428 		hhi_update_bits(HHI_HDMI_PLL_CNTL,
429 				HDMI_PLL_RESET, 0);
430 
431 		/* Poll for lock bit */
432 		readl_poll_timeout(priv->hhi_base + HHI_HDMI_PLL_CNTL, val,
433 				   (val & HDMI_PLL_LOCK), 10);
434 	}
435 
436 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
437 		hhi_update_bits(HHI_HDMI_PLL_CNTL2,
438 				3 << 16, pll_od_to_reg(od1) << 16);
439 	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
440 		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
441 		hhi_update_bits(HHI_HDMI_PLL_CNTL3,
442 				3 << 21, pll_od_to_reg(od1) << 21);
443 
444 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
445 		hhi_update_bits(HHI_HDMI_PLL_CNTL2,
446 				3 << 22, pll_od_to_reg(od2) << 22);
447 	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
448 		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
449 		hhi_update_bits(HHI_HDMI_PLL_CNTL3,
450 				3 << 23, pll_od_to_reg(od2) << 23);
451 
452 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
453 		hhi_update_bits(HHI_HDMI_PLL_CNTL2,
454 				3 << 18, pll_od_to_reg(od3) << 18);
455 	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
456 		 meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL))
457 		hhi_update_bits(HHI_HDMI_PLL_CNTL3,
458 				3 << 19, pll_od_to_reg(od3) << 19);
459 }
460 
461 #define XTAL_FREQ 24000
462 
meson_hdmi_pll_get_m(struct meson_vpu_priv * priv,unsigned int pll_freq)463 static unsigned int meson_hdmi_pll_get_m(struct meson_vpu_priv *priv,
464 					 unsigned int pll_freq)
465 {
466 	/* The GXBB PLL has a /2 pre-multiplier */
467 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB))
468 		pll_freq /= 2;
469 
470 	return pll_freq / XTAL_FREQ;
471 }
472 
473 #define HDMI_FRAC_MAX_GXBB	4096
474 #define HDMI_FRAC_MAX_GXL	1024
475 
meson_hdmi_pll_get_frac(struct meson_vpu_priv * priv,unsigned int m,unsigned int pll_freq)476 static unsigned int meson_hdmi_pll_get_frac(struct meson_vpu_priv *priv,
477 					    unsigned int m,
478 					    unsigned int pll_freq)
479 {
480 	unsigned int parent_freq = XTAL_FREQ;
481 	unsigned int frac_max = HDMI_FRAC_MAX_GXL;
482 	unsigned int frac_m;
483 	unsigned int frac;
484 
485 	/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */
486 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
487 		frac_max = HDMI_FRAC_MAX_GXBB;
488 		parent_freq *= 2;
489 	}
490 
491 	/* We can have a perfect match !*/
492 	if (pll_freq / m == parent_freq &&
493 	    pll_freq % m == 0)
494 		return 0;
495 
496 	frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq);
497 	frac_m = m * frac_max;
498 	if (frac_m > frac)
499 		return frac_max;
500 	frac -= frac_m;
501 
502 	return min((u16)frac, (u16)(frac_max - 1));
503 }
504 
meson_hdmi_pll_validate_params(struct meson_vpu_priv * priv,unsigned int m,unsigned int frac)505 static bool meson_hdmi_pll_validate_params(struct meson_vpu_priv *priv,
506 					   unsigned int m,
507 					   unsigned int frac)
508 {
509 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
510 		/* Empiric supported min/max dividers */
511 		if (m < 53 || m > 123)
512 			return false;
513 		if (frac >= HDMI_FRAC_MAX_GXBB)
514 			return false;
515 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
516 		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
517 		/* Empiric supported min/max dividers */
518 		if (m < 106 || m > 247)
519 			return false;
520 		if (frac >= HDMI_FRAC_MAX_GXL)
521 			return false;
522 	}
523 
524 	return true;
525 }
526 
meson_hdmi_pll_find_params(struct meson_vpu_priv * priv,unsigned int freq,unsigned int * m,unsigned int * frac,unsigned int * od)527 static bool meson_hdmi_pll_find_params(struct meson_vpu_priv *priv,
528 				       unsigned int freq,
529 				       unsigned int *m,
530 				       unsigned int *frac,
531 				       unsigned int *od)
532 {
533 	/* Cycle from /16 to /2 */
534 	for (*od = 16 ; *od > 1 ; *od >>= 1) {
535 		*m = meson_hdmi_pll_get_m(priv, freq * *od);
536 		if (!*m)
537 			continue;
538 		*frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
539 
540 		debug("PLL params for %dkHz: m=%x frac=%x od=%d\n",
541 		      freq, *m, *frac, *od);
542 
543 		if (meson_hdmi_pll_validate_params(priv, *m, *frac))
544 			return true;
545 	}
546 
547 	return false;
548 }
549 
550 /* pll_freq is the frequency after the OD dividers */
meson_vclk_dmt_supported_freq(struct meson_vpu_priv * priv,unsigned int freq)551 bool meson_vclk_dmt_supported_freq(struct meson_vpu_priv *priv,
552 				   unsigned int freq)
553 {
554 	unsigned int od, m, frac;
555 
556 	/* In DMT mode, path after PLL is always /10 */
557 	freq *= 10;
558 
559 	if (meson_hdmi_pll_find_params(priv, freq, &m, &frac, &od))
560 		return true;
561 
562 	return false;
563 }
564 
565 /* pll_freq is the frequency after the OD dividers */
meson_hdmi_pll_generic_set(struct meson_vpu_priv * priv,unsigned int pll_freq)566 static void meson_hdmi_pll_generic_set(struct meson_vpu_priv *priv,
567 				       unsigned int pll_freq)
568 {
569 	unsigned int od, m, frac, od1, od2, od3;
570 
571 	if (meson_hdmi_pll_find_params(priv, pll_freq, &m, &frac, &od)) {
572 		od3 = 1;
573 		if (od < 4) {
574 			od1 = 2;
575 			od2 = 1;
576 		} else {
577 			od2 = od / 4;
578 			od1 = od / od2;
579 		}
580 
581 		debug("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n",
582 		      pll_freq, m, frac, od1, od2, od3);
583 
584 		meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3);
585 
586 		return;
587 	}
588 
589 	printf("Fatal, unable to find parameters for PLL freq %d\n",
590 	       pll_freq);
591 }
592 
593 static void
meson_vclk_set(struct meson_vpu_priv * priv,unsigned int pll_base_freq,unsigned int od1,unsigned int od2,unsigned int od3,unsigned int vid_pll_div,unsigned int vclk_div,unsigned int hdmi_tx_div,unsigned int venc_div,bool hdmi_use_enci)594 meson_vclk_set(struct meson_vpu_priv *priv, unsigned int pll_base_freq,
595 	       unsigned int od1, unsigned int od2, unsigned int od3,
596 	       unsigned int vid_pll_div, unsigned int vclk_div,
597 	       unsigned int hdmi_tx_div, unsigned int venc_div,
598 	       bool hdmi_use_enci)
599 {
600 	/* Set HDMI-TX sys clock */
601 	hhi_update_bits(HHI_HDMI_CLK_CNTL,
602 			CTS_HDMI_SYS_SEL_MASK, 0);
603 	hhi_update_bits(HHI_HDMI_CLK_CNTL,
604 			CTS_HDMI_SYS_DIV_MASK, 0);
605 	hhi_update_bits(HHI_HDMI_CLK_CNTL,
606 			CTS_HDMI_SYS_EN, CTS_HDMI_SYS_EN);
607 
608 	/* Set HDMI PLL rate */
609 	if (!od1 && !od2 && !od3) {
610 		meson_hdmi_pll_generic_set(priv, pll_base_freq);
611 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) {
612 		switch (pll_base_freq) {
613 		case 2970000:
614 			meson_hdmi_pll_set_params(priv, 0x3d, 0xe00,
615 						  od1, od2, od3);
616 			break;
617 		case 4320000:
618 			meson_hdmi_pll_set_params(priv, 0x5a, 0,
619 						  od1, od2, od3);
620 			break;
621 		case 5940000:
622 			meson_hdmi_pll_set_params(priv, 0x7b, 0xc00,
623 						  od1, od2, od3);
624 			break;
625 		}
626 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
627 		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
628 		switch (pll_base_freq) {
629 		case 2970000:
630 			meson_hdmi_pll_set_params(priv, 0x7b, 0x300,
631 						  od1, od2, od3);
632 			break;
633 		case 4320000:
634 			meson_hdmi_pll_set_params(priv, 0xb4, 0,
635 						  od1, od2, od3);
636 			break;
637 		case 5940000:
638 			meson_hdmi_pll_set_params(priv, 0xf7, 0x200,
639 						  od1, od2, od3);
640 			break;
641 		}
642 	}
643 
644 	/* Setup vid_pll divider */
645 	meson_vid_pll_set(priv, vid_pll_div);
646 
647 	/* Set VCLK div */
648 	hhi_update_bits(HHI_VID_CLK_CNTL,
649 			VCLK_SEL_MASK, 0);
650 	hhi_update_bits(HHI_VID_CLK_DIV,
651 			VCLK_DIV_MASK, vclk_div - 1);
652 
653 	/* Set HDMI-TX source */
654 	switch (hdmi_tx_div) {
655 	case 1:
656 		/* enable vclk_div1 gate */
657 		hhi_update_bits(HHI_VID_CLK_CNTL,
658 				VCLK_DIV1_EN, VCLK_DIV1_EN);
659 
660 		/* select vclk_div1 for HDMI-TX */
661 		hhi_update_bits(HHI_HDMI_CLK_CNTL,
662 				HDMI_TX_PIXEL_SEL_MASK, 0);
663 		break;
664 	case 2:
665 		/* enable vclk_div2 gate */
666 		hhi_update_bits(HHI_VID_CLK_CNTL,
667 				VCLK_DIV2_EN, VCLK_DIV2_EN);
668 
669 		/* select vclk_div2 for HDMI-TX */
670 		hhi_update_bits(HHI_HDMI_CLK_CNTL,
671 				HDMI_TX_PIXEL_SEL_MASK,
672 				1 << HDMI_TX_PIXEL_SEL_SHIFT);
673 		break;
674 	case 4:
675 		/* enable vclk_div4 gate */
676 		hhi_update_bits(HHI_VID_CLK_CNTL,
677 				VCLK_DIV4_EN, VCLK_DIV4_EN);
678 
679 		/* select vclk_div4 for HDMI-TX */
680 		hhi_update_bits(HHI_HDMI_CLK_CNTL,
681 				HDMI_TX_PIXEL_SEL_MASK,
682 				2 << HDMI_TX_PIXEL_SEL_SHIFT);
683 		break;
684 	case 6:
685 		/* enable vclk_div6 gate */
686 		hhi_update_bits(HHI_VID_CLK_CNTL,
687 				VCLK_DIV6_EN, VCLK_DIV6_EN);
688 
689 		/* select vclk_div6 for HDMI-TX */
690 		hhi_update_bits(HHI_HDMI_CLK_CNTL,
691 				HDMI_TX_PIXEL_SEL_MASK,
692 				3 << HDMI_TX_PIXEL_SEL_SHIFT);
693 		break;
694 	case 12:
695 		/* enable vclk_div12 gate */
696 		hhi_update_bits(HHI_VID_CLK_CNTL,
697 				VCLK_DIV12_EN, VCLK_DIV12_EN);
698 
699 		/* select vclk_div12 for HDMI-TX */
700 		hhi_update_bits(HHI_HDMI_CLK_CNTL,
701 				HDMI_TX_PIXEL_SEL_MASK,
702 				4 << HDMI_TX_PIXEL_SEL_SHIFT);
703 		break;
704 	}
705 	hhi_update_bits(HHI_VID_CLK_CNTL2,
706 			HDMI_TX_PIXEL_EN, HDMI_TX_PIXEL_EN);
707 
708 	/* Set ENCI/ENCP Source */
709 	switch (venc_div) {
710 	case 1:
711 		/* enable vclk_div1 gate */
712 		hhi_update_bits(HHI_VID_CLK_CNTL,
713 				VCLK_DIV1_EN, VCLK_DIV1_EN);
714 
715 		if (hdmi_use_enci)
716 			/* select vclk_div1 for enci */
717 			hhi_update_bits(HHI_VID_CLK_DIV,
718 					CTS_ENCI_SEL_MASK, 0);
719 		else
720 			/* select vclk_div1 for encp */
721 			hhi_update_bits(HHI_VID_CLK_DIV,
722 					CTS_ENCP_SEL_MASK, 0);
723 		break;
724 	case 2:
725 		/* enable vclk_div2 gate */
726 		hhi_update_bits(HHI_VID_CLK_CNTL,
727 				VCLK_DIV2_EN, VCLK_DIV2_EN);
728 
729 		if (hdmi_use_enci)
730 			/* select vclk_div2 for enci */
731 			hhi_update_bits(HHI_VID_CLK_DIV,
732 					CTS_ENCI_SEL_MASK,
733 					1 << CTS_ENCI_SEL_SHIFT);
734 		else
735 			/* select vclk_div2 for encp */
736 			hhi_update_bits(HHI_VID_CLK_DIV,
737 					CTS_ENCP_SEL_MASK,
738 					1 << CTS_ENCP_SEL_SHIFT);
739 		break;
740 	case 4:
741 		/* enable vclk_div4 gate */
742 		hhi_update_bits(HHI_VID_CLK_CNTL,
743 				VCLK_DIV4_EN, VCLK_DIV4_EN);
744 
745 		if (hdmi_use_enci)
746 			/* select vclk_div4 for enci */
747 			hhi_update_bits(HHI_VID_CLK_DIV,
748 					CTS_ENCI_SEL_MASK,
749 					2 << CTS_ENCI_SEL_SHIFT);
750 		else
751 			/* select vclk_div4 for encp */
752 			hhi_update_bits(HHI_VID_CLK_DIV,
753 					CTS_ENCP_SEL_MASK,
754 					2 << CTS_ENCP_SEL_SHIFT);
755 		break;
756 	case 6:
757 		/* enable vclk_div6 gate */
758 		hhi_update_bits(HHI_VID_CLK_CNTL,
759 				VCLK_DIV6_EN, VCLK_DIV6_EN);
760 
761 		if (hdmi_use_enci)
762 			/* select vclk_div6 for enci */
763 			hhi_update_bits(HHI_VID_CLK_DIV,
764 					CTS_ENCI_SEL_MASK,
765 					3 << CTS_ENCI_SEL_SHIFT);
766 		else
767 			/* select vclk_div6 for encp */
768 			hhi_update_bits(HHI_VID_CLK_DIV,
769 					CTS_ENCP_SEL_MASK,
770 					3 << CTS_ENCP_SEL_SHIFT);
771 		break;
772 	case 12:
773 		/* enable vclk_div12 gate */
774 		hhi_update_bits(HHI_VID_CLK_CNTL,
775 				VCLK_DIV12_EN, VCLK_DIV12_EN);
776 
777 		if (hdmi_use_enci)
778 			/* select vclk_div12 for enci */
779 			hhi_update_bits(HHI_VID_CLK_DIV,
780 					CTS_ENCI_SEL_MASK,
781 					4 << CTS_ENCI_SEL_SHIFT);
782 		else
783 			/* select vclk_div12 for encp */
784 			hhi_update_bits(HHI_VID_CLK_DIV,
785 					CTS_ENCP_SEL_MASK,
786 					4 << CTS_ENCP_SEL_SHIFT);
787 		break;
788 	}
789 
790 	if (hdmi_use_enci)
791 		/* Enable ENCI clock gate */
792 		hhi_update_bits(HHI_VID_CLK_CNTL2,
793 				CTS_ENCI_EN, CTS_ENCI_EN);
794 	else
795 		/* Enable ENCP clock gate */
796 		hhi_update_bits(HHI_VID_CLK_CNTL2,
797 				CTS_ENCP_EN, CTS_ENCP_EN);
798 
799 	hhi_update_bits(HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
800 }
801 
meson_vclk_setup(struct meson_vpu_priv * priv,unsigned int target,unsigned int vclk_freq,unsigned int venc_freq,unsigned int dac_freq,bool hdmi_use_enci)802 static void meson_vclk_setup(struct meson_vpu_priv *priv, unsigned int target,
803 			     unsigned int vclk_freq, unsigned int venc_freq,
804 			     unsigned int dac_freq, bool hdmi_use_enci)
805 {
806 	unsigned int freq;
807 	unsigned int hdmi_tx_div;
808 	unsigned int venc_div;
809 
810 	if (target == MESON_VCLK_TARGET_CVBS) {
811 		meson_venci_cvbs_clock_config(priv);
812 		return;
813 	} else if (target == MESON_VCLK_TARGET_DMT) {
814 		/* The DMT clock path is fixed after the PLL:
815 		 * - automatic PLL freq + OD management
816 		 * - vid_pll_div = VID_PLL_DIV_5
817 		 * - vclk_div = 2
818 		 * - hdmi_tx_div = 1
819 		 * - venc_div = 1
820 		 * - encp encoder
821 		 */
822 		meson_vclk_set(priv, vclk_freq * 10, 0, 0, 0,
823 			       VID_PLL_DIV_5, 2, 1, 1, false);
824 
825 		return;
826 	}
827 
828 	hdmi_tx_div = vclk_freq / dac_freq;
829 
830 	if (hdmi_tx_div == 0) {
831 		printf("Fatal Error, invalid HDMI-TX freq %d\n",
832 		       dac_freq);
833 		return;
834 	}
835 
836 	venc_div = vclk_freq / venc_freq;
837 
838 	if (venc_div == 0) {
839 		printf("Fatal Error, invalid HDMI venc freq %d\n",
840 		       venc_freq);
841 		return;
842 	}
843 
844 	switch (vclk_freq) {
845 	case 54000:
846 		if (hdmi_use_enci)
847 			freq = MESON_VCLK_HDMI_ENCI_54000;
848 		else
849 			freq = MESON_VCLK_HDMI_DDR_54000;
850 		break;
851 	case 74250:
852 		freq = MESON_VCLK_HDMI_74250;
853 		break;
854 	case 148500:
855 		if (dac_freq != 148500)
856 			freq = MESON_VCLK_HDMI_DDR_148500;
857 		else
858 			freq = MESON_VCLK_HDMI_148500;
859 		break;
860 	case 297000:
861 		freq = MESON_VCLK_HDMI_297000;
862 		break;
863 	case 594000:
864 		freq = MESON_VCLK_HDMI_594000;
865 		break;
866 	default:
867 		printf("Fatal Error, invalid HDMI vclk freq %d\n",
868 		       vclk_freq);
869 		return;
870 	}
871 
872 	meson_vclk_set(priv, params[freq].pll_base_freq,
873 		       params[freq].pll_od1, params[freq].pll_od2,
874 		       params[freq].pll_od3, params[freq].vid_pll_div,
875 		       params[freq].vclk_div, hdmi_tx_div, venc_div,
876 		       hdmi_use_enci);
877 }
878 
meson_vpu_setup_vclk(struct udevice * dev,const struct display_timing * mode,bool is_cvbs)879 void meson_vpu_setup_vclk(struct udevice *dev,
880 			  const struct display_timing *mode, bool is_cvbs)
881 {
882 	struct meson_vpu_priv *priv = dev_get_priv(dev);
883 	unsigned int vclk_freq;
884 
885 	if (is_cvbs)
886 		return meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS,
887 					0, 0, 0, false);
888 
889 	vclk_freq = mode->pixelclock.typ / 1000;
890 
891 	return meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT,
892 				vclk_freq, vclk_freq, vclk_freq, false);
893 }
894