18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * X1830 SoC CGU driver
48c2ecf20Sopenharmony_ci * Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
88c2ecf20Sopenharmony_ci#include <linux/delay.h>
98c2ecf20Sopenharmony_ci#include <linux/io.h>
108c2ecf20Sopenharmony_ci#include <linux/of.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <dt-bindings/clock/x1830-cgu.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include "cgu.h"
158c2ecf20Sopenharmony_ci#include "pm.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci/* CGU register offsets */
188c2ecf20Sopenharmony_ci#define CGU_REG_CPCCR		0x00
198c2ecf20Sopenharmony_ci#define CGU_REG_CPPCR		0x0c
208c2ecf20Sopenharmony_ci#define CGU_REG_APLL		0x10
218c2ecf20Sopenharmony_ci#define CGU_REG_MPLL		0x14
228c2ecf20Sopenharmony_ci#define CGU_REG_CLKGR0		0x20
238c2ecf20Sopenharmony_ci#define CGU_REG_OPCR		0x24
248c2ecf20Sopenharmony_ci#define CGU_REG_CLKGR1		0x28
258c2ecf20Sopenharmony_ci#define CGU_REG_DDRCDR		0x2c
268c2ecf20Sopenharmony_ci#define CGU_REG_USBPCR		0x3c
278c2ecf20Sopenharmony_ci#define CGU_REG_USBRDT		0x40
288c2ecf20Sopenharmony_ci#define CGU_REG_USBVBFIL	0x44
298c2ecf20Sopenharmony_ci#define CGU_REG_USBPCR1		0x48
308c2ecf20Sopenharmony_ci#define CGU_REG_MACCDR		0x54
318c2ecf20Sopenharmony_ci#define CGU_REG_EPLL		0x58
328c2ecf20Sopenharmony_ci#define CGU_REG_I2SCDR		0x60
338c2ecf20Sopenharmony_ci#define CGU_REG_LPCDR		0x64
348c2ecf20Sopenharmony_ci#define CGU_REG_MSC0CDR		0x68
358c2ecf20Sopenharmony_ci#define CGU_REG_I2SCDR1		0x70
368c2ecf20Sopenharmony_ci#define CGU_REG_SSICDR		0x74
378c2ecf20Sopenharmony_ci#define CGU_REG_CIMCDR		0x7c
388c2ecf20Sopenharmony_ci#define CGU_REG_MSC1CDR		0xa4
398c2ecf20Sopenharmony_ci#define CGU_REG_CMP_INTR	0xb0
408c2ecf20Sopenharmony_ci#define CGU_REG_CMP_INTRE	0xb4
418c2ecf20Sopenharmony_ci#define CGU_REG_DRCG		0xd0
428c2ecf20Sopenharmony_ci#define CGU_REG_CPCSR		0xd4
438c2ecf20Sopenharmony_ci#define CGU_REG_VPLL		0xe0
448c2ecf20Sopenharmony_ci#define CGU_REG_MACPHYC		0xe8
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* bits within the OPCR register */
478c2ecf20Sopenharmony_ci#define OPCR_GATE_USBPHYCLK	BIT(23)
488c2ecf20Sopenharmony_ci#define OPCR_SPENDN0		BIT(7)
498c2ecf20Sopenharmony_ci#define OPCR_SPENDN1		BIT(6)
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci/* bits within the USBPCR register */
528c2ecf20Sopenharmony_ci#define USBPCR_SIDDQ		BIT(21)
538c2ecf20Sopenharmony_ci#define USBPCR_OTG_DISABLE	BIT(20)
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic struct ingenic_cgu *cgu;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic int x1830_usb_phy_enable(struct clk_hw *hw)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
608c2ecf20Sopenharmony_ci	void __iomem *reg_usbpcr	= cgu->base + CGU_REG_USBPCR;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
638c2ecf20Sopenharmony_ci	writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
648c2ecf20Sopenharmony_ci	return 0;
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic void x1830_usb_phy_disable(struct clk_hw *hw)
688c2ecf20Sopenharmony_ci{
698c2ecf20Sopenharmony_ci	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
708c2ecf20Sopenharmony_ci	void __iomem *reg_usbpcr	= cgu->base + CGU_REG_USBPCR;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
738c2ecf20Sopenharmony_ci	writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic int x1830_usb_phy_is_enabled(struct clk_hw *hw)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
798c2ecf20Sopenharmony_ci	void __iomem *reg_usbpcr	= cgu->base + CGU_REG_USBPCR;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	return (readl(reg_opcr) & OPCR_SPENDN0) &&
828c2ecf20Sopenharmony_ci		!(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
838c2ecf20Sopenharmony_ci		!(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic const struct clk_ops x1830_otg_phy_ops = {
878c2ecf20Sopenharmony_ci	.enable		= x1830_usb_phy_enable,
888c2ecf20Sopenharmony_ci	.disable	= x1830_usb_phy_disable,
898c2ecf20Sopenharmony_ci	.is_enabled	= x1830_usb_phy_is_enabled,
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic const s8 pll_od_encoding[64] = {
938c2ecf20Sopenharmony_ci	0x0, 0x1,  -1, 0x2,  -1,  -1,  -1, 0x3,
948c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1, 0x4,
958c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
968c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1, 0x5,
978c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
988c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
998c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
1008c2ecf20Sopenharmony_ci	 -1,  -1,  -1,  -1,  -1,  -1,  -1, 0x6,
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/* External clocks */
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	[X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
1088c2ecf20Sopenharmony_ci	[X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* PLLs */
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	[X1830_CLK_APLL] = {
1138c2ecf20Sopenharmony_ci		"apll", CGU_CLK_PLL,
1148c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
1158c2ecf20Sopenharmony_ci		.pll = {
1168c2ecf20Sopenharmony_ci			.reg = CGU_REG_APLL,
1178c2ecf20Sopenharmony_ci			.rate_multiplier = 2,
1188c2ecf20Sopenharmony_ci			.m_shift = 20,
1198c2ecf20Sopenharmony_ci			.m_bits = 9,
1208c2ecf20Sopenharmony_ci			.m_offset = 1,
1218c2ecf20Sopenharmony_ci			.n_shift = 14,
1228c2ecf20Sopenharmony_ci			.n_bits = 6,
1238c2ecf20Sopenharmony_ci			.n_offset = 1,
1248c2ecf20Sopenharmony_ci			.od_shift = 11,
1258c2ecf20Sopenharmony_ci			.od_bits = 3,
1268c2ecf20Sopenharmony_ci			.od_max = 64,
1278c2ecf20Sopenharmony_ci			.od_encoding = pll_od_encoding,
1288c2ecf20Sopenharmony_ci			.bypass_reg = CGU_REG_CPPCR,
1298c2ecf20Sopenharmony_ci			.bypass_bit = 30,
1308c2ecf20Sopenharmony_ci			.enable_bit = 0,
1318c2ecf20Sopenharmony_ci			.stable_bit = 3,
1328c2ecf20Sopenharmony_ci		},
1338c2ecf20Sopenharmony_ci	},
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci	[X1830_CLK_MPLL] = {
1368c2ecf20Sopenharmony_ci		"mpll", CGU_CLK_PLL,
1378c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
1388c2ecf20Sopenharmony_ci		.pll = {
1398c2ecf20Sopenharmony_ci			.reg = CGU_REG_MPLL,
1408c2ecf20Sopenharmony_ci			.rate_multiplier = 2,
1418c2ecf20Sopenharmony_ci			.m_shift = 20,
1428c2ecf20Sopenharmony_ci			.m_bits = 9,
1438c2ecf20Sopenharmony_ci			.m_offset = 1,
1448c2ecf20Sopenharmony_ci			.n_shift = 14,
1458c2ecf20Sopenharmony_ci			.n_bits = 6,
1468c2ecf20Sopenharmony_ci			.n_offset = 1,
1478c2ecf20Sopenharmony_ci			.od_shift = 11,
1488c2ecf20Sopenharmony_ci			.od_bits = 3,
1498c2ecf20Sopenharmony_ci			.od_max = 64,
1508c2ecf20Sopenharmony_ci			.od_encoding = pll_od_encoding,
1518c2ecf20Sopenharmony_ci			.bypass_reg = CGU_REG_CPPCR,
1528c2ecf20Sopenharmony_ci			.bypass_bit = 28,
1538c2ecf20Sopenharmony_ci			.enable_bit = 0,
1548c2ecf20Sopenharmony_ci			.stable_bit = 3,
1558c2ecf20Sopenharmony_ci		},
1568c2ecf20Sopenharmony_ci	},
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	[X1830_CLK_EPLL] = {
1598c2ecf20Sopenharmony_ci		"epll", CGU_CLK_PLL,
1608c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
1618c2ecf20Sopenharmony_ci		.pll = {
1628c2ecf20Sopenharmony_ci			.reg = CGU_REG_EPLL,
1638c2ecf20Sopenharmony_ci			.rate_multiplier = 2,
1648c2ecf20Sopenharmony_ci			.m_shift = 20,
1658c2ecf20Sopenharmony_ci			.m_bits = 9,
1668c2ecf20Sopenharmony_ci			.m_offset = 1,
1678c2ecf20Sopenharmony_ci			.n_shift = 14,
1688c2ecf20Sopenharmony_ci			.n_bits = 6,
1698c2ecf20Sopenharmony_ci			.n_offset = 1,
1708c2ecf20Sopenharmony_ci			.od_shift = 11,
1718c2ecf20Sopenharmony_ci			.od_bits = 3,
1728c2ecf20Sopenharmony_ci			.od_max = 64,
1738c2ecf20Sopenharmony_ci			.od_encoding = pll_od_encoding,
1748c2ecf20Sopenharmony_ci			.bypass_reg = CGU_REG_CPPCR,
1758c2ecf20Sopenharmony_ci			.bypass_bit = 24,
1768c2ecf20Sopenharmony_ci			.enable_bit = 0,
1778c2ecf20Sopenharmony_ci			.stable_bit = 3,
1788c2ecf20Sopenharmony_ci		},
1798c2ecf20Sopenharmony_ci	},
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	[X1830_CLK_VPLL] = {
1828c2ecf20Sopenharmony_ci		"vpll", CGU_CLK_PLL,
1838c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
1848c2ecf20Sopenharmony_ci		.pll = {
1858c2ecf20Sopenharmony_ci			.reg = CGU_REG_VPLL,
1868c2ecf20Sopenharmony_ci			.rate_multiplier = 2,
1878c2ecf20Sopenharmony_ci			.m_shift = 20,
1888c2ecf20Sopenharmony_ci			.m_bits = 9,
1898c2ecf20Sopenharmony_ci			.m_offset = 1,
1908c2ecf20Sopenharmony_ci			.n_shift = 14,
1918c2ecf20Sopenharmony_ci			.n_bits = 6,
1928c2ecf20Sopenharmony_ci			.n_offset = 1,
1938c2ecf20Sopenharmony_ci			.od_shift = 11,
1948c2ecf20Sopenharmony_ci			.od_bits = 3,
1958c2ecf20Sopenharmony_ci			.od_max = 64,
1968c2ecf20Sopenharmony_ci			.od_encoding = pll_od_encoding,
1978c2ecf20Sopenharmony_ci			.bypass_reg = CGU_REG_CPPCR,
1988c2ecf20Sopenharmony_ci			.bypass_bit = 26,
1998c2ecf20Sopenharmony_ci			.enable_bit = 0,
2008c2ecf20Sopenharmony_ci			.stable_bit = 3,
2018c2ecf20Sopenharmony_ci		},
2028c2ecf20Sopenharmony_ci	},
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	/* Custom (SoC-specific) OTG PHY */
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	[X1830_CLK_OTGPHY] = {
2078c2ecf20Sopenharmony_ci		"otg_phy", CGU_CLK_CUSTOM,
2088c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
2098c2ecf20Sopenharmony_ci		.custom = { &x1830_otg_phy_ops },
2108c2ecf20Sopenharmony_ci	},
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	/* Muxes & dividers */
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	[X1830_CLK_SCLKA] = {
2158c2ecf20Sopenharmony_ci		"sclk_a", CGU_CLK_MUX,
2168c2ecf20Sopenharmony_ci		.parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
2178c2ecf20Sopenharmony_ci		.mux = { CGU_REG_CPCCR, 30, 2 },
2188c2ecf20Sopenharmony_ci	},
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	[X1830_CLK_CPUMUX] = {
2218c2ecf20Sopenharmony_ci		"cpu_mux", CGU_CLK_MUX,
2228c2ecf20Sopenharmony_ci		.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
2238c2ecf20Sopenharmony_ci		.mux = { CGU_REG_CPCCR, 28, 2 },
2248c2ecf20Sopenharmony_ci	},
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	[X1830_CLK_CPU] = {
2278c2ecf20Sopenharmony_ci		"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
2288c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
2298c2ecf20Sopenharmony_ci		.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
2308c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 15 },
2318c2ecf20Sopenharmony_ci	},
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	[X1830_CLK_L2CACHE] = {
2348c2ecf20Sopenharmony_ci		"l2cache", CGU_CLK_DIV,
2358c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
2368c2ecf20Sopenharmony_ci		.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
2378c2ecf20Sopenharmony_ci	},
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	[X1830_CLK_AHB0] = {
2408c2ecf20Sopenharmony_ci		"ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
2418c2ecf20Sopenharmony_ci		.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
2428c2ecf20Sopenharmony_ci		.mux = { CGU_REG_CPCCR, 26, 2 },
2438c2ecf20Sopenharmony_ci		.div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
2448c2ecf20Sopenharmony_ci	},
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	[X1830_CLK_AHB2PMUX] = {
2478c2ecf20Sopenharmony_ci		"ahb2_apb_mux", CGU_CLK_MUX,
2488c2ecf20Sopenharmony_ci		.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
2498c2ecf20Sopenharmony_ci		.mux = { CGU_REG_CPCCR, 24, 2 },
2508c2ecf20Sopenharmony_ci	},
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	[X1830_CLK_AHB2] = {
2538c2ecf20Sopenharmony_ci		"ahb2", CGU_CLK_DIV,
2548c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
2558c2ecf20Sopenharmony_ci		.div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
2568c2ecf20Sopenharmony_ci	},
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	[X1830_CLK_PCLK] = {
2598c2ecf20Sopenharmony_ci		"pclk", CGU_CLK_DIV | CGU_CLK_GATE,
2608c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
2618c2ecf20Sopenharmony_ci		.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
2628c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 14 },
2638c2ecf20Sopenharmony_ci	},
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	[X1830_CLK_DDR] = {
2668c2ecf20Sopenharmony_ci		"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
2678c2ecf20Sopenharmony_ci		.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
2688c2ecf20Sopenharmony_ci		.mux = { CGU_REG_DDRCDR, 30, 2 },
2698c2ecf20Sopenharmony_ci		.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
2708c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 31 },
2718c2ecf20Sopenharmony_ci	},
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	[X1830_CLK_MAC] = {
2748c2ecf20Sopenharmony_ci		"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
2758c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
2768c2ecf20Sopenharmony_ci					 X1830_CLK_VPLL, X1830_CLK_EPLL },
2778c2ecf20Sopenharmony_ci		.mux = { CGU_REG_MACCDR, 30, 2 },
2788c2ecf20Sopenharmony_ci		.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
2798c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 4 },
2808c2ecf20Sopenharmony_ci	},
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	[X1830_CLK_LCD] = {
2838c2ecf20Sopenharmony_ci		"lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
2848c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
2858c2ecf20Sopenharmony_ci					 X1830_CLK_VPLL, X1830_CLK_EPLL },
2868c2ecf20Sopenharmony_ci		.mux = { CGU_REG_LPCDR, 30, 2 },
2878c2ecf20Sopenharmony_ci		.div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
2888c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 9 },
2898c2ecf20Sopenharmony_ci	},
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	[X1830_CLK_MSCMUX] = {
2928c2ecf20Sopenharmony_ci		"msc_mux", CGU_CLK_MUX,
2938c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
2948c2ecf20Sopenharmony_ci					 X1830_CLK_VPLL, X1830_CLK_EPLL },
2958c2ecf20Sopenharmony_ci		.mux = { CGU_REG_MSC0CDR, 30, 2 },
2968c2ecf20Sopenharmony_ci	},
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	[X1830_CLK_MSC0] = {
2998c2ecf20Sopenharmony_ci		"msc0", CGU_CLK_DIV | CGU_CLK_GATE,
3008c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
3018c2ecf20Sopenharmony_ci		.div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
3028c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 4 },
3038c2ecf20Sopenharmony_ci	},
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	[X1830_CLK_MSC1] = {
3068c2ecf20Sopenharmony_ci		"msc1", CGU_CLK_DIV | CGU_CLK_GATE,
3078c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
3088c2ecf20Sopenharmony_ci		.div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
3098c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 5 },
3108c2ecf20Sopenharmony_ci	},
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci	[X1830_CLK_SSIPLL] = {
3138c2ecf20Sopenharmony_ci		"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
3148c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
3158c2ecf20Sopenharmony_ci					 X1830_CLK_VPLL, X1830_CLK_EPLL },
3168c2ecf20Sopenharmony_ci		.mux = { CGU_REG_SSICDR, 30, 2 },
3178c2ecf20Sopenharmony_ci		.div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
3188c2ecf20Sopenharmony_ci	},
3198c2ecf20Sopenharmony_ci
3208c2ecf20Sopenharmony_ci	[X1830_CLK_SSIPLL_DIV2] = {
3218c2ecf20Sopenharmony_ci		"ssi_pll_div2", CGU_CLK_FIXDIV,
3228c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SSIPLL },
3238c2ecf20Sopenharmony_ci		.fixdiv = { 2 },
3248c2ecf20Sopenharmony_ci	},
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	[X1830_CLK_SSIMUX] = {
3278c2ecf20Sopenharmony_ci		"ssi_mux", CGU_CLK_MUX,
3288c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
3298c2ecf20Sopenharmony_ci		.mux = { CGU_REG_SSICDR, 29, 1 },
3308c2ecf20Sopenharmony_ci	},
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	[X1830_CLK_EXCLK_DIV512] = {
3338c2ecf20Sopenharmony_ci		"exclk_div512", CGU_CLK_FIXDIV,
3348c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK },
3358c2ecf20Sopenharmony_ci		.fixdiv = { 512 },
3368c2ecf20Sopenharmony_ci	},
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	[X1830_CLK_RTC] = {
3398c2ecf20Sopenharmony_ci		"rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE,
3408c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK_DIV512, X1830_CLK_RTCLK },
3418c2ecf20Sopenharmony_ci		.mux = { CGU_REG_OPCR, 2, 1},
3428c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 29 },
3438c2ecf20Sopenharmony_ci	},
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	/* Gate-only clocks */
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	[X1830_CLK_EMC] = {
3488c2ecf20Sopenharmony_ci		"emc", CGU_CLK_GATE,
3498c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_AHB2, -1, -1, -1 },
3508c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 0 },
3518c2ecf20Sopenharmony_ci	},
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci	[X1830_CLK_EFUSE] = {
3548c2ecf20Sopenharmony_ci		"efuse", CGU_CLK_GATE,
3558c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_AHB2, -1, -1, -1 },
3568c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 1 },
3578c2ecf20Sopenharmony_ci	},
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	[X1830_CLK_OTG] = {
3608c2ecf20Sopenharmony_ci		"otg", CGU_CLK_GATE,
3618c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
3628c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 3 },
3638c2ecf20Sopenharmony_ci	},
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci	[X1830_CLK_SSI0] = {
3668c2ecf20Sopenharmony_ci		"ssi0", CGU_CLK_GATE,
3678c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
3688c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 6 },
3698c2ecf20Sopenharmony_ci	},
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	[X1830_CLK_SMB0] = {
3728c2ecf20Sopenharmony_ci		"smb0", CGU_CLK_GATE,
3738c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_PCLK, -1, -1, -1 },
3748c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 7 },
3758c2ecf20Sopenharmony_ci	},
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	[X1830_CLK_SMB1] = {
3788c2ecf20Sopenharmony_ci		"smb1", CGU_CLK_GATE,
3798c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_PCLK, -1, -1, -1 },
3808c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 8 },
3818c2ecf20Sopenharmony_ci	},
3828c2ecf20Sopenharmony_ci
3838c2ecf20Sopenharmony_ci	[X1830_CLK_SMB2] = {
3848c2ecf20Sopenharmony_ci		"smb2", CGU_CLK_GATE,
3858c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_PCLK, -1, -1, -1 },
3868c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 9 },
3878c2ecf20Sopenharmony_ci	},
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	[X1830_CLK_UART0] = {
3908c2ecf20Sopenharmony_ci		"uart0", CGU_CLK_GATE,
3918c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
3928c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 14 },
3938c2ecf20Sopenharmony_ci	},
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	[X1830_CLK_UART1] = {
3968c2ecf20Sopenharmony_ci		"uart1", CGU_CLK_GATE,
3978c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
3988c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 15 },
3998c2ecf20Sopenharmony_ci	},
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci	[X1830_CLK_SSI1] = {
4028c2ecf20Sopenharmony_ci		"ssi1", CGU_CLK_GATE,
4038c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
4048c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 19 },
4058c2ecf20Sopenharmony_ci	},
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	[X1830_CLK_SFC] = {
4088c2ecf20Sopenharmony_ci		"sfc", CGU_CLK_GATE,
4098c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
4108c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 20 },
4118c2ecf20Sopenharmony_ci	},
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	[X1830_CLK_PDMA] = {
4148c2ecf20Sopenharmony_ci		"pdma", CGU_CLK_GATE,
4158c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
4168c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 21 },
4178c2ecf20Sopenharmony_ci	},
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci	[X1830_CLK_TCU] = {
4208c2ecf20Sopenharmony_ci		"tcu", CGU_CLK_GATE,
4218c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
4228c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR0, 30 },
4238c2ecf20Sopenharmony_ci	},
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	[X1830_CLK_DTRNG] = {
4268c2ecf20Sopenharmony_ci		"dtrng", CGU_CLK_GATE,
4278c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_PCLK, -1, -1, -1 },
4288c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 1 },
4298c2ecf20Sopenharmony_ci	},
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci	[X1830_CLK_OST] = {
4328c2ecf20Sopenharmony_ci		"ost", CGU_CLK_GATE,
4338c2ecf20Sopenharmony_ci		.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
4348c2ecf20Sopenharmony_ci		.gate = { CGU_REG_CLKGR1, 11 },
4358c2ecf20Sopenharmony_ci	},
4368c2ecf20Sopenharmony_ci};
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_cistatic void __init x1830_cgu_init(struct device_node *np)
4398c2ecf20Sopenharmony_ci{
4408c2ecf20Sopenharmony_ci	int retval;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	cgu = ingenic_cgu_new(x1830_cgu_clocks,
4438c2ecf20Sopenharmony_ci			      ARRAY_SIZE(x1830_cgu_clocks), np);
4448c2ecf20Sopenharmony_ci	if (!cgu) {
4458c2ecf20Sopenharmony_ci		pr_err("%s: failed to initialise CGU\n", __func__);
4468c2ecf20Sopenharmony_ci		return;
4478c2ecf20Sopenharmony_ci	}
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	retval = ingenic_cgu_register_clocks(cgu);
4508c2ecf20Sopenharmony_ci	if (retval) {
4518c2ecf20Sopenharmony_ci		pr_err("%s: failed to register CGU Clocks\n", __func__);
4528c2ecf20Sopenharmony_ci		return;
4538c2ecf20Sopenharmony_ci	}
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	ingenic_cgu_register_syscore_ops(cgu);
4568c2ecf20Sopenharmony_ci}
4578c2ecf20Sopenharmony_ci/*
4588c2ecf20Sopenharmony_ci * CGU has some children devices, this is useful for probing children devices
4598c2ecf20Sopenharmony_ci * in the case where the device node is compatible with "simple-mfd".
4608c2ecf20Sopenharmony_ci */
4618c2ecf20Sopenharmony_ciCLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
462