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