GNU Linux-libre 6.8.9-gnu
[releases.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/ingenic,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                 /*
345                  * Disabling the CPU clock or any parent clocks will hang the
346                  * system; mark it critical.
347                  */
348                 .flags = CLK_IS_CRITICAL,
349                 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
350                 .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
351         },
352
353         [JZ4780_CLK_L2CACHE] = {
354                 "l2cache", CGU_CLK_DIV,
355                 /*
356                  * The L2 cache clock is critical if caches are enabled and
357                  * disabling it or any parent clocks will hang the system.
358                  */
359                 .flags = CLK_IS_CRITICAL,
360                 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
361                 .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
362         },
363
364         [JZ4780_CLK_AHB0] = {
365                 "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
366                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
367                              JZ4780_CLK_EPLL },
368                 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
369                 .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 },
370         },
371
372         [JZ4780_CLK_AHB2PMUX] = {
373                 "ahb2_apb_mux", CGU_CLK_MUX,
374                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
375                              JZ4780_CLK_RTCLK },
376                 .mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
377         },
378
379         [JZ4780_CLK_AHB2] = {
380                 "ahb2", CGU_CLK_DIV,
381                 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
382                 .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 },
383         },
384
385         [JZ4780_CLK_PCLK] = {
386                 "pclk", CGU_CLK_DIV,
387                 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
388                 .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 },
389         },
390
391         [JZ4780_CLK_DDR] = {
392                 "ddr", CGU_CLK_MUX | CGU_CLK_DIV,
393                 /*
394                  * Disabling DDR clock or its parents will render DRAM
395                  * inaccessible; mark it critical.
396                  */
397                 .flags = CLK_IS_CRITICAL,
398                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
399                 .mux = { CGU_REG_DDRCDR, 30, 2 },
400                 .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
401         },
402
403         [JZ4780_CLK_VPU] = {
404                 "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
405                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
406                              JZ4780_CLK_EPLL, -1 },
407                 .mux = { CGU_REG_VPUCDR, 30, 2 },
408                 .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 },
409                 .gate = { CGU_REG_CLKGR1, 2 },
410         },
411
412         [JZ4780_CLK_I2SPLL] = {
413                 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
414                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 },
415                 .mux = { CGU_REG_I2SCDR, 30, 1 },
416                 .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 },
417         },
418
419         [JZ4780_CLK_I2S] = {
420                 "i2s", CGU_CLK_MUX,
421                 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 },
422                 .mux = { CGU_REG_I2SCDR, 31, 1 },
423         },
424
425         [JZ4780_CLK_LCD0PIXCLK] = {
426                 "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
427                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
428                              JZ4780_CLK_VPLL, -1 },
429                 .mux = { CGU_REG_LP0CDR, 30, 2 },
430                 .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 },
431         },
432
433         [JZ4780_CLK_LCD1PIXCLK] = {
434                 "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
435                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
436                              JZ4780_CLK_VPLL, -1 },
437                 .mux = { CGU_REG_LP1CDR, 30, 2 },
438                 .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 },
439         },
440
441         [JZ4780_CLK_MSCMUX] = {
442                 "msc_mux", CGU_CLK_MUX,
443                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
444                 .mux = { CGU_REG_MSC0CDR, 30, 2 },
445         },
446
447         [JZ4780_CLK_MSC0] = {
448                 "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
449                 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
450                 .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
451                 .gate = { CGU_REG_CLKGR0, 3 },
452         },
453
454         [JZ4780_CLK_MSC1] = {
455                 "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
456                 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
457                 .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
458                 .gate = { CGU_REG_CLKGR0, 11 },
459         },
460
461         [JZ4780_CLK_MSC2] = {
462                 "msc2", CGU_CLK_DIV | CGU_CLK_GATE,
463                 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
464                 .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 },
465                 .gate = { CGU_REG_CLKGR0, 12 },
466         },
467
468         [JZ4780_CLK_UHC] = {
469                 "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
470                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
471                              JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
472                 .mux = { CGU_REG_UHCCDR, 30, 2 },
473                 .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 },
474                 .gate = { CGU_REG_CLKGR0, 24 },
475         },
476
477         [JZ4780_CLK_SSIPLL] = {
478                 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
479                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
480                 .mux = { CGU_REG_SSICDR, 30, 1 },
481                 .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
482         },
483
484         [JZ4780_CLK_SSI] = {
485                 "ssi", CGU_CLK_MUX,
486                 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 },
487                 .mux = { CGU_REG_SSICDR, 31, 1 },
488         },
489
490         [JZ4780_CLK_CIMMCLK] = {
491                 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
492                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
493                 .mux = { CGU_REG_CIMCDR, 31, 1 },
494                 .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 },
495         },
496
497         [JZ4780_CLK_PCMPLL] = {
498                 "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
499                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
500                              JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
501                 .mux = { CGU_REG_PCMCDR, 29, 2 },
502                 .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 },
503         },
504
505         [JZ4780_CLK_PCM] = {
506                 "pcm", CGU_CLK_MUX | CGU_CLK_GATE,
507                 .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 },
508                 .mux = { CGU_REG_PCMCDR, 31, 1 },
509                 .gate = { CGU_REG_CLKGR1, 3 },
510         },
511
512         [JZ4780_CLK_GPU] = {
513                 "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
514                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
515                              JZ4780_CLK_EPLL },
516                 .mux = { CGU_REG_GPUCDR, 30, 2 },
517                 .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 },
518                 .gate = { CGU_REG_CLKGR1, 4 },
519         },
520
521         [JZ4780_CLK_HDMI] = {
522                 "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
523                 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
524                              JZ4780_CLK_VPLL, -1 },
525                 .mux = { CGU_REG_HDMICDR, 30, 2 },
526                 .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 },
527                 .gate = { CGU_REG_CLKGR1, 9 },
528         },
529
530         [JZ4780_CLK_BCH] = {
531                 "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
532                 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
533                              JZ4780_CLK_EPLL },
534                 .mux = { CGU_REG_BCHCDR, 30, 2 },
535                 .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 },
536                 .gate = { CGU_REG_CLKGR0, 1 },
537         },
538
539         [JZ4780_CLK_EXCLK_DIV512] = {
540                 "exclk_div512", CGU_CLK_FIXDIV,
541                 .parents = { JZ4780_CLK_EXCLK },
542                 .fixdiv = { 512 },
543         },
544
545         [JZ4780_CLK_RTC] = {
546                 "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
547                 .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK },
548                 .mux = { CGU_REG_OPCR, 2, 1},
549         },
550
551         /* Gate-only clocks */
552
553         [JZ4780_CLK_NEMC] = {
554                 "nemc", CGU_CLK_GATE,
555                 .parents = { JZ4780_CLK_AHB2, -1, -1, -1 },
556                 .gate = { CGU_REG_CLKGR0, 0 },
557         },
558
559         [JZ4780_CLK_OTG0] = {
560                 "otg0", CGU_CLK_GATE,
561                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
562                 .gate = { CGU_REG_CLKGR0, 2 },
563         },
564
565         [JZ4780_CLK_SSI0] = {
566                 "ssi0", CGU_CLK_GATE,
567                 .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
568                 .gate = { CGU_REG_CLKGR0, 4 },
569         },
570
571         [JZ4780_CLK_SMB0] = {
572                 "smb0", CGU_CLK_GATE,
573                 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
574                 .gate = { CGU_REG_CLKGR0, 5 },
575         },
576
577         [JZ4780_CLK_SMB1] = {
578                 "smb1", CGU_CLK_GATE,
579                 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
580                 .gate = { CGU_REG_CLKGR0, 6 },
581         },
582
583         [JZ4780_CLK_SCC] = {
584                 "scc", CGU_CLK_GATE,
585                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
586                 .gate = { CGU_REG_CLKGR0, 7 },
587         },
588
589         [JZ4780_CLK_AIC] = {
590                 "aic", CGU_CLK_GATE,
591                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
592                 .gate = { CGU_REG_CLKGR0, 8 },
593         },
594
595         [JZ4780_CLK_TSSI0] = {
596                 "tssi0", CGU_CLK_GATE,
597                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
598                 .gate = { CGU_REG_CLKGR0, 9 },
599         },
600
601         [JZ4780_CLK_OWI] = {
602                 "owi", CGU_CLK_GATE,
603                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
604                 .gate = { CGU_REG_CLKGR0, 10 },
605         },
606
607         [JZ4780_CLK_KBC] = {
608                 "kbc", CGU_CLK_GATE,
609                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
610                 .gate = { CGU_REG_CLKGR0, 13 },
611         },
612
613         [JZ4780_CLK_SADC] = {
614                 "sadc", CGU_CLK_GATE,
615                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
616                 .gate = { CGU_REG_CLKGR0, 14 },
617         },
618
619         [JZ4780_CLK_UART0] = {
620                 "uart0", CGU_CLK_GATE,
621                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
622                 .gate = { CGU_REG_CLKGR0, 15 },
623         },
624
625         [JZ4780_CLK_UART1] = {
626                 "uart1", CGU_CLK_GATE,
627                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
628                 .gate = { CGU_REG_CLKGR0, 16 },
629         },
630
631         [JZ4780_CLK_UART2] = {
632                 "uart2", CGU_CLK_GATE,
633                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
634                 .gate = { CGU_REG_CLKGR0, 17 },
635         },
636
637         [JZ4780_CLK_UART3] = {
638                 "uart3", CGU_CLK_GATE,
639                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
640                 .gate = { CGU_REG_CLKGR0, 18 },
641         },
642
643         [JZ4780_CLK_SSI1] = {
644                 "ssi1", CGU_CLK_GATE,
645                 .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
646                 .gate = { CGU_REG_CLKGR0, 19 },
647         },
648
649         [JZ4780_CLK_SSI2] = {
650                 "ssi2", CGU_CLK_GATE,
651                 .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
652                 .gate = { CGU_REG_CLKGR0, 20 },
653         },
654
655         [JZ4780_CLK_PDMA] = {
656                 "pdma", CGU_CLK_GATE,
657                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
658                 .gate = { CGU_REG_CLKGR0, 21 },
659         },
660
661         [JZ4780_CLK_GPS] = {
662                 "gps", CGU_CLK_GATE,
663                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
664                 .gate = { CGU_REG_CLKGR0, 22 },
665         },
666
667         [JZ4780_CLK_MAC] = {
668                 "mac", CGU_CLK_GATE,
669                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
670                 .gate = { CGU_REG_CLKGR0, 23 },
671         },
672
673         [JZ4780_CLK_SMB2] = {
674                 "smb2", CGU_CLK_GATE,
675                 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
676                 .gate = { CGU_REG_CLKGR0, 24 },
677         },
678
679         [JZ4780_CLK_CIM] = {
680                 "cim", CGU_CLK_GATE,
681                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
682                 .gate = { CGU_REG_CLKGR0, 26 },
683         },
684
685         [JZ4780_CLK_LCD] = {
686                 "lcd", CGU_CLK_GATE,
687                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
688                 .gate = { CGU_REG_CLKGR0, 28 },
689         },
690
691         [JZ4780_CLK_TVE] = {
692                 "tve", CGU_CLK_GATE,
693                 .parents = { JZ4780_CLK_LCD, -1, -1, -1 },
694                 .gate = { CGU_REG_CLKGR0, 27 },
695         },
696
697         [JZ4780_CLK_IPU] = {
698                 "ipu", CGU_CLK_GATE,
699                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
700                 .gate = { CGU_REG_CLKGR0, 29 },
701         },
702
703         [JZ4780_CLK_DDR0] = {
704                 "ddr0", CGU_CLK_GATE,
705                 .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
706                 .gate = { CGU_REG_CLKGR0, 30 },
707         },
708
709         [JZ4780_CLK_DDR1] = {
710                 "ddr1", CGU_CLK_GATE,
711                 .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
712                 .gate = { CGU_REG_CLKGR0, 31 },
713         },
714
715         [JZ4780_CLK_SMB3] = {
716                 "smb3", CGU_CLK_GATE,
717                 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
718                 .gate = { CGU_REG_CLKGR1, 0 },
719         },
720
721         [JZ4780_CLK_TSSI1] = {
722                 "tssi1", CGU_CLK_GATE,
723                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
724                 .gate = { CGU_REG_CLKGR1, 1 },
725         },
726
727         [JZ4780_CLK_COMPRESS] = {
728                 "compress", CGU_CLK_GATE,
729                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
730                 .gate = { CGU_REG_CLKGR1, 5 },
731         },
732
733         [JZ4780_CLK_AIC1] = {
734                 "aic1", CGU_CLK_GATE,
735                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
736                 .gate = { CGU_REG_CLKGR1, 6 },
737         },
738
739         [JZ4780_CLK_GPVLC] = {
740                 "gpvlc", CGU_CLK_GATE,
741                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
742                 .gate = { CGU_REG_CLKGR1, 7 },
743         },
744
745         [JZ4780_CLK_OTG1] = {
746                 "otg1", CGU_CLK_GATE,
747                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
748                 .gate = { CGU_REG_CLKGR1, 8 },
749         },
750
751         [JZ4780_CLK_UART4] = {
752                 "uart4", CGU_CLK_GATE,
753                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
754                 .gate = { CGU_REG_CLKGR1, 10 },
755         },
756
757         [JZ4780_CLK_AHBMON] = {
758                 "ahb_mon", CGU_CLK_GATE,
759                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
760                 .gate = { CGU_REG_CLKGR1, 11 },
761         },
762
763         [JZ4780_CLK_SMB4] = {
764                 "smb4", CGU_CLK_GATE,
765                 .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
766                 .gate = { CGU_REG_CLKGR1, 12 },
767         },
768
769         [JZ4780_CLK_DES] = {
770                 "des", CGU_CLK_GATE,
771                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
772                 .gate = { CGU_REG_CLKGR1, 13 },
773         },
774
775         [JZ4780_CLK_X2D] = {
776                 "x2d", CGU_CLK_GATE,
777                 .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
778                 .gate = { CGU_REG_CLKGR1, 14 },
779         },
780
781         [JZ4780_CLK_CORE1] = {
782                 "core1", CGU_CLK_CUSTOM,
783                 .parents = { JZ4780_CLK_CPU, -1, -1, -1 },
784                 .custom = { &jz4780_core1_ops },
785         },
786
787 };
788
789 static void __init jz4780_cgu_init(struct device_node *np)
790 {
791         int retval;
792
793         cgu = ingenic_cgu_new(jz4780_cgu_clocks,
794                               ARRAY_SIZE(jz4780_cgu_clocks), np);
795         if (!cgu) {
796                 pr_err("%s: failed to initialise CGU\n", __func__);
797                 return;
798         }
799
800         retval = ingenic_cgu_register_clocks(cgu);
801         if (retval) {
802                 pr_err("%s: failed to register CGU Clocks\n", __func__);
803                 return;
804         }
805
806         ingenic_cgu_register_syscore_ops(cgu);
807 }
808 CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);