18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * X1000 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/x1000-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_APLL 0x10 208c2ecf20Sopenharmony_ci#define CGU_REG_MPLL 0x14 218c2ecf20Sopenharmony_ci#define CGU_REG_CLKGR 0x20 228c2ecf20Sopenharmony_ci#define CGU_REG_OPCR 0x24 238c2ecf20Sopenharmony_ci#define CGU_REG_DDRCDR 0x2c 248c2ecf20Sopenharmony_ci#define CGU_REG_USBPCR 0x3c 258c2ecf20Sopenharmony_ci#define CGU_REG_USBPCR1 0x48 268c2ecf20Sopenharmony_ci#define CGU_REG_USBCDR 0x50 278c2ecf20Sopenharmony_ci#define CGU_REG_MACCDR 0x54 288c2ecf20Sopenharmony_ci#define CGU_REG_I2SCDR 0x60 298c2ecf20Sopenharmony_ci#define CGU_REG_LPCDR 0x64 308c2ecf20Sopenharmony_ci#define CGU_REG_MSC0CDR 0x68 318c2ecf20Sopenharmony_ci#define CGU_REG_I2SCDR1 0x70 328c2ecf20Sopenharmony_ci#define CGU_REG_SSICDR 0x74 338c2ecf20Sopenharmony_ci#define CGU_REG_CIMCDR 0x7c 348c2ecf20Sopenharmony_ci#define CGU_REG_PCMCDR 0x84 358c2ecf20Sopenharmony_ci#define CGU_REG_MSC1CDR 0xa4 368c2ecf20Sopenharmony_ci#define CGU_REG_CMP_INTR 0xb0 378c2ecf20Sopenharmony_ci#define CGU_REG_CMP_INTRE 0xb4 388c2ecf20Sopenharmony_ci#define CGU_REG_DRCG 0xd0 398c2ecf20Sopenharmony_ci#define CGU_REG_CPCSR 0xd4 408c2ecf20Sopenharmony_ci#define CGU_REG_PCMCDR1 0xe0 418c2ecf20Sopenharmony_ci#define CGU_REG_MACPHYC 0xe8 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* bits within the OPCR register */ 448c2ecf20Sopenharmony_ci#define OPCR_SPENDN0 BIT(7) 458c2ecf20Sopenharmony_ci#define OPCR_SPENDN1 BIT(6) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* bits within the USBPCR register */ 488c2ecf20Sopenharmony_ci#define USBPCR_SIDDQ BIT(21) 498c2ecf20Sopenharmony_ci#define USBPCR_OTG_DISABLE BIT(20) 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* bits within the USBPCR1 register */ 528c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKSEL_SHIFT 26 538c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT) 548c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT) 558c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKDIV_SHIFT 24 568c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT) 578c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) 588c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) 598c2ecf20Sopenharmony_ci#define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic struct ingenic_cgu *cgu; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic unsigned long x1000_otg_phy_recalc_rate(struct clk_hw *hw, 648c2ecf20Sopenharmony_ci unsigned long parent_rate) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci u32 usbpcr1; 678c2ecf20Sopenharmony_ci unsigned refclk_div; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 708c2ecf20Sopenharmony_ci refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci switch (refclk_div) { 738c2ecf20Sopenharmony_ci case USBPCR1_REFCLKDIV_12: 748c2ecf20Sopenharmony_ci return 12000000; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci case USBPCR1_REFCLKDIV_24: 778c2ecf20Sopenharmony_ci return 24000000; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci case USBPCR1_REFCLKDIV_48: 808c2ecf20Sopenharmony_ci return 48000000; 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci return parent_rate; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic long x1000_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, 878c2ecf20Sopenharmony_ci unsigned long *parent_rate) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci if (req_rate < 18000000) 908c2ecf20Sopenharmony_ci return 12000000; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci if (req_rate < 36000000) 938c2ecf20Sopenharmony_ci return 24000000; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci return 48000000; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic int x1000_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, 998c2ecf20Sopenharmony_ci unsigned long parent_rate) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci unsigned long flags; 1028c2ecf20Sopenharmony_ci u32 usbpcr1, div_bits; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci switch (req_rate) { 1058c2ecf20Sopenharmony_ci case 12000000: 1068c2ecf20Sopenharmony_ci div_bits = USBPCR1_REFCLKDIV_12; 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci case 24000000: 1108c2ecf20Sopenharmony_ci div_bits = USBPCR1_REFCLKDIV_24; 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci case 48000000: 1148c2ecf20Sopenharmony_ci div_bits = USBPCR1_REFCLKDIV_48; 1158c2ecf20Sopenharmony_ci break; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci default: 1188c2ecf20Sopenharmony_ci return -EINVAL; 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci spin_lock_irqsave(&cgu->lock, flags); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); 1248c2ecf20Sopenharmony_ci usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK; 1258c2ecf20Sopenharmony_ci usbpcr1 |= div_bits; 1268c2ecf20Sopenharmony_ci writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&cgu->lock, flags); 1298c2ecf20Sopenharmony_ci return 0; 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic int x1000_usb_phy_enable(struct clk_hw *hw) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 1358c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr); 1388c2ecf20Sopenharmony_ci writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr); 1398c2ecf20Sopenharmony_ci return 0; 1408c2ecf20Sopenharmony_ci} 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic void x1000_usb_phy_disable(struct clk_hw *hw) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 1458c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr); 1488c2ecf20Sopenharmony_ci writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr); 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic int x1000_usb_phy_is_enabled(struct clk_hw *hw) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 1548c2ecf20Sopenharmony_ci void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci return (readl(reg_opcr) & OPCR_SPENDN0) && 1578c2ecf20Sopenharmony_ci !(readl(reg_usbpcr) & USBPCR_SIDDQ) && 1588c2ecf20Sopenharmony_ci !(readl(reg_usbpcr) & USBPCR_OTG_DISABLE); 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic const struct clk_ops x1000_otg_phy_ops = { 1628c2ecf20Sopenharmony_ci .recalc_rate = x1000_otg_phy_recalc_rate, 1638c2ecf20Sopenharmony_ci .round_rate = x1000_otg_phy_round_rate, 1648c2ecf20Sopenharmony_ci .set_rate = x1000_otg_phy_set_rate, 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci .enable = x1000_usb_phy_enable, 1678c2ecf20Sopenharmony_ci .disable = x1000_usb_phy_disable, 1688c2ecf20Sopenharmony_ci .is_enabled = x1000_usb_phy_is_enabled, 1698c2ecf20Sopenharmony_ci}; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic const s8 pll_od_encoding[8] = { 1728c2ecf20Sopenharmony_ci 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = { 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci /* External clocks */ 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci [X1000_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, 1808c2ecf20Sopenharmony_ci [X1000_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci /* PLLs */ 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci [X1000_CLK_APLL] = { 1858c2ecf20Sopenharmony_ci "apll", CGU_CLK_PLL, 1868c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 1878c2ecf20Sopenharmony_ci .pll = { 1888c2ecf20Sopenharmony_ci .reg = CGU_REG_APLL, 1898c2ecf20Sopenharmony_ci .rate_multiplier = 1, 1908c2ecf20Sopenharmony_ci .m_shift = 24, 1918c2ecf20Sopenharmony_ci .m_bits = 7, 1928c2ecf20Sopenharmony_ci .m_offset = 1, 1938c2ecf20Sopenharmony_ci .n_shift = 18, 1948c2ecf20Sopenharmony_ci .n_bits = 5, 1958c2ecf20Sopenharmony_ci .n_offset = 1, 1968c2ecf20Sopenharmony_ci .od_shift = 16, 1978c2ecf20Sopenharmony_ci .od_bits = 2, 1988c2ecf20Sopenharmony_ci .od_max = 8, 1998c2ecf20Sopenharmony_ci .od_encoding = pll_od_encoding, 2008c2ecf20Sopenharmony_ci .bypass_reg = CGU_REG_APLL, 2018c2ecf20Sopenharmony_ci .bypass_bit = 9, 2028c2ecf20Sopenharmony_ci .enable_bit = 8, 2038c2ecf20Sopenharmony_ci .stable_bit = 10, 2048c2ecf20Sopenharmony_ci }, 2058c2ecf20Sopenharmony_ci }, 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci [X1000_CLK_MPLL] = { 2088c2ecf20Sopenharmony_ci "mpll", CGU_CLK_PLL, 2098c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 2108c2ecf20Sopenharmony_ci .pll = { 2118c2ecf20Sopenharmony_ci .reg = CGU_REG_MPLL, 2128c2ecf20Sopenharmony_ci .rate_multiplier = 1, 2138c2ecf20Sopenharmony_ci .m_shift = 24, 2148c2ecf20Sopenharmony_ci .m_bits = 7, 2158c2ecf20Sopenharmony_ci .m_offset = 1, 2168c2ecf20Sopenharmony_ci .n_shift = 18, 2178c2ecf20Sopenharmony_ci .n_bits = 5, 2188c2ecf20Sopenharmony_ci .n_offset = 1, 2198c2ecf20Sopenharmony_ci .od_shift = 16, 2208c2ecf20Sopenharmony_ci .od_bits = 2, 2218c2ecf20Sopenharmony_ci .od_max = 8, 2228c2ecf20Sopenharmony_ci .od_encoding = pll_od_encoding, 2238c2ecf20Sopenharmony_ci .bypass_reg = CGU_REG_MPLL, 2248c2ecf20Sopenharmony_ci .bypass_bit = 6, 2258c2ecf20Sopenharmony_ci .enable_bit = 7, 2268c2ecf20Sopenharmony_ci .stable_bit = 0, 2278c2ecf20Sopenharmony_ci }, 2288c2ecf20Sopenharmony_ci }, 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci /* Custom (SoC-specific) OTG PHY */ 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci [X1000_CLK_OTGPHY] = { 2338c2ecf20Sopenharmony_ci "otg_phy", CGU_CLK_CUSTOM, 2348c2ecf20Sopenharmony_ci .parents = { -1, -1, X1000_CLK_EXCLK, -1 }, 2358c2ecf20Sopenharmony_ci .custom = { &x1000_otg_phy_ops }, 2368c2ecf20Sopenharmony_ci }, 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* Muxes & dividers */ 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci [X1000_CLK_SCLKA] = { 2418c2ecf20Sopenharmony_ci "sclk_a", CGU_CLK_MUX, 2428c2ecf20Sopenharmony_ci .parents = { -1, X1000_CLK_EXCLK, X1000_CLK_APLL, -1 }, 2438c2ecf20Sopenharmony_ci .mux = { CGU_REG_CPCCR, 30, 2 }, 2448c2ecf20Sopenharmony_ci }, 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci [X1000_CLK_CPUMUX] = { 2478c2ecf20Sopenharmony_ci "cpu_mux", CGU_CLK_MUX, 2488c2ecf20Sopenharmony_ci .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 2498c2ecf20Sopenharmony_ci .mux = { CGU_REG_CPCCR, 28, 2 }, 2508c2ecf20Sopenharmony_ci }, 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci [X1000_CLK_CPU] = { 2538c2ecf20Sopenharmony_ci "cpu", CGU_CLK_DIV | CGU_CLK_GATE, 2548c2ecf20Sopenharmony_ci .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, 2558c2ecf20Sopenharmony_ci .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, 2568c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 30 }, 2578c2ecf20Sopenharmony_ci }, 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci [X1000_CLK_L2CACHE] = { 2608c2ecf20Sopenharmony_ci "l2cache", CGU_CLK_DIV, 2618c2ecf20Sopenharmony_ci .parents = { X1000_CLK_CPUMUX, -1, -1, -1 }, 2628c2ecf20Sopenharmony_ci .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, 2638c2ecf20Sopenharmony_ci }, 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci [X1000_CLK_AHB0] = { 2668c2ecf20Sopenharmony_ci "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, 2678c2ecf20Sopenharmony_ci .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 2688c2ecf20Sopenharmony_ci .mux = { CGU_REG_CPCCR, 26, 2 }, 2698c2ecf20Sopenharmony_ci .div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 }, 2708c2ecf20Sopenharmony_ci }, 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci [X1000_CLK_AHB2PMUX] = { 2738c2ecf20Sopenharmony_ci "ahb2_apb_mux", CGU_CLK_MUX, 2748c2ecf20Sopenharmony_ci .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 2758c2ecf20Sopenharmony_ci .mux = { CGU_REG_CPCCR, 24, 2 }, 2768c2ecf20Sopenharmony_ci }, 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci [X1000_CLK_AHB2] = { 2798c2ecf20Sopenharmony_ci "ahb2", CGU_CLK_DIV, 2808c2ecf20Sopenharmony_ci .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, 2818c2ecf20Sopenharmony_ci .div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 }, 2828c2ecf20Sopenharmony_ci }, 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci [X1000_CLK_PCLK] = { 2858c2ecf20Sopenharmony_ci "pclk", CGU_CLK_DIV | CGU_CLK_GATE, 2868c2ecf20Sopenharmony_ci .parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 }, 2878c2ecf20Sopenharmony_ci .div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 }, 2888c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 28 }, 2898c2ecf20Sopenharmony_ci }, 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci [X1000_CLK_DDR] = { 2928c2ecf20Sopenharmony_ci "ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 2938c2ecf20Sopenharmony_ci .parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 }, 2948c2ecf20Sopenharmony_ci .mux = { CGU_REG_DDRCDR, 30, 2 }, 2958c2ecf20Sopenharmony_ci .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, 2968c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 31 }, 2978c2ecf20Sopenharmony_ci }, 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci [X1000_CLK_MAC] = { 3008c2ecf20Sopenharmony_ci "mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 3018c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL }, 3028c2ecf20Sopenharmony_ci .mux = { CGU_REG_MACCDR, 31, 1 }, 3038c2ecf20Sopenharmony_ci .div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 }, 3048c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 25 }, 3058c2ecf20Sopenharmony_ci }, 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci [X1000_CLK_LCD] = { 3088c2ecf20Sopenharmony_ci "lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 3098c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL }, 3108c2ecf20Sopenharmony_ci .mux = { CGU_REG_LPCDR, 31, 1 }, 3118c2ecf20Sopenharmony_ci .div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 }, 3128c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 23 }, 3138c2ecf20Sopenharmony_ci }, 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci [X1000_CLK_MSCMUX] = { 3168c2ecf20Sopenharmony_ci "msc_mux", CGU_CLK_MUX, 3178c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL}, 3188c2ecf20Sopenharmony_ci .mux = { CGU_REG_MSC0CDR, 31, 1 }, 3198c2ecf20Sopenharmony_ci }, 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci [X1000_CLK_MSC0] = { 3228c2ecf20Sopenharmony_ci "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 3238c2ecf20Sopenharmony_ci .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, 3248c2ecf20Sopenharmony_ci .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, 3258c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 4 }, 3268c2ecf20Sopenharmony_ci }, 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci [X1000_CLK_MSC1] = { 3298c2ecf20Sopenharmony_ci "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 3308c2ecf20Sopenharmony_ci .parents = { X1000_CLK_MSCMUX, -1, -1, -1 }, 3318c2ecf20Sopenharmony_ci .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, 3328c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 5 }, 3338c2ecf20Sopenharmony_ci }, 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci [X1000_CLK_OTG] = { 3368c2ecf20Sopenharmony_ci "otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 3378c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, 3388c2ecf20Sopenharmony_ci X1000_CLK_APLL, X1000_CLK_MPLL }, 3398c2ecf20Sopenharmony_ci .mux = { CGU_REG_USBCDR, 30, 2 }, 3408c2ecf20Sopenharmony_ci .div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 }, 3418c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 3 }, 3428c2ecf20Sopenharmony_ci }, 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci [X1000_CLK_SSIPLL] = { 3458c2ecf20Sopenharmony_ci "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 3468c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 }, 3478c2ecf20Sopenharmony_ci .mux = { CGU_REG_SSICDR, 31, 1 }, 3488c2ecf20Sopenharmony_ci .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, 3498c2ecf20Sopenharmony_ci }, 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci [X1000_CLK_SSIPLL_DIV2] = { 3528c2ecf20Sopenharmony_ci "ssi_pll_div2", CGU_CLK_FIXDIV, 3538c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SSIPLL }, 3548c2ecf20Sopenharmony_ci .fixdiv = { 2 }, 3558c2ecf20Sopenharmony_ci }, 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci [X1000_CLK_SSIMUX] = { 3588c2ecf20Sopenharmony_ci "ssi_mux", CGU_CLK_MUX, 3598c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 }, 3608c2ecf20Sopenharmony_ci .mux = { CGU_REG_SSICDR, 30, 1 }, 3618c2ecf20Sopenharmony_ci }, 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci [X1000_CLK_EXCLK_DIV512] = { 3648c2ecf20Sopenharmony_ci "exclk_div512", CGU_CLK_FIXDIV, 3658c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK }, 3668c2ecf20Sopenharmony_ci .fixdiv = { 512 }, 3678c2ecf20Sopenharmony_ci }, 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci [X1000_CLK_RTC] = { 3708c2ecf20Sopenharmony_ci "rtc_ercs", CGU_CLK_MUX | CGU_CLK_GATE, 3718c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK_DIV512, X1000_CLK_RTCLK }, 3728c2ecf20Sopenharmony_ci .mux = { CGU_REG_OPCR, 2, 1}, 3738c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 27 }, 3748c2ecf20Sopenharmony_ci }, 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci /* Gate-only clocks */ 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci [X1000_CLK_EMC] = { 3798c2ecf20Sopenharmony_ci "emc", CGU_CLK_GATE, 3808c2ecf20Sopenharmony_ci .parents = { X1000_CLK_AHB2, -1, -1, -1 }, 3818c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 0 }, 3828c2ecf20Sopenharmony_ci }, 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci [X1000_CLK_EFUSE] = { 3858c2ecf20Sopenharmony_ci "efuse", CGU_CLK_GATE, 3868c2ecf20Sopenharmony_ci .parents = { X1000_CLK_AHB2, -1, -1, -1 }, 3878c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 1 }, 3888c2ecf20Sopenharmony_ci }, 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci [X1000_CLK_SFC] = { 3918c2ecf20Sopenharmony_ci "sfc", CGU_CLK_GATE, 3928c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SSIPLL, -1, -1, -1 }, 3938c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 2 }, 3948c2ecf20Sopenharmony_ci }, 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci [X1000_CLK_I2C0] = { 3978c2ecf20Sopenharmony_ci "i2c0", CGU_CLK_GATE, 3988c2ecf20Sopenharmony_ci .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 3998c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 7 }, 4008c2ecf20Sopenharmony_ci }, 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci [X1000_CLK_I2C1] = { 4038c2ecf20Sopenharmony_ci "i2c1", CGU_CLK_GATE, 4048c2ecf20Sopenharmony_ci .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 4058c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 8 }, 4068c2ecf20Sopenharmony_ci }, 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci [X1000_CLK_I2C2] = { 4098c2ecf20Sopenharmony_ci "i2c2", CGU_CLK_GATE, 4108c2ecf20Sopenharmony_ci .parents = { X1000_CLK_PCLK, -1, -1, -1 }, 4118c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 9 }, 4128c2ecf20Sopenharmony_ci }, 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci [X1000_CLK_UART0] = { 4158c2ecf20Sopenharmony_ci "uart0", CGU_CLK_GATE, 4168c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4178c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 14 }, 4188c2ecf20Sopenharmony_ci }, 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci [X1000_CLK_UART1] = { 4218c2ecf20Sopenharmony_ci "uart1", CGU_CLK_GATE, 4228c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4238c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 15 }, 4248c2ecf20Sopenharmony_ci }, 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci [X1000_CLK_UART2] = { 4278c2ecf20Sopenharmony_ci "uart2", CGU_CLK_GATE, 4288c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4298c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 16 }, 4308c2ecf20Sopenharmony_ci }, 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ci [X1000_CLK_TCU] = { 4338c2ecf20Sopenharmony_ci "tcu", CGU_CLK_GATE, 4348c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4358c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 18 }, 4368c2ecf20Sopenharmony_ci }, 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci [X1000_CLK_SSI] = { 4398c2ecf20Sopenharmony_ci "ssi", CGU_CLK_GATE, 4408c2ecf20Sopenharmony_ci .parents = { X1000_CLK_SSIMUX, -1, -1, -1 }, 4418c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 19 }, 4428c2ecf20Sopenharmony_ci }, 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci [X1000_CLK_OST] = { 4458c2ecf20Sopenharmony_ci "ost", CGU_CLK_GATE, 4468c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4478c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 20 }, 4488c2ecf20Sopenharmony_ci }, 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci [X1000_CLK_PDMA] = { 4518c2ecf20Sopenharmony_ci "pdma", CGU_CLK_GATE, 4528c2ecf20Sopenharmony_ci .parents = { X1000_CLK_EXCLK, -1, -1, -1 }, 4538c2ecf20Sopenharmony_ci .gate = { CGU_REG_CLKGR, 21 }, 4548c2ecf20Sopenharmony_ci }, 4558c2ecf20Sopenharmony_ci}; 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_cistatic void __init x1000_cgu_init(struct device_node *np) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci int retval; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci cgu = ingenic_cgu_new(x1000_cgu_clocks, 4628c2ecf20Sopenharmony_ci ARRAY_SIZE(x1000_cgu_clocks), np); 4638c2ecf20Sopenharmony_ci if (!cgu) { 4648c2ecf20Sopenharmony_ci pr_err("%s: failed to initialise CGU\n", __func__); 4658c2ecf20Sopenharmony_ci return; 4668c2ecf20Sopenharmony_ci } 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci retval = ingenic_cgu_register_clocks(cgu); 4698c2ecf20Sopenharmony_ci if (retval) { 4708c2ecf20Sopenharmony_ci pr_err("%s: failed to register CGU Clocks\n", __func__); 4718c2ecf20Sopenharmony_ci return; 4728c2ecf20Sopenharmony_ci } 4738c2ecf20Sopenharmony_ci 4748c2ecf20Sopenharmony_ci ingenic_cgu_register_syscore_ops(cgu); 4758c2ecf20Sopenharmony_ci} 4768c2ecf20Sopenharmony_ci/* 4778c2ecf20Sopenharmony_ci * CGU has some children devices, this is useful for probing children devices 4788c2ecf20Sopenharmony_ci * in the case where the device node is compatible with "simple-mfd". 4798c2ecf20Sopenharmony_ci */ 4808c2ecf20Sopenharmony_ciCLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init); 481