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