linux/drivers/clk/ingenic/jz4780-cgu.c
<<
>>
Prefs
   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 \xE5\x91\xA8\xE7\x90\xB0\xE6\x9D\xB0 (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
 103static struct ingenic_cgu *cgu;
 104
 105static 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
 131static 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
 146static 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
 184static 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
 194static 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
 203static 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
 213static 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
 223static 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
 255static const struct clk_ops jz4780_core1_ops = {
 256        .enable = jz4780_core1_enable,
 257};
 258
 259static 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
 264static 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
 774static 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}
 793CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
 794