diff options
Diffstat (limited to 'drivers/clk/rockchip')
-rw-r--r-- | drivers/clk/rockchip/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-mmc-phase.c | 154 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-pll.c | 81 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3188.c | 79 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-rk3288.c | 246 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.c | 20 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk.h | 45 |
7 files changed, 470 insertions, 156 deletions
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index bd8514d63634..2714097f90db 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -6,6 +6,7 @@ obj-y += clk-rockchip.o obj-y += clk.o obj-y += clk-pll.o obj-y += clk-cpu.o +obj-y += clk-mmc-phase.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-y += clk-rk3188.o diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c new file mode 100644 index 000000000000..c842e3b60f21 --- /dev/null +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -0,0 +1,154 @@ +/* + * Copyright 2014 Google, Inc + * Author: Alexandru M Stan <amstan@chromium.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/slab.h> +#include <linux/clk-provider.h> +#include "clk.h" + +struct rockchip_mmc_clock { + struct clk_hw hw; + void __iomem *reg; + int id; + int shift; +}; + +#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw) + +#define RK3288_MMC_CLKGEN_DIV 2 + +static unsigned long rockchip_mmc_recalc(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / RK3288_MMC_CLKGEN_DIV; +} + +#define ROCKCHIP_MMC_DELAY_SEL BIT(10) +#define ROCKCHIP_MMC_DEGREE_MASK 0x3 +#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 +#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) + +#define PSECS_PER_SEC 1000000000000LL + +/* + * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to + * simplify calculations. So 45degs could be anywhere between 33deg and 66deg. + */ +#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 + +static int rockchip_mmc_get_phase(struct clk_hw *hw) +{ + struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); + unsigned long rate = clk_get_rate(hw->clk); + u32 raw_value; + u16 degrees; + u32 delay_num = 0; + + raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); + + degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; + + if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { + /* degrees/delaynum * 10000 */ + unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * + 36 * (rate / 1000000); + + delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); + delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; + degrees += delay_num * factor / 10000; + } + + return degrees % 360; +} + +static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) +{ + struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); + unsigned long rate = clk_get_rate(hw->clk); + u8 nineties, remainder; + u8 delay_num; + u32 raw_value; + u64 delay; + + /* allow 22 to be 22.5 */ + degrees++; + /* floor to 22.5 increment */ + degrees -= ((degrees) * 10 % 225) / 10; + + nineties = degrees / 90; + /* 22.5 multiples */ + remainder = (degrees % 90) / 22; + + delay = PSECS_PER_SEC; + do_div(delay, rate); + /* / 360 / 22.5 */ + do_div(delay, 16); + do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC); + + delay *= remainder; + delay_num = (u8) min(delay, 255ULL); + + raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; + raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; + raw_value |= nineties; + writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg); + + pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", + __clk_get_name(hw->clk), degrees, delay_num, + mmc_clock->reg, raw_value>>(mmc_clock->shift), + rockchip_mmc_get_phase(hw) + ); + + return 0; +} + +static const struct clk_ops rockchip_mmc_clk_ops = { + .recalc_rate = rockchip_mmc_recalc, + .get_phase = rockchip_mmc_get_phase, + .set_phase = rockchip_mmc_set_phase, +}; + +struct clk *rockchip_clk_register_mmc(const char *name, + const char **parent_names, u8 num_parents, + void __iomem *reg, int shift) +{ + struct clk_init_data init; + struct rockchip_mmc_clock *mmc_clock; + struct clk *clk; + + mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); + if (!mmc_clock) + return NULL; + + init.num_parents = num_parents; + init.parent_names = parent_names; + init.ops = &rockchip_mmc_clk_ops; + + mmc_clock->hw.init = &init; + mmc_clock->reg = reg; + mmc_clock->shift = shift; + + if (name) + init.name = name; + + clk = clk_register(NULL, &mmc_clock->hw); + if (IS_ERR(clk)) + goto err_free; + + return clk; + +err_free: + kfree(mmc_clock); + return NULL; +} diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index a3e886a38480..f8d3baf275b2 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -39,6 +39,7 @@ struct rockchip_clk_pll { int lock_offset; unsigned int lock_shift; enum rockchip_pll_type type; + u8 flags; const struct rockchip_pll_rate_table *rate_table; unsigned int rate_count; spinlock_t *lock; @@ -257,6 +258,55 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) return !(pllcon & RK3066_PLLCON3_PWRDOWN); } +static void rockchip_rk3066_pll_init(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); + const struct rockchip_pll_rate_table *rate; + unsigned int nf, nr, no, bwadj; + unsigned long drate; + u32 pllcon; + + if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) + return; + + drate = __clk_get_rate(hw->clk); + rate = rockchip_get_pll_settings(pll, drate); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + return; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); + nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1; + no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); + nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1; + + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); + bwadj = (pllcon >> RK3066_PLLCON2_BWADJ_SHIFT) & RK3066_PLLCON2_BWADJ_MASK; + + pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), bwadj(%d:%d)\n", + __func__, __clk_get_name(hw->clk), drate, rate->nr, nr, + rate->no, no, rate->nf, nf, rate->bwadj, bwadj); + if (rate->nr != nr || rate->no != no || rate->nf != nf + || rate->bwadj != bwadj) { + struct clk *parent = __clk_get_parent(hw->clk); + unsigned long prate; + + if (!parent) { + pr_warn("%s: parent of %s not available\n", + __func__, __clk_get_name(hw->clk)); + return; + } + + pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", + __func__, __clk_get_name(hw->clk)); + prate = __clk_get_rate(parent); + rockchip_rk3066_pll_set_rate(hw, drate, prate); + } +} + static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { .recalc_rate = rockchip_rk3066_pll_recalc_rate, .enable = rockchip_rk3066_pll_enable, @@ -271,6 +321,7 @@ static const struct clk_ops rockchip_rk3066_pll_clk_ops = { .enable = rockchip_rk3066_pll_enable, .disable = rockchip_rk3066_pll_disable, .is_enabled = rockchip_rk3066_pll_is_enabled, + .init = rockchip_rk3066_pll_init, }; /* @@ -282,7 +333,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock) + u8 clk_pll_flags, spinlock_t *lock) { const char *pll_parents[3]; struct clk_init_data init; @@ -345,8 +396,22 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, pll->reg_base = base + con_offset; pll->lock_offset = grf_lock_offset; pll->lock_shift = lock_shift; + pll->flags = clk_pll_flags; pll->lock = lock; + /* create the mux on top of the real pll */ + pll->pll_mux_ops = &clk_mux_ops; + pll_mux = &pll->pll_mux; + pll_mux->reg = base + mode_offset; + pll_mux->shift = mode_shift; + pll_mux->mask = PLL_MODE_MASK; + pll_mux->flags = 0; + pll_mux->lock = lock; + pll_mux->hw.init = &init; + + if (pll_type == pll_rk3066) + pll_mux->flags |= CLK_MUX_HIWORD_MASK; + pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { pr_err("%s: failed to register pll clock %s : %ld\n", @@ -355,10 +420,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, goto err_pll; } - /* create the mux on top of the real pll */ - pll->pll_mux_ops = &clk_mux_ops; - pll_mux = &pll->pll_mux; - /* the actual muxing is xin24m, pll-output, xin32k */ pll_parents[0] = parent_names[0]; pll_parents[1] = pll_name; @@ -370,16 +431,6 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, init.parent_names = pll_parents; init.num_parents = ARRAY_SIZE(pll_parents); - pll_mux->reg = base + mode_offset; - pll_mux->shift = mode_shift; - pll_mux->mask = PLL_MODE_MASK; - pll_mux->flags = 0; - pll_mux->lock = lock; - pll_mux->hw.init = &init; - - if (pll_type == pll_rk3066) - pll_mux->flags |= CLK_MUX_HIWORD_MASK; - mux_clk = clk_register(NULL, &pll_mux->hw); if (IS_ERR(mux_clk)) goto err_mux; diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index beed49c79126..c54078960847 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -212,13 +212,13 @@ PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), - RK2928_MODE_CON, 0, 6, rk3188_pll_rates), + RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), - RK2928_MODE_CON, 4, 5, NULL), + RK2928_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), - RK2928_MODE_CON, 8, 7, rk3188_pll_rates), + RK2928_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), - RK2928_MODE_CON, 12, 8, rk3188_pll_rates), + RK2928_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), }; #define MFLAGS CLK_MUX_HIWORD_MASK @@ -257,9 +257,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "hclk_vdpu", "aclk_vdpu", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), - GATE(0, "gpll_ddr", "gpll", 0, + GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 7, GFLAGS), - COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(0), 2, GFLAGS), @@ -270,10 +270,10 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 6, GFLAGS), GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, RK2928_CLKGATE_CON(0), 5, GFLAGS), - GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, + GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 4, GFLAGS), - COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 0, GFLAGS), COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0, @@ -304,9 +304,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -320,9 +320,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), - COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", + COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0, RK2928_CLKSEL_CON(23), 0, - RK2928_CLKGATE_CON(2), 7, 0, GFLAGS), + RK2928_CLKGATE_CON(2), 7, GFLAGS), MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0, RK2928_CLKSEL_CON(22), 4, 2, MFLAGS), @@ -330,6 +330,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, + RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, + RK2928_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, + RK2928_CLKSEL_CON(9), 0, + RK2928_CLKGATE_CON(0), 14, GFLAGS), + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), + /* * Clock-Architecture Diagram 4 */ @@ -399,8 +408,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* aclk_cpu gates */ GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), @@ -410,14 +419,14 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { /* hclk_ahb2apb is part of a clk branch */ GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), - GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), + GATE(HCLK_LCDC1, "hclk_lcdc1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS), GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS), + GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), @@ -457,18 +466,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS), - GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS), /* aclk_peri */ GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS), - GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS), - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 4, GFLAGS), + GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS), + GATE(0, "pclk_peri_axi_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS), GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), @@ -511,7 +520,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { | CLK_DIVIDER_READ_ONLY, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, + GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, @@ -577,14 +586,6 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 12, GFLAGS), MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, RK2928_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(0), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), @@ -618,7 +619,7 @@ PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { - COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, + COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), @@ -633,7 +634,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK2928_CLKGATE_CON(4), 9, GFLAGS), - GATE(CORE_L2C, "core_l2c", "armclk", 0, + GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 4, GFLAGS), COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, @@ -663,7 +664,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKSEL_CON(30), 0, 2, DFLAGS, RK2928_CLKGATE_CON(3), 6, GFLAGS), DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0, - RK2928_CLKGATE_CON(11), 8, 6, DFLAGS), + RK2928_CLKSEL_CON(11), 8, 6, DFLAGS), MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), @@ -675,14 +676,6 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 10, GFLAGS), MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), - COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, - RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, - RK2928_CLKGATE_CON(13), 13, GFLAGS), - COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, - RK2928_CLKSEL_CON(9), 0, - RK2928_CLKGATE_CON(0), 14, GFLAGS), - MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, - RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 23278291da44..ac6be7c0132d 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -16,6 +16,7 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/syscore_ops.h> #include <dt-bindings/clock/rk3288-cru.h> #include "clk.h" @@ -83,11 +84,13 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE( 742500000, 8, 495, 2), RK3066_PLL_RATE( 696000000, 1, 58, 2), RK3066_PLL_RATE( 600000000, 1, 50, 2), - RK3066_PLL_RATE( 594000000, 2, 198, 4), + RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1), RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 504000000, 1, 84, 4), + RK3066_PLL_RATE( 500000000, 3, 125, 2), RK3066_PLL_RATE( 456000000, 1, 76, 4), RK3066_PLL_RATE( 408000000, 1, 68, 4), + RK3066_PLL_RATE( 400000000, 3, 100, 2), RK3066_PLL_RATE( 384000000, 2, 128, 4), RK3066_PLL_RATE( 360000000, 1, 60, 4), RK3066_PLL_RATE( 312000000, 1, 52, 4), @@ -173,14 +176,14 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; -PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" }; +PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" }; +PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" }; PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; -PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" }; PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; @@ -192,22 +195,22 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1", - "sclk_otgphy2" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", + "sclk_otgphy0" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), - RK3288_MODE_CON, 0, 6, rk3288_pll_rates), + RK3288_MODE_CON, 0, 6, 0, rk3288_pll_rates), [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), - RK3288_MODE_CON, 4, 5, NULL), + RK3288_MODE_CON, 4, 5, 0, NULL), [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), - RK3288_MODE_CON, 8, 7, rk3288_pll_rates), + RK3288_MODE_CON, 8, 7, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), - RK3288_MODE_CON, 12, 8, rk3288_pll_rates), + RK3288_MODE_CON, 12, 8, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), - RK3288_MODE_CON, 14, 9, rk3288_pll_rates), + RK3288_MODE_CON, 14, 9, ROCKCHIP_PLL_SYNC_RATE, rk3288_pll_rates), }; static struct clk_div_table div_hclk_cpu_t[] = { @@ -226,67 +229,67 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { * Clock-Architecture Diagram 1 */ - GATE(0, "apll_core", "apll", 0, + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 1, GFLAGS), - GATE(0, "gpll_core", "gpll", 0, + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 0, GFLAGS), - COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 1, GFLAGS), - COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 2, GFLAGS), - COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, + COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 3, GFLAGS), - COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, + COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 4, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 5, GFLAGS), - COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, + COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 6, GFLAGS), COMPOSITE_NOMUX(0, "atclk", "armclk", 0, RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 7, GFLAGS), - COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, + COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, RK3288_CLKGATE_CON(12), 8, GFLAGS), GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 9, GFLAGS), - GATE(0, "cs_dbg", "pclk_dbg_pre", 0, + GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(12), 10, GFLAGS), GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, RK3288_CLKGATE_CON(12), 11, GFLAGS), - GATE(0, "dpll_ddr", "dpll", 0, + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 8, GFLAGS), GATE(0, "gpll_ddr", "gpll", 0, RK3288_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0, + COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), - GATE(0, "gpll_aclk_cpu", "gpll", 0, + GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 10, GFLAGS), - GATE(0, "cpll_aclk_cpu", "cpll", 0, + GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 11, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, + COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), - DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, + DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), - GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0, + GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 3, GFLAGS), - COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, RK3288_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, @@ -294,7 +297,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), - GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0, + GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, @@ -305,7 +308,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(4), 2, GFLAGS), MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT, RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), - COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT, + COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0, RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, RK3288_CLKGATE_CON(4), 0, GFLAGS), GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT, @@ -325,7 +328,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 7, GFLAGS), - COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0, + COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0, RK3288_CLKSEL_CON(41), 0, RK3288_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, @@ -373,12 +376,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), - COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(3), 0, GFLAGS), DIV(0, "hclk_vio", "aclk_vio0", 0, RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), - COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(3), 2, GFLAGS), @@ -436,24 +439,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { DIV(0, "pclk_pd_alive", "gpll", 0, RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), - COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0, + COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 8, GFLAGS), - COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0, + COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(5), 7, GFLAGS), - COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, + COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(2), 0, GFLAGS), COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0, RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 3, GFLAGS), - COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0, + COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, RK3288_CLKGATE_CON(2), 2, GFLAGS), - GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0, + GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(2), 1, GFLAGS), /* @@ -483,6 +486,18 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, RK3288_CLKGATE_CON(13), 3, GFLAGS), + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3288_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3288_SDMMC_CON1, 0), + + MMC(SCLK_SDIO0_DRV, "sdio0_drv", "sclk_sdio0", RK3288_SDIO0_CON0, 1), + MMC(SCLK_SDIO0_SAMPLE, "sdio0_sample", "sclk_sdio0", RK3288_SDIO0_CON1, 0), + + MMC(SCLK_SDIO1_DRV, "sdio1_drv", "sclk_sdio1", RK3288_SDIO1_CON0, 1), + MMC(SCLK_SDIO1_SAMPLE, "sdio1_sample", "sclk_sdio1", RK3288_SDIO1_CON1, 0), + + MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3288_EMMC_CON0, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3288_EMMC_CON1, 0), + COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0, RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(4), 11, GFLAGS), @@ -490,13 +505,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), - GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0, + GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, @@ -517,7 +532,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, RK3288_CLKGATE_CON(5), 6, GFLAGS), - COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0, + COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0, RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(1), 8, GFLAGS), COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0, @@ -585,7 +600,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0, RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, - RK3288_CLKGATE_CON(5), 15, GFLAGS), + RK3288_CLKGATE_CON(5), 14, GFLAGS), COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, RK3288_CLKGATE_CON(3), 6, GFLAGS), @@ -601,19 +616,19 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ /* aclk_cpu gates */ - GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS), - GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS), - GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS), + GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS), + GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS), + GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS), GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), - GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS), - GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS), + GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS), + GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS), GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), /* hclk_cpu gates */ GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), - GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS), + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS), GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), @@ -622,42 +637,42 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), - GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), - GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), - GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), - GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), + GATE(PCLK_DDRUPCTL0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), + GATE(PCLK_PUBL0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), + GATE(PCLK_DDRUPCTL1, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), + GATE(PCLK_PUBL1, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), - GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS), + GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS), /* ddrctrl [DDR Controller PHY clock] gates */ - GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS), - GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS), + GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS), + GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS), /* ddrphy gates */ - GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS), - GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS), + GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS), /* aclk_peri gates */ - GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS), + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS), GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), - GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS), - GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS), + GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS), GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), /* hclk_peri gates */ - GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS), - GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS), + GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS), + GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS), GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), - GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS), + GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS), GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), - GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS), - GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS), - GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS), - GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS), + GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS), + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS), + GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS), + GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS), GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), @@ -669,7 +684,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), /* pclk_peri gates */ - GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS), + GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), @@ -705,48 +720,48 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), - GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS), - GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), + GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS), + GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS), /* pclk_pd_pmu gates */ - GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS), - GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS), - GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS), - GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS), + GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS), + GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS), + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS), GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), /* hclk_vio gates */ GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), - GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), - GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), + GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS), + GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS), GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), - GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), + GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 10, GFLAGS), GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), - GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS), GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), - GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), + GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 11, GFLAGS), /* aclk_vio0 gates */ GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), - GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), + GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS), GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), /* aclk_vio1 gates */ GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), - GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), + GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS), /* aclk_rga_pre gates */ GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), - GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), + GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS), /* * Other ungrouped clocks. @@ -762,6 +777,64 @@ static const char *rk3288_critical_clocks[] __initconst = { "hclk_peri", }; +#ifdef CONFIG_PM_SLEEP +static void __iomem *rk3288_cru_base; + +/* Some CRU registers will be reset in maskrom when the system + * wakes up from fastboot. + * So save them before suspend, restore them after resume. + */ +static const int rk3288_saved_cru_reg_ids[] = { + RK3288_MODE_CON, + RK3288_CLKSEL_CON(0), + RK3288_CLKSEL_CON(1), + RK3288_CLKSEL_CON(10), + RK3288_CLKSEL_CON(33), + RK3288_CLKSEL_CON(37), +}; + +static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; + +static int rk3288_clk_suspend(void) +{ + int i, reg_id; + + for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + rk3288_saved_cru_regs[i] = + readl_relaxed(rk3288_cru_base + reg_id); + } + return 0; +} + +static void rk3288_clk_resume(void) +{ + int i, reg_id; + + for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) { + reg_id = rk3288_saved_cru_reg_ids[i]; + + writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000, + rk3288_cru_base + reg_id); + } +} + +static struct syscore_ops rk3288_clk_syscore_ops = { + .suspend = rk3288_clk_suspend, + .resume = rk3288_clk_resume, +}; + +static void rk3288_clk_sleep_init(void __iomem *reg_base) +{ + rk3288_cru_base = reg_base; + register_syscore_ops(&rk3288_clk_syscore_ops); +} + +#else /* CONFIG_PM_SLEEP */ +static void rk3288_clk_sleep_init(void __iomem *reg_base) {} +#endif + static void __init rk3288_clk_init(struct device_node *np) { void __iomem *reg_base; @@ -810,5 +883,6 @@ static void __init rk3288_clk_init(struct device_node *np) ROCKCHIP_SOFTRST_HIWORD_MASK); rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); + rk3288_clk_sleep_init(reg_base); } CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 880a266f0143..20e05bbb3a67 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -197,7 +197,8 @@ void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, list->parent_names, list->num_parents, reg_base, list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, - list->mode_shift, list->rate_table, &clk_lock); + list->mode_shift, list->rate_table, + list->pll_flags, &clk_lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); @@ -244,9 +245,6 @@ void __init rockchip_clk_register_branches( list->div_flags, &clk_lock); break; case branch_fraction_divider: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_frac_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->div_flags, @@ -256,18 +254,12 @@ void __init rockchip_clk_register_branches( case branch_gate: flags |= CLK_SET_RATE_PARENT; - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = clk_register_gate(NULL, list->name, list->parent_names[0], flags, reg_base + list->gate_offset, list->gate_shift, list->gate_flags, &clk_lock); break; case branch_composite: - /* keep all gates untouched for now */ - flags |= CLK_IGNORE_UNUSED; - clk = rockchip_clk_register_branch(list->name, list->parent_names, list->num_parents, reg_base, list->muxdiv_offset, list->mux_shift, @@ -277,6 +269,14 @@ void __init rockchip_clk_register_branches( list->gate_offset, list->gate_shift, list->gate_flags, flags, &clk_lock); break; + case branch_mmc: + clk = rockchip_clk_register_mmc( + list->name, + list->parent_names, list->num_parents, + reg_base + list->muxdiv_offset, + list->div_shift + ); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ca009ab0a33a..58d2e3bdf22f 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -48,6 +48,14 @@ #define RK3288_GLB_SRST_SND 0x1b4 #define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8) #define RK3288_MISC_CON 0x1e8 +#define RK3288_SDMMC_CON0 0x200 +#define RK3288_SDMMC_CON1 0x204 +#define RK3288_SDIO0_CON0 0x208 +#define RK3288_SDIO0_CON1 0x20c +#define RK3288_SDIO1_CON0 0x210 +#define RK3288_SDIO1_CON1 0x214 +#define RK3288_EMMC_CON0 0x218 +#define RK3288_EMMC_CON1 0x21c enum rockchip_pll_type { pll_rk3066, @@ -62,6 +70,15 @@ enum rockchip_pll_type { .bwadj = (_nf >> 1), \ } +#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw) \ +{ \ + .rate = _rate##U, \ + .nr = _nr, \ + .nf = _nf, \ + .no = _no, \ + .bwadj = _bw, \ +} + struct rockchip_pll_rate_table { unsigned long rate; unsigned int nr; @@ -81,7 +98,12 @@ struct rockchip_pll_rate_table { * @mode_shift: offset inside the mode-register for the mode of this pll. * @lock_shift: offset inside the lock register for the lock status. * @type: Type of PLL to be registered. + * @pll_flags: hardware-specific flags * @rate_table: Table of usable pll rates + * + * Flags: + * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the + * rate_table parameters and ajust them if necessary. */ struct rockchip_pll_clock { unsigned int id; @@ -94,11 +116,14 @@ struct rockchip_pll_clock { int mode_shift; int lock_shift; enum rockchip_pll_type type; + u8 pll_flags; struct rockchip_pll_rate_table *rate_table; }; +#define ROCKCHIP_PLL_SYNC_RATE BIT(0) + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ - _lshift, _rtable) \ + _lshift, _pflags, _rtable) \ { \ .id = _id, \ .type = _type, \ @@ -110,6 +135,7 @@ struct rockchip_pll_clock { .mode_offset = _mode, \ .mode_shift = _mshift, \ .lock_shift = _lshift, \ + .pll_flags = _pflags, \ .rate_table = _rtable, \ } @@ -118,7 +144,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, void __iomem *base, int con_offset, int grf_lock_offset, int lock_shift, int reg_mode, int mode_shift, struct rockchip_pll_rate_table *rate_table, - spinlock_t *lock); + u8 clk_pll_flags, spinlock_t *lock); struct rockchip_cpuclk_clksel { int reg; @@ -152,6 +178,10 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, const struct rockchip_cpuclk_rate_table *rates, int nrates, void __iomem *reg_base, spinlock_t *lock); +struct clk *rockchip_clk_register_mmc(const char *name, + const char **parent_names, u8 num_parents, + void __iomem *reg, int shift); + #define PNAME(x) static const char *x[] __initconst enum rockchip_clk_branch_type { @@ -160,6 +190,7 @@ enum rockchip_clk_branch_type { branch_divider, branch_fraction_divider, branch_gate, + branch_mmc, }; struct rockchip_clk_branch { @@ -352,6 +383,16 @@ struct rockchip_clk_branch { .gate_flags = gf, \ } +#define MMC(_id, cname, pname, offset, shift) \ + { \ + .id = _id, \ + .branch_type = branch_mmc, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .muxdiv_offset = offset, \ + .div_shift = shift, \ + } void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); |