18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * JZ4770 SoC CGU driver 48c2ecf20Sopenharmony_ci * Copyright 2018, Paul Cercueil <paul@crapouillou.net> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/bitops.h> 88c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/of.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <dt-bindings/clock/jz4770-cgu.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include "cgu.h" 168c2ecf20Sopenharmony_ci#include "pm.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* 198c2ecf20Sopenharmony_ci * CPM registers offset address definition 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci#define CGU_REG_CPCCR 0x00 228c2ecf20Sopenharmony_ci#define CGU_REG_LCR 0x04 238c2ecf20Sopenharmony_ci#define CGU_REG_CPPCR0 0x10 248c2ecf20Sopenharmony_ci#define CGU_REG_CLKGR0 0x20 258c2ecf20Sopenharmony_ci#define CGU_REG_OPCR 0x24 268c2ecf20Sopenharmony_ci#define CGU_REG_CLKGR1 0x28 278c2ecf20Sopenharmony_ci#define CGU_REG_CPPCR1 0x30 288c2ecf20Sopenharmony_ci#define CGU_REG_USBPCR1 0x48 298c2ecf20Sopenharmony_ci#define CGU_REG_USBCDR 0x50 308c2ecf20Sopenharmony_ci#define CGU_REG_I2SCDR 0x60 318c2ecf20Sopenharmony_ci#define CGU_REG_LPCDR 0x64 328c2ecf20Sopenharmony_ci#define CGU_REG_MSC0CDR 0x68 338c2ecf20Sopenharmony_ci#define CGU_REG_UHCCDR 0x6c 348c2ecf20Sopenharmony_ci#define CGU_REG_SSICDR 0x74 358c2ecf20Sopenharmony_ci#define CGU_REG_CIMCDR 0x7c 368c2ecf20Sopenharmony_ci#define CGU_REG_GPSCDR 0x80 378c2ecf20Sopenharmony_ci#define CGU_REG_PCMCDR 0x84 388c2ecf20Sopenharmony_ci#define CGU_REG_GPUCDR 0x88 398c2ecf20Sopenharmony_ci#define CGU_REG_MSC1CDR 0xA4 408c2ecf20Sopenharmony_ci#define CGU_REG_MSC2CDR 0xA8 418c2ecf20Sopenharmony_ci#define CGU_REG_BCHCDR 0xAC 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* bits within the OPCR register */ 448c2ecf20Sopenharmony_ci#define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* bits within the USBPCR1 register */ 478c2ecf20Sopenharmony_ci#define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic struct ingenic_cgu *cgu; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic int jz4770_uhc_phy_enable(struct clk_hw *hw) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 548c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr); 578c2ecf20Sopenharmony_ci writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1); 588c2ecf20Sopenharmony_ci return 0; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void jz4770_uhc_phy_disable(struct clk_hw *hw) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 648c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1); 678c2ecf20Sopenharmony_ci writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic int jz4770_uhc_phy_is_enabled(struct clk_hw *hw) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 738c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci return !(readl(reg_opcr) & OPCR_SPENDH) && 768c2ecf20Sopenharmony_ci (readl(reg_usbpcr1) & USBPCR1_UHC_POWER); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic const struct clk_ops jz4770_uhc_phy_ops = { 808c2ecf20Sopenharmony_ci .enable = jz4770_uhc_phy_enable, 818c2ecf20Sopenharmony_ci .disable = jz4770_uhc_phy_disable, 828c2ecf20Sopenharmony_ci .is_enabled = jz4770_uhc_phy_is_enabled, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic const s8 pll_od_encoding[8] = { 868c2ecf20Sopenharmony_ci 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic const u8 jz4770_cgu_cpccr_div_table[] = { 908c2ecf20Sopenharmony_ci 1, 2, 3, 4, 6, 8, 12, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci /* External clocks */ 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci [JZ4770_CLK_EXT] = { "ext", CGU_CLK_EXT }, 988c2ecf20Sopenharmony_ci [JZ4770_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT }, 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* PLLs */ 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci [JZ4770_CLK_PLL0] = { 1038c2ecf20Sopenharmony_ci "pll0", CGU_CLK_PLL, 1048c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 1058c2ecf20Sopenharmony_ci .pll = { 1068c2ecf20Sopenharmony_ci .reg = CGU_REG_CPPCR0, 1078c2ecf20Sopenharmony_ci .rate_multiplier = 1, 1088c2ecf20Sopenharmony_ci .m_shift = 24, 1098c2ecf20Sopenharmony_ci .m_bits = 7, 1108c2ecf20Sopenharmony_ci .m_offset = 1, 1118c2ecf20Sopenharmony_ci .n_shift = 18, 1128c2ecf20Sopenharmony_ci .n_bits = 5, 1138c2ecf20Sopenharmony_ci .n_offset = 1, 1148c2ecf20Sopenharmony_ci .od_shift = 16, 1158c2ecf20Sopenharmony_ci .od_bits = 2, 1168c2ecf20Sopenharmony_ci .od_max = 8, 1178c2ecf20Sopenharmony_ci .od_encoding = pll_od_encoding, 1188c2ecf20Sopenharmony_ci .bypass_reg = CGU_REG_CPPCR0, 1198c2ecf20Sopenharmony_ci .bypass_bit = 9, 1208c2ecf20Sopenharmony_ci .enable_bit = 8, 1218c2ecf20Sopenharmony_ci .stable_bit = 10, 1228c2ecf20Sopenharmony_ci }, 1238c2ecf20Sopenharmony_ci }, 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci [JZ4770_CLK_PLL1] = { 1268c2ecf20Sopenharmony_ci /* TODO: PLL1 can depend on PLL0 */ 1278c2ecf20Sopenharmony_ci "pll1", CGU_CLK_PLL, 1288c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 1298c2ecf20Sopenharmony_ci .pll = { 1308c2ecf20Sopenharmony_ci .reg = CGU_REG_CPPCR1, 1318c2ecf20Sopenharmony_ci .rate_multiplier = 1, 1328c2ecf20Sopenharmony_ci .m_shift = 24, 1338c2ecf20Sopenharmony_ci .m_bits = 7, 1348c2ecf20Sopenharmony_ci .m_offset = 1, 1358c2ecf20Sopenharmony_ci .n_shift = 18, 1368c2ecf20Sopenharmony_ci .n_bits = 5, 1378c2ecf20Sopenharmony_ci .n_offset = 1, 1388c2ecf20Sopenharmony_ci .od_shift = 16, 1398c2ecf20Sopenharmony_ci .od_bits = 2, 1408c2ecf20Sopenharmony_ci .od_max = 8, 1418c2ecf20Sopenharmony_ci .od_encoding = pll_od_encoding, 1428c2ecf20Sopenharmony_ci .bypass_reg = CGU_REG_CPPCR1, 1438c2ecf20Sopenharmony_ci .no_bypass_bit = true, 1448c2ecf20Sopenharmony_ci .enable_bit = 7, 1458c2ecf20Sopenharmony_ci .stable_bit = 6, 1468c2ecf20Sopenharmony_ci }, 1478c2ecf20Sopenharmony_ci }, 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci /* Main clocks */ 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci [JZ4770_CLK_CCLK] = { 1528c2ecf20Sopenharmony_ci "cclk", CGU_CLK_DIV, 1538c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1548c2ecf20Sopenharmony_ci .div = { 1558c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 1568c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1578c2ecf20Sopenharmony_ci }, 1588c2ecf20Sopenharmony_ci }, 1598c2ecf20Sopenharmony_ci [JZ4770_CLK_H0CLK] = { 1608c2ecf20Sopenharmony_ci "h0clk", CGU_CLK_DIV, 1618c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1628c2ecf20Sopenharmony_ci .div = { 1638c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 1648c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1658c2ecf20Sopenharmony_ci }, 1668c2ecf20Sopenharmony_ci }, 1678c2ecf20Sopenharmony_ci [JZ4770_CLK_H1CLK] = { 1688c2ecf20Sopenharmony_ci "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, 1698c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1708c2ecf20Sopenharmony_ci .div = { 1718c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 1728c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1738c2ecf20Sopenharmony_ci }, 1748c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 7 }, 1758c2ecf20Sopenharmony_ci }, 1768c2ecf20Sopenharmony_ci [JZ4770_CLK_H2CLK] = { 1778c2ecf20Sopenharmony_ci "h2clk", CGU_CLK_DIV, 1788c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1798c2ecf20Sopenharmony_ci .div = { 1808c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 1818c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1828c2ecf20Sopenharmony_ci }, 1838c2ecf20Sopenharmony_ci }, 1848c2ecf20Sopenharmony_ci [JZ4770_CLK_C1CLK] = { 1858c2ecf20Sopenharmony_ci "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, 1868c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1878c2ecf20Sopenharmony_ci .div = { 1888c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 1898c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1908c2ecf20Sopenharmony_ci }, 1918c2ecf20Sopenharmony_ci .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle 1928c2ecf20Sopenharmony_ci }, 1938c2ecf20Sopenharmony_ci [JZ4770_CLK_PCLK] = { 1948c2ecf20Sopenharmony_ci "pclk", CGU_CLK_DIV, 1958c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 1968c2ecf20Sopenharmony_ci .div = { 1978c2ecf20Sopenharmony_ci CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 1988c2ecf20Sopenharmony_ci jz4770_cgu_cpccr_div_table, 1998c2ecf20Sopenharmony_ci }, 2008c2ecf20Sopenharmony_ci }, 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* Those divided clocks can connect to PLL0 or PLL1 */ 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC0_MUX] = { 2058c2ecf20Sopenharmony_ci "mmc0_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2068c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2078c2ecf20Sopenharmony_ci .mux = { CGU_REG_MSC0CDR, 30, 1 }, 2088c2ecf20Sopenharmony_ci .div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 }, 2098c2ecf20Sopenharmony_ci .gate = { CGU_REG_MSC0CDR, 31 }, 2108c2ecf20Sopenharmony_ci }, 2118c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC1_MUX] = { 2128c2ecf20Sopenharmony_ci "mmc1_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2138c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2148c2ecf20Sopenharmony_ci .mux = { CGU_REG_MSC1CDR, 30, 1 }, 2158c2ecf20Sopenharmony_ci .div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 }, 2168c2ecf20Sopenharmony_ci .gate = { CGU_REG_MSC1CDR, 31 }, 2178c2ecf20Sopenharmony_ci }, 2188c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC2_MUX] = { 2198c2ecf20Sopenharmony_ci "mmc2_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2208c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2218c2ecf20Sopenharmony_ci .mux = { CGU_REG_MSC2CDR, 30, 1 }, 2228c2ecf20Sopenharmony_ci .div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 }, 2238c2ecf20Sopenharmony_ci .gate = { CGU_REG_MSC2CDR, 31 }, 2248c2ecf20Sopenharmony_ci }, 2258c2ecf20Sopenharmony_ci [JZ4770_CLK_CIM] = { 2268c2ecf20Sopenharmony_ci "cim", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2278c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2288c2ecf20Sopenharmony_ci .mux = { CGU_REG_CIMCDR, 31, 1 }, 2298c2ecf20Sopenharmony_ci .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 }, 2308c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 26 }, 2318c2ecf20Sopenharmony_ci }, 2328c2ecf20Sopenharmony_ci [JZ4770_CLK_UHC] = { 2338c2ecf20Sopenharmony_ci "uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2348c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2358c2ecf20Sopenharmony_ci .mux = { CGU_REG_UHCCDR, 29, 1 }, 2368c2ecf20Sopenharmony_ci .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, 2378c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 24 }, 2388c2ecf20Sopenharmony_ci }, 2398c2ecf20Sopenharmony_ci [JZ4770_CLK_GPU] = { 2408c2ecf20Sopenharmony_ci "gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2418c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 }, 2428c2ecf20Sopenharmony_ci .mux = { CGU_REG_GPUCDR, 31, 1 }, 2438c2ecf20Sopenharmony_ci .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 }, 2448c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 9 }, 2458c2ecf20Sopenharmony_ci }, 2468c2ecf20Sopenharmony_ci [JZ4770_CLK_BCH] = { 2478c2ecf20Sopenharmony_ci "bch", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2488c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2498c2ecf20Sopenharmony_ci .mux = { CGU_REG_BCHCDR, 31, 1 }, 2508c2ecf20Sopenharmony_ci .div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 }, 2518c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 1 }, 2528c2ecf20Sopenharmony_ci }, 2538c2ecf20Sopenharmony_ci [JZ4770_CLK_LPCLK_MUX] = { 2548c2ecf20Sopenharmony_ci "lpclk", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2558c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2568c2ecf20Sopenharmony_ci .mux = { CGU_REG_LPCDR, 29, 1 }, 2578c2ecf20Sopenharmony_ci .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, 2588c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 28 }, 2598c2ecf20Sopenharmony_ci }, 2608c2ecf20Sopenharmony_ci [JZ4770_CLK_GPS] = { 2618c2ecf20Sopenharmony_ci "gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2628c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 2638c2ecf20Sopenharmony_ci .mux = { CGU_REG_GPSCDR, 31, 1 }, 2648c2ecf20Sopenharmony_ci .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 }, 2658c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 22 }, 2668c2ecf20Sopenharmony_ci }, 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci /* Those divided clocks can connect to EXT, PLL0 or PLL1 */ 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci [JZ4770_CLK_SSI_MUX] = { 2718c2ecf20Sopenharmony_ci "ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX, 2728c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 2738c2ecf20Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 2748c2ecf20Sopenharmony_ci .mux = { CGU_REG_SSICDR, 30, 2 }, 2758c2ecf20Sopenharmony_ci .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 }, 2768c2ecf20Sopenharmony_ci }, 2778c2ecf20Sopenharmony_ci [JZ4770_CLK_PCM_MUX] = { 2788c2ecf20Sopenharmony_ci "pcm_mux", CGU_CLK_DIV | CGU_CLK_MUX, 2798c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 2808c2ecf20Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 2818c2ecf20Sopenharmony_ci .mux = { CGU_REG_PCMCDR, 30, 2 }, 2828c2ecf20Sopenharmony_ci .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 }, 2838c2ecf20Sopenharmony_ci }, 2848c2ecf20Sopenharmony_ci [JZ4770_CLK_I2S] = { 2858c2ecf20Sopenharmony_ci "i2s", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2868c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 2878c2ecf20Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 2888c2ecf20Sopenharmony_ci .mux = { CGU_REG_I2SCDR, 30, 2 }, 2898c2ecf20Sopenharmony_ci .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, 2908c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 13 }, 2918c2ecf20Sopenharmony_ci }, 2928c2ecf20Sopenharmony_ci [JZ4770_CLK_OTG] = { 2938c2ecf20Sopenharmony_ci "usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 2948c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 2958c2ecf20Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 2968c2ecf20Sopenharmony_ci .mux = { CGU_REG_USBCDR, 30, 2 }, 2978c2ecf20Sopenharmony_ci .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 }, 2988c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 2 }, 2998c2ecf20Sopenharmony_ci }, 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci /* Gate-only clocks */ 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci [JZ4770_CLK_SSI0] = { 3048c2ecf20Sopenharmony_ci "ssi0", CGU_CLK_GATE, 3058c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 3068c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 4 }, 3078c2ecf20Sopenharmony_ci }, 3088c2ecf20Sopenharmony_ci [JZ4770_CLK_SSI1] = { 3098c2ecf20Sopenharmony_ci "ssi1", CGU_CLK_GATE, 3108c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 3118c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 19 }, 3128c2ecf20Sopenharmony_ci }, 3138c2ecf20Sopenharmony_ci [JZ4770_CLK_SSI2] = { 3148c2ecf20Sopenharmony_ci "ssi2", CGU_CLK_GATE, 3158c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 3168c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 20 }, 3178c2ecf20Sopenharmony_ci }, 3188c2ecf20Sopenharmony_ci [JZ4770_CLK_PCM0] = { 3198c2ecf20Sopenharmony_ci "pcm0", CGU_CLK_GATE, 3208c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PCM_MUX, }, 3218c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 8 }, 3228c2ecf20Sopenharmony_ci }, 3238c2ecf20Sopenharmony_ci [JZ4770_CLK_PCM1] = { 3248c2ecf20Sopenharmony_ci "pcm1", CGU_CLK_GATE, 3258c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_PCM_MUX, }, 3268c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 10 }, 3278c2ecf20Sopenharmony_ci }, 3288c2ecf20Sopenharmony_ci [JZ4770_CLK_DMA] = { 3298c2ecf20Sopenharmony_ci "dma", CGU_CLK_GATE, 3308c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_H2CLK, }, 3318c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 21 }, 3328c2ecf20Sopenharmony_ci }, 3338c2ecf20Sopenharmony_ci [JZ4770_CLK_I2C0] = { 3348c2ecf20Sopenharmony_ci "i2c0", CGU_CLK_GATE, 3358c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3368c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 5 }, 3378c2ecf20Sopenharmony_ci }, 3388c2ecf20Sopenharmony_ci [JZ4770_CLK_I2C1] = { 3398c2ecf20Sopenharmony_ci "i2c1", CGU_CLK_GATE, 3408c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3418c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 6 }, 3428c2ecf20Sopenharmony_ci }, 3438c2ecf20Sopenharmony_ci [JZ4770_CLK_I2C2] = { 3448c2ecf20Sopenharmony_ci "i2c2", CGU_CLK_GATE, 3458c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3468c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 15 }, 3478c2ecf20Sopenharmony_ci }, 3488c2ecf20Sopenharmony_ci [JZ4770_CLK_UART0] = { 3498c2ecf20Sopenharmony_ci "uart0", CGU_CLK_GATE, 3508c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3518c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 15 }, 3528c2ecf20Sopenharmony_ci }, 3538c2ecf20Sopenharmony_ci [JZ4770_CLK_UART1] = { 3548c2ecf20Sopenharmony_ci "uart1", CGU_CLK_GATE, 3558c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3568c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 16 }, 3578c2ecf20Sopenharmony_ci }, 3588c2ecf20Sopenharmony_ci [JZ4770_CLK_UART2] = { 3598c2ecf20Sopenharmony_ci "uart2", CGU_CLK_GATE, 3608c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3618c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 17 }, 3628c2ecf20Sopenharmony_ci }, 3638c2ecf20Sopenharmony_ci [JZ4770_CLK_UART3] = { 3648c2ecf20Sopenharmony_ci "uart3", CGU_CLK_GATE, 3658c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3668c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 18 }, 3678c2ecf20Sopenharmony_ci }, 3688c2ecf20Sopenharmony_ci [JZ4770_CLK_IPU] = { 3698c2ecf20Sopenharmony_ci "ipu", CGU_CLK_GATE, 3708c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_H0CLK, }, 3718c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 29 }, 3728c2ecf20Sopenharmony_ci }, 3738c2ecf20Sopenharmony_ci [JZ4770_CLK_ADC] = { 3748c2ecf20Sopenharmony_ci "adc", CGU_CLK_GATE, 3758c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3768c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 14 }, 3778c2ecf20Sopenharmony_ci }, 3788c2ecf20Sopenharmony_ci [JZ4770_CLK_AIC] = { 3798c2ecf20Sopenharmony_ci "aic", CGU_CLK_GATE, 3808c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 3818c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 8 }, 3828c2ecf20Sopenharmony_ci }, 3838c2ecf20Sopenharmony_ci [JZ4770_CLK_AUX] = { 3848c2ecf20Sopenharmony_ci "aux", CGU_CLK_GATE, 3858c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_C1CLK, }, 3868c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 14 }, 3878c2ecf20Sopenharmony_ci }, 3888c2ecf20Sopenharmony_ci [JZ4770_CLK_VPU] = { 3898c2ecf20Sopenharmony_ci "vpu", CGU_CLK_GATE, 3908c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_H1CLK, }, 3918c2ecf20Sopenharmony_ci .gate = { CGU_REG_LCR, 30, false, 150 }, 3928c2ecf20Sopenharmony_ci }, 3938c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC0] = { 3948c2ecf20Sopenharmony_ci "mmc0", CGU_CLK_GATE, 3958c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_MMC0_MUX, }, 3968c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 3 }, 3978c2ecf20Sopenharmony_ci }, 3988c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC1] = { 3998c2ecf20Sopenharmony_ci "mmc1", CGU_CLK_GATE, 4008c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_MMC1_MUX, }, 4018c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 11 }, 4028c2ecf20Sopenharmony_ci }, 4038c2ecf20Sopenharmony_ci [JZ4770_CLK_MMC2] = { 4048c2ecf20Sopenharmony_ci "mmc2", CGU_CLK_GATE, 4058c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_MMC2_MUX, }, 4068c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 12 }, 4078c2ecf20Sopenharmony_ci }, 4088c2ecf20Sopenharmony_ci [JZ4770_CLK_OTG_PHY] = { 4098c2ecf20Sopenharmony_ci "usb_phy", CGU_CLK_GATE, 4108c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_OTG }, 4118c2ecf20Sopenharmony_ci .gate = { CGU_REG_OPCR, 7, true, 50 }, 4128c2ecf20Sopenharmony_ci }, 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci /* Custom clocks */ 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci [JZ4770_CLK_UHC_PHY] = { 4178c2ecf20Sopenharmony_ci "uhc_phy", CGU_CLK_CUSTOM, 4188c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_UHC, -1, -1, -1 }, 4198c2ecf20Sopenharmony_ci .custom = { &jz4770_uhc_phy_ops }, 4208c2ecf20Sopenharmony_ci }, 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci [JZ4770_CLK_EXT512] = { 4238c2ecf20Sopenharmony_ci "ext/512", CGU_CLK_FIXDIV, 4248c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 4258c2ecf20Sopenharmony_ci .fixdiv = { 512 }, 4268c2ecf20Sopenharmony_ci }, 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci [JZ4770_CLK_RTC] = { 4298c2ecf20Sopenharmony_ci "rtc", CGU_CLK_MUX, 4308c2ecf20Sopenharmony_ci .parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, }, 4318c2ecf20Sopenharmony_ci .mux = { CGU_REG_OPCR, 2, 1}, 4328c2ecf20Sopenharmony_ci }, 4338c2ecf20Sopenharmony_ci}; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_cistatic void __init jz4770_cgu_init(struct device_node *np) 4368c2ecf20Sopenharmony_ci{ 4378c2ecf20Sopenharmony_ci int retval; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci cgu = ingenic_cgu_new(jz4770_cgu_clocks, 4408c2ecf20Sopenharmony_ci ARRAY_SIZE(jz4770_cgu_clocks), np); 4418c2ecf20Sopenharmony_ci if (!cgu) { 4428c2ecf20Sopenharmony_ci pr_err("%s: failed to initialise CGU\n", __func__); 4438c2ecf20Sopenharmony_ci return; 4448c2ecf20Sopenharmony_ci } 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci retval = ingenic_cgu_register_clocks(cgu); 4478c2ecf20Sopenharmony_ci if (retval) 4488c2ecf20Sopenharmony_ci pr_err("%s: failed to register CGU Clocks\n", __func__); 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci ingenic_cgu_register_syscore_ops(cgu); 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci/* We only probe via devicetree, no need for a platform driver */ 4548c2ecf20Sopenharmony_ciCLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init); 455