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