xref: /openbmc/linux/drivers/clk/ingenic/jz4780-cgu.c (revision d9e32672)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Ingenic JZ4780 SoC CGU driver
4  *
5  * Copyright (c) 2013-2015 Imagination Technologies
6  * Author: Paul Burton <paul.burton@mips.com>
7  */
8 
9 #include <linux/clk-provider.h>
10 #include <linux/delay.h>
11 #include <linux/io.h>
12 #include <linux/of.h>
13 #include <dt-bindings/clock/jz4780-cgu.h>
14 #include "cgu.h"
15 #include "pm.h"
16 
17 /* CGU register offsets */
18 #define CGU_REG_CLOCKCONTROL	0x00
19 #define CGU_REG_PLLCONTROL	0x0c
20 #define CGU_REG_APLL		0x10
21 #define CGU_REG_MPLL		0x14
22 #define CGU_REG_EPLL		0x18
23 #define CGU_REG_VPLL		0x1c
24 #define CGU_REG_CLKGR0		0x20
25 #define CGU_REG_OPCR		0x24
26 #define CGU_REG_CLKGR1		0x28
27 #define CGU_REG_DDRCDR		0x2c
28 #define CGU_REG_VPUCDR		0x30
29 #define CGU_REG_USBPCR		0x3c
30 #define CGU_REG_USBRDT		0x40
31 #define CGU_REG_USBVBFIL	0x44
32 #define CGU_REG_USBPCR1		0x48
33 #define CGU_REG_LP0CDR		0x54
34 #define CGU_REG_I2SCDR		0x60
35 #define CGU_REG_LP1CDR		0x64
36 #define CGU_REG_MSC0CDR		0x68
37 #define CGU_REG_UHCCDR		0x6c
38 #define CGU_REG_SSICDR		0x74
39 #define CGU_REG_CIMCDR		0x7c
40 #define CGU_REG_PCMCDR		0x84
41 #define CGU_REG_GPUCDR		0x88
42 #define CGU_REG_HDMICDR		0x8c
43 #define CGU_REG_MSC1CDR		0xa4
44 #define CGU_REG_MSC2CDR		0xa8
45 #define CGU_REG_BCHCDR		0xac
46 #define CGU_REG_CLOCKSTATUS	0xd4
47 
48 /* bits within the OPCR register */
49 #define OPCR_SPENDN0		(1 << 7)
50 #define OPCR_SPENDN1		(1 << 6)
51 
52 /* bits within the USBPCR register */
53 #define USBPCR_USB_MODE		BIT(31)
54 #define USBPCR_IDPULLUP_MASK	(0x3 << 28)
55 #define USBPCR_COMMONONN	BIT(25)
56 #define USBPCR_VBUSVLDEXT	BIT(24)
57 #define USBPCR_VBUSVLDEXTSEL	BIT(23)
58 #define USBPCR_POR		BIT(22)
59 #define USBPCR_OTG_DISABLE	BIT(20)
60 #define USBPCR_COMPDISTUNE_MASK	(0x7 << 17)
61 #define USBPCR_OTGTUNE_MASK	(0x7 << 14)
62 #define USBPCR_SQRXTUNE_MASK	(0x7 << 11)
63 #define USBPCR_TXFSLSTUNE_MASK	(0xf << 7)
64 #define USBPCR_TXPREEMPHTUNE	BIT(6)
65 #define USBPCR_TXHSXVTUNE_MASK	(0x3 << 4)
66 #define USBPCR_TXVREFTUNE_MASK	0xf
67 
68 /* bits within the USBPCR1 register */
69 #define USBPCR1_REFCLKSEL_SHIFT	26
70 #define USBPCR1_REFCLKSEL_MASK	(0x3 << USBPCR1_REFCLKSEL_SHIFT)
71 #define USBPCR1_REFCLKSEL_CORE	(0x2 << USBPCR1_REFCLKSEL_SHIFT)
72 #define USBPCR1_REFCLKDIV_SHIFT	24
73 #define USBPCR1_REFCLKDIV_MASK	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
74 #define USBPCR1_REFCLKDIV_19_2	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
75 #define USBPCR1_REFCLKDIV_48	(0x2 << USBPCR1_REFCLKDIV_SHIFT)
76 #define USBPCR1_REFCLKDIV_24	(0x1 << USBPCR1_REFCLKDIV_SHIFT)
77 #define USBPCR1_REFCLKDIV_12	(0x0 << USBPCR1_REFCLKDIV_SHIFT)
78 #define USBPCR1_USB_SEL		BIT(28)
79 #define USBPCR1_WORD_IF0	BIT(19)
80 #define USBPCR1_WORD_IF1	BIT(18)
81 
82 /* bits within the USBRDT register */
83 #define USBRDT_VBFIL_LD_EN	BIT(25)
84 #define USBRDT_USBRDT_MASK	0x7fffff
85 
86 /* bits within the USBVBFIL register */
87 #define USBVBFIL_IDDIGFIL_SHIFT	16
88 #define USBVBFIL_IDDIGFIL_MASK	(0xffff << USBVBFIL_IDDIGFIL_SHIFT)
89 #define USBVBFIL_USBVBFIL_MASK	(0xffff)
90 
91 static struct ingenic_cgu *cgu;
92 
93 static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
94 {
95 	/* we only use CLKCORE, revisit if that ever changes */
96 	return 0;
97 }
98 
99 static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
100 {
101 	unsigned long flags;
102 	u32 usbpcr1;
103 
104 	if (idx > 0)
105 		return -EINVAL;
106 
107 	spin_lock_irqsave(&cgu->lock, flags);
108 
109 	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
110 	usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
111 	/* we only use CLKCORE */
112 	usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
113 	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
114 
115 	spin_unlock_irqrestore(&cgu->lock, flags);
116 	return 0;
117 }
118 
119 static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
120 						unsigned long parent_rate)
121 {
122 	u32 usbpcr1;
123 	unsigned refclk_div;
124 
125 	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
126 	refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
127 
128 	switch (refclk_div) {
129 	case USBPCR1_REFCLKDIV_12:
130 		return 12000000;
131 
132 	case USBPCR1_REFCLKDIV_24:
133 		return 24000000;
134 
135 	case USBPCR1_REFCLKDIV_48:
136 		return 48000000;
137 
138 	case USBPCR1_REFCLKDIV_19_2:
139 		return 19200000;
140 	}
141 
142 	BUG();
143 	return parent_rate;
144 }
145 
146 static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
147 				      unsigned long *parent_rate)
148 {
149 	if (req_rate < 15600000)
150 		return 12000000;
151 
152 	if (req_rate < 21600000)
153 		return 19200000;
154 
155 	if (req_rate < 36000000)
156 		return 24000000;
157 
158 	return 48000000;
159 }
160 
161 static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
162 				   unsigned long parent_rate)
163 {
164 	unsigned long flags;
165 	u32 usbpcr1, div_bits;
166 
167 	switch (req_rate) {
168 	case 12000000:
169 		div_bits = USBPCR1_REFCLKDIV_12;
170 		break;
171 
172 	case 19200000:
173 		div_bits = USBPCR1_REFCLKDIV_19_2;
174 		break;
175 
176 	case 24000000:
177 		div_bits = USBPCR1_REFCLKDIV_24;
178 		break;
179 
180 	case 48000000:
181 		div_bits = USBPCR1_REFCLKDIV_48;
182 		break;
183 
184 	default:
185 		return -EINVAL;
186 	}
187 
188 	spin_lock_irqsave(&cgu->lock, flags);
189 
190 	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
191 	usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
192 	usbpcr1 |= div_bits;
193 	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
194 
195 	spin_unlock_irqrestore(&cgu->lock, flags);
196 	return 0;
197 }
198 
199 static const struct clk_ops jz4780_otg_phy_ops = {
200 	.get_parent = jz4780_otg_phy_get_parent,
201 	.set_parent = jz4780_otg_phy_set_parent,
202 
203 	.recalc_rate = jz4780_otg_phy_recalc_rate,
204 	.round_rate = jz4780_otg_phy_round_rate,
205 	.set_rate = jz4780_otg_phy_set_rate,
206 };
207 
208 static const s8 pll_od_encoding[16] = {
209 	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
210 	0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
211 };
212 
213 static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
214 
215 	/* External clocks */
216 
217 	[JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
218 	[JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
219 
220 	/* PLLs */
221 
222 #define DEF_PLL(name) { \
223 	.reg = CGU_REG_ ## name, \
224 	.m_shift = 19, \
225 	.m_bits = 13, \
226 	.m_offset = 1, \
227 	.n_shift = 13, \
228 	.n_bits = 6, \
229 	.n_offset = 1, \
230 	.od_shift = 9, \
231 	.od_bits = 4, \
232 	.od_max = 16, \
233 	.od_encoding = pll_od_encoding, \
234 	.stable_bit = 6, \
235 	.bypass_bit = 1, \
236 	.enable_bit = 0, \
237 }
238 
239 	[JZ4780_CLK_APLL] = {
240 		"apll", CGU_CLK_PLL,
241 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
242 		.pll = DEF_PLL(APLL),
243 	},
244 
245 	[JZ4780_CLK_MPLL] = {
246 		"mpll", CGU_CLK_PLL,
247 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
248 		.pll = DEF_PLL(MPLL),
249 	},
250 
251 	[JZ4780_CLK_EPLL] = {
252 		"epll", CGU_CLK_PLL,
253 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
254 		.pll = DEF_PLL(EPLL),
255 	},
256 
257 	[JZ4780_CLK_VPLL] = {
258 		"vpll", CGU_CLK_PLL,
259 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
260 		.pll = DEF_PLL(VPLL),
261 	},
262 
263 #undef DEF_PLL
264 
265 	/* Custom (SoC-specific) OTG PHY */
266 
267 	[JZ4780_CLK_OTGPHY] = {
268 		"otg_phy", CGU_CLK_CUSTOM,
269 		.parents = { -1, -1, JZ4780_CLK_EXCLK, -1 },
270 		.custom = { &jz4780_otg_phy_ops },
271 	},
272 
273 	/* Muxes & dividers */
274 
275 	[JZ4780_CLK_SCLKA] = {
276 		"sclk_a", CGU_CLK_MUX,
277 		.parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK,
278 			     JZ4780_CLK_RTCLK },
279 		.mux = { CGU_REG_CLOCKCONTROL, 30, 2 },
280 	},
281 
282 	[JZ4780_CLK_CPUMUX] = {
283 		"cpumux", CGU_CLK_MUX,
284 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
285 			     JZ4780_CLK_EPLL },
286 		.mux = { CGU_REG_CLOCKCONTROL, 28, 2 },
287 	},
288 
289 	[JZ4780_CLK_CPU] = {
290 		"cpu", CGU_CLK_DIV,
291 		.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
292 		.div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
293 	},
294 
295 	[JZ4780_CLK_L2CACHE] = {
296 		"l2cache", CGU_CLK_DIV,
297 		.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
298 		.div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
299 	},
300 
301 	[JZ4780_CLK_AHB0] = {
302 		"ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
303 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
304 			     JZ4780_CLK_EPLL },
305 		.mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
306 		.div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 },
307 	},
308 
309 	[JZ4780_CLK_AHB2PMUX] = {
310 		"ahb2_apb_mux", CGU_CLK_MUX,
311 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
312 			     JZ4780_CLK_RTCLK },
313 		.mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
314 	},
315 
316 	[JZ4780_CLK_AHB2] = {
317 		"ahb2", CGU_CLK_DIV,
318 		.parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
319 		.div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 },
320 	},
321 
322 	[JZ4780_CLK_PCLK] = {
323 		"pclk", CGU_CLK_DIV,
324 		.parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
325 		.div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 },
326 	},
327 
328 	[JZ4780_CLK_DDR] = {
329 		"ddr", CGU_CLK_MUX | CGU_CLK_DIV,
330 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
331 		.mux = { CGU_REG_DDRCDR, 30, 2 },
332 		.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
333 	},
334 
335 	[JZ4780_CLK_VPU] = {
336 		"vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
337 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
338 			     JZ4780_CLK_EPLL, -1 },
339 		.mux = { CGU_REG_VPUCDR, 30, 2 },
340 		.div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 },
341 		.gate = { CGU_REG_CLKGR1, 2 },
342 	},
343 
344 	[JZ4780_CLK_I2SPLL] = {
345 		"i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
346 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 },
347 		.mux = { CGU_REG_I2SCDR, 30, 1 },
348 		.div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 },
349 	},
350 
351 	[JZ4780_CLK_I2S] = {
352 		"i2s", CGU_CLK_MUX,
353 		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 },
354 		.mux = { CGU_REG_I2SCDR, 31, 1 },
355 	},
356 
357 	[JZ4780_CLK_LCD0PIXCLK] = {
358 		"lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
359 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
360 			     JZ4780_CLK_VPLL, -1 },
361 		.mux = { CGU_REG_LP0CDR, 30, 2 },
362 		.div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 },
363 	},
364 
365 	[JZ4780_CLK_LCD1PIXCLK] = {
366 		"lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
367 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
368 			     JZ4780_CLK_VPLL, -1 },
369 		.mux = { CGU_REG_LP1CDR, 30, 2 },
370 		.div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 },
371 	},
372 
373 	[JZ4780_CLK_MSCMUX] = {
374 		"msc_mux", CGU_CLK_MUX,
375 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
376 		.mux = { CGU_REG_MSC0CDR, 30, 2 },
377 	},
378 
379 	[JZ4780_CLK_MSC0] = {
380 		"msc0", CGU_CLK_DIV | CGU_CLK_GATE,
381 		.parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
382 		.div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
383 		.gate = { CGU_REG_CLKGR0, 3 },
384 	},
385 
386 	[JZ4780_CLK_MSC1] = {
387 		"msc1", CGU_CLK_DIV | CGU_CLK_GATE,
388 		.parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
389 		.div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
390 		.gate = { CGU_REG_CLKGR0, 11 },
391 	},
392 
393 	[JZ4780_CLK_MSC2] = {
394 		"msc2", CGU_CLK_DIV | CGU_CLK_GATE,
395 		.parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
396 		.div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 },
397 		.gate = { CGU_REG_CLKGR0, 12 },
398 	},
399 
400 	[JZ4780_CLK_UHC] = {
401 		"uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
402 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
403 			     JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
404 		.mux = { CGU_REG_UHCCDR, 30, 2 },
405 		.div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 },
406 		.gate = { CGU_REG_CLKGR0, 24 },
407 	},
408 
409 	[JZ4780_CLK_SSIPLL] = {
410 		"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
411 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
412 		.mux = { CGU_REG_SSICDR, 30, 1 },
413 		.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
414 	},
415 
416 	[JZ4780_CLK_SSI] = {
417 		"ssi", CGU_CLK_MUX,
418 		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 },
419 		.mux = { CGU_REG_SSICDR, 31, 1 },
420 	},
421 
422 	[JZ4780_CLK_CIMMCLK] = {
423 		"cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
424 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
425 		.mux = { CGU_REG_CIMCDR, 31, 1 },
426 		.div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 },
427 	},
428 
429 	[JZ4780_CLK_PCMPLL] = {
430 		"pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
431 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
432 			     JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
433 		.mux = { CGU_REG_PCMCDR, 29, 2 },
434 		.div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 },
435 	},
436 
437 	[JZ4780_CLK_PCM] = {
438 		"pcm", CGU_CLK_MUX | CGU_CLK_GATE,
439 		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 },
440 		.mux = { CGU_REG_PCMCDR, 31, 1 },
441 		.gate = { CGU_REG_CLKGR1, 3 },
442 	},
443 
444 	[JZ4780_CLK_GPU] = {
445 		"gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
446 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
447 			     JZ4780_CLK_EPLL },
448 		.mux = { CGU_REG_GPUCDR, 30, 2 },
449 		.div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 },
450 		.gate = { CGU_REG_CLKGR1, 4 },
451 	},
452 
453 	[JZ4780_CLK_HDMI] = {
454 		"hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
455 		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
456 			     JZ4780_CLK_VPLL, -1 },
457 		.mux = { CGU_REG_HDMICDR, 30, 2 },
458 		.div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 },
459 		.gate = { CGU_REG_CLKGR1, 9 },
460 	},
461 
462 	[JZ4780_CLK_BCH] = {
463 		"bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
464 		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
465 			     JZ4780_CLK_EPLL },
466 		.mux = { CGU_REG_BCHCDR, 30, 2 },
467 		.div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 },
468 		.gate = { CGU_REG_CLKGR0, 1 },
469 	},
470 
471 	/* Gate-only clocks */
472 
473 	[JZ4780_CLK_NEMC] = {
474 		"nemc", CGU_CLK_GATE,
475 		.parents = { JZ4780_CLK_AHB2, -1, -1, -1 },
476 		.gate = { CGU_REG_CLKGR0, 0 },
477 	},
478 
479 	[JZ4780_CLK_OTG0] = {
480 		"otg0", CGU_CLK_GATE,
481 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
482 		.gate = { CGU_REG_CLKGR0, 2 },
483 	},
484 
485 	[JZ4780_CLK_SSI0] = {
486 		"ssi0", CGU_CLK_GATE,
487 		.parents = { JZ4780_CLK_SSI, -1, -1, -1 },
488 		.gate = { CGU_REG_CLKGR0, 4 },
489 	},
490 
491 	[JZ4780_CLK_SMB0] = {
492 		"smb0", CGU_CLK_GATE,
493 		.parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
494 		.gate = { CGU_REG_CLKGR0, 5 },
495 	},
496 
497 	[JZ4780_CLK_SMB1] = {
498 		"smb1", CGU_CLK_GATE,
499 		.parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
500 		.gate = { CGU_REG_CLKGR0, 6 },
501 	},
502 
503 	[JZ4780_CLK_SCC] = {
504 		"scc", CGU_CLK_GATE,
505 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
506 		.gate = { CGU_REG_CLKGR0, 7 },
507 	},
508 
509 	[JZ4780_CLK_AIC] = {
510 		"aic", CGU_CLK_GATE,
511 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
512 		.gate = { CGU_REG_CLKGR0, 8 },
513 	},
514 
515 	[JZ4780_CLK_TSSI0] = {
516 		"tssi0", CGU_CLK_GATE,
517 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
518 		.gate = { CGU_REG_CLKGR0, 9 },
519 	},
520 
521 	[JZ4780_CLK_OWI] = {
522 		"owi", CGU_CLK_GATE,
523 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
524 		.gate = { CGU_REG_CLKGR0, 10 },
525 	},
526 
527 	[JZ4780_CLK_KBC] = {
528 		"kbc", CGU_CLK_GATE,
529 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
530 		.gate = { CGU_REG_CLKGR0, 13 },
531 	},
532 
533 	[JZ4780_CLK_SADC] = {
534 		"sadc", CGU_CLK_GATE,
535 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
536 		.gate = { CGU_REG_CLKGR0, 14 },
537 	},
538 
539 	[JZ4780_CLK_UART0] = {
540 		"uart0", CGU_CLK_GATE,
541 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
542 		.gate = { CGU_REG_CLKGR0, 15 },
543 	},
544 
545 	[JZ4780_CLK_UART1] = {
546 		"uart1", CGU_CLK_GATE,
547 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
548 		.gate = { CGU_REG_CLKGR0, 16 },
549 	},
550 
551 	[JZ4780_CLK_UART2] = {
552 		"uart2", CGU_CLK_GATE,
553 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
554 		.gate = { CGU_REG_CLKGR0, 17 },
555 	},
556 
557 	[JZ4780_CLK_UART3] = {
558 		"uart3", CGU_CLK_GATE,
559 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
560 		.gate = { CGU_REG_CLKGR0, 18 },
561 	},
562 
563 	[JZ4780_CLK_SSI1] = {
564 		"ssi1", CGU_CLK_GATE,
565 		.parents = { JZ4780_CLK_SSI, -1, -1, -1 },
566 		.gate = { CGU_REG_CLKGR0, 19 },
567 	},
568 
569 	[JZ4780_CLK_SSI2] = {
570 		"ssi2", CGU_CLK_GATE,
571 		.parents = { JZ4780_CLK_SSI, -1, -1, -1 },
572 		.gate = { CGU_REG_CLKGR0, 20 },
573 	},
574 
575 	[JZ4780_CLK_PDMA] = {
576 		"pdma", CGU_CLK_GATE,
577 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
578 		.gate = { CGU_REG_CLKGR0, 21 },
579 	},
580 
581 	[JZ4780_CLK_GPS] = {
582 		"gps", CGU_CLK_GATE,
583 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
584 		.gate = { CGU_REG_CLKGR0, 22 },
585 	},
586 
587 	[JZ4780_CLK_MAC] = {
588 		"mac", CGU_CLK_GATE,
589 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
590 		.gate = { CGU_REG_CLKGR0, 23 },
591 	},
592 
593 	[JZ4780_CLK_SMB2] = {
594 		"smb2", CGU_CLK_GATE,
595 		.parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
596 		.gate = { CGU_REG_CLKGR0, 24 },
597 	},
598 
599 	[JZ4780_CLK_CIM] = {
600 		"cim", CGU_CLK_GATE,
601 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
602 		.gate = { CGU_REG_CLKGR0, 26 },
603 	},
604 
605 	[JZ4780_CLK_LCD] = {
606 		"lcd", CGU_CLK_GATE,
607 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
608 		.gate = { CGU_REG_CLKGR0, 28 },
609 	},
610 
611 	[JZ4780_CLK_TVE] = {
612 		"tve", CGU_CLK_GATE,
613 		.parents = { JZ4780_CLK_LCD, -1, -1, -1 },
614 		.gate = { CGU_REG_CLKGR0, 27 },
615 	},
616 
617 	[JZ4780_CLK_IPU] = {
618 		"ipu", CGU_CLK_GATE,
619 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
620 		.gate = { CGU_REG_CLKGR0, 29 },
621 	},
622 
623 	[JZ4780_CLK_DDR0] = {
624 		"ddr0", CGU_CLK_GATE,
625 		.parents = { JZ4780_CLK_DDR, -1, -1, -1 },
626 		.gate = { CGU_REG_CLKGR0, 30 },
627 	},
628 
629 	[JZ4780_CLK_DDR1] = {
630 		"ddr1", CGU_CLK_GATE,
631 		.parents = { JZ4780_CLK_DDR, -1, -1, -1 },
632 		.gate = { CGU_REG_CLKGR0, 31 },
633 	},
634 
635 	[JZ4780_CLK_SMB3] = {
636 		"smb3", CGU_CLK_GATE,
637 		.parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
638 		.gate = { CGU_REG_CLKGR1, 0 },
639 	},
640 
641 	[JZ4780_CLK_TSSI1] = {
642 		"tssi1", CGU_CLK_GATE,
643 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
644 		.gate = { CGU_REG_CLKGR1, 1 },
645 	},
646 
647 	[JZ4780_CLK_COMPRESS] = {
648 		"compress", CGU_CLK_GATE,
649 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
650 		.gate = { CGU_REG_CLKGR1, 5 },
651 	},
652 
653 	[JZ4780_CLK_AIC1] = {
654 		"aic1", CGU_CLK_GATE,
655 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
656 		.gate = { CGU_REG_CLKGR1, 6 },
657 	},
658 
659 	[JZ4780_CLK_GPVLC] = {
660 		"gpvlc", CGU_CLK_GATE,
661 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
662 		.gate = { CGU_REG_CLKGR1, 7 },
663 	},
664 
665 	[JZ4780_CLK_OTG1] = {
666 		"otg1", CGU_CLK_GATE,
667 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
668 		.gate = { CGU_REG_CLKGR1, 8 },
669 	},
670 
671 	[JZ4780_CLK_UART4] = {
672 		"uart4", CGU_CLK_GATE,
673 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
674 		.gate = { CGU_REG_CLKGR1, 10 },
675 	},
676 
677 	[JZ4780_CLK_AHBMON] = {
678 		"ahb_mon", CGU_CLK_GATE,
679 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
680 		.gate = { CGU_REG_CLKGR1, 11 },
681 	},
682 
683 	[JZ4780_CLK_SMB4] = {
684 		"smb4", CGU_CLK_GATE,
685 		.parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
686 		.gate = { CGU_REG_CLKGR1, 12 },
687 	},
688 
689 	[JZ4780_CLK_DES] = {
690 		"des", CGU_CLK_GATE,
691 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
692 		.gate = { CGU_REG_CLKGR1, 13 },
693 	},
694 
695 	[JZ4780_CLK_X2D] = {
696 		"x2d", CGU_CLK_GATE,
697 		.parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
698 		.gate = { CGU_REG_CLKGR1, 14 },
699 	},
700 
701 	[JZ4780_CLK_CORE1] = {
702 		"core1", CGU_CLK_GATE,
703 		.parents = { JZ4780_CLK_CPU, -1, -1, -1 },
704 		.gate = { CGU_REG_CLKGR1, 15 },
705 	},
706 
707 };
708 
709 static void __init jz4780_cgu_init(struct device_node *np)
710 {
711 	int retval;
712 
713 	cgu = ingenic_cgu_new(jz4780_cgu_clocks,
714 			      ARRAY_SIZE(jz4780_cgu_clocks), np);
715 	if (!cgu) {
716 		pr_err("%s: failed to initialise CGU\n", __func__);
717 		return;
718 	}
719 
720 	retval = ingenic_cgu_register_clocks(cgu);
721 	if (retval) {
722 		pr_err("%s: failed to register CGU Clocks\n", __func__);
723 		return;
724 	}
725 
726 	ingenic_cgu_register_syscore_ops(cgu);
727 }
728 CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
729