cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

jz4780-cgu.c (20242B)


      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
    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		/*
    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
    789static 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}
    808CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);