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