162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * JZ4770 SoC CGU driver 462306a36Sopenharmony_ci * Copyright 2018, Paul Cercueil <paul@crapouillou.net> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/bitops.h> 862306a36Sopenharmony_ci#include <linux/clk-provider.h> 962306a36Sopenharmony_ci#include <linux/delay.h> 1062306a36Sopenharmony_ci#include <linux/io.h> 1162306a36Sopenharmony_ci#include <linux/of.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <dt-bindings/clock/ingenic,jz4770-cgu.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "cgu.h" 1662306a36Sopenharmony_ci#include "pm.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * CPM registers offset address definition 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci#define CGU_REG_CPCCR 0x00 2262306a36Sopenharmony_ci#define CGU_REG_LCR 0x04 2362306a36Sopenharmony_ci#define CGU_REG_CPPCR0 0x10 2462306a36Sopenharmony_ci#define CGU_REG_CLKGR0 0x20 2562306a36Sopenharmony_ci#define CGU_REG_OPCR 0x24 2662306a36Sopenharmony_ci#define CGU_REG_CLKGR1 0x28 2762306a36Sopenharmony_ci#define CGU_REG_CPPCR1 0x30 2862306a36Sopenharmony_ci#define CGU_REG_USBPCR1 0x48 2962306a36Sopenharmony_ci#define CGU_REG_USBCDR 0x50 3062306a36Sopenharmony_ci#define CGU_REG_I2SCDR 0x60 3162306a36Sopenharmony_ci#define CGU_REG_LPCDR 0x64 3262306a36Sopenharmony_ci#define CGU_REG_MSC0CDR 0x68 3362306a36Sopenharmony_ci#define CGU_REG_UHCCDR 0x6c 3462306a36Sopenharmony_ci#define CGU_REG_SSICDR 0x74 3562306a36Sopenharmony_ci#define CGU_REG_CIMCDR 0x7c 3662306a36Sopenharmony_ci#define CGU_REG_GPSCDR 0x80 3762306a36Sopenharmony_ci#define CGU_REG_PCMCDR 0x84 3862306a36Sopenharmony_ci#define CGU_REG_GPUCDR 0x88 3962306a36Sopenharmony_ci#define CGU_REG_MSC1CDR 0xA4 4062306a36Sopenharmony_ci#define CGU_REG_MSC2CDR 0xA8 4162306a36Sopenharmony_ci#define CGU_REG_BCHCDR 0xAC 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* bits within the OPCR register */ 4462306a36Sopenharmony_ci#define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* bits within the USBPCR1 register */ 4762306a36Sopenharmony_ci#define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */ 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic struct ingenic_cgu *cgu; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int jz4770_uhc_phy_enable(struct clk_hw *hw) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 5462306a36Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr); 5762306a36Sopenharmony_ci writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1); 5862306a36Sopenharmony_ci return 0; 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic void jz4770_uhc_phy_disable(struct clk_hw *hw) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 6462306a36Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1); 6762306a36Sopenharmony_ci writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr); 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic int jz4770_uhc_phy_is_enabled(struct clk_hw *hw) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; 7362306a36Sopenharmony_ci void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci return !(readl(reg_opcr) & OPCR_SPENDH) && 7662306a36Sopenharmony_ci (readl(reg_usbpcr1) & USBPCR1_UHC_POWER); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic const struct clk_ops jz4770_uhc_phy_ops = { 8062306a36Sopenharmony_ci .enable = jz4770_uhc_phy_enable, 8162306a36Sopenharmony_ci .disable = jz4770_uhc_phy_disable, 8262306a36Sopenharmony_ci .is_enabled = jz4770_uhc_phy_is_enabled, 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic const s8 pll_od_encoding[8] = { 8662306a36Sopenharmony_ci 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic const u8 jz4770_cgu_cpccr_div_table[] = { 9062306a36Sopenharmony_ci 1, 2, 3, 4, 6, 8, 12, 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* External clocks */ 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci [JZ4770_CLK_EXT] = { "ext", CGU_CLK_EXT }, 9862306a36Sopenharmony_ci [JZ4770_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT }, 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* PLLs */ 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci [JZ4770_CLK_PLL0] = { 10362306a36Sopenharmony_ci "pll0", CGU_CLK_PLL, 10462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 10562306a36Sopenharmony_ci .pll = { 10662306a36Sopenharmony_ci .reg = CGU_REG_CPPCR0, 10762306a36Sopenharmony_ci .rate_multiplier = 1, 10862306a36Sopenharmony_ci .m_shift = 24, 10962306a36Sopenharmony_ci .m_bits = 7, 11062306a36Sopenharmony_ci .m_offset = 1, 11162306a36Sopenharmony_ci .n_shift = 18, 11262306a36Sopenharmony_ci .n_bits = 5, 11362306a36Sopenharmony_ci .n_offset = 1, 11462306a36Sopenharmony_ci .od_shift = 16, 11562306a36Sopenharmony_ci .od_bits = 2, 11662306a36Sopenharmony_ci .od_max = 8, 11762306a36Sopenharmony_ci .od_encoding = pll_od_encoding, 11862306a36Sopenharmony_ci .bypass_reg = CGU_REG_CPPCR0, 11962306a36Sopenharmony_ci .bypass_bit = 9, 12062306a36Sopenharmony_ci .enable_bit = 8, 12162306a36Sopenharmony_ci .stable_bit = 10, 12262306a36Sopenharmony_ci }, 12362306a36Sopenharmony_ci }, 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci [JZ4770_CLK_PLL1] = { 12662306a36Sopenharmony_ci /* TODO: PLL1 can depend on PLL0 */ 12762306a36Sopenharmony_ci "pll1", CGU_CLK_PLL, 12862306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 12962306a36Sopenharmony_ci .pll = { 13062306a36Sopenharmony_ci .reg = CGU_REG_CPPCR1, 13162306a36Sopenharmony_ci .rate_multiplier = 1, 13262306a36Sopenharmony_ci .m_shift = 24, 13362306a36Sopenharmony_ci .m_bits = 7, 13462306a36Sopenharmony_ci .m_offset = 1, 13562306a36Sopenharmony_ci .n_shift = 18, 13662306a36Sopenharmony_ci .n_bits = 5, 13762306a36Sopenharmony_ci .n_offset = 1, 13862306a36Sopenharmony_ci .od_shift = 16, 13962306a36Sopenharmony_ci .od_bits = 2, 14062306a36Sopenharmony_ci .od_max = 8, 14162306a36Sopenharmony_ci .od_encoding = pll_od_encoding, 14262306a36Sopenharmony_ci .bypass_bit = -1, 14362306a36Sopenharmony_ci .enable_bit = 7, 14462306a36Sopenharmony_ci .stable_bit = 6, 14562306a36Sopenharmony_ci }, 14662306a36Sopenharmony_ci }, 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci /* Main clocks */ 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci [JZ4770_CLK_CCLK] = { 15162306a36Sopenharmony_ci "cclk", CGU_CLK_DIV, 15262306a36Sopenharmony_ci /* 15362306a36Sopenharmony_ci * Disabling the CPU clock or any parent clocks will hang the 15462306a36Sopenharmony_ci * system; mark it critical. 15562306a36Sopenharmony_ci */ 15662306a36Sopenharmony_ci .flags = CLK_IS_CRITICAL, 15762306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 15862306a36Sopenharmony_ci .div = { 15962306a36Sopenharmony_ci CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, 16062306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 16162306a36Sopenharmony_ci }, 16262306a36Sopenharmony_ci }, 16362306a36Sopenharmony_ci [JZ4770_CLK_H0CLK] = { 16462306a36Sopenharmony_ci "h0clk", CGU_CLK_DIV, 16562306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 16662306a36Sopenharmony_ci .div = { 16762306a36Sopenharmony_ci CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, 16862306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 16962306a36Sopenharmony_ci }, 17062306a36Sopenharmony_ci }, 17162306a36Sopenharmony_ci [JZ4770_CLK_H1CLK] = { 17262306a36Sopenharmony_ci "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, 17362306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 17462306a36Sopenharmony_ci .div = { 17562306a36Sopenharmony_ci CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0, 17662306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 17762306a36Sopenharmony_ci }, 17862306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 7 }, 17962306a36Sopenharmony_ci }, 18062306a36Sopenharmony_ci [JZ4770_CLK_H2CLK] = { 18162306a36Sopenharmony_ci "h2clk", CGU_CLK_DIV, 18262306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 18362306a36Sopenharmony_ci .div = { 18462306a36Sopenharmony_ci CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0, 18562306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 18662306a36Sopenharmony_ci }, 18762306a36Sopenharmony_ci }, 18862306a36Sopenharmony_ci [JZ4770_CLK_C1CLK] = { 18962306a36Sopenharmony_ci "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, 19062306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 19162306a36Sopenharmony_ci .div = { 19262306a36Sopenharmony_ci CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, 19362306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 19462306a36Sopenharmony_ci }, 19562306a36Sopenharmony_ci .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle 19662306a36Sopenharmony_ci }, 19762306a36Sopenharmony_ci [JZ4770_CLK_PCLK] = { 19862306a36Sopenharmony_ci "pclk", CGU_CLK_DIV, 19962306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, }, 20062306a36Sopenharmony_ci .div = { 20162306a36Sopenharmony_ci CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, 20262306a36Sopenharmony_ci jz4770_cgu_cpccr_div_table, 20362306a36Sopenharmony_ci }, 20462306a36Sopenharmony_ci }, 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci /* Those divided clocks can connect to PLL0 or PLL1 */ 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci [JZ4770_CLK_MMC0_MUX] = { 20962306a36Sopenharmony_ci "mmc0_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 21062306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 21162306a36Sopenharmony_ci .mux = { CGU_REG_MSC0CDR, 30, 1 }, 21262306a36Sopenharmony_ci .div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 }, 21362306a36Sopenharmony_ci .gate = { CGU_REG_MSC0CDR, 31 }, 21462306a36Sopenharmony_ci }, 21562306a36Sopenharmony_ci [JZ4770_CLK_MMC1_MUX] = { 21662306a36Sopenharmony_ci "mmc1_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 21762306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 21862306a36Sopenharmony_ci .mux = { CGU_REG_MSC1CDR, 30, 1 }, 21962306a36Sopenharmony_ci .div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 }, 22062306a36Sopenharmony_ci .gate = { CGU_REG_MSC1CDR, 31 }, 22162306a36Sopenharmony_ci }, 22262306a36Sopenharmony_ci [JZ4770_CLK_MMC2_MUX] = { 22362306a36Sopenharmony_ci "mmc2_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 22462306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 22562306a36Sopenharmony_ci .mux = { CGU_REG_MSC2CDR, 30, 1 }, 22662306a36Sopenharmony_ci .div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 }, 22762306a36Sopenharmony_ci .gate = { CGU_REG_MSC2CDR, 31 }, 22862306a36Sopenharmony_ci }, 22962306a36Sopenharmony_ci [JZ4770_CLK_CIM] = { 23062306a36Sopenharmony_ci "cim", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 23162306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 23262306a36Sopenharmony_ci .mux = { CGU_REG_CIMCDR, 31, 1 }, 23362306a36Sopenharmony_ci .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 }, 23462306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 26 }, 23562306a36Sopenharmony_ci }, 23662306a36Sopenharmony_ci [JZ4770_CLK_UHC] = { 23762306a36Sopenharmony_ci "uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 23862306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 23962306a36Sopenharmony_ci .mux = { CGU_REG_UHCCDR, 29, 1 }, 24062306a36Sopenharmony_ci .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, 24162306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 24 }, 24262306a36Sopenharmony_ci }, 24362306a36Sopenharmony_ci [JZ4770_CLK_GPU] = { 24462306a36Sopenharmony_ci "gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 24562306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 }, 24662306a36Sopenharmony_ci .mux = { CGU_REG_GPUCDR, 31, 1 }, 24762306a36Sopenharmony_ci .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 }, 24862306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 9 }, 24962306a36Sopenharmony_ci }, 25062306a36Sopenharmony_ci [JZ4770_CLK_BCH] = { 25162306a36Sopenharmony_ci "bch", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 25262306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 25362306a36Sopenharmony_ci .mux = { CGU_REG_BCHCDR, 31, 1 }, 25462306a36Sopenharmony_ci .div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 }, 25562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 1 }, 25662306a36Sopenharmony_ci }, 25762306a36Sopenharmony_ci [JZ4770_CLK_LPCLK_MUX] = { 25862306a36Sopenharmony_ci "lpclk", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 25962306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 26062306a36Sopenharmony_ci .mux = { CGU_REG_LPCDR, 29, 1 }, 26162306a36Sopenharmony_ci .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, 26262306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 28 }, 26362306a36Sopenharmony_ci }, 26462306a36Sopenharmony_ci [JZ4770_CLK_GPS] = { 26562306a36Sopenharmony_ci "gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 26662306a36Sopenharmony_ci .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, 26762306a36Sopenharmony_ci .mux = { CGU_REG_GPSCDR, 31, 1 }, 26862306a36Sopenharmony_ci .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 }, 26962306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 22 }, 27062306a36Sopenharmony_ci }, 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci /* Those divided clocks can connect to EXT, PLL0 or PLL1 */ 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci [JZ4770_CLK_SSI_MUX] = { 27562306a36Sopenharmony_ci "ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX, 27662306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 27762306a36Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 27862306a36Sopenharmony_ci .mux = { CGU_REG_SSICDR, 30, 2 }, 27962306a36Sopenharmony_ci .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 }, 28062306a36Sopenharmony_ci }, 28162306a36Sopenharmony_ci [JZ4770_CLK_PCM_MUX] = { 28262306a36Sopenharmony_ci "pcm_mux", CGU_CLK_DIV | CGU_CLK_MUX, 28362306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 28462306a36Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 28562306a36Sopenharmony_ci .mux = { CGU_REG_PCMCDR, 30, 2 }, 28662306a36Sopenharmony_ci .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 }, 28762306a36Sopenharmony_ci }, 28862306a36Sopenharmony_ci [JZ4770_CLK_I2S] = { 28962306a36Sopenharmony_ci "i2s", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 29062306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 29162306a36Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 29262306a36Sopenharmony_ci .mux = { CGU_REG_I2SCDR, 30, 2 }, 29362306a36Sopenharmony_ci .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, 29462306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 13 }, 29562306a36Sopenharmony_ci }, 29662306a36Sopenharmony_ci [JZ4770_CLK_OTG] = { 29762306a36Sopenharmony_ci "usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, 29862306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, -1, 29962306a36Sopenharmony_ci JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, 30062306a36Sopenharmony_ci .mux = { CGU_REG_USBCDR, 30, 2 }, 30162306a36Sopenharmony_ci .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 }, 30262306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 2 }, 30362306a36Sopenharmony_ci }, 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci /* Gate-only clocks */ 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci [JZ4770_CLK_SSI0] = { 30862306a36Sopenharmony_ci "ssi0", CGU_CLK_GATE, 30962306a36Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 31062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 4 }, 31162306a36Sopenharmony_ci }, 31262306a36Sopenharmony_ci [JZ4770_CLK_SSI1] = { 31362306a36Sopenharmony_ci "ssi1", CGU_CLK_GATE, 31462306a36Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 31562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 19 }, 31662306a36Sopenharmony_ci }, 31762306a36Sopenharmony_ci [JZ4770_CLK_SSI2] = { 31862306a36Sopenharmony_ci "ssi2", CGU_CLK_GATE, 31962306a36Sopenharmony_ci .parents = { JZ4770_CLK_SSI_MUX, }, 32062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 20 }, 32162306a36Sopenharmony_ci }, 32262306a36Sopenharmony_ci [JZ4770_CLK_PCM0] = { 32362306a36Sopenharmony_ci "pcm0", CGU_CLK_GATE, 32462306a36Sopenharmony_ci .parents = { JZ4770_CLK_PCM_MUX, }, 32562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 8 }, 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci [JZ4770_CLK_PCM1] = { 32862306a36Sopenharmony_ci "pcm1", CGU_CLK_GATE, 32962306a36Sopenharmony_ci .parents = { JZ4770_CLK_PCM_MUX, }, 33062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 10 }, 33162306a36Sopenharmony_ci }, 33262306a36Sopenharmony_ci [JZ4770_CLK_DMA] = { 33362306a36Sopenharmony_ci "dma", CGU_CLK_GATE, 33462306a36Sopenharmony_ci .parents = { JZ4770_CLK_H2CLK, }, 33562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 21 }, 33662306a36Sopenharmony_ci }, 33762306a36Sopenharmony_ci [JZ4770_CLK_BDMA] = { 33862306a36Sopenharmony_ci "bdma", CGU_CLK_GATE, 33962306a36Sopenharmony_ci .parents = { JZ4770_CLK_H2CLK, }, 34062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 0 }, 34162306a36Sopenharmony_ci }, 34262306a36Sopenharmony_ci [JZ4770_CLK_I2C0] = { 34362306a36Sopenharmony_ci "i2c0", CGU_CLK_GATE, 34462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 34562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 5 }, 34662306a36Sopenharmony_ci }, 34762306a36Sopenharmony_ci [JZ4770_CLK_I2C1] = { 34862306a36Sopenharmony_ci "i2c1", CGU_CLK_GATE, 34962306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 35062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 6 }, 35162306a36Sopenharmony_ci }, 35262306a36Sopenharmony_ci [JZ4770_CLK_I2C2] = { 35362306a36Sopenharmony_ci "i2c2", CGU_CLK_GATE, 35462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 35562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 15 }, 35662306a36Sopenharmony_ci }, 35762306a36Sopenharmony_ci [JZ4770_CLK_UART0] = { 35862306a36Sopenharmony_ci "uart0", CGU_CLK_GATE, 35962306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 36062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 15 }, 36162306a36Sopenharmony_ci }, 36262306a36Sopenharmony_ci [JZ4770_CLK_UART1] = { 36362306a36Sopenharmony_ci "uart1", CGU_CLK_GATE, 36462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 36562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 16 }, 36662306a36Sopenharmony_ci }, 36762306a36Sopenharmony_ci [JZ4770_CLK_UART2] = { 36862306a36Sopenharmony_ci "uart2", CGU_CLK_GATE, 36962306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 37062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 17 }, 37162306a36Sopenharmony_ci }, 37262306a36Sopenharmony_ci [JZ4770_CLK_UART3] = { 37362306a36Sopenharmony_ci "uart3", CGU_CLK_GATE, 37462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 37562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 18 }, 37662306a36Sopenharmony_ci }, 37762306a36Sopenharmony_ci [JZ4770_CLK_IPU] = { 37862306a36Sopenharmony_ci "ipu", CGU_CLK_GATE, 37962306a36Sopenharmony_ci .parents = { JZ4770_CLK_H0CLK, }, 38062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 29 }, 38162306a36Sopenharmony_ci }, 38262306a36Sopenharmony_ci [JZ4770_CLK_ADC] = { 38362306a36Sopenharmony_ci "adc", CGU_CLK_GATE, 38462306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 38562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 14 }, 38662306a36Sopenharmony_ci }, 38762306a36Sopenharmony_ci [JZ4770_CLK_AIC] = { 38862306a36Sopenharmony_ci "aic", CGU_CLK_GATE, 38962306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT, }, 39062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 8 }, 39162306a36Sopenharmony_ci }, 39262306a36Sopenharmony_ci [JZ4770_CLK_AUX] = { 39362306a36Sopenharmony_ci "aux", CGU_CLK_GATE, 39462306a36Sopenharmony_ci .parents = { JZ4770_CLK_C1CLK, }, 39562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR1, 14 }, 39662306a36Sopenharmony_ci }, 39762306a36Sopenharmony_ci [JZ4770_CLK_VPU] = { 39862306a36Sopenharmony_ci "vpu", CGU_CLK_GATE, 39962306a36Sopenharmony_ci .parents = { JZ4770_CLK_H1CLK, }, 40062306a36Sopenharmony_ci .gate = { CGU_REG_LCR, 30, false, 150 }, 40162306a36Sopenharmony_ci }, 40262306a36Sopenharmony_ci [JZ4770_CLK_MMC0] = { 40362306a36Sopenharmony_ci "mmc0", CGU_CLK_GATE, 40462306a36Sopenharmony_ci .parents = { JZ4770_CLK_MMC0_MUX, }, 40562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 3 }, 40662306a36Sopenharmony_ci }, 40762306a36Sopenharmony_ci [JZ4770_CLK_MMC1] = { 40862306a36Sopenharmony_ci "mmc1", CGU_CLK_GATE, 40962306a36Sopenharmony_ci .parents = { JZ4770_CLK_MMC1_MUX, }, 41062306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 11 }, 41162306a36Sopenharmony_ci }, 41262306a36Sopenharmony_ci [JZ4770_CLK_MMC2] = { 41362306a36Sopenharmony_ci "mmc2", CGU_CLK_GATE, 41462306a36Sopenharmony_ci .parents = { JZ4770_CLK_MMC2_MUX, }, 41562306a36Sopenharmony_ci .gate = { CGU_REG_CLKGR0, 12 }, 41662306a36Sopenharmony_ci }, 41762306a36Sopenharmony_ci [JZ4770_CLK_OTG_PHY] = { 41862306a36Sopenharmony_ci "usb_phy", CGU_CLK_GATE, 41962306a36Sopenharmony_ci .parents = { JZ4770_CLK_OTG }, 42062306a36Sopenharmony_ci .gate = { CGU_REG_OPCR, 7, true, 50 }, 42162306a36Sopenharmony_ci }, 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ci /* Custom clocks */ 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci [JZ4770_CLK_UHC_PHY] = { 42662306a36Sopenharmony_ci "uhc_phy", CGU_CLK_CUSTOM, 42762306a36Sopenharmony_ci .parents = { JZ4770_CLK_UHC, -1, -1, -1 }, 42862306a36Sopenharmony_ci .custom = { &jz4770_uhc_phy_ops }, 42962306a36Sopenharmony_ci }, 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci [JZ4770_CLK_EXT512] = { 43262306a36Sopenharmony_ci "ext/512", CGU_CLK_FIXDIV, 43362306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT }, 43462306a36Sopenharmony_ci .fixdiv = { 512 }, 43562306a36Sopenharmony_ci }, 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ci [JZ4770_CLK_RTC] = { 43862306a36Sopenharmony_ci "rtc", CGU_CLK_MUX, 43962306a36Sopenharmony_ci .parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, }, 44062306a36Sopenharmony_ci .mux = { CGU_REG_OPCR, 2, 1}, 44162306a36Sopenharmony_ci }, 44262306a36Sopenharmony_ci}; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic void __init jz4770_cgu_init(struct device_node *np) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci int retval; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci cgu = ingenic_cgu_new(jz4770_cgu_clocks, 44962306a36Sopenharmony_ci ARRAY_SIZE(jz4770_cgu_clocks), np); 45062306a36Sopenharmony_ci if (!cgu) { 45162306a36Sopenharmony_ci pr_err("%s: failed to initialise CGU\n", __func__); 45262306a36Sopenharmony_ci return; 45362306a36Sopenharmony_ci } 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci retval = ingenic_cgu_register_clocks(cgu); 45662306a36Sopenharmony_ci if (retval) 45762306a36Sopenharmony_ci pr_err("%s: failed to register CGU Clocks\n", __func__); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci ingenic_cgu_register_syscore_ops(cgu); 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci/* We only probe via devicetree, no need for a platform driver */ 46362306a36Sopenharmony_ciCLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init); 464