Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Ingenic JZ4780 SoC CGU driver
0004  *
0005  * Copyright (c) 2013-2015 Imagination Technologies
0006  * Author: Paul Burton <paul.burton@mips.com>
0007  * Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
0008  */
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/delay.h>
0012 #include <linux/io.h>
0013 #include <linux/iopoll.h>
0014 #include <linux/of.h>
0015 
0016 #include <dt-bindings/clock/ingenic,jz4780-cgu.h>
0017 
0018 #include "cgu.h"
0019 #include "pm.h"
0020 
0021 /* CGU register offsets */
0022 #define CGU_REG_CLOCKCONTROL    0x00
0023 #define CGU_REG_LCR             0x04
0024 #define CGU_REG_APLL            0x10
0025 #define CGU_REG_MPLL            0x14
0026 #define CGU_REG_EPLL            0x18
0027 #define CGU_REG_VPLL            0x1c
0028 #define CGU_REG_CLKGR0          0x20
0029 #define CGU_REG_OPCR            0x24
0030 #define CGU_REG_CLKGR1          0x28
0031 #define CGU_REG_DDRCDR          0x2c
0032 #define CGU_REG_VPUCDR          0x30
0033 #define CGU_REG_USBPCR          0x3c
0034 #define CGU_REG_USBRDT          0x40
0035 #define CGU_REG_USBVBFIL        0x44
0036 #define CGU_REG_USBPCR1         0x48
0037 #define CGU_REG_LP0CDR          0x54
0038 #define CGU_REG_I2SCDR          0x60
0039 #define CGU_REG_LP1CDR          0x64
0040 #define CGU_REG_MSC0CDR         0x68
0041 #define CGU_REG_UHCCDR          0x6c
0042 #define CGU_REG_SSICDR          0x74
0043 #define CGU_REG_CIMCDR          0x7c
0044 #define CGU_REG_PCMCDR          0x84
0045 #define CGU_REG_GPUCDR          0x88
0046 #define CGU_REG_HDMICDR         0x8c
0047 #define CGU_REG_MSC1CDR         0xa4
0048 #define CGU_REG_MSC2CDR         0xa8
0049 #define CGU_REG_BCHCDR          0xac
0050 #define CGU_REG_CLOCKSTATUS     0xd4
0051 
0052 /* bits within the OPCR register */
0053 #define OPCR_SPENDN0            BIT(7)
0054 #define OPCR_SPENDN1            BIT(6)
0055 
0056 /* bits within the USBPCR register */
0057 #define USBPCR_USB_MODE         BIT(31)
0058 #define USBPCR_IDPULLUP_MASK    (0x3 << 28)
0059 #define USBPCR_COMMONONN        BIT(25)
0060 #define USBPCR_VBUSVLDEXT       BIT(24)
0061 #define USBPCR_VBUSVLDEXTSEL    BIT(23)
0062 #define USBPCR_POR              BIT(22)
0063 #define USBPCR_SIDDQ            BIT(21)
0064 #define USBPCR_OTG_DISABLE      BIT(20)
0065 #define USBPCR_COMPDISTUNE_MASK (0x7 << 17)
0066 #define USBPCR_OTGTUNE_MASK     (0x7 << 14)
0067 #define USBPCR_SQRXTUNE_MASK    (0x7 << 11)
0068 #define USBPCR_TXFSLSTUNE_MASK  (0xf << 7)
0069 #define USBPCR_TXPREEMPHTUNE    BIT(6)
0070 #define USBPCR_TXHSXVTUNE_MASK  (0x3 << 4)
0071 #define USBPCR_TXVREFTUNE_MASK  0xf
0072 
0073 /* bits within the USBPCR1 register */
0074 #define USBPCR1_REFCLKSEL_SHIFT 26
0075 #define USBPCR1_REFCLKSEL_MASK  (0x3 << USBPCR1_REFCLKSEL_SHIFT)
0076 #define USBPCR1_REFCLKSEL_CORE  (0x2 << USBPCR1_REFCLKSEL_SHIFT)
0077 #define USBPCR1_REFCLKDIV_SHIFT 24
0078 #define USBPCR1_REFCLKDIV_MASK  (0x3 << USBPCR1_REFCLKDIV_SHIFT)
0079 #define USBPCR1_REFCLKDIV_19_2  (0x3 << USBPCR1_REFCLKDIV_SHIFT)
0080 #define USBPCR1_REFCLKDIV_48    (0x2 << USBPCR1_REFCLKDIV_SHIFT)
0081 #define USBPCR1_REFCLKDIV_24    (0x1 << USBPCR1_REFCLKDIV_SHIFT)
0082 #define USBPCR1_REFCLKDIV_12    (0x0 << USBPCR1_REFCLKDIV_SHIFT)
0083 #define USBPCR1_USB_SEL         BIT(28)
0084 #define USBPCR1_WORD_IF0        BIT(19)
0085 #define USBPCR1_WORD_IF1        BIT(18)
0086 
0087 /* bits within the USBRDT register */
0088 #define USBRDT_VBFIL_LD_EN      BIT(25)
0089 #define USBRDT_USBRDT_MASK      0x7fffff
0090 
0091 /* bits within the USBVBFIL register */
0092 #define USBVBFIL_IDDIGFIL_SHIFT 16
0093 #define USBVBFIL_IDDIGFIL_MASK  (0xffff << USBVBFIL_IDDIGFIL_SHIFT)
0094 #define USBVBFIL_USBVBFIL_MASK  (0xffff)
0095 
0096 /* bits within the LCR register */
0097 #define LCR_PD_SCPU             BIT(31)
0098 #define LCR_SCPUS               BIT(27)
0099 
0100 /* bits within the CLKGR1 register */
0101 #define CLKGR1_CORE1            BIT(15)
0102 
0103 static struct ingenic_cgu *cgu;
0104 
0105 static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
0106                         unsigned long parent_rate)
0107 {
0108     u32 usbpcr1;
0109     unsigned refclk_div;
0110 
0111     usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
0112     refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
0113 
0114     switch (refclk_div) {
0115     case USBPCR1_REFCLKDIV_12:
0116         return 12000000;
0117 
0118     case USBPCR1_REFCLKDIV_24:
0119         return 24000000;
0120 
0121     case USBPCR1_REFCLKDIV_48:
0122         return 48000000;
0123 
0124     case USBPCR1_REFCLKDIV_19_2:
0125         return 19200000;
0126     }
0127 
0128     return parent_rate;
0129 }
0130 
0131 static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
0132                       unsigned long *parent_rate)
0133 {
0134     if (req_rate < 15600000)
0135         return 12000000;
0136 
0137     if (req_rate < 21600000)
0138         return 19200000;
0139 
0140     if (req_rate < 36000000)
0141         return 24000000;
0142 
0143     return 48000000;
0144 }
0145 
0146 static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
0147                    unsigned long parent_rate)
0148 {
0149     unsigned long flags;
0150     u32 usbpcr1, div_bits;
0151 
0152     switch (req_rate) {
0153     case 12000000:
0154         div_bits = USBPCR1_REFCLKDIV_12;
0155         break;
0156 
0157     case 19200000:
0158         div_bits = USBPCR1_REFCLKDIV_19_2;
0159         break;
0160 
0161     case 24000000:
0162         div_bits = USBPCR1_REFCLKDIV_24;
0163         break;
0164 
0165     case 48000000:
0166         div_bits = USBPCR1_REFCLKDIV_48;
0167         break;
0168 
0169     default:
0170         return -EINVAL;
0171     }
0172 
0173     spin_lock_irqsave(&cgu->lock, flags);
0174 
0175     usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
0176     usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
0177     usbpcr1 |= div_bits;
0178     writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
0179 
0180     spin_unlock_irqrestore(&cgu->lock, flags);
0181     return 0;
0182 }
0183 
0184 static int jz4780_otg_phy_enable(struct clk_hw *hw)
0185 {
0186     void __iomem *reg_opcr      = cgu->base + CGU_REG_OPCR;
0187     void __iomem *reg_usbpcr    = cgu->base + CGU_REG_USBPCR;
0188 
0189     writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
0190     writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
0191     return 0;
0192 }
0193 
0194 static void jz4780_otg_phy_disable(struct clk_hw *hw)
0195 {
0196     void __iomem *reg_opcr      = cgu->base + CGU_REG_OPCR;
0197     void __iomem *reg_usbpcr    = cgu->base + CGU_REG_USBPCR;
0198 
0199     writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
0200     writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
0201 }
0202 
0203 static int jz4780_otg_phy_is_enabled(struct clk_hw *hw)
0204 {
0205     void __iomem *reg_opcr      = cgu->base + CGU_REG_OPCR;
0206     void __iomem *reg_usbpcr    = cgu->base + CGU_REG_USBPCR;
0207 
0208     return (readl(reg_opcr) & OPCR_SPENDN0) &&
0209         !(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
0210         !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
0211 }
0212 
0213 static const struct clk_ops jz4780_otg_phy_ops = {
0214     .recalc_rate = jz4780_otg_phy_recalc_rate,
0215     .round_rate = jz4780_otg_phy_round_rate,
0216     .set_rate = jz4780_otg_phy_set_rate,
0217 
0218     .enable     = jz4780_otg_phy_enable,
0219     .disable    = jz4780_otg_phy_disable,
0220     .is_enabled = jz4780_otg_phy_is_enabled,
0221 };
0222 
0223 static int jz4780_core1_enable(struct clk_hw *hw)
0224 {
0225     struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
0226     struct ingenic_cgu *cgu = ingenic_clk->cgu;
0227     const unsigned int timeout = 5000;
0228     unsigned long flags;
0229     int retval;
0230     u32 lcr, clkgr1;
0231 
0232     spin_lock_irqsave(&cgu->lock, flags);
0233 
0234     lcr = readl(cgu->base + CGU_REG_LCR);
0235     lcr &= ~LCR_PD_SCPU;
0236     writel(lcr, cgu->base + CGU_REG_LCR);
0237 
0238     clkgr1 = readl(cgu->base + CGU_REG_CLKGR1);
0239     clkgr1 &= ~CLKGR1_CORE1;
0240     writel(clkgr1, cgu->base + CGU_REG_CLKGR1);
0241 
0242     spin_unlock_irqrestore(&cgu->lock, flags);
0243 
0244     /* wait for the CPU to be powered up */
0245     retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr,
0246                  !(lcr & LCR_SCPUS), 10, timeout);
0247     if (retval == -ETIMEDOUT) {
0248         pr_err("%s: Wait for power up core1 timeout\n", __func__);
0249         return retval;
0250     }
0251 
0252     return 0;
0253 }
0254 
0255 static const struct clk_ops jz4780_core1_ops = {
0256     .enable = jz4780_core1_enable,
0257 };
0258 
0259 static const s8 pll_od_encoding[16] = {
0260     0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0261     0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
0262 };
0263 
0264 static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
0265 
0266     /* External clocks */
0267 
0268     [JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
0269     [JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
0270 
0271     /* PLLs */
0272 
0273 #define DEF_PLL(name) { \
0274     .reg = CGU_REG_ ## name, \
0275     .rate_multiplier = 1, \
0276     .m_shift = 19, \
0277     .m_bits = 13, \
0278     .m_offset = 1, \
0279     .n_shift = 13, \
0280     .n_bits = 6, \
0281     .n_offset = 1, \
0282     .od_shift = 9, \
0283     .od_bits = 4, \
0284     .od_max = 16, \
0285     .od_encoding = pll_od_encoding, \
0286     .stable_bit = 6, \
0287     .bypass_reg = CGU_REG_ ## name, \
0288     .bypass_bit = 1, \
0289     .enable_bit = 0, \
0290 }
0291 
0292     [JZ4780_CLK_APLL] = {
0293         "apll", CGU_CLK_PLL,
0294         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0295         .pll = DEF_PLL(APLL),
0296     },
0297 
0298     [JZ4780_CLK_MPLL] = {
0299         "mpll", CGU_CLK_PLL,
0300         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0301         .pll = DEF_PLL(MPLL),
0302     },
0303 
0304     [JZ4780_CLK_EPLL] = {
0305         "epll", CGU_CLK_PLL,
0306         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0307         .pll = DEF_PLL(EPLL),
0308     },
0309 
0310     [JZ4780_CLK_VPLL] = {
0311         "vpll", CGU_CLK_PLL,
0312         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0313         .pll = DEF_PLL(VPLL),
0314     },
0315 
0316 #undef DEF_PLL
0317 
0318     /* Custom (SoC-specific) OTG PHY */
0319 
0320     [JZ4780_CLK_OTGPHY] = {
0321         "otg_phy", CGU_CLK_CUSTOM,
0322         .parents = { -1, -1, JZ4780_CLK_EXCLK, -1 },
0323         .custom = { &jz4780_otg_phy_ops },
0324     },
0325 
0326     /* Muxes & dividers */
0327 
0328     [JZ4780_CLK_SCLKA] = {
0329         "sclk_a", CGU_CLK_MUX,
0330         .parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK,
0331                  JZ4780_CLK_RTCLK },
0332         .mux = { CGU_REG_CLOCKCONTROL, 30, 2 },
0333     },
0334 
0335     [JZ4780_CLK_CPUMUX] = {
0336         "cpumux", CGU_CLK_MUX,
0337         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0338                  JZ4780_CLK_EPLL },
0339         .mux = { CGU_REG_CLOCKCONTROL, 28, 2 },
0340     },
0341 
0342     [JZ4780_CLK_CPU] = {
0343         "cpu", CGU_CLK_DIV,
0344         /*
0345          * Disabling the CPU clock or any parent clocks will hang the
0346          * system; mark it critical.
0347          */
0348         .flags = CLK_IS_CRITICAL,
0349         .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
0350         .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
0351     },
0352 
0353     [JZ4780_CLK_L2CACHE] = {
0354         "l2cache", CGU_CLK_DIV,
0355         /*
0356          * The L2 cache clock is critical if caches are enabled and
0357          * disabling it or any parent clocks will hang the system.
0358          */
0359         .flags = CLK_IS_CRITICAL,
0360         .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
0361         .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
0362     },
0363 
0364     [JZ4780_CLK_AHB0] = {
0365         "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
0366         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0367                  JZ4780_CLK_EPLL },
0368         .mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
0369         .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 },
0370     },
0371 
0372     [JZ4780_CLK_AHB2PMUX] = {
0373         "ahb2_apb_mux", CGU_CLK_MUX,
0374         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0375                  JZ4780_CLK_RTCLK },
0376         .mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
0377     },
0378 
0379     [JZ4780_CLK_AHB2] = {
0380         "ahb2", CGU_CLK_DIV,
0381         .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
0382         .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 },
0383     },
0384 
0385     [JZ4780_CLK_PCLK] = {
0386         "pclk", CGU_CLK_DIV,
0387         .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
0388         .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 },
0389     },
0390 
0391     [JZ4780_CLK_DDR] = {
0392         "ddr", CGU_CLK_MUX | CGU_CLK_DIV,
0393         /*
0394          * Disabling DDR clock or its parents will render DRAM
0395          * inaccessible; mark it critical.
0396          */
0397         .flags = CLK_IS_CRITICAL,
0398         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
0399         .mux = { CGU_REG_DDRCDR, 30, 2 },
0400         .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
0401     },
0402 
0403     [JZ4780_CLK_VPU] = {
0404         "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
0405         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0406                  JZ4780_CLK_EPLL, -1 },
0407         .mux = { CGU_REG_VPUCDR, 30, 2 },
0408         .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 },
0409         .gate = { CGU_REG_CLKGR1, 2 },
0410     },
0411 
0412     [JZ4780_CLK_I2SPLL] = {
0413         "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
0414         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 },
0415         .mux = { CGU_REG_I2SCDR, 30, 1 },
0416         .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 },
0417     },
0418 
0419     [JZ4780_CLK_I2S] = {
0420         "i2s", CGU_CLK_MUX,
0421         .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 },
0422         .mux = { CGU_REG_I2SCDR, 31, 1 },
0423     },
0424 
0425     [JZ4780_CLK_LCD0PIXCLK] = {
0426         "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
0427         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0428                  JZ4780_CLK_VPLL, -1 },
0429         .mux = { CGU_REG_LP0CDR, 30, 2 },
0430         .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 },
0431     },
0432 
0433     [JZ4780_CLK_LCD1PIXCLK] = {
0434         "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
0435         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0436                  JZ4780_CLK_VPLL, -1 },
0437         .mux = { CGU_REG_LP1CDR, 30, 2 },
0438         .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 },
0439     },
0440 
0441     [JZ4780_CLK_MSCMUX] = {
0442         "msc_mux", CGU_CLK_MUX,
0443         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
0444         .mux = { CGU_REG_MSC0CDR, 30, 2 },
0445     },
0446 
0447     [JZ4780_CLK_MSC0] = {
0448         "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
0449         .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
0450         .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
0451         .gate = { CGU_REG_CLKGR0, 3 },
0452     },
0453 
0454     [JZ4780_CLK_MSC1] = {
0455         "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
0456         .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
0457         .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
0458         .gate = { CGU_REG_CLKGR0, 11 },
0459     },
0460 
0461     [JZ4780_CLK_MSC2] = {
0462         "msc2", CGU_CLK_DIV | CGU_CLK_GATE,
0463         .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
0464         .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 },
0465         .gate = { CGU_REG_CLKGR0, 12 },
0466     },
0467 
0468     [JZ4780_CLK_UHC] = {
0469         "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
0470         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0471                  JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
0472         .mux = { CGU_REG_UHCCDR, 30, 2 },
0473         .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 },
0474         .gate = { CGU_REG_CLKGR0, 24 },
0475     },
0476 
0477     [JZ4780_CLK_SSIPLL] = {
0478         "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
0479         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
0480         .mux = { CGU_REG_SSICDR, 30, 1 },
0481         .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
0482     },
0483 
0484     [JZ4780_CLK_SSI] = {
0485         "ssi", CGU_CLK_MUX,
0486         .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 },
0487         .mux = { CGU_REG_SSICDR, 31, 1 },
0488     },
0489 
0490     [JZ4780_CLK_CIMMCLK] = {
0491         "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
0492         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
0493         .mux = { CGU_REG_CIMCDR, 31, 1 },
0494         .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 },
0495     },
0496 
0497     [JZ4780_CLK_PCMPLL] = {
0498         "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
0499         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0500                  JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
0501         .mux = { CGU_REG_PCMCDR, 29, 2 },
0502         .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 },
0503     },
0504 
0505     [JZ4780_CLK_PCM] = {
0506         "pcm", CGU_CLK_MUX | CGU_CLK_GATE,
0507         .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 },
0508         .mux = { CGU_REG_PCMCDR, 31, 1 },
0509         .gate = { CGU_REG_CLKGR1, 3 },
0510     },
0511 
0512     [JZ4780_CLK_GPU] = {
0513         "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
0514         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0515                  JZ4780_CLK_EPLL },
0516         .mux = { CGU_REG_GPUCDR, 30, 2 },
0517         .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 },
0518         .gate = { CGU_REG_CLKGR1, 4 },
0519     },
0520 
0521     [JZ4780_CLK_HDMI] = {
0522         "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
0523         .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0524                  JZ4780_CLK_VPLL, -1 },
0525         .mux = { CGU_REG_HDMICDR, 30, 2 },
0526         .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 },
0527         .gate = { CGU_REG_CLKGR1, 9 },
0528     },
0529 
0530     [JZ4780_CLK_BCH] = {
0531         "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
0532         .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
0533                  JZ4780_CLK_EPLL },
0534         .mux = { CGU_REG_BCHCDR, 30, 2 },
0535         .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 },
0536         .gate = { CGU_REG_CLKGR0, 1 },
0537     },
0538 
0539     [JZ4780_CLK_EXCLK_DIV512] = {
0540         "exclk_div512", CGU_CLK_FIXDIV,
0541         .parents = { JZ4780_CLK_EXCLK },
0542         .fixdiv = { 512 },
0543     },
0544 
0545     [JZ4780_CLK_RTC] = {
0546         "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
0547         .parents = { JZ4780_CLK_EXCLK_DIV512, JZ4780_CLK_RTCLK },
0548         .mux = { CGU_REG_OPCR, 2, 1},
0549     },
0550 
0551     /* Gate-only clocks */
0552 
0553     [JZ4780_CLK_NEMC] = {
0554         "nemc", CGU_CLK_GATE,
0555         .parents = { JZ4780_CLK_AHB2, -1, -1, -1 },
0556         .gate = { CGU_REG_CLKGR0, 0 },
0557     },
0558 
0559     [JZ4780_CLK_OTG0] = {
0560         "otg0", CGU_CLK_GATE,
0561         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0562         .gate = { CGU_REG_CLKGR0, 2 },
0563     },
0564 
0565     [JZ4780_CLK_SSI0] = {
0566         "ssi0", CGU_CLK_GATE,
0567         .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
0568         .gate = { CGU_REG_CLKGR0, 4 },
0569     },
0570 
0571     [JZ4780_CLK_SMB0] = {
0572         "smb0", CGU_CLK_GATE,
0573         .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
0574         .gate = { CGU_REG_CLKGR0, 5 },
0575     },
0576 
0577     [JZ4780_CLK_SMB1] = {
0578         "smb1", CGU_CLK_GATE,
0579         .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
0580         .gate = { CGU_REG_CLKGR0, 6 },
0581     },
0582 
0583     [JZ4780_CLK_SCC] = {
0584         "scc", CGU_CLK_GATE,
0585         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0586         .gate = { CGU_REG_CLKGR0, 7 },
0587     },
0588 
0589     [JZ4780_CLK_AIC] = {
0590         "aic", CGU_CLK_GATE,
0591         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0592         .gate = { CGU_REG_CLKGR0, 8 },
0593     },
0594 
0595     [JZ4780_CLK_TSSI0] = {
0596         "tssi0", CGU_CLK_GATE,
0597         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0598         .gate = { CGU_REG_CLKGR0, 9 },
0599     },
0600 
0601     [JZ4780_CLK_OWI] = {
0602         "owi", CGU_CLK_GATE,
0603         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0604         .gate = { CGU_REG_CLKGR0, 10 },
0605     },
0606 
0607     [JZ4780_CLK_KBC] = {
0608         "kbc", CGU_CLK_GATE,
0609         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0610         .gate = { CGU_REG_CLKGR0, 13 },
0611     },
0612 
0613     [JZ4780_CLK_SADC] = {
0614         "sadc", CGU_CLK_GATE,
0615         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0616         .gate = { CGU_REG_CLKGR0, 14 },
0617     },
0618 
0619     [JZ4780_CLK_UART0] = {
0620         "uart0", CGU_CLK_GATE,
0621         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0622         .gate = { CGU_REG_CLKGR0, 15 },
0623     },
0624 
0625     [JZ4780_CLK_UART1] = {
0626         "uart1", CGU_CLK_GATE,
0627         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0628         .gate = { CGU_REG_CLKGR0, 16 },
0629     },
0630 
0631     [JZ4780_CLK_UART2] = {
0632         "uart2", CGU_CLK_GATE,
0633         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0634         .gate = { CGU_REG_CLKGR0, 17 },
0635     },
0636 
0637     [JZ4780_CLK_UART3] = {
0638         "uart3", CGU_CLK_GATE,
0639         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0640         .gate = { CGU_REG_CLKGR0, 18 },
0641     },
0642 
0643     [JZ4780_CLK_SSI1] = {
0644         "ssi1", CGU_CLK_GATE,
0645         .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
0646         .gate = { CGU_REG_CLKGR0, 19 },
0647     },
0648 
0649     [JZ4780_CLK_SSI2] = {
0650         "ssi2", CGU_CLK_GATE,
0651         .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
0652         .gate = { CGU_REG_CLKGR0, 20 },
0653     },
0654 
0655     [JZ4780_CLK_PDMA] = {
0656         "pdma", CGU_CLK_GATE,
0657         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0658         .gate = { CGU_REG_CLKGR0, 21 },
0659     },
0660 
0661     [JZ4780_CLK_GPS] = {
0662         "gps", CGU_CLK_GATE,
0663         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0664         .gate = { CGU_REG_CLKGR0, 22 },
0665     },
0666 
0667     [JZ4780_CLK_MAC] = {
0668         "mac", CGU_CLK_GATE,
0669         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0670         .gate = { CGU_REG_CLKGR0, 23 },
0671     },
0672 
0673     [JZ4780_CLK_SMB2] = {
0674         "smb2", CGU_CLK_GATE,
0675         .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
0676         .gate = { CGU_REG_CLKGR0, 24 },
0677     },
0678 
0679     [JZ4780_CLK_CIM] = {
0680         "cim", CGU_CLK_GATE,
0681         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0682         .gate = { CGU_REG_CLKGR0, 26 },
0683     },
0684 
0685     [JZ4780_CLK_LCD] = {
0686         "lcd", CGU_CLK_GATE,
0687         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0688         .gate = { CGU_REG_CLKGR0, 28 },
0689     },
0690 
0691     [JZ4780_CLK_TVE] = {
0692         "tve", CGU_CLK_GATE,
0693         .parents = { JZ4780_CLK_LCD, -1, -1, -1 },
0694         .gate = { CGU_REG_CLKGR0, 27 },
0695     },
0696 
0697     [JZ4780_CLK_IPU] = {
0698         "ipu", CGU_CLK_GATE,
0699         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0700         .gate = { CGU_REG_CLKGR0, 29 },
0701     },
0702 
0703     [JZ4780_CLK_DDR0] = {
0704         "ddr0", CGU_CLK_GATE,
0705         .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
0706         .gate = { CGU_REG_CLKGR0, 30 },
0707     },
0708 
0709     [JZ4780_CLK_DDR1] = {
0710         "ddr1", CGU_CLK_GATE,
0711         .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
0712         .gate = { CGU_REG_CLKGR0, 31 },
0713     },
0714 
0715     [JZ4780_CLK_SMB3] = {
0716         "smb3", CGU_CLK_GATE,
0717         .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
0718         .gate = { CGU_REG_CLKGR1, 0 },
0719     },
0720 
0721     [JZ4780_CLK_TSSI1] = {
0722         "tssi1", CGU_CLK_GATE,
0723         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0724         .gate = { CGU_REG_CLKGR1, 1 },
0725     },
0726 
0727     [JZ4780_CLK_COMPRESS] = {
0728         "compress", CGU_CLK_GATE,
0729         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0730         .gate = { CGU_REG_CLKGR1, 5 },
0731     },
0732 
0733     [JZ4780_CLK_AIC1] = {
0734         "aic1", CGU_CLK_GATE,
0735         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0736         .gate = { CGU_REG_CLKGR1, 6 },
0737     },
0738 
0739     [JZ4780_CLK_GPVLC] = {
0740         "gpvlc", CGU_CLK_GATE,
0741         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0742         .gate = { CGU_REG_CLKGR1, 7 },
0743     },
0744 
0745     [JZ4780_CLK_OTG1] = {
0746         "otg1", CGU_CLK_GATE,
0747         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0748         .gate = { CGU_REG_CLKGR1, 8 },
0749     },
0750 
0751     [JZ4780_CLK_UART4] = {
0752         "uart4", CGU_CLK_GATE,
0753         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0754         .gate = { CGU_REG_CLKGR1, 10 },
0755     },
0756 
0757     [JZ4780_CLK_AHBMON] = {
0758         "ahb_mon", CGU_CLK_GATE,
0759         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0760         .gate = { CGU_REG_CLKGR1, 11 },
0761     },
0762 
0763     [JZ4780_CLK_SMB4] = {
0764         "smb4", CGU_CLK_GATE,
0765         .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
0766         .gate = { CGU_REG_CLKGR1, 12 },
0767     },
0768 
0769     [JZ4780_CLK_DES] = {
0770         "des", CGU_CLK_GATE,
0771         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0772         .gate = { CGU_REG_CLKGR1, 13 },
0773     },
0774 
0775     [JZ4780_CLK_X2D] = {
0776         "x2d", CGU_CLK_GATE,
0777         .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
0778         .gate = { CGU_REG_CLKGR1, 14 },
0779     },
0780 
0781     [JZ4780_CLK_CORE1] = {
0782         "core1", CGU_CLK_CUSTOM,
0783         .parents = { JZ4780_CLK_CPU, -1, -1, -1 },
0784         .custom = { &jz4780_core1_ops },
0785     },
0786 
0787 };
0788 
0789 static void __init jz4780_cgu_init(struct device_node *np)
0790 {
0791     int retval;
0792 
0793     cgu = ingenic_cgu_new(jz4780_cgu_clocks,
0794                   ARRAY_SIZE(jz4780_cgu_clocks), np);
0795     if (!cgu) {
0796         pr_err("%s: failed to initialise CGU\n", __func__);
0797         return;
0798     }
0799 
0800     retval = ingenic_cgu_register_clocks(cgu);
0801     if (retval) {
0802         pr_err("%s: failed to register CGU Clocks\n", __func__);
0803         return;
0804     }
0805 
0806     ingenic_cgu_register_syscore_ops(cgu);
0807 }
0808 CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);