Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'clk-rockchip' of git://git.linaro.org/people/mike.turquette/linux into next/soc

This is a dependency for the rk3288 DT updates, the branch should
first get merged through Mike's clk git.

* 'clk-rockchip' of git://git.linaro.org/people/mike.turquette/linux:
ARM: rockchip: Select ARCH_HAS_RESET_CONTROLLER
clk: rockchip: add clock controller for rk3288
dt-bindings: add documentation for rk3288 cru
clk: rockchip: add clock driver for rk3188 and rk3066 clocks
dt-bindings: add documentation for rk3188 clock and reset unit
clk: rockchip: add reset controller
clk: rockchip: add clock type for pll clocks and pll used on rk3066
clk: rockchip: add basic infrastructure for clock branches
clk: composite: improve rate_hw sanity check logic
clk: composite: allow read-only clocks
clk: composite: support determine_rate using rate_ops->round_rate + mux_ops->set_parent

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+3338 -15
+61
Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt
··· 1 + * Rockchip RK3188/RK3066 Clock and Reset Unit 2 + 3 + The RK3188/RK3066 clock controller generates and supplies clock to various 4 + controllers within the SoC and also implements a reset controller for SoC 5 + peripherals. 6 + 7 + Required Properties: 8 + 9 + - compatible: should be "rockchip,rk3188-cru", "rockchip,rk3188a-cru" or 10 + "rockchip,rk3066a-cru" 11 + - reg: physical base address of the controller and length of memory mapped 12 + region. 13 + - #clock-cells: should be 1. 14 + - #reset-cells: should be 1. 15 + 16 + Optional Properties: 17 + 18 + - rockchip,grf: phandle to the syscon managing the "general register files" 19 + If missing pll rates are not changable, due to the missing pll lock status. 20 + 21 + Each clock is assigned an identifier and client nodes can use this identifier 22 + to specify the clock which they consume. All available clocks are defined as 23 + preprocessor macros in the dt-bindings/clock/rk3188-cru.h and 24 + dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources. 25 + Similar macros exist for the reset sources in these files. 26 + 27 + External clocks: 28 + 29 + There are several clocks that are generated outside the SoC. It is expected 30 + that they are defined using standard clock bindings with following 31 + clock-output-names: 32 + - "xin24m" - crystal input - required, 33 + - "xin32k" - rtc clock - optional, 34 + - "xin27m" - 27mhz crystal input on rk3066 - optional, 35 + - "ext_hsadc" - external HSADC clock - optional, 36 + - "ext_cif0" - external camera clock - optional, 37 + - "ext_rmii" - external RMII clock - optional, 38 + - "ext_jtag" - externalJTAG clock - optional 39 + 40 + Example: Clock controller node: 41 + 42 + cru: cru@20000000 { 43 + compatible = "rockchip,rk3188-cru"; 44 + reg = <0x20000000 0x1000>; 45 + rockchip,grf = <&grf>; 46 + 47 + #clock-cells = <1>; 48 + #reset-cells = <1>; 49 + }; 50 + 51 + Example: UART controller node that consumes the clock generated by the clock 52 + controller: 53 + 54 + uart0: serial@10124000 { 55 + compatible = "snps,dw-apb-uart"; 56 + reg = <0x10124000 0x400>; 57 + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; 58 + reg-shift = <2>; 59 + reg-io-width = <1>; 60 + clocks = <&cru SCLK_UART0>; 61 + };
+61
Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
··· 1 + * Rockchip RK3288 Clock and Reset Unit 2 + 3 + The RK3288 clock controller generates and supplies clock to various 4 + controllers within the SoC and also implements a reset controller for SoC 5 + peripherals. 6 + 7 + Required Properties: 8 + 9 + - compatible: should be "rockchip,rk3288-cru" 10 + - reg: physical base address of the controller and length of memory mapped 11 + region. 12 + - #clock-cells: should be 1. 13 + - #reset-cells: should be 1. 14 + 15 + Optional Properties: 16 + 17 + - rockchip,grf: phandle to the syscon managing the "general register files" 18 + If missing pll rates are not changable, due to the missing pll lock status. 19 + 20 + Each clock is assigned an identifier and client nodes can use this identifier 21 + to specify the clock which they consume. All available clocks are defined as 22 + preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be 23 + used in device tree sources. Similar macros exist for the reset sources in 24 + these files. 25 + 26 + External clocks: 27 + 28 + There are several clocks that are generated outside the SoC. It is expected 29 + that they are defined using standard clock bindings with following 30 + clock-output-names: 31 + - "xin24m" - crystal input - required, 32 + - "xin32k" - rtc clock - optional, 33 + - "ext_i2s" - external I2S clock - optional, 34 + - "ext_hsadc" - external HSADC clock - optional, 35 + - "ext_edp_24m" - external display port clock - optional, 36 + - "ext_vip" - external VIP clock - optional, 37 + - "ext_isp" - external ISP clock - optional, 38 + - "ext_jtag" - external JTAG clock - optional 39 + 40 + Example: Clock controller node: 41 + 42 + cru: cru@20000000 { 43 + compatible = "rockchip,rk3188-cru"; 44 + reg = <0x20000000 0x1000>; 45 + rockchip,grf = <&grf>; 46 + 47 + #clock-cells = <1>; 48 + #reset-cells = <1>; 49 + }; 50 + 51 + Example: UART controller node that consumes the clock generated by the clock 52 + controller: 53 + 54 + uart0: serial@10124000 { 55 + compatible = "snps,dw-apb-uart"; 56 + reg = <0x10124000 0x400>; 57 + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; 58 + reg-shift = <2>; 59 + reg-io-width = <1>; 60 + clocks = <&cru SCLK_UART0>; 61 + };
+3
Documentation/devicetree/bindings/clock/rockchip.txt
··· 6 6 7 7 == Gate clocks == 8 8 9 + These bindings are deprecated! 10 + Please use the soc specific CRU bindings instead. 11 + 9 12 The gate registers form a continuos block which makes the dt node 10 13 structure a matter of taste, as either all gates can be put into 11 14 one gate clock spanning all registers or they can be divided into
+1
arch/arm/mach-rockchip/Kconfig
··· 2 2 bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7 3 3 select PINCTRL 4 4 select PINCTRL_ROCKCHIP 5 + select ARCH_HAS_RESET_CONTROLLER 5 6 select ARCH_REQUIRE_GPIOLIB 6 7 select ARM_GIC 7 8 select CACHE_L2X0
+64 -15
drivers/clk/clk-composite.c
··· 64 64 const struct clk_ops *mux_ops = composite->mux_ops; 65 65 struct clk_hw *rate_hw = composite->rate_hw; 66 66 struct clk_hw *mux_hw = composite->mux_hw; 67 + struct clk *parent; 68 + unsigned long parent_rate; 69 + long tmp_rate, best_rate = 0; 70 + unsigned long rate_diff; 71 + unsigned long best_rate_diff = ULONG_MAX; 72 + int i; 67 73 68 74 if (rate_hw && rate_ops && rate_ops->determine_rate) { 69 75 rate_hw->clk = hw->clk; 70 76 return rate_ops->determine_rate(rate_hw, rate, best_parent_rate, 71 77 best_parent_p); 78 + } else if (rate_hw && rate_ops && rate_ops->round_rate && 79 + mux_hw && mux_ops && mux_ops->set_parent) { 80 + *best_parent_p = NULL; 81 + 82 + if (__clk_get_flags(hw->clk) & CLK_SET_RATE_NO_REPARENT) { 83 + *best_parent_p = clk_get_parent(mux_hw->clk); 84 + *best_parent_rate = __clk_get_rate(*best_parent_p); 85 + 86 + return rate_ops->round_rate(rate_hw, rate, 87 + best_parent_rate); 88 + } 89 + 90 + for (i = 0; i < __clk_get_num_parents(mux_hw->clk); i++) { 91 + parent = clk_get_parent_by_index(mux_hw->clk, i); 92 + if (!parent) 93 + continue; 94 + 95 + parent_rate = __clk_get_rate(parent); 96 + 97 + tmp_rate = rate_ops->round_rate(rate_hw, rate, 98 + &parent_rate); 99 + if (tmp_rate < 0) 100 + continue; 101 + 102 + rate_diff = abs(rate - tmp_rate); 103 + 104 + if (!rate_diff || !*best_parent_p 105 + || best_rate_diff > rate_diff) { 106 + *best_parent_p = parent; 107 + *best_parent_rate = parent_rate; 108 + best_rate_diff = rate_diff; 109 + best_rate = tmp_rate; 110 + } 111 + 112 + if (!rate_diff) 113 + return rate; 114 + } 115 + 116 + return best_rate; 72 117 } else if (mux_hw && mux_ops && mux_ops->determine_rate) { 73 118 mux_hw->clk = hw->clk; 74 119 return mux_ops->determine_rate(mux_hw, rate, best_parent_rate, ··· 207 162 clk_composite_ops = &composite->ops; 208 163 209 164 if (mux_hw && mux_ops) { 210 - if (!mux_ops->get_parent || !mux_ops->set_parent) { 165 + if (!mux_ops->get_parent) { 211 166 clk = ERR_PTR(-EINVAL); 212 167 goto err; 213 168 } ··· 215 170 composite->mux_hw = mux_hw; 216 171 composite->mux_ops = mux_ops; 217 172 clk_composite_ops->get_parent = clk_composite_get_parent; 218 - clk_composite_ops->set_parent = clk_composite_set_parent; 173 + if (mux_ops->set_parent) 174 + clk_composite_ops->set_parent = clk_composite_set_parent; 219 175 if (mux_ops->determine_rate) 220 176 clk_composite_ops->determine_rate = clk_composite_determine_rate; 221 177 } ··· 226 180 clk = ERR_PTR(-EINVAL); 227 181 goto err; 228 182 } 183 + clk_composite_ops->recalc_rate = clk_composite_recalc_rate; 229 184 230 - /* .round_rate is a prerequisite for .set_rate */ 231 - if (rate_ops->round_rate) { 232 - clk_composite_ops->round_rate = clk_composite_round_rate; 233 - if (rate_ops->set_rate) { 234 - clk_composite_ops->set_rate = clk_composite_set_rate; 235 - } 236 - } else { 237 - WARN(rate_ops->set_rate, 238 - "%s: missing round_rate op is required\n", 239 - __func__); 185 + if (rate_ops->determine_rate) 186 + clk_composite_ops->determine_rate = 187 + clk_composite_determine_rate; 188 + else if (rate_ops->round_rate) 189 + clk_composite_ops->round_rate = 190 + clk_composite_round_rate; 191 + 192 + /* .set_rate requires either .round_rate or .determine_rate */ 193 + if (rate_ops->set_rate) { 194 + if (rate_ops->determine_rate || rate_ops->round_rate) 195 + clk_composite_ops->set_rate = 196 + clk_composite_set_rate; 197 + else 198 + WARN(1, "%s: missing round_rate op is required\n", 199 + __func__); 240 200 } 241 201 242 202 composite->rate_hw = rate_hw; 243 203 composite->rate_ops = rate_ops; 244 - clk_composite_ops->recalc_rate = clk_composite_recalc_rate; 245 - if (rate_ops->determine_rate) 246 - clk_composite_ops->determine_rate = clk_composite_determine_rate; 247 204 } 248 205 249 206 if (gate_hw && gate_ops) {
+6
drivers/clk/rockchip/Makefile
··· 3 3 # 4 4 5 5 obj-y += clk-rockchip.o 6 + obj-y += clk.o 7 + obj-y += clk-pll.o 8 + obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 9 + 10 + obj-y += clk-rk3188.o 11 + obj-y += clk-rk3288.o
+431
drivers/clk/rockchip/clk-pll.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <asm/div64.h> 17 + #include <linux/slab.h> 18 + #include <linux/io.h> 19 + #include <linux/delay.h> 20 + #include <linux/clk.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/regmap.h> 23 + #include "clk.h" 24 + 25 + #define PLL_MODE_MASK 0x3 26 + #define PLL_MODE_SLOW 0x0 27 + #define PLL_MODE_NORM 0x1 28 + #define PLL_MODE_DEEP 0x2 29 + 30 + struct rockchip_clk_pll { 31 + struct clk_hw hw; 32 + 33 + struct clk_mux pll_mux; 34 + const struct clk_ops *pll_mux_ops; 35 + 36 + struct notifier_block clk_nb; 37 + bool rate_change_remuxed; 38 + 39 + void __iomem *reg_base; 40 + int lock_offset; 41 + unsigned int lock_shift; 42 + enum rockchip_pll_type type; 43 + const struct rockchip_pll_rate_table *rate_table; 44 + unsigned int rate_count; 45 + spinlock_t *lock; 46 + }; 47 + 48 + #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) 49 + #define to_rockchip_clk_pll_nb(nb) \ 50 + container_of(nb, struct rockchip_clk_pll, clk_nb) 51 + 52 + static const struct rockchip_pll_rate_table *rockchip_get_pll_settings( 53 + struct rockchip_clk_pll *pll, unsigned long rate) 54 + { 55 + const struct rockchip_pll_rate_table *rate_table = pll->rate_table; 56 + int i; 57 + 58 + for (i = 0; i < pll->rate_count; i++) { 59 + if (rate == rate_table[i].rate) 60 + return &rate_table[i]; 61 + } 62 + 63 + return NULL; 64 + } 65 + 66 + static long rockchip_pll_round_rate(struct clk_hw *hw, 67 + unsigned long drate, unsigned long *prate) 68 + { 69 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 70 + const struct rockchip_pll_rate_table *rate_table = pll->rate_table; 71 + int i; 72 + 73 + /* Assumming rate_table is in descending order */ 74 + for (i = 0; i < pll->rate_count; i++) { 75 + if (drate >= rate_table[i].rate) 76 + return rate_table[i].rate; 77 + } 78 + 79 + /* return minimum supported value */ 80 + return rate_table[i - 1].rate; 81 + } 82 + 83 + /* 84 + * Wait for the pll to reach the locked state. 85 + * The calling set_rate function is responsible for making sure the 86 + * grf regmap is available. 87 + */ 88 + static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) 89 + { 90 + struct regmap *grf = rockchip_clk_get_grf(); 91 + unsigned int val; 92 + int delay = 24000000, ret; 93 + 94 + while (delay > 0) { 95 + ret = regmap_read(grf, pll->lock_offset, &val); 96 + if (ret) { 97 + pr_err("%s: failed to read pll lock status: %d\n", 98 + __func__, ret); 99 + return ret; 100 + } 101 + 102 + if (val & BIT(pll->lock_shift)) 103 + return 0; 104 + delay--; 105 + } 106 + 107 + pr_err("%s: timeout waiting for pll to lock\n", __func__); 108 + return -ETIMEDOUT; 109 + } 110 + 111 + /** 112 + * Set pll mux when changing the pll rate. 113 + * This makes sure to move the pll mux away from the actual pll before 114 + * changing its rate and back to the original parent after the change. 115 + */ 116 + static int rockchip_pll_notifier_cb(struct notifier_block *nb, 117 + unsigned long event, void *data) 118 + { 119 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll_nb(nb); 120 + struct clk_mux *pll_mux = &pll->pll_mux; 121 + const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 122 + int cur_parent; 123 + 124 + switch (event) { 125 + case PRE_RATE_CHANGE: 126 + cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 127 + if (cur_parent == PLL_MODE_NORM) { 128 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 129 + pll->rate_change_remuxed = 1; 130 + } 131 + break; 132 + case POST_RATE_CHANGE: 133 + if (pll->rate_change_remuxed) { 134 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 135 + pll->rate_change_remuxed = 0; 136 + } 137 + break; 138 + } 139 + 140 + return NOTIFY_OK; 141 + } 142 + 143 + /** 144 + * PLL used in RK3066, RK3188 and RK3288 145 + */ 146 + 147 + #define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1) 148 + 149 + #define RK3066_PLLCON(i) (i * 0x4) 150 + #define RK3066_PLLCON0_OD_MASK 0xf 151 + #define RK3066_PLLCON0_OD_SHIFT 0 152 + #define RK3066_PLLCON0_NR_MASK 0x3f 153 + #define RK3066_PLLCON0_NR_SHIFT 8 154 + #define RK3066_PLLCON1_NF_MASK 0x1fff 155 + #define RK3066_PLLCON1_NF_SHIFT 0 156 + #define RK3066_PLLCON2_BWADJ_MASK 0xfff 157 + #define RK3066_PLLCON2_BWADJ_SHIFT 0 158 + #define RK3066_PLLCON3_RESET (1 << 5) 159 + #define RK3066_PLLCON3_PWRDOWN (1 << 1) 160 + #define RK3066_PLLCON3_BYPASS (1 << 0) 161 + 162 + static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, 163 + unsigned long prate) 164 + { 165 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 166 + u64 nf, nr, no, rate64 = prate; 167 + u32 pllcon; 168 + 169 + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3)); 170 + if (pllcon & RK3066_PLLCON3_BYPASS) { 171 + pr_debug("%s: pll %s is bypassed\n", __func__, 172 + __clk_get_name(hw->clk)); 173 + return prate; 174 + } 175 + 176 + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); 177 + nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK; 178 + 179 + pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); 180 + nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK; 181 + no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK; 182 + 183 + rate64 *= (nf + 1); 184 + do_div(rate64, nr + 1); 185 + do_div(rate64, no + 1); 186 + 187 + return (unsigned long)rate64; 188 + } 189 + 190 + static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, 191 + unsigned long prate) 192 + { 193 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 194 + const struct rockchip_pll_rate_table *rate; 195 + unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); 196 + struct regmap *grf = rockchip_clk_get_grf(); 197 + int ret; 198 + 199 + if (IS_ERR(grf)) { 200 + pr_debug("%s: grf regmap not available, aborting rate change\n", 201 + __func__); 202 + return PTR_ERR(grf); 203 + } 204 + 205 + pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", 206 + __func__, __clk_get_name(hw->clk), old_rate, drate, prate); 207 + 208 + /* Get required rate settings from table */ 209 + rate = rockchip_get_pll_settings(pll, drate); 210 + if (!rate) { 211 + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 212 + drate, __clk_get_name(hw->clk)); 213 + return -EINVAL; 214 + } 215 + 216 + pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", 217 + __func__, rate->rate, rate->nr, rate->no, rate->nf); 218 + 219 + /* enter reset mode */ 220 + writel(HIWORD_UPDATE(RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0), 221 + pll->reg_base + RK3066_PLLCON(3)); 222 + 223 + /* update pll values */ 224 + writel(HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK, 225 + RK3066_PLLCON0_NR_SHIFT) | 226 + HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK, 227 + RK3066_PLLCON0_OD_SHIFT), 228 + pll->reg_base + RK3066_PLLCON(0)); 229 + 230 + writel_relaxed(HIWORD_UPDATE(rate->nf - 1, RK3066_PLLCON1_NF_MASK, 231 + RK3066_PLLCON1_NF_SHIFT), 232 + pll->reg_base + RK3066_PLLCON(1)); 233 + writel_relaxed(HIWORD_UPDATE(rate->bwadj, RK3066_PLLCON2_BWADJ_MASK, 234 + RK3066_PLLCON2_BWADJ_SHIFT), 235 + pll->reg_base + RK3066_PLLCON(2)); 236 + 237 + /* leave reset and wait the reset_delay */ 238 + writel(HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0), 239 + pll->reg_base + RK3066_PLLCON(3)); 240 + udelay(RK3066_PLL_RESET_DELAY(rate->nr)); 241 + 242 + /* wait for the pll to lock */ 243 + ret = rockchip_pll_wait_lock(pll); 244 + if (ret) { 245 + pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", 246 + __func__, old_rate); 247 + rockchip_rk3066_pll_set_rate(hw, old_rate, prate); 248 + } 249 + 250 + return ret; 251 + } 252 + 253 + static int rockchip_rk3066_pll_enable(struct clk_hw *hw) 254 + { 255 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 256 + 257 + writel(HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0), 258 + pll->reg_base + RK3066_PLLCON(3)); 259 + 260 + return 0; 261 + } 262 + 263 + static void rockchip_rk3066_pll_disable(struct clk_hw *hw) 264 + { 265 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 266 + 267 + writel(HIWORD_UPDATE(RK3066_PLLCON3_PWRDOWN, 268 + RK3066_PLLCON3_PWRDOWN, 0), 269 + pll->reg_base + RK3066_PLLCON(3)); 270 + } 271 + 272 + static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw) 273 + { 274 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 275 + u32 pllcon = readl(pll->reg_base + RK3066_PLLCON(3)); 276 + 277 + return !(pllcon & RK3066_PLLCON3_PWRDOWN); 278 + } 279 + 280 + static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = { 281 + .recalc_rate = rockchip_rk3066_pll_recalc_rate, 282 + .enable = rockchip_rk3066_pll_enable, 283 + .disable = rockchip_rk3066_pll_disable, 284 + .is_enabled = rockchip_rk3066_pll_is_enabled, 285 + }; 286 + 287 + static const struct clk_ops rockchip_rk3066_pll_clk_ops = { 288 + .recalc_rate = rockchip_rk3066_pll_recalc_rate, 289 + .round_rate = rockchip_pll_round_rate, 290 + .set_rate = rockchip_rk3066_pll_set_rate, 291 + .enable = rockchip_rk3066_pll_enable, 292 + .disable = rockchip_rk3066_pll_disable, 293 + .is_enabled = rockchip_rk3066_pll_is_enabled, 294 + }; 295 + 296 + /* 297 + * Common registering of pll clocks 298 + */ 299 + 300 + struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 301 + const char *name, const char **parent_names, u8 num_parents, 302 + void __iomem *base, int con_offset, int grf_lock_offset, 303 + int lock_shift, int mode_offset, int mode_shift, 304 + struct rockchip_pll_rate_table *rate_table, 305 + spinlock_t *lock) 306 + { 307 + const char *pll_parents[3]; 308 + struct clk_init_data init; 309 + struct rockchip_clk_pll *pll; 310 + struct clk_mux *pll_mux; 311 + struct clk *pll_clk, *mux_clk; 312 + char pll_name[20]; 313 + int ret; 314 + 315 + if (num_parents != 2) { 316 + pr_err("%s: needs two parent clocks\n", __func__); 317 + return ERR_PTR(-EINVAL); 318 + } 319 + 320 + /* name the actual pll */ 321 + snprintf(pll_name, sizeof(pll_name), "pll_%s", name); 322 + 323 + pll = kzalloc(sizeof(*pll), GFP_KERNEL); 324 + if (!pll) 325 + return ERR_PTR(-ENOMEM); 326 + 327 + init.name = pll_name; 328 + 329 + /* keep all plls untouched for now */ 330 + init.flags = CLK_IGNORE_UNUSED; 331 + 332 + init.parent_names = &parent_names[0]; 333 + init.num_parents = 1; 334 + 335 + if (rate_table) { 336 + int len; 337 + 338 + /* find count of rates in rate_table */ 339 + for (len = 0; rate_table[len].rate != 0; ) 340 + len++; 341 + 342 + pll->rate_count = len; 343 + pll->rate_table = kmemdup(rate_table, 344 + pll->rate_count * 345 + sizeof(struct rockchip_pll_rate_table), 346 + GFP_KERNEL); 347 + WARN(!pll->rate_table, 348 + "%s: could not allocate rate table for %s\n", 349 + __func__, name); 350 + } 351 + 352 + switch (pll_type) { 353 + case pll_rk3066: 354 + if (!pll->rate_table) 355 + init.ops = &rockchip_rk3066_pll_clk_norate_ops; 356 + else 357 + init.ops = &rockchip_rk3066_pll_clk_ops; 358 + break; 359 + default: 360 + pr_warn("%s: Unknown pll type for pll clk %s\n", 361 + __func__, name); 362 + } 363 + 364 + pll->hw.init = &init; 365 + pll->type = pll_type; 366 + pll->reg_base = base + con_offset; 367 + pll->lock_offset = grf_lock_offset; 368 + pll->lock_shift = lock_shift; 369 + pll->lock = lock; 370 + pll->clk_nb.notifier_call = rockchip_pll_notifier_cb; 371 + 372 + pll_clk = clk_register(NULL, &pll->hw); 373 + if (IS_ERR(pll_clk)) { 374 + pr_err("%s: failed to register pll clock %s : %ld\n", 375 + __func__, name, PTR_ERR(pll_clk)); 376 + mux_clk = pll_clk; 377 + goto err_pll; 378 + } 379 + 380 + ret = clk_notifier_register(pll_clk, &pll->clk_nb); 381 + if (ret) { 382 + pr_err("%s: failed to register clock notifier for %s : %d\n", 383 + __func__, name, ret); 384 + mux_clk = ERR_PTR(ret); 385 + goto err_pll_notifier; 386 + } 387 + 388 + /* create the mux on top of the real pll */ 389 + pll->pll_mux_ops = &clk_mux_ops; 390 + pll_mux = &pll->pll_mux; 391 + 392 + /* the actual muxing is xin24m, pll-output, xin32k */ 393 + pll_parents[0] = parent_names[0]; 394 + pll_parents[1] = pll_name; 395 + pll_parents[2] = parent_names[1]; 396 + 397 + init.name = name; 398 + init.flags = CLK_SET_RATE_PARENT; 399 + init.ops = pll->pll_mux_ops; 400 + init.parent_names = pll_parents; 401 + init.num_parents = ARRAY_SIZE(pll_parents); 402 + 403 + pll_mux->reg = base + mode_offset; 404 + pll_mux->shift = mode_shift; 405 + pll_mux->mask = PLL_MODE_MASK; 406 + pll_mux->flags = 0; 407 + pll_mux->lock = lock; 408 + pll_mux->hw.init = &init; 409 + 410 + if (pll_type == pll_rk3066) 411 + pll_mux->flags |= CLK_MUX_HIWORD_MASK; 412 + 413 + mux_clk = clk_register(NULL, &pll_mux->hw); 414 + if (IS_ERR(mux_clk)) 415 + goto err_mux; 416 + 417 + return mux_clk; 418 + 419 + err_mux: 420 + ret = clk_notifier_unregister(pll_clk, &pll->clk_nb); 421 + if (ret) { 422 + pr_err("%s: could not unregister clock notifier in error path : %d\n", 423 + __func__, ret); 424 + return mux_clk; 425 + } 426 + err_pll_notifier: 427 + clk_unregister(pll_clk); 428 + err_pll: 429 + kfree(pll); 430 + return mux_clk; 431 + }
+672
drivers/clk/rockchip/clk-rk3188.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/clk-provider.h> 17 + #include <linux/of.h> 18 + #include <linux/of_address.h> 19 + #include <dt-bindings/clock/rk3188-cru-common.h> 20 + #include "clk.h" 21 + 22 + #define RK3188_GRF_SOC_STATUS 0xac 23 + 24 + enum rk3188_plls { 25 + apll, cpll, dpll, gpll, 26 + }; 27 + 28 + struct rockchip_pll_rate_table rk3188_pll_rates[] = { 29 + RK3066_PLL_RATE(2208000000, 1, 92, 1), 30 + RK3066_PLL_RATE(2184000000, 1, 91, 1), 31 + RK3066_PLL_RATE(2160000000, 1, 90, 1), 32 + RK3066_PLL_RATE(2136000000, 1, 89, 1), 33 + RK3066_PLL_RATE(2112000000, 1, 88, 1), 34 + RK3066_PLL_RATE(2088000000, 1, 87, 1), 35 + RK3066_PLL_RATE(2064000000, 1, 86, 1), 36 + RK3066_PLL_RATE(2040000000, 1, 85, 1), 37 + RK3066_PLL_RATE(2016000000, 1, 84, 1), 38 + RK3066_PLL_RATE(1992000000, 1, 83, 1), 39 + RK3066_PLL_RATE(1968000000, 1, 82, 1), 40 + RK3066_PLL_RATE(1944000000, 1, 81, 1), 41 + RK3066_PLL_RATE(1920000000, 1, 80, 1), 42 + RK3066_PLL_RATE(1896000000, 1, 79, 1), 43 + RK3066_PLL_RATE(1872000000, 1, 78, 1), 44 + RK3066_PLL_RATE(1848000000, 1, 77, 1), 45 + RK3066_PLL_RATE(1824000000, 1, 76, 1), 46 + RK3066_PLL_RATE(1800000000, 1, 75, 1), 47 + RK3066_PLL_RATE(1776000000, 1, 74, 1), 48 + RK3066_PLL_RATE(1752000000, 1, 73, 1), 49 + RK3066_PLL_RATE(1728000000, 1, 72, 1), 50 + RK3066_PLL_RATE(1704000000, 1, 71, 1), 51 + RK3066_PLL_RATE(1680000000, 1, 70, 1), 52 + RK3066_PLL_RATE(1656000000, 1, 69, 1), 53 + RK3066_PLL_RATE(1632000000, 1, 68, 1), 54 + RK3066_PLL_RATE(1608000000, 1, 67, 1), 55 + RK3066_PLL_RATE(1560000000, 1, 65, 1), 56 + RK3066_PLL_RATE(1512000000, 1, 63, 1), 57 + RK3066_PLL_RATE(1488000000, 1, 62, 1), 58 + RK3066_PLL_RATE(1464000000, 1, 61, 1), 59 + RK3066_PLL_RATE(1440000000, 1, 60, 1), 60 + RK3066_PLL_RATE(1416000000, 1, 59, 1), 61 + RK3066_PLL_RATE(1392000000, 1, 58, 1), 62 + RK3066_PLL_RATE(1368000000, 1, 57, 1), 63 + RK3066_PLL_RATE(1344000000, 1, 56, 1), 64 + RK3066_PLL_RATE(1320000000, 1, 55, 1), 65 + RK3066_PLL_RATE(1296000000, 1, 54, 1), 66 + RK3066_PLL_RATE(1272000000, 1, 53, 1), 67 + RK3066_PLL_RATE(1248000000, 1, 52, 1), 68 + RK3066_PLL_RATE(1224000000, 1, 51, 1), 69 + RK3066_PLL_RATE(1200000000, 1, 50, 1), 70 + RK3066_PLL_RATE(1188000000, 2, 99, 1), 71 + RK3066_PLL_RATE(1176000000, 1, 49, 1), 72 + RK3066_PLL_RATE(1128000000, 1, 47, 1), 73 + RK3066_PLL_RATE(1104000000, 1, 46, 1), 74 + RK3066_PLL_RATE(1008000000, 1, 84, 2), 75 + RK3066_PLL_RATE( 912000000, 1, 76, 2), 76 + RK3066_PLL_RATE( 891000000, 8, 594, 2), 77 + RK3066_PLL_RATE( 888000000, 1, 74, 2), 78 + RK3066_PLL_RATE( 816000000, 1, 68, 2), 79 + RK3066_PLL_RATE( 798000000, 2, 133, 2), 80 + RK3066_PLL_RATE( 792000000, 1, 66, 2), 81 + RK3066_PLL_RATE( 768000000, 1, 64, 2), 82 + RK3066_PLL_RATE( 742500000, 8, 495, 2), 83 + RK3066_PLL_RATE( 696000000, 1, 58, 2), 84 + RK3066_PLL_RATE( 600000000, 1, 50, 2), 85 + RK3066_PLL_RATE( 594000000, 2, 198, 4), 86 + RK3066_PLL_RATE( 552000000, 1, 46, 2), 87 + RK3066_PLL_RATE( 504000000, 1, 84, 4), 88 + RK3066_PLL_RATE( 456000000, 1, 76, 4), 89 + RK3066_PLL_RATE( 408000000, 1, 68, 4), 90 + RK3066_PLL_RATE( 384000000, 2, 128, 4), 91 + RK3066_PLL_RATE( 360000000, 1, 60, 4), 92 + RK3066_PLL_RATE( 312000000, 1, 52, 4), 93 + RK3066_PLL_RATE( 300000000, 1, 50, 4), 94 + RK3066_PLL_RATE( 297000000, 2, 198, 8), 95 + RK3066_PLL_RATE( 252000000, 1, 84, 8), 96 + RK3066_PLL_RATE( 216000000, 1, 72, 8), 97 + RK3066_PLL_RATE( 148500000, 2, 99, 8), 98 + RK3066_PLL_RATE( 126000000, 1, 84, 16), 99 + RK3066_PLL_RATE( 48000000, 1, 64, 32), 100 + { /* sentinel */ }, 101 + }; 102 + 103 + PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 104 + PNAME(mux_armclk_p) = { "apll", "gpll_armclk" }; 105 + PNAME(mux_ddrphy_p) = { "dpll", "gpll_ddr" }; 106 + PNAME(mux_pll_src_gpll_cpll_p) = { "gpll", "cpll" }; 107 + PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 108 + PNAME(mux_aclk_cpu_p) = { "apll", "gpll" }; 109 + PNAME(mux_sclk_cif0_p) = { "cif0_pre", "xin24m" }; 110 + PNAME(mux_sclk_i2s0_p) = { "i2s0_pre", "i2s0_frac", "xin12m" }; 111 + PNAME(mux_sclk_spdif_p) = { "spdif_src", "spdif_frac", "xin12m" }; 112 + PNAME(mux_sclk_uart0_p) = { "uart0_pre", "uart0_frac", "xin24m" }; 113 + PNAME(mux_sclk_uart1_p) = { "uart1_pre", "uart1_frac", "xin24m" }; 114 + PNAME(mux_sclk_uart2_p) = { "uart2_pre", "uart2_frac", "xin24m" }; 115 + PNAME(mux_sclk_uart3_p) = { "uart3_pre", "uart3_frac", "xin24m" }; 116 + PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" }; 117 + PNAME(mux_mac_p) = { "gpll", "dpll" }; 118 + PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; 119 + 120 + static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { 121 + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), 122 + RK2928_MODE_CON, 0, 6, rk3188_pll_rates), 123 + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), 124 + RK2928_MODE_CON, 4, 5, NULL), 125 + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), 126 + RK2928_MODE_CON, 8, 7, rk3188_pll_rates), 127 + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), 128 + RK2928_MODE_CON, 12, 8, rk3188_pll_rates), 129 + }; 130 + 131 + #define MFLAGS CLK_MUX_HIWORD_MASK 132 + #define DFLAGS CLK_DIVIDER_HIWORD_MASK 133 + #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) 134 + 135 + /* 2 ^ (val + 1) */ 136 + static struct clk_div_table div_core_peri_t[] = { 137 + { .val = 0, .div = 2 }, 138 + { .val = 1, .div = 4 }, 139 + { .val = 2, .div = 8 }, 140 + { .val = 3, .div = 16 }, 141 + { /* sentinel */ }, 142 + }; 143 + 144 + static struct rockchip_clk_branch common_clk_branches[] __initdata = { 145 + /* 146 + * Clock-Architecture Diagram 2 147 + */ 148 + 149 + GATE(0, "gpll_armclk", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS), 150 + 151 + /* these two are set by the cpuclk and should not be changed */ 152 + COMPOSITE_NOMUX_DIVTBL(CORE_PERI, "core_peri", "armclk", 0, 153 + RK2928_CLKSEL_CON(0), 6, 2, DFLAGS | CLK_DIVIDER_READ_ONLY, 154 + div_core_peri_t, RK2928_CLKGATE_CON(0), 0, GFLAGS), 155 + 156 + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_p, 0, 157 + RK2928_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 5, DFLAGS, 158 + RK2928_CLKGATE_CON(3), 9, GFLAGS), 159 + GATE(0, "hclk_vepu", "aclk_vepu", 0, 160 + RK2928_CLKGATE_CON(3), 10, GFLAGS), 161 + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_p, 0, 162 + RK2928_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS, 163 + RK2928_CLKGATE_CON(3), 11, GFLAGS), 164 + GATE(0, "hclk_vdpu", "aclk_vdpu", 0, 165 + RK2928_CLKGATE_CON(3), 12, GFLAGS), 166 + 167 + GATE(0, "gpll_ddr", "gpll", 0, 168 + RK2928_CLKGATE_CON(1), 7, GFLAGS), 169 + COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0, 170 + RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 171 + RK2928_CLKGATE_CON(0), 2, GFLAGS), 172 + 173 + GATE(0, "aclk_cpu", "aclk_cpu_pre", 0, 174 + RK2928_CLKGATE_CON(0), 3, GFLAGS), 175 + 176 + DIV(0, "pclk_cpu_pre", "aclk_cpu_pre", 0, 177 + RK2928_CLKSEL_CON(1), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 178 + GATE(0, "atclk_cpu", "pclk_cpu_pre", 0, 179 + RK2928_CLKGATE_CON(0), 6, GFLAGS), 180 + GATE(0, "pclk_cpu", "pclk_cpu_pre", 0, 181 + RK2928_CLKGATE_CON(0), 5, GFLAGS), 182 + DIV(0, "hclk_cpu_pre", "aclk_cpu_pre", 0, 183 + RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 184 + COMPOSITE_NOMUX(0, "hclk_ahb2apb", "hclk_cpu_pre", 0, 185 + RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 186 + RK2928_CLKGATE_CON(4), 9, GFLAGS), 187 + GATE(0, "hclk_cpu", "hclk_cpu_pre", 0, 188 + RK2928_CLKGATE_CON(0), 4, GFLAGS), 189 + 190 + COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0, 191 + RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS, 192 + RK2928_CLKGATE_CON(3), 0, GFLAGS), 193 + COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0, 194 + RK2928_CLKSEL_CON(31), 15, 1, MFLAGS, 8, 5, DFLAGS, 195 + RK2928_CLKGATE_CON(1), 4, GFLAGS), 196 + 197 + GATE(0, "aclk_peri", "aclk_peri_pre", 0, 198 + RK2928_CLKGATE_CON(2), 1, GFLAGS), 199 + COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_pre", 0, 200 + RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 201 + RK2928_CLKGATE_CON(2), 2, GFLAGS), 202 + COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_pre", 0, 203 + RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 204 + RK2928_CLKGATE_CON(2), 3, GFLAGS), 205 + 206 + MUX(0, "cif_src", mux_pll_src_cpll_gpll_p, 0, 207 + RK2928_CLKSEL_CON(29), 0, 1, MFLAGS), 208 + COMPOSITE_NOMUX(0, "cif0_pre", "cif_src", 0, 209 + RK2928_CLKSEL_CON(29), 1, 5, DFLAGS, 210 + RK2928_CLKGATE_CON(3), 7, GFLAGS), 211 + MUX(SCLK_CIF0, "sclk_cif0", mux_sclk_cif0_p, 0, 212 + RK2928_CLKSEL_CON(29), 7, 1, MFLAGS), 213 + 214 + GATE(0, "pclkin_cif0", "ext_cif0", 0, 215 + RK2928_CLKGATE_CON(3), 3, GFLAGS), 216 + 217 + /* 218 + * the 480m are generated inside the usb block from these clocks, 219 + * but they are also a source for the hsicphy clock. 220 + */ 221 + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, 222 + RK2928_CLKGATE_CON(1), 5, GFLAGS), 223 + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, 224 + RK2928_CLKGATE_CON(1), 6, GFLAGS), 225 + 226 + COMPOSITE(0, "mac_src", mux_mac_p, 0, 227 + RK2928_CLKSEL_CON(21), 0, 1, MFLAGS, 8, 5, DFLAGS, 228 + RK2928_CLKGATE_CON(2), 5, GFLAGS), 229 + MUX(SCLK_MAC, "sclk_macref", mux_sclk_macref_p, CLK_SET_RATE_PARENT, 230 + RK2928_CLKSEL_CON(21), 4, 1, MFLAGS), 231 + GATE(0, "sclk_mac_lbtest", "sclk_macref", 232 + RK2928_CLKGATE_CON(2), 12, 0, GFLAGS), 233 + 234 + COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0, 235 + RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, 236 + RK2928_CLKGATE_CON(2), 6, GFLAGS), 237 + COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 238 + RK2928_CLKSEL_CON(23), 0, 239 + RK2928_CLKGATE_CON(2), 7, 0, GFLAGS), 240 + MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0, 241 + RK2928_CLKSEL_CON(22), 4, 2, MFLAGS), 242 + 243 + COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, 244 + RK2928_CLKSEL_CON(24), 8, 8, DFLAGS, 245 + RK2928_CLKGATE_CON(2), 8, GFLAGS), 246 + 247 + /* 248 + * Clock-Architecture Diagram 4 249 + */ 250 + 251 + GATE(SCLK_SMC, "sclk_smc", "hclk_peri", 252 + RK2928_CLKGATE_CON(2), 4, 0, GFLAGS), 253 + 254 + COMPOSITE_NOMUX(SCLK_SPI0, "sclk_spi0", "pclk_peri", 0, 255 + RK2928_CLKSEL_CON(25), 0, 7, DFLAGS, 256 + RK2928_CLKGATE_CON(2), 9, GFLAGS), 257 + COMPOSITE_NOMUX(SCLK_SPI1, "sclk_spi1", "pclk_peri", 0, 258 + RK2928_CLKSEL_CON(25), 8, 7, DFLAGS, 259 + RK2928_CLKGATE_CON(2), 10, GFLAGS), 260 + 261 + COMPOSITE_NOMUX(SCLK_SDMMC, "sclk_sdmmc", "hclk_peri", 0, 262 + RK2928_CLKSEL_CON(11), 0, 6, DFLAGS, 263 + RK2928_CLKGATE_CON(2), 11, GFLAGS), 264 + COMPOSITE_NOMUX(SCLK_SDIO, "sclk_sdio", "hclk_peri", 0, 265 + RK2928_CLKSEL_CON(12), 0, 6, DFLAGS, 266 + RK2928_CLKGATE_CON(2), 13, GFLAGS), 267 + COMPOSITE_NOMUX(SCLK_EMMC, "sclk_emmc", "hclk_peri", 0, 268 + RK2928_CLKSEL_CON(12), 8, 6, DFLAGS, 269 + RK2928_CLKGATE_CON(2), 14, GFLAGS), 270 + 271 + MUX(0, "uart_src", mux_pll_src_gpll_cpll_p, 0, 272 + RK2928_CLKSEL_CON(12), 15, 1, MFLAGS), 273 + COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0, 274 + RK2928_CLKSEL_CON(13), 0, 7, DFLAGS, 275 + RK2928_CLKGATE_CON(1), 8, GFLAGS), 276 + COMPOSITE_FRAC(0, "uart0_frac", "uart0_pre", 0, 277 + RK2928_CLKSEL_CON(17), 0, 278 + RK2928_CLKGATE_CON(1), 9, GFLAGS), 279 + MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0, 280 + RK2928_CLKSEL_CON(13), 8, 2, MFLAGS), 281 + COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0, 282 + RK2928_CLKSEL_CON(14), 0, 7, DFLAGS, 283 + RK2928_CLKGATE_CON(1), 10, GFLAGS), 284 + COMPOSITE_FRAC(0, "uart1_frac", "uart1_pre", 0, 285 + RK2928_CLKSEL_CON(18), 0, 286 + RK2928_CLKGATE_CON(1), 11, GFLAGS), 287 + MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0, 288 + RK2928_CLKSEL_CON(14), 8, 2, MFLAGS), 289 + COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0, 290 + RK2928_CLKSEL_CON(15), 0, 7, DFLAGS, 291 + RK2928_CLKGATE_CON(1), 12, GFLAGS), 292 + COMPOSITE_FRAC(0, "uart2_frac", "uart2_pre", 0, 293 + RK2928_CLKSEL_CON(19), 0, 294 + RK2928_CLKGATE_CON(1), 13, GFLAGS), 295 + MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0, 296 + RK2928_CLKSEL_CON(15), 8, 2, MFLAGS), 297 + COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0, 298 + RK2928_CLKSEL_CON(16), 0, 7, DFLAGS, 299 + RK2928_CLKGATE_CON(1), 14, GFLAGS), 300 + COMPOSITE_FRAC(0, "uart3_frac", "uart3_pre", 0, 301 + RK2928_CLKSEL_CON(20), 0, 302 + RK2928_CLKGATE_CON(1), 15, GFLAGS), 303 + MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0, 304 + RK2928_CLKSEL_CON(16), 8, 2, MFLAGS), 305 + 306 + GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS), 307 + 308 + GATE(SCLK_TIMER0, "timer0", "xin24m", 0, RK2928_CLKGATE_CON(1), 0, GFLAGS), 309 + GATE(SCLK_TIMER1, "timer1", "xin24m", 0, RK2928_CLKGATE_CON(1), 1, GFLAGS), 310 + 311 + /* clk_core_pre gates */ 312 + GATE(0, "core_dbg", "armclk", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS), 313 + 314 + /* aclk_cpu gates */ 315 + GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS), 316 + GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS), 317 + GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS), 318 + 319 + /* hclk_cpu gates */ 320 + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), 321 + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), 322 + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS), 323 + GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS), 324 + /* hclk_ahb2apb is part of a clk branch */ 325 + GATE(0, "hclk_vio_bus", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), 326 + GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS), 327 + GATE(HCLK_LCDC1, "hclk_lcdc1", "aclk_cpu", 0, RK2928_CLKGATE_CON(6), 2, GFLAGS), 328 + GATE(HCLK_CIF0, "hclk_cif0", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS), 329 + GATE(HCLK_IPP, "hclk_ipp", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 9, GFLAGS), 330 + GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS), 331 + 332 + /* hclk_peri gates */ 333 + GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS), 334 + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS), 335 + GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), 336 + GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), 337 + GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), 338 + GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), 339 + GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), 340 + GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), 341 + GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), 342 + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), 343 + GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS), 344 + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 12, GFLAGS), 345 + 346 + /* aclk_lcdc0_pre gates */ 347 + GATE(0, "aclk_vio0", "aclk_lcdc0_pre", 0, RK2928_CLKGATE_CON(6), 13, GFLAGS), 348 + GATE(ACLK_LCDC0, "aclk_lcdc0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS), 349 + GATE(ACLK_CIF0, "aclk_cif0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 5, GFLAGS), 350 + GATE(ACLK_IPP, "aclk_ipp", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 8, GFLAGS), 351 + 352 + /* aclk_lcdc1_pre gates */ 353 + GATE(0, "aclk_vio1", "aclk_lcdc1_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), 354 + GATE(ACLK_LCDC1, "aclk_lcdc1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 3, GFLAGS), 355 + GATE(ACLK_RGA, "aclk_rga", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 11, GFLAGS), 356 + 357 + /* atclk_cpu gates */ 358 + GATE(0, "atclk", "atclk_cpu", 0, RK2928_CLKGATE_CON(9), 3, GFLAGS), 359 + GATE(0, "trace", "atclk_cpu", 0, RK2928_CLKGATE_CON(9), 2, GFLAGS), 360 + 361 + /* pclk_cpu gates */ 362 + GATE(PCLK_PWM01, "pclk_pwm01", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS), 363 + GATE(PCLK_TIMER0, "pclk_timer0", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS), 364 + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), 365 + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS), 366 + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS), 367 + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS), 368 + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), 369 + GATE(PCLK_EFUSE, "pclk_efuse", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS), 370 + GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 3, GFLAGS), 371 + GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS), 372 + GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), 373 + GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS), 374 + GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS), 375 + GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS), 376 + 377 + /* aclk_peri */ 378 + GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), 379 + GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS), 380 + GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS), 381 + GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS), 382 + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS), 383 + 384 + /* pclk_peri gates */ 385 + GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS), 386 + GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS), 387 + GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), 388 + GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS), 389 + GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 13, GFLAGS), 390 + GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS), 391 + GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS), 392 + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS), 393 + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS), 394 + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS), 395 + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS), 396 + GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), 397 + }; 398 + 399 + PNAME(mux_rk3066_lcdc0_p) = { "dclk_lcdc0_src", "xin27m" }; 400 + PNAME(mux_rk3066_lcdc1_p) = { "dclk_lcdc1_src", "xin27m" }; 401 + PNAME(mux_sclk_cif1_p) = { "cif1_pre", "xin24m" }; 402 + PNAME(mux_sclk_i2s1_p) = { "i2s1_pre", "i2s1_frac", "xin12m" }; 403 + PNAME(mux_sclk_i2s2_p) = { "i2s2_pre", "i2s2_frac", "xin12m" }; 404 + 405 + static struct clk_div_table div_aclk_cpu_t[] = { 406 + { .val = 0, .div = 1 }, 407 + { .val = 1, .div = 2 }, 408 + { .val = 2, .div = 3 }, 409 + { .val = 3, .div = 4 }, 410 + { .val = 4, .div = 8 }, 411 + { /* sentinel */ }, 412 + }; 413 + 414 + static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { 415 + COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 416 + RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 0, 5, DFLAGS), 417 + DIVTBL(0, "aclk_cpu_pre", "armclk", 0, 418 + RK2928_CLKSEL_CON(1), 0, 3, DFLAGS, div_aclk_cpu_t), 419 + 420 + GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0, 421 + RK2928_CLKGATE_CON(9), 4, GFLAGS), 422 + 423 + COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0, 424 + RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, 425 + RK2928_CLKGATE_CON(2), 0, GFLAGS), 426 + 427 + COMPOSITE(0, "dclk_lcdc0_src", mux_pll_src_cpll_gpll_p, 0, 428 + RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS, 429 + RK2928_CLKGATE_CON(3), 1, GFLAGS), 430 + MUX(DCLK_LCDC0, "dclk_lcdc0", mux_rk3066_lcdc0_p, 0, 431 + RK2928_CLKSEL_CON(27), 4, 1, MFLAGS), 432 + COMPOSITE(0, "dclk_lcdc1_src", mux_pll_src_cpll_gpll_p, 0, 433 + RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS, 434 + RK2928_CLKGATE_CON(3), 2, GFLAGS), 435 + MUX(DCLK_LCDC1, "dclk_lcdc1", mux_rk3066_lcdc1_p, 0, 436 + RK2928_CLKSEL_CON(28), 4, 1, MFLAGS), 437 + 438 + COMPOSITE_NOMUX(0, "cif1_pre", "cif_src", 0, 439 + RK2928_CLKSEL_CON(29), 8, 5, DFLAGS, 440 + RK2928_CLKGATE_CON(3), 8, GFLAGS), 441 + MUX(SCLK_CIF1, "sclk_cif1", mux_sclk_cif1_p, 0, 442 + RK2928_CLKSEL_CON(29), 15, 1, MFLAGS), 443 + 444 + GATE(0, "pclkin_cif1", "ext_cif1", 0, 445 + RK2928_CLKGATE_CON(3), 4, GFLAGS), 446 + 447 + COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0, 448 + RK2928_CLKSEL_CON(33), 8, 1, MFLAGS, 0, 5, DFLAGS, 449 + RK2928_CLKGATE_CON(3), 13, GFLAGS), 450 + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_src", 0, 451 + RK2928_CLKGATE_CON(5), 15, GFLAGS), 452 + 453 + GATE(SCLK_TIMER2, "timer2", "xin24m", 0, 454 + RK2928_CLKGATE_CON(3), 2, GFLAGS), 455 + 456 + COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, 457 + RK2928_CLKSEL_CON(34), 0, 16, DFLAGS, 458 + RK2928_CLKGATE_CON(2), 15, GFLAGS), 459 + 460 + MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, 461 + RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), 462 + COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, 463 + RK2928_CLKSEL_CON(2), 0, 7, DFLAGS, 464 + RK2928_CLKGATE_CON(0), 7, GFLAGS), 465 + COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0, 466 + RK2928_CLKSEL_CON(6), 0, 467 + RK2928_CLKGATE_CON(0), 8, GFLAGS), 468 + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, 469 + RK2928_CLKSEL_CON(2), 8, 2, MFLAGS), 470 + COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0, 471 + RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, 472 + RK2928_CLKGATE_CON(0), 9, GFLAGS), 473 + COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_pre", 0, 474 + RK2928_CLKSEL_CON(7), 0, 475 + RK2928_CLKGATE_CON(0), 10, GFLAGS), 476 + MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0, 477 + RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), 478 + COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0, 479 + RK2928_CLKSEL_CON(4), 0, 7, DFLAGS, 480 + RK2928_CLKGATE_CON(0), 11, GFLAGS), 481 + COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_pre", 0, 482 + RK2928_CLKSEL_CON(8), 0, 483 + RK2928_CLKGATE_CON(0), 12, GFLAGS), 484 + MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, 485 + RK2928_CLKSEL_CON(4), 8, 2, MFLAGS), 486 + COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, 487 + RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, 488 + RK2928_CLKGATE_CON(0), 13, GFLAGS), 489 + COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, 490 + RK2928_CLKSEL_CON(9), 0, 491 + RK2928_CLKGATE_CON(0), 14, GFLAGS), 492 + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, 493 + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), 494 + 495 + GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), 496 + GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 497 + GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), 498 + GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), 499 + 500 + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), 501 + 502 + GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), 503 + 504 + GATE(PCLK_TIMER1, "pclk_timer1", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 8, GFLAGS), 505 + GATE(PCLK_TIMER2, "pclk_timer2", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), 506 + GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS), 507 + GATE(PCLK_UART0, "pclk_uart0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS), 508 + GATE(PCLK_UART1, "pclk_uart1", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), 509 + 510 + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), 511 + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 13, GFLAGS), 512 + }; 513 + 514 + static struct clk_div_table div_rk3188_aclk_core_t[] = { 515 + { .val = 0, .div = 1 }, 516 + { .val = 1, .div = 2 }, 517 + { .val = 2, .div = 3 }, 518 + { .val = 3, .div = 4 }, 519 + { .val = 4, .div = 8 }, 520 + { /* sentinel */ }, 521 + }; 522 + 523 + PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", 524 + "gpll", "cpll" }; 525 + 526 + static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { 527 + COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 528 + RK2928_CLKSEL_CON(0), 8, 1, MFLAGS, 9, 5, DFLAGS), 529 + COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0, 530 + RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 531 + div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS), 532 + 533 + /* do not source aclk_cpu_pre from the apll, to keep complexity down */ 534 + COMPOSITE_NOGATE(0, "aclk_cpu_pre", mux_aclk_cpu_p, CLK_SET_RATE_NO_REPARENT, 535 + RK2928_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS), 536 + 537 + GATE(CORE_L2C, "core_l2c", "armclk", 0, 538 + RK2928_CLKGATE_CON(9), 4, GFLAGS), 539 + 540 + COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0, 541 + RK2928_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, 542 + RK2928_CLKGATE_CON(2), 0, GFLAGS), 543 + 544 + COMPOSITE(DCLK_LCDC0, "dclk_lcdc0", mux_pll_src_cpll_gpll_p, 0, 545 + RK2928_CLKSEL_CON(27), 0, 1, MFLAGS, 8, 8, DFLAGS, 546 + RK2928_CLKGATE_CON(3), 1, GFLAGS), 547 + COMPOSITE(DCLK_LCDC1, "dclk_lcdc1", mux_pll_src_cpll_gpll_p, 0, 548 + RK2928_CLKSEL_CON(28), 0, 1, MFLAGS, 8, 8, DFLAGS, 549 + RK2928_CLKGATE_CON(3), 2, GFLAGS), 550 + 551 + COMPOSITE(0, "aclk_gpu_src", mux_pll_src_cpll_gpll_p, 0, 552 + RK2928_CLKSEL_CON(34), 7, 1, MFLAGS, 0, 5, DFLAGS, 553 + RK2928_CLKGATE_CON(3), 15, GFLAGS), 554 + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_src", 0, 555 + RK2928_CLKGATE_CON(9), 7, GFLAGS), 556 + 557 + GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 4, GFLAGS), 558 + GATE(SCLK_TIMER3, "timer3", "xin24m", 0, RK2928_CLKGATE_CON(1), 2, GFLAGS), 559 + GATE(SCLK_TIMER4, "timer4", "xin24m", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), 560 + GATE(SCLK_TIMER5, "timer5", "xin24m", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), 561 + GATE(SCLK_TIMER6, "timer6", "xin24m", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), 562 + 563 + COMPOSITE_NODIV(0, "sclk_hsicphy_480m", mux_hsicphy_p, 0, 564 + RK2928_CLKSEL_CON(30), 0, 2, DFLAGS, 565 + RK2928_CLKGATE_CON(3), 6, GFLAGS), 566 + DIV(0, "sclk_hsicphy_12m", "sclk_hsicphy_480m", 0, 567 + RK2928_CLKGATE_CON(11), 8, 6, DFLAGS), 568 + 569 + MUX(0, "i2s_src", mux_pll_src_gpll_cpll_p, 0, 570 + RK2928_CLKSEL_CON(2), 15, 1, MFLAGS), 571 + COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, 572 + RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, 573 + RK2928_CLKGATE_CON(0), 9, GFLAGS), 574 + COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0, 575 + RK2928_CLKSEL_CON(7), 0, 576 + RK2928_CLKGATE_CON(0), 10, GFLAGS), 577 + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, 578 + RK2928_CLKSEL_CON(3), 8, 2, MFLAGS), 579 + COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0, 580 + RK2928_CLKSEL_CON(5), 0, 7, DFLAGS, 581 + RK2928_CLKGATE_CON(13), 13, GFLAGS), 582 + COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0, 583 + RK2928_CLKSEL_CON(9), 0, 584 + RK2928_CLKGATE_CON(0), 14, GFLAGS), 585 + MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0, 586 + RK2928_CLKSEL_CON(5), 8, 2, MFLAGS), 587 + 588 + GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), 589 + GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), 590 + 591 + GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), 592 + GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 593 + 594 + GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), 595 + 596 + GATE(PCLK_UART0, "pclk_uart0", "hclk_ahb2apb", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS), 597 + GATE(PCLK_UART1, "pclk_uart1", "hclk_ahb2apb", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), 598 + 599 + GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS), 600 + }; 601 + 602 + static void __init rk3188_common_clk_init(struct device_node *np) 603 + { 604 + void __iomem *reg_base; 605 + struct clk *clk; 606 + 607 + reg_base = of_iomap(np, 0); 608 + if (!reg_base) { 609 + pr_err("%s: could not map cru region\n", __func__); 610 + return; 611 + } 612 + 613 + rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 614 + 615 + /* xin12m is created by an cru-internal divider */ 616 + clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); 617 + if (IS_ERR(clk)) 618 + pr_warn("%s: could not register clock xin12m: %ld\n", 619 + __func__, PTR_ERR(clk)); 620 + 621 + clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); 622 + if (IS_ERR(clk)) 623 + pr_warn("%s: could not register clock usb480m: %ld\n", 624 + __func__, PTR_ERR(clk)); 625 + 626 + rockchip_clk_register_plls(rk3188_pll_clks, 627 + ARRAY_SIZE(rk3188_pll_clks), 628 + RK3188_GRF_SOC_STATUS); 629 + rockchip_clk_register_branches(common_clk_branches, 630 + ARRAY_SIZE(common_clk_branches)); 631 + 632 + rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 633 + ROCKCHIP_SOFTRST_HIWORD_MASK); 634 + } 635 + 636 + static void __init rk3066a_clk_init(struct device_node *np) 637 + { 638 + rk3188_common_clk_init(np); 639 + rockchip_clk_register_branches(rk3066a_clk_branches, 640 + ARRAY_SIZE(rk3066a_clk_branches)); 641 + } 642 + CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); 643 + 644 + static void __init rk3188a_clk_init(struct device_node *np) 645 + { 646 + rk3188_common_clk_init(np); 647 + rockchip_clk_register_branches(rk3188_clk_branches, 648 + ARRAY_SIZE(rk3188_clk_branches)); 649 + } 650 + CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); 651 + 652 + static void __init rk3188_clk_init(struct device_node *np) 653 + { 654 + int i; 655 + 656 + for (i = 0; i < ARRAY_SIZE(rk3188_pll_clks); i++) { 657 + struct rockchip_pll_clock *pll = &rk3188_pll_clks[i]; 658 + struct rockchip_pll_rate_table *rate; 659 + 660 + if (!pll->rate_table) 661 + continue; 662 + 663 + rate = pll->rate_table; 664 + while (rate->rate > 0) { 665 + rate->bwadj = 0; 666 + rate++; 667 + } 668 + } 669 + 670 + rk3188a_clk_init(np); 671 + } 672 + CLK_OF_DECLARE(rk3188_cru, "rockchip,rk3188-cru", rk3188_clk_init);
+717
drivers/clk/rockchip/clk-rk3288.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/clk-provider.h> 17 + #include <linux/of.h> 18 + #include <linux/of_address.h> 19 + #include <dt-bindings/clock/rk3288-cru.h> 20 + #include "clk.h" 21 + 22 + #define RK3288_GRF_SOC_CON(x) (0x244 + x * 4) 23 + #define RK3288_GRF_SOC_STATUS 0x280 24 + 25 + enum rk3288_plls { 26 + apll, dpll, cpll, gpll, npll, 27 + }; 28 + 29 + struct rockchip_pll_rate_table rk3288_pll_rates[] = { 30 + RK3066_PLL_RATE(2208000000, 1, 92, 1), 31 + RK3066_PLL_RATE(2184000000, 1, 91, 1), 32 + RK3066_PLL_RATE(2160000000, 1, 90, 1), 33 + RK3066_PLL_RATE(2136000000, 1, 89, 1), 34 + RK3066_PLL_RATE(2112000000, 1, 88, 1), 35 + RK3066_PLL_RATE(2088000000, 1, 87, 1), 36 + RK3066_PLL_RATE(2064000000, 1, 86, 1), 37 + RK3066_PLL_RATE(2040000000, 1, 85, 1), 38 + RK3066_PLL_RATE(2016000000, 1, 84, 1), 39 + RK3066_PLL_RATE(1992000000, 1, 83, 1), 40 + RK3066_PLL_RATE(1968000000, 1, 82, 1), 41 + RK3066_PLL_RATE(1944000000, 1, 81, 1), 42 + RK3066_PLL_RATE(1920000000, 1, 80, 1), 43 + RK3066_PLL_RATE(1896000000, 1, 79, 1), 44 + RK3066_PLL_RATE(1872000000, 1, 78, 1), 45 + RK3066_PLL_RATE(1848000000, 1, 77, 1), 46 + RK3066_PLL_RATE(1824000000, 1, 76, 1), 47 + RK3066_PLL_RATE(1800000000, 1, 75, 1), 48 + RK3066_PLL_RATE(1776000000, 1, 74, 1), 49 + RK3066_PLL_RATE(1752000000, 1, 73, 1), 50 + RK3066_PLL_RATE(1728000000, 1, 72, 1), 51 + RK3066_PLL_RATE(1704000000, 1, 71, 1), 52 + RK3066_PLL_RATE(1680000000, 1, 70, 1), 53 + RK3066_PLL_RATE(1656000000, 1, 69, 1), 54 + RK3066_PLL_RATE(1632000000, 1, 68, 1), 55 + RK3066_PLL_RATE(1608000000, 1, 67, 1), 56 + RK3066_PLL_RATE(1560000000, 1, 65, 1), 57 + RK3066_PLL_RATE(1512000000, 1, 63, 1), 58 + RK3066_PLL_RATE(1488000000, 1, 62, 1), 59 + RK3066_PLL_RATE(1464000000, 1, 61, 1), 60 + RK3066_PLL_RATE(1440000000, 1, 60, 1), 61 + RK3066_PLL_RATE(1416000000, 1, 59, 1), 62 + RK3066_PLL_RATE(1392000000, 1, 58, 1), 63 + RK3066_PLL_RATE(1368000000, 1, 57, 1), 64 + RK3066_PLL_RATE(1344000000, 1, 56, 1), 65 + RK3066_PLL_RATE(1320000000, 1, 55, 1), 66 + RK3066_PLL_RATE(1296000000, 1, 54, 1), 67 + RK3066_PLL_RATE(1272000000, 1, 53, 1), 68 + RK3066_PLL_RATE(1248000000, 1, 52, 1), 69 + RK3066_PLL_RATE(1224000000, 1, 51, 1), 70 + RK3066_PLL_RATE(1200000000, 1, 50, 1), 71 + RK3066_PLL_RATE(1188000000, 2, 99, 1), 72 + RK3066_PLL_RATE(1176000000, 1, 49, 1), 73 + RK3066_PLL_RATE(1128000000, 1, 47, 1), 74 + RK3066_PLL_RATE(1104000000, 1, 46, 1), 75 + RK3066_PLL_RATE(1008000000, 1, 84, 2), 76 + RK3066_PLL_RATE( 912000000, 1, 76, 2), 77 + RK3066_PLL_RATE( 891000000, 8, 594, 2), 78 + RK3066_PLL_RATE( 888000000, 1, 74, 2), 79 + RK3066_PLL_RATE( 816000000, 1, 68, 2), 80 + RK3066_PLL_RATE( 798000000, 2, 133, 2), 81 + RK3066_PLL_RATE( 792000000, 1, 66, 2), 82 + RK3066_PLL_RATE( 768000000, 1, 64, 2), 83 + RK3066_PLL_RATE( 742500000, 8, 495, 2), 84 + RK3066_PLL_RATE( 696000000, 1, 58, 2), 85 + RK3066_PLL_RATE( 600000000, 1, 50, 2), 86 + RK3066_PLL_RATE( 594000000, 2, 198, 4), 87 + RK3066_PLL_RATE( 552000000, 1, 46, 2), 88 + RK3066_PLL_RATE( 504000000, 1, 84, 4), 89 + RK3066_PLL_RATE( 456000000, 1, 76, 4), 90 + RK3066_PLL_RATE( 408000000, 1, 68, 4), 91 + RK3066_PLL_RATE( 384000000, 2, 128, 4), 92 + RK3066_PLL_RATE( 360000000, 1, 60, 4), 93 + RK3066_PLL_RATE( 312000000, 1, 52, 4), 94 + RK3066_PLL_RATE( 300000000, 1, 50, 4), 95 + RK3066_PLL_RATE( 297000000, 2, 198, 8), 96 + RK3066_PLL_RATE( 252000000, 1, 84, 8), 97 + RK3066_PLL_RATE( 216000000, 1, 72, 8), 98 + RK3066_PLL_RATE( 148500000, 2, 99, 8), 99 + RK3066_PLL_RATE( 126000000, 1, 84, 16), 100 + RK3066_PLL_RATE( 48000000, 1, 64, 32), 101 + { /* sentinel */ }, 102 + }; 103 + 104 + PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 105 + PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; 106 + PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; 107 + PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" }; 108 + 109 + PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 110 + PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; 111 + PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; 112 + PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" }; 113 + 114 + PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" }; 115 + PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; 116 + PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" }; 117 + PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" }; 118 + PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" }; 119 + PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" }; 120 + PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; 121 + PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; 122 + PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; 123 + PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" }; 124 + PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" }; 125 + PNAME(mux_cif_out_p) = { "cif_src", "xin24m" }; 126 + PNAME(mux_macref_p) = { "mac_src", "ext_gmac" }; 127 + PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; 128 + PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; 129 + PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; 130 + 131 + PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1", 132 + "sclk_otgphy2" }; 133 + PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; 134 + PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; 135 + 136 + static struct rockchip_pll_clock rk3288_pll_clks[] __initdata = { 137 + [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK3288_PLL_CON(0), 138 + RK3288_MODE_CON, 0, 6, rk3288_pll_rates), 139 + [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK3288_PLL_CON(4), 140 + RK3288_MODE_CON, 4, 5, NULL), 141 + [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK3288_PLL_CON(8), 142 + RK3288_MODE_CON, 8, 7, rk3288_pll_rates), 143 + [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK3288_PLL_CON(12), 144 + RK3288_MODE_CON, 12, 8, rk3288_pll_rates), 145 + [npll] = PLL(pll_rk3066, PLL_NPLL, "npll", mux_pll_p, 0, RK3288_PLL_CON(16), 146 + RK3288_MODE_CON, 14, 9, NULL), 147 + }; 148 + 149 + static struct clk_div_table div_hclk_cpu_t[] = { 150 + { .val = 0, .div = 1 }, 151 + { .val = 1, .div = 2 }, 152 + { .val = 3, .div = 4 }, 153 + { /* sentinel */}, 154 + }; 155 + 156 + #define MFLAGS CLK_MUX_HIWORD_MASK 157 + #define DFLAGS CLK_DIVIDER_HIWORD_MASK 158 + #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) 159 + 160 + static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { 161 + /* 162 + * Clock-Architecture Diagram 1 163 + */ 164 + 165 + GATE(0, "apll_core", "apll", 0, 166 + RK3288_CLKGATE_CON(0), 1, GFLAGS), 167 + GATE(0, "gpll_core", "gpll", 0, 168 + RK3288_CLKGATE_CON(0), 2, GFLAGS), 169 + COMPOSITE_NOGATE(0, "armclk", mux_armclk_p, 0, 170 + RK3288_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS), 171 + 172 + COMPOSITE_NOMUX(0, "armcore0", "armclk", 0, 173 + RK3288_CLKSEL_CON(36), 0, 3, DFLAGS, 174 + RK3288_CLKGATE_CON(12), 0, GFLAGS), 175 + COMPOSITE_NOMUX(0, "armcore1", "armclk", 0, 176 + RK3288_CLKSEL_CON(36), 4, 3, DFLAGS, 177 + RK3288_CLKGATE_CON(12), 1, GFLAGS), 178 + COMPOSITE_NOMUX(0, "armcore2", "armclk", 0, 179 + RK3288_CLKSEL_CON(36), 8, 3, DFLAGS, 180 + RK3288_CLKGATE_CON(12), 2, GFLAGS), 181 + COMPOSITE_NOMUX(0, "armcore3", "armclk", 0, 182 + RK3288_CLKSEL_CON(36), 12, 3, DFLAGS, 183 + RK3288_CLKGATE_CON(12), 3, GFLAGS), 184 + COMPOSITE_NOMUX(0, "l2ram", "armclk", 0, 185 + RK3288_CLKSEL_CON(37), 0, 3, DFLAGS, 186 + RK3288_CLKGATE_CON(12), 4, GFLAGS), 187 + COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0, 188 + RK3288_CLKSEL_CON(0), 0, 4, DFLAGS, 189 + RK3288_CLKGATE_CON(12), 5, GFLAGS), 190 + COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0, 191 + RK3288_CLKSEL_CON(0), 4, 4, DFLAGS, 192 + RK3288_CLKGATE_CON(12), 6, GFLAGS), 193 + COMPOSITE_NOMUX(0, "atclk", "armclk", 0, 194 + RK3288_CLKSEL_CON(37), 4, 5, DFLAGS, 195 + RK3288_CLKGATE_CON(12), 7, GFLAGS), 196 + COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0, 197 + RK3288_CLKSEL_CON(37), 9, 5, DFLAGS, 198 + RK3288_CLKGATE_CON(12), 8, GFLAGS), 199 + GATE(0, "pclk_dbg", "pclk_dbg_pre", 0, 200 + RK3288_CLKGATE_CON(12), 9, GFLAGS), 201 + GATE(0, "cs_dbg", "pclk_dbg_pre", 0, 202 + RK3288_CLKGATE_CON(12), 10, GFLAGS), 203 + GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0, 204 + RK3288_CLKGATE_CON(12), 11, GFLAGS), 205 + 206 + GATE(0, "dpll_ddr", "dpll", 0, 207 + RK3288_CLKGATE_CON(0), 8, GFLAGS), 208 + GATE(0, "gpll_ddr", "gpll", 0, 209 + RK3288_CLKGATE_CON(0), 9, GFLAGS), 210 + COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0, 211 + RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2, 212 + DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 213 + 214 + GATE(0, "gpll_aclk_cpu", "gpll", 0, 215 + RK3288_CLKGATE_CON(0), 10, GFLAGS), 216 + GATE(0, "cpll_aclk_cpu", "cpll", 0, 217 + RK3288_CLKGATE_CON(0), 11, GFLAGS), 218 + COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0, 219 + RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS), 220 + DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0, 221 + RK3288_CLKSEL_CON(1), 0, 3, DFLAGS), 222 + GATE(0, "aclk_cpu", "aclk_cpu_pre", 0, 223 + RK3288_CLKGATE_CON(0), 3, GFLAGS), 224 + COMPOSITE_NOMUX(0, "pclk_cpu", "aclk_cpu_pre", 0, 225 + RK3288_CLKSEL_CON(1), 12, 3, DFLAGS, 226 + RK3288_CLKGATE_CON(0), 5, GFLAGS), 227 + COMPOSITE_NOMUX_DIVTBL(0, "hclk_cpu", "aclk_cpu_pre", 0, 228 + RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t, 229 + RK3288_CLKGATE_CON(0), 4, GFLAGS), 230 + GATE(0, "c2c_host", "aclk_cpu_src", 0, 231 + RK3288_CLKGATE_CON(13), 8, GFLAGS), 232 + COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, 233 + RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, 234 + RK3288_CLKGATE_CON(5), 4, GFLAGS), 235 + GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0, 236 + RK3288_CLKGATE_CON(0), 7, GFLAGS), 237 + 238 + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, 239 + RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, 240 + RK3288_CLKGATE_CON(4), 1, GFLAGS), 241 + COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", 0, 242 + RK3288_CLKSEL_CON(8), 0, 243 + RK3288_CLKGATE_CON(4), 2, GFLAGS), 244 + MUX(0, "i2s_pre", mux_i2s_pre_p, 0, 245 + RK3288_CLKSEL_CON(4), 8, 2, MFLAGS), 246 + COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, 0, 247 + RK3288_CLKSEL_CON(4), 12, 1, MFLAGS, 248 + RK3288_CLKGATE_CON(4), 0, GFLAGS), 249 + GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", 0, 250 + RK3288_CLKGATE_CON(4), 3, GFLAGS), 251 + 252 + MUX(0, "spdif_src", mux_pll_src_cpll_gpll_p, 0, 253 + RK3288_CLKSEL_CON(5), 15, 1, MFLAGS), 254 + COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", 0, 255 + RK3288_CLKSEL_CON(5), 0, 7, DFLAGS, 256 + RK3288_CLKGATE_CON(4), 4, GFLAGS), 257 + COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0, 258 + RK3288_CLKSEL_CON(9), 0, 259 + RK3288_CLKGATE_CON(4), 5, GFLAGS), 260 + COMPOSITE_NODIV(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0, 261 + RK3288_CLKSEL_CON(5), 8, 2, MFLAGS, 262 + RK3288_CLKGATE_CON(4), 6, GFLAGS), 263 + COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0, 264 + RK3288_CLKSEL_CON(40), 0, 7, DFLAGS, 265 + RK3288_CLKGATE_CON(4), 7, GFLAGS), 266 + COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0, 267 + RK3288_CLKSEL_CON(41), 0, 268 + RK3288_CLKGATE_CON(4), 8, GFLAGS), 269 + COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, 270 + RK3288_CLKSEL_CON(40), 8, 2, MFLAGS, 271 + RK3288_CLKGATE_CON(4), 9, GFLAGS), 272 + 273 + GATE(0, "sclk_acc_efuse", "xin24m", 0, 274 + RK3288_CLKGATE_CON(0), 12, GFLAGS), 275 + 276 + GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, 277 + RK3288_CLKGATE_CON(1), 0, GFLAGS), 278 + GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, 279 + RK3288_CLKGATE_CON(1), 1, GFLAGS), 280 + GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, 281 + RK3288_CLKGATE_CON(1), 2, GFLAGS), 282 + GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, 283 + RK3288_CLKGATE_CON(1), 3, GFLAGS), 284 + GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, 285 + RK3288_CLKGATE_CON(1), 4, GFLAGS), 286 + GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, 287 + RK3288_CLKGATE_CON(1), 5, GFLAGS), 288 + 289 + /* 290 + * Clock-Architecture Diagram 2 291 + */ 292 + 293 + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb480m_p, 0, 294 + RK3288_CLKSEL_CON(32), 6, 2, MFLAGS, 0, 5, DFLAGS, 295 + RK3288_CLKGATE_CON(3), 9, GFLAGS), 296 + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 297 + RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 298 + RK3288_CLKGATE_CON(3), 11, GFLAGS), 299 + 300 + COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0, 301 + RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS, 302 + RK3288_CLKGATE_CON(3), 0, GFLAGS), 303 + DIV(0, "hclk_vio", "aclk_vio0", 0, 304 + RK3288_CLKSEL_CON(28), 8, 5, DFLAGS), 305 + COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0, 306 + RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS, 307 + RK3288_CLKGATE_CON(3), 2, GFLAGS), 308 + 309 + COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_usb480m_p, 0, 310 + RK3288_CLKSEL_CON(30), 6, 2, MFLAGS, 0, 5, DFLAGS, 311 + RK3288_CLKGATE_CON(3), 5, GFLAGS), 312 + COMPOSITE(0, "sclk_rga", mux_pll_src_cpll_gpll_usb480m_p, 0, 313 + RK3288_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, 314 + RK3288_CLKGATE_CON(3), 4, GFLAGS), 315 + 316 + COMPOSITE(DCLK_VOP0, "dclk_vop0", mux_pll_src_cpll_gpll_npll_p, 0, 317 + RK3288_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS, 318 + RK3288_CLKGATE_CON(3), 1, GFLAGS), 319 + COMPOSITE(DCLK_VOP1, "dclk_vop1", mux_pll_src_cpll_gpll_npll_p, 0, 320 + RK3288_CLKSEL_CON(29), 6, 2, MFLAGS, 8, 8, DFLAGS, 321 + RK3288_CLKGATE_CON(3), 3, GFLAGS), 322 + 323 + COMPOSITE_NODIV(0, "sclk_edp_24m", mux_edp_24m_p, 0, 324 + RK3288_CLKSEL_CON(28), 15, 1, MFLAGS, 325 + RK3288_CLKGATE_CON(3), 12, GFLAGS), 326 + COMPOSITE(0, "sclk_edp", mux_pll_src_cpll_gpll_npll_p, 0, 327 + RK3288_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 6, DFLAGS, 328 + RK3288_CLKGATE_CON(3), 13, GFLAGS), 329 + 330 + COMPOSITE(0, "sclk_isp", mux_pll_src_cpll_gpll_npll_p, 0, 331 + RK3288_CLKSEL_CON(6), 6, 2, MFLAGS, 0, 6, DFLAGS, 332 + RK3288_CLKGATE_CON(3), 14, GFLAGS), 333 + COMPOSITE(0, "sclk_isp_jpe", mux_pll_src_cpll_gpll_npll_p, 0, 334 + RK3288_CLKSEL_CON(6), 14, 2, MFLAGS, 8, 6, DFLAGS, 335 + RK3288_CLKGATE_CON(3), 15, GFLAGS), 336 + 337 + GATE(0, "sclk_hdmi_hdcp", "xin24m", 0, 338 + RK3288_CLKGATE_CON(5), 12, GFLAGS), 339 + GATE(0, "sclk_hdmi_cec", "xin32k", 0, 340 + RK3288_CLKGATE_CON(5), 11, GFLAGS), 341 + 342 + COMPOSITE(0, "aclk_hevc", mux_pll_src_cpll_gpll_npll_p, 0, 343 + RK3288_CLKSEL_CON(39), 14, 2, MFLAGS, 8, 5, DFLAGS, 344 + RK3288_CLKGATE_CON(13), 13, GFLAGS), 345 + DIV(0, "hclk_hevc", "aclk_hevc", 0, 346 + RK3288_CLKSEL_CON(40), 12, 2, DFLAGS), 347 + 348 + COMPOSITE(0, "sclk_hevc_cabac", mux_pll_src_cpll_gpll_npll_p, 0, 349 + RK3288_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, 350 + RK3288_CLKGATE_CON(13), 14, GFLAGS), 351 + COMPOSITE(0, "sclk_hevc_core", mux_pll_src_cpll_gpll_npll_p, 0, 352 + RK3288_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, 353 + RK3288_CLKGATE_CON(13), 15, GFLAGS), 354 + 355 + COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, 356 + RK3288_CLKSEL_CON(26), 8, 1, MFLAGS, 357 + RK3288_CLKGATE_CON(3), 7, GFLAGS), 358 + COMPOSITE_NOGATE(0, "sclk_vip_out", mux_cif_out_p, 0, 359 + RK3288_CLKSEL_CON(26), 15, 1, MFLAGS, 9, 5, DFLAGS), 360 + 361 + DIV(0, "pclk_pd_alive", "gpll", 0, 362 + RK3288_CLKSEL_CON(33), 8, 5, DFLAGS), 363 + COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0, 364 + RK3288_CLKSEL_CON(33), 0, 5, DFLAGS, 365 + RK3288_CLKGATE_CON(5), 8, GFLAGS), 366 + 367 + COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0, 368 + RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS, 369 + RK3288_CLKGATE_CON(5), 7, GFLAGS), 370 + 371 + COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0, 372 + RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS, 373 + RK3288_CLKGATE_CON(2), 0, GFLAGS), 374 + COMPOSITE_NOMUX(0, "pclk_peri", "aclk_peri_src", 0, 375 + RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 376 + RK3288_CLKGATE_CON(2), 3, GFLAGS), 377 + COMPOSITE_NOMUX(0, "hclk_peri", "aclk_peri_src", 0, 378 + RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 379 + RK3288_CLKGATE_CON(2), 2, GFLAGS), 380 + GATE(0, "aclk_peri", "aclk_peri_src", 0, 381 + RK3288_CLKGATE_CON(2), 1, GFLAGS), 382 + 383 + /* 384 + * Clock-Architecture Diagram 3 385 + */ 386 + 387 + COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_cpll_gpll_p, 0, 388 + RK3288_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 7, DFLAGS, 389 + RK3288_CLKGATE_CON(2), 9, GFLAGS), 390 + COMPOSITE(SCLK_SPI1, "sclk_spi1", mux_pll_src_cpll_gpll_p, 0, 391 + RK3288_CLKSEL_CON(25), 15, 1, MFLAGS, 8, 7, DFLAGS, 392 + RK3288_CLKGATE_CON(2), 10, GFLAGS), 393 + COMPOSITE(SCLK_SPI2, "sclk_spi2", mux_pll_src_cpll_gpll_p, 0, 394 + RK3288_CLKSEL_CON(39), 7, 1, MFLAGS, 0, 7, DFLAGS, 395 + RK3288_CLKGATE_CON(2), 11, GFLAGS), 396 + 397 + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, 398 + RK3288_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS, 399 + RK3288_CLKGATE_CON(13), 0, GFLAGS), 400 + COMPOSITE(SCLK_SDIO0, "sclk_sdio0", mux_mmc_src_p, 0, 401 + RK3288_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 6, DFLAGS, 402 + RK3288_CLKGATE_CON(13), 1, GFLAGS), 403 + COMPOSITE(SCLK_SDIO1, "sclk_sdio1", mux_mmc_src_p, 0, 404 + RK3288_CLKSEL_CON(34), 14, 2, MFLAGS, 8, 6, DFLAGS, 405 + RK3288_CLKGATE_CON(13), 2, GFLAGS), 406 + COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0, 407 + RK3288_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS, 408 + RK3288_CLKGATE_CON(13), 3, GFLAGS), 409 + 410 + COMPOSITE(0, "sclk_tspout", mux_tspout_p, 0, 411 + RK3288_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, 412 + RK3288_CLKGATE_CON(4), 11, GFLAGS), 413 + COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0, 414 + RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, 415 + RK3288_CLKGATE_CON(4), 10, GFLAGS), 416 + 417 + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0, 418 + RK3288_CLKGATE_CON(13), 4, GFLAGS), 419 + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0, 420 + RK3288_CLKGATE_CON(13), 5, GFLAGS), 421 + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0, 422 + RK3288_CLKGATE_CON(13), 6, GFLAGS), 423 + GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0, 424 + RK3288_CLKGATE_CON(13), 7, GFLAGS), 425 + 426 + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0, 427 + RK3288_CLKSEL_CON(2), 0, 6, DFLAGS, 428 + RK3288_CLKGATE_CON(2), 7, GFLAGS), 429 + 430 + COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, 431 + RK3288_CLKSEL_CON(24), 8, 8, DFLAGS, 432 + RK3288_CLKGATE_CON(2), 8, GFLAGS), 433 + 434 + GATE(SCLK_PS2C, "sclk_ps2c", "xin24m", 0, 435 + RK3288_CLKGATE_CON(5), 13, GFLAGS), 436 + 437 + COMPOSITE(SCLK_NANDC0, "sclk_nandc0", mux_pll_src_cpll_gpll_p, 0, 438 + RK3288_CLKSEL_CON(38), 7, 1, MFLAGS, 0, 5, DFLAGS, 439 + RK3288_CLKGATE_CON(5), 5, GFLAGS), 440 + COMPOSITE(SCLK_NANDC1, "sclk_nandc1", mux_pll_src_cpll_gpll_p, 0, 441 + RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS, 442 + RK3288_CLKGATE_CON(5), 6, GFLAGS), 443 + 444 + COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0, 445 + RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS, 446 + RK3288_CLKGATE_CON(1), 8, GFLAGS), 447 + COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0, 448 + RK3288_CLKSEL_CON(17), 0, 449 + RK3288_CLKGATE_CON(1), 9, GFLAGS), 450 + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, 0, 451 + RK3288_CLKSEL_CON(13), 8, 2, MFLAGS), 452 + MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0, 453 + RK3288_CLKSEL_CON(13), 15, 1, MFLAGS), 454 + COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0, 455 + RK3288_CLKSEL_CON(14), 0, 7, DFLAGS, 456 + RK3288_CLKGATE_CON(1), 10, GFLAGS), 457 + COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", 0, 458 + RK3288_CLKSEL_CON(18), 0, 459 + RK3288_CLKGATE_CON(1), 11, GFLAGS), 460 + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, 0, 461 + RK3288_CLKSEL_CON(14), 8, 2, MFLAGS), 462 + COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0, 463 + RK3288_CLKSEL_CON(15), 0, 7, DFLAGS, 464 + RK3288_CLKGATE_CON(1), 12, GFLAGS), 465 + COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", 0, 466 + RK3288_CLKSEL_CON(19), 0, 467 + RK3288_CLKGATE_CON(1), 13, GFLAGS), 468 + MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, 0, 469 + RK3288_CLKSEL_CON(15), 8, 2, MFLAGS), 470 + COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0, 471 + RK3288_CLKSEL_CON(16), 0, 7, DFLAGS, 472 + RK3288_CLKGATE_CON(1), 14, GFLAGS), 473 + COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", 0, 474 + RK3288_CLKSEL_CON(20), 0, 475 + RK3288_CLKGATE_CON(1), 15, GFLAGS), 476 + MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, 0, 477 + RK3288_CLKSEL_CON(16), 8, 2, MFLAGS), 478 + COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0, 479 + RK3288_CLKSEL_CON(3), 0, 7, DFLAGS, 480 + RK3288_CLKGATE_CON(2), 12, GFLAGS), 481 + COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", 0, 482 + RK3288_CLKSEL_CON(7), 0, 483 + RK3288_CLKGATE_CON(2), 13, GFLAGS), 484 + MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0, 485 + RK3288_CLKSEL_CON(3), 8, 2, MFLAGS), 486 + 487 + COMPOSITE(0, "mac_src", mux_pll_src_npll_cpll_gpll_p, 0, 488 + RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS, 489 + RK3288_CLKGATE_CON(2), 5, GFLAGS), 490 + MUX(0, "macref", mux_macref_p, 0, 491 + RK3288_CLKSEL_CON(21), 4, 1, MFLAGS), 492 + GATE(0, "sclk_macref_out", "macref", 0, 493 + RK3288_CLKGATE_CON(5), 3, GFLAGS), 494 + GATE(SCLK_MACREF, "sclk_macref", "macref", 0, 495 + RK3288_CLKGATE_CON(5), 2, GFLAGS), 496 + GATE(SCLK_MAC_RX, "sclk_mac_rx", "macref", 0, 497 + RK3288_CLKGATE_CON(5), 0, GFLAGS), 498 + GATE(SCLK_MAC_TX, "sclk_mac_tx", "macref", 0, 499 + RK3288_CLKGATE_CON(5), 1, GFLAGS), 500 + 501 + COMPOSITE(0, "hsadc_src", mux_pll_src_cpll_gpll_p, 0, 502 + RK3288_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS, 503 + RK3288_CLKGATE_CON(2), 6, GFLAGS), 504 + MUX(SCLK_HSADC, "sclk_hsadc_out", mux_hsadcout_p, 0, 505 + RK3288_CLKSEL_CON(22), 4, 1, MFLAGS), 506 + 507 + GATE(0, "jtag", "ext_jtag", 0, 508 + RK3288_CLKGATE_CON(4), 14, GFLAGS), 509 + 510 + COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0, 511 + RK3288_CLKSEL_CON(13), 11, 2, MFLAGS, 512 + RK3288_CLKGATE_CON(5), 15, GFLAGS), 513 + COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0, 514 + RK3288_CLKSEL_CON(29), 0, 2, MFLAGS, 515 + RK3288_CLKGATE_CON(3), 6, GFLAGS), 516 + GATE(0, "hsicphy12m_xin12m", "xin12m", 0, 517 + RK3288_CLKGATE_CON(13), 9, GFLAGS), 518 + DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0, 519 + RK3288_CLKSEL_CON(11), 8, 6, DFLAGS), 520 + MUX(SCLK_HSICPHY12M, "sclk_hsicphy12m", mux_hsicphy12m_p, 0, 521 + RK3288_CLKSEL_CON(22), 4, 1, MFLAGS), 522 + 523 + /* 524 + * Clock-Architecture Diagram 4 525 + */ 526 + 527 + /* aclk_cpu gates */ 528 + GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS), 529 + GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS), 530 + GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS), 531 + GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS), 532 + GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS), 533 + GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS), 534 + GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS), 535 + GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS), 536 + 537 + /* hclk_cpu gates */ 538 + GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS), 539 + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS), 540 + GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS), 541 + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS), 542 + GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS), 543 + 544 + /* pclk_cpu gates */ 545 + GATE(PCLK_PWM, "pclk_pwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 0, GFLAGS), 546 + GATE(PCLK_TIMER, "pclk_timer", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 1, GFLAGS), 547 + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 2, GFLAGS), 548 + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 3, GFLAGS), 549 + GATE(0, "pclk_ddrupctl0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 14, GFLAGS), 550 + GATE(0, "pclk_publ0", "pclk_cpu", 0, RK3288_CLKGATE_CON(10), 15, GFLAGS), 551 + GATE(0, "pclk_ddrupctl1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 0, GFLAGS), 552 + GATE(0, "pclk_publ1", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 1, GFLAGS), 553 + GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 2, GFLAGS), 554 + GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS), 555 + GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS), 556 + GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS), 557 + GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS), 558 + 559 + /* ddrctrl [DDR Controller PHY clock] gates */ 560 + GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS), 561 + GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS), 562 + 563 + /* ddrphy gates */ 564 + GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS), 565 + GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS), 566 + 567 + /* aclk_peri gates */ 568 + GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS), 569 + GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS), 570 + GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS), 571 + GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS), 572 + GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS), 573 + GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS), 574 + 575 + /* hclk_peri gates */ 576 + GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS), 577 + GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS), 578 + GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS), 579 + GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS), 580 + GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS), 581 + GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS), 582 + GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS), 583 + GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS), 584 + GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS), 585 + GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS), 586 + GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS), 587 + GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS), 588 + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 3, GFLAGS), 589 + GATE(HCLK_SDIO0, "hclk_sdio0", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 4, GFLAGS), 590 + GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 5, GFLAGS), 591 + GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 6, GFLAGS), 592 + GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 7, GFLAGS), 593 + GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS), 594 + 595 + /* pclk_peri gates */ 596 + GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS), 597 + GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS), 598 + GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS), 599 + GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS), 600 + GATE(PCLK_PS2C, "pclk_ps2c", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 7, GFLAGS), 601 + GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 8, GFLAGS), 602 + GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 9, GFLAGS), 603 + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 15, GFLAGS), 604 + GATE(PCLK_UART3, "pclk_uart3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 11, GFLAGS), 605 + GATE(PCLK_UART4, "pclk_uart4", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 12, GFLAGS), 606 + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 13, GFLAGS), 607 + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 14, GFLAGS), 608 + GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 1, GFLAGS), 609 + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 2, GFLAGS), 610 + GATE(PCLK_SIM, "pclk_sim", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 3, GFLAGS), 611 + GATE(PCLK_I2C5, "pclk_i2c5", "pclk_peri", 0, RK3288_CLKGATE_CON(7), 0, GFLAGS), 612 + GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK3288_CLKGATE_CON(8), 1, GFLAGS), 613 + 614 + GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS), 615 + GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS), 616 + GATE(0, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS), 617 + GATE(0, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS), 618 + GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS), 619 + 620 + /* sclk_gpu gates */ 621 + GATE(ACLK_GPU, "aclk_gpu", "sclk_gpu", 0, RK3288_CLKGATE_CON(18), 0, GFLAGS), 622 + 623 + /* pclk_pd_alive gates */ 624 + GATE(PCLK_GPIO8, "pclk_gpio8", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 8, GFLAGS), 625 + GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 7, GFLAGS), 626 + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 1, GFLAGS), 627 + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 2, GFLAGS), 628 + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 3, GFLAGS), 629 + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS), 630 + GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS), 631 + GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS), 632 + GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS), 633 + GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS), 634 + 635 + /* pclk_pd_pmu gates */ 636 + GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS), 637 + GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS), 638 + GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS), 639 + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS), 640 + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS), 641 + 642 + /* hclk_vio gates */ 643 + GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS), 644 + GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS), 645 + GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS), 646 + GATE(0, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS), 647 + GATE(0, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS), 648 + GATE(0, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS), 649 + GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS), 650 + GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS), 651 + GATE(0, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS), 652 + GATE(0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS), 653 + GATE(0, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS), 654 + GATE(0, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS), 655 + GATE(0, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS), 656 + GATE(0, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS), 657 + GATE(0, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS), 658 + GATE(0, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS), 659 + 660 + /* aclk_vio0 gates */ 661 + GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS), 662 + GATE(0, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS), 663 + GATE(0, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS), 664 + GATE(0, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS), 665 + 666 + /* aclk_vio1 gates */ 667 + GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS), 668 + GATE(0, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS), 669 + GATE(0, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS), 670 + 671 + /* aclk_rga_pre gates */ 672 + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS), 673 + GATE(0, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS), 674 + 675 + /* 676 + * Other ungrouped clocks. 677 + */ 678 + 679 + GATE(0, "pclk_vip_in", "ext_vip", 0, RK3288_CLKGATE_CON(16), 0, GFLAGS), 680 + GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS), 681 + }; 682 + 683 + static void __init rk3288_clk_init(struct device_node *np) 684 + { 685 + void __iomem *reg_base; 686 + struct clk *clk; 687 + 688 + reg_base = of_iomap(np, 0); 689 + if (!reg_base) { 690 + pr_err("%s: could not map cru region\n", __func__); 691 + return; 692 + } 693 + 694 + rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 695 + 696 + /* xin12m is created by an cru-internal divider */ 697 + clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); 698 + if (IS_ERR(clk)) 699 + pr_warn("%s: could not register clock xin12m: %ld\n", 700 + __func__, PTR_ERR(clk)); 701 + 702 + 703 + clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); 704 + if (IS_ERR(clk)) 705 + pr_warn("%s: could not register clock usb480m: %ld\n", 706 + __func__, PTR_ERR(clk)); 707 + 708 + rockchip_clk_register_plls(rk3288_pll_clks, 709 + ARRAY_SIZE(rk3288_pll_clks), 710 + RK3288_GRF_SOC_STATUS); 711 + rockchip_clk_register_branches(rk3288_clk_branches, 712 + ARRAY_SIZE(rk3288_clk_branches)); 713 + 714 + rockchip_register_softrst(np, 9, reg_base + RK3288_SOFTRST_CON(0), 715 + ROCKCHIP_SOFTRST_HIWORD_MASK); 716 + } 717 + CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
+244
drivers/clk/rockchip/clk.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * based on 6 + * 7 + * samsung/clk.c 8 + * Copyright (c) 2013 Samsung Electronics Co., Ltd. 9 + * Copyright (c) 2013 Linaro Ltd. 10 + * Author: Thomas Abraham <thomas.ab@samsung.com> 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation; either version 2 of the License, or 15 + * (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + */ 22 + 23 + #include <linux/slab.h> 24 + #include <linux/clk.h> 25 + #include <linux/clk-provider.h> 26 + #include <linux/mfd/syscon.h> 27 + #include <linux/regmap.h> 28 + #include "clk.h" 29 + 30 + /** 31 + * Register a clock branch. 32 + * Most clock branches have a form like 33 + * 34 + * src1 --|--\ 35 + * |M |--[GATE]-[DIV]- 36 + * src2 --|--/ 37 + * 38 + * sometimes without one of those components. 39 + */ 40 + struct clk *rockchip_clk_register_branch(const char *name, 41 + const char **parent_names, u8 num_parents, void __iomem *base, 42 + int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 43 + u8 div_shift, u8 div_width, u8 div_flags, 44 + struct clk_div_table *div_table, int gate_offset, 45 + u8 gate_shift, u8 gate_flags, unsigned long flags, 46 + spinlock_t *lock) 47 + { 48 + struct clk *clk; 49 + struct clk_mux *mux = NULL; 50 + struct clk_gate *gate = NULL; 51 + struct clk_divider *div = NULL; 52 + const struct clk_ops *mux_ops = NULL, *div_ops = NULL, 53 + *gate_ops = NULL; 54 + 55 + if (num_parents > 1) { 56 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 57 + if (!mux) 58 + return ERR_PTR(-ENOMEM); 59 + 60 + mux->reg = base + muxdiv_offset; 61 + mux->shift = mux_shift; 62 + mux->mask = BIT(mux_width) - 1; 63 + mux->flags = mux_flags; 64 + mux->lock = lock; 65 + mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops 66 + : &clk_mux_ops; 67 + } 68 + 69 + if (gate_offset >= 0) { 70 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 71 + if (!gate) 72 + return ERR_PTR(-ENOMEM); 73 + 74 + gate->flags = gate_flags; 75 + gate->reg = base + gate_offset; 76 + gate->bit_idx = gate_shift; 77 + gate->lock = lock; 78 + gate_ops = &clk_gate_ops; 79 + } 80 + 81 + if (div_width > 0) { 82 + div = kzalloc(sizeof(*div), GFP_KERNEL); 83 + if (!div) 84 + return ERR_PTR(-ENOMEM); 85 + 86 + div->flags = div_flags; 87 + div->reg = base + muxdiv_offset; 88 + div->shift = div_shift; 89 + div->width = div_width; 90 + div->lock = lock; 91 + div->table = div_table; 92 + div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) 93 + ? &clk_divider_ro_ops 94 + : &clk_divider_ops; 95 + } 96 + 97 + clk = clk_register_composite(NULL, name, parent_names, num_parents, 98 + mux ? &mux->hw : NULL, mux_ops, 99 + div ? &div->hw : NULL, div_ops, 100 + gate ? &gate->hw : NULL, gate_ops, 101 + flags); 102 + 103 + return clk; 104 + } 105 + 106 + static DEFINE_SPINLOCK(clk_lock); 107 + static struct clk **clk_table; 108 + static void __iomem *reg_base; 109 + static struct clk_onecell_data clk_data; 110 + static struct device_node *cru_node; 111 + static struct regmap *grf; 112 + 113 + void __init rockchip_clk_init(struct device_node *np, void __iomem *base, 114 + unsigned long nr_clks) 115 + { 116 + reg_base = base; 117 + cru_node = np; 118 + grf = ERR_PTR(-EPROBE_DEFER); 119 + 120 + clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 121 + if (!clk_table) 122 + pr_err("%s: could not allocate clock lookup table\n", __func__); 123 + 124 + clk_data.clks = clk_table; 125 + clk_data.clk_num = nr_clks; 126 + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 127 + } 128 + 129 + struct regmap *rockchip_clk_get_grf(void) 130 + { 131 + if (IS_ERR(grf)) 132 + grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf"); 133 + return grf; 134 + } 135 + 136 + void rockchip_clk_add_lookup(struct clk *clk, unsigned int id) 137 + { 138 + if (clk_table && id) 139 + clk_table[id] = clk; 140 + } 141 + 142 + void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, 143 + unsigned int nr_pll, int grf_lock_offset) 144 + { 145 + struct clk *clk; 146 + int idx; 147 + 148 + for (idx = 0; idx < nr_pll; idx++, list++) { 149 + clk = rockchip_clk_register_pll(list->type, list->name, 150 + list->parent_names, list->num_parents, 151 + reg_base, list->con_offset, grf_lock_offset, 152 + list->lock_shift, list->mode_offset, 153 + list->mode_shift, list->rate_table, &clk_lock); 154 + if (IS_ERR(clk)) { 155 + pr_err("%s: failed to register clock %s\n", __func__, 156 + list->name); 157 + continue; 158 + } 159 + 160 + rockchip_clk_add_lookup(clk, list->id); 161 + } 162 + } 163 + 164 + void __init rockchip_clk_register_branches( 165 + struct rockchip_clk_branch *list, 166 + unsigned int nr_clk) 167 + { 168 + struct clk *clk = NULL; 169 + unsigned int idx; 170 + unsigned long flags; 171 + 172 + for (idx = 0; idx < nr_clk; idx++, list++) { 173 + flags = list->flags; 174 + 175 + /* catch simple muxes */ 176 + switch (list->branch_type) { 177 + case branch_mux: 178 + clk = clk_register_mux(NULL, list->name, 179 + list->parent_names, list->num_parents, 180 + flags, reg_base + list->muxdiv_offset, 181 + list->mux_shift, list->mux_width, 182 + list->mux_flags, &clk_lock); 183 + break; 184 + case branch_divider: 185 + if (list->div_table) 186 + clk = clk_register_divider_table(NULL, 187 + list->name, list->parent_names[0], 188 + flags, reg_base + list->muxdiv_offset, 189 + list->div_shift, list->div_width, 190 + list->div_flags, list->div_table, 191 + &clk_lock); 192 + else 193 + clk = clk_register_divider(NULL, list->name, 194 + list->parent_names[0], flags, 195 + reg_base + list->muxdiv_offset, 196 + list->div_shift, list->div_width, 197 + list->div_flags, &clk_lock); 198 + break; 199 + case branch_fraction_divider: 200 + /* unimplemented */ 201 + continue; 202 + break; 203 + case branch_gate: 204 + flags |= CLK_SET_RATE_PARENT; 205 + 206 + /* keep all gates untouched for now */ 207 + flags |= CLK_IGNORE_UNUSED; 208 + 209 + clk = clk_register_gate(NULL, list->name, 210 + list->parent_names[0], flags, 211 + reg_base + list->gate_offset, 212 + list->gate_shift, list->gate_flags, &clk_lock); 213 + break; 214 + case branch_composite: 215 + /* keep all gates untouched for now */ 216 + flags |= CLK_IGNORE_UNUSED; 217 + 218 + clk = rockchip_clk_register_branch(list->name, 219 + list->parent_names, list->num_parents, 220 + reg_base, list->muxdiv_offset, list->mux_shift, 221 + list->mux_width, list->mux_flags, 222 + list->div_shift, list->div_width, 223 + list->div_flags, list->div_table, 224 + list->gate_offset, list->gate_shift, 225 + list->gate_flags, flags, &clk_lock); 226 + break; 227 + } 228 + 229 + /* none of the cases above matched */ 230 + if (!clk) { 231 + pr_err("%s: unknown clock type %d\n", 232 + __func__, list->branch_type); 233 + continue; 234 + } 235 + 236 + if (IS_ERR(clk)) { 237 + pr_err("%s: failed to register clock %s: %ld\n", 238 + __func__, list->name, PTR_ERR(clk)); 239 + continue; 240 + } 241 + 242 + rockchip_clk_add_lookup(clk, list->id); 243 + } 244 + }
+347
drivers/clk/rockchip/clk.h
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * based on 6 + * 7 + * samsung/clk.h 8 + * Copyright (c) 2013 Samsung Electronics Co., Ltd. 9 + * Copyright (c) 2013 Linaro Ltd. 10 + * Author: Thomas Abraham <thomas.ab@samsung.com> 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License as published by 14 + * the Free Software Foundation; either version 2 of the License, or 15 + * (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + */ 22 + 23 + #ifndef CLK_ROCKCHIP_CLK_H 24 + #define CLK_ROCKCHIP_CLK_H 25 + 26 + #include <linux/io.h> 27 + #include <linux/clk.h> 28 + #include <linux/clk-provider.h> 29 + 30 + #define HIWORD_UPDATE(val, mask, shift) \ 31 + ((val) << (shift) | (mask) << ((shift) + 16)) 32 + 33 + /* register positions shared by RK2928, RK3066 and RK3188 */ 34 + #define RK2928_PLL_CON(x) (x * 0x4) 35 + #define RK2928_MODE_CON 0x40 36 + #define RK2928_CLKSEL_CON(x) (x * 0x4 + 0x44) 37 + #define RK2928_CLKGATE_CON(x) (x * 0x4 + 0xd0) 38 + #define RK2928_GLB_SRST_FST 0x100 39 + #define RK2928_GLB_SRST_SND 0x104 40 + #define RK2928_SOFTRST_CON(x) (x * 0x4 + 0x110) 41 + #define RK2928_MISC_CON 0x134 42 + 43 + #define RK3288_PLL_CON(x) RK2928_PLL_CON(x) 44 + #define RK3288_MODE_CON 0x50 45 + #define RK3288_CLKSEL_CON(x) (x * 0x4 + 0x60) 46 + #define RK3288_CLKGATE_CON(x) (x * 0x4 + 0x160) 47 + #define RK3288_GLB_SRST_FST 0x1b0 48 + #define RK3288_GLB_SRST_SND 0x1b4 49 + #define RK3288_SOFTRST_CON(x) (x * 0x4 + 0x1b8) 50 + #define RK3288_MISC_CON 0x1e8 51 + 52 + enum rockchip_pll_type { 53 + pll_rk3066, 54 + }; 55 + 56 + #define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \ 57 + { \ 58 + .rate = _rate##U, \ 59 + .nr = _nr, \ 60 + .nf = _nf, \ 61 + .no = _no, \ 62 + .bwadj = (_nf >> 1), \ 63 + } 64 + 65 + struct rockchip_pll_rate_table { 66 + unsigned long rate; 67 + unsigned int nr; 68 + unsigned int nf; 69 + unsigned int no; 70 + unsigned int bwadj; 71 + }; 72 + 73 + /** 74 + * struct rockchip_pll_clock: information about pll clock 75 + * @id: platform specific id of the clock. 76 + * @name: name of this pll clock. 77 + * @parent_name: name of the parent clock. 78 + * @flags: optional flags for basic clock. 79 + * @con_offset: offset of the register for configuring the PLL. 80 + * @mode_offset: offset of the register for configuring the PLL-mode. 81 + * @mode_shift: offset inside the mode-register for the mode of this pll. 82 + * @lock_shift: offset inside the lock register for the lock status. 83 + * @type: Type of PLL to be registered. 84 + * @rate_table: Table of usable pll rates 85 + */ 86 + struct rockchip_pll_clock { 87 + unsigned int id; 88 + const char *name; 89 + const char **parent_names; 90 + u8 num_parents; 91 + unsigned long flags; 92 + int con_offset; 93 + int mode_offset; 94 + int mode_shift; 95 + int lock_shift; 96 + enum rockchip_pll_type type; 97 + struct rockchip_pll_rate_table *rate_table; 98 + }; 99 + 100 + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 101 + _lshift, _rtable) \ 102 + { \ 103 + .id = _id, \ 104 + .type = _type, \ 105 + .name = _name, \ 106 + .parent_names = _pnames, \ 107 + .num_parents = ARRAY_SIZE(_pnames), \ 108 + .flags = CLK_GET_RATE_NOCACHE | _flags, \ 109 + .con_offset = _con, \ 110 + .mode_offset = _mode, \ 111 + .mode_shift = _mshift, \ 112 + .lock_shift = _lshift, \ 113 + .rate_table = _rtable, \ 114 + } 115 + 116 + struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 117 + const char *name, const char **parent_names, u8 num_parents, 118 + void __iomem *base, int con_offset, int grf_lock_offset, 119 + int lock_shift, int reg_mode, int mode_shift, 120 + struct rockchip_pll_rate_table *rate_table, 121 + spinlock_t *lock); 122 + 123 + #define PNAME(x) static const char *x[] __initconst 124 + 125 + enum rockchip_clk_branch_type { 126 + branch_composite, 127 + branch_mux, 128 + branch_divider, 129 + branch_fraction_divider, 130 + branch_gate, 131 + }; 132 + 133 + struct rockchip_clk_branch { 134 + unsigned int id; 135 + enum rockchip_clk_branch_type branch_type; 136 + const char *name; 137 + const char **parent_names; 138 + u8 num_parents; 139 + unsigned long flags; 140 + int muxdiv_offset; 141 + u8 mux_shift; 142 + u8 mux_width; 143 + u8 mux_flags; 144 + u8 div_shift; 145 + u8 div_width; 146 + u8 div_flags; 147 + struct clk_div_table *div_table; 148 + int gate_offset; 149 + u8 gate_shift; 150 + u8 gate_flags; 151 + }; 152 + 153 + #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 154 + df, go, gs, gf) \ 155 + { \ 156 + .id = _id, \ 157 + .branch_type = branch_composite, \ 158 + .name = cname, \ 159 + .parent_names = pnames, \ 160 + .num_parents = ARRAY_SIZE(pnames), \ 161 + .flags = f, \ 162 + .muxdiv_offset = mo, \ 163 + .mux_shift = ms, \ 164 + .mux_width = mw, \ 165 + .mux_flags = mf, \ 166 + .div_shift = ds, \ 167 + .div_width = dw, \ 168 + .div_flags = df, \ 169 + .gate_offset = go, \ 170 + .gate_shift = gs, \ 171 + .gate_flags = gf, \ 172 + } 173 + 174 + #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 175 + go, gs, gf) \ 176 + { \ 177 + .id = _id, \ 178 + .branch_type = branch_composite, \ 179 + .name = cname, \ 180 + .parent_names = (const char *[]){ pname }, \ 181 + .num_parents = 1, \ 182 + .flags = f, \ 183 + .muxdiv_offset = mo, \ 184 + .div_shift = ds, \ 185 + .div_width = dw, \ 186 + .div_flags = df, \ 187 + .gate_offset = go, \ 188 + .gate_shift = gs, \ 189 + .gate_flags = gf, \ 190 + } 191 + 192 + #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ 193 + df, dt, go, gs, gf) \ 194 + { \ 195 + .id = _id, \ 196 + .branch_type = branch_composite, \ 197 + .name = cname, \ 198 + .parent_names = (const char *[]){ pname }, \ 199 + .num_parents = 1, \ 200 + .flags = f, \ 201 + .muxdiv_offset = mo, \ 202 + .div_shift = ds, \ 203 + .div_width = dw, \ 204 + .div_flags = df, \ 205 + .div_table = dt, \ 206 + .gate_offset = go, \ 207 + .gate_shift = gs, \ 208 + .gate_flags = gf, \ 209 + } 210 + 211 + #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 212 + go, gs, gf) \ 213 + { \ 214 + .id = _id, \ 215 + .branch_type = branch_composite, \ 216 + .name = cname, \ 217 + .parent_names = pnames, \ 218 + .num_parents = ARRAY_SIZE(pnames), \ 219 + .flags = f, \ 220 + .muxdiv_offset = mo, \ 221 + .mux_shift = ms, \ 222 + .mux_width = mw, \ 223 + .mux_flags = mf, \ 224 + .gate_offset = go, \ 225 + .gate_shift = gs, \ 226 + .gate_flags = gf, \ 227 + } 228 + 229 + #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ 230 + ds, dw, df) \ 231 + { \ 232 + .id = _id, \ 233 + .branch_type = branch_composite, \ 234 + .name = cname, \ 235 + .parent_names = pnames, \ 236 + .num_parents = ARRAY_SIZE(pnames), \ 237 + .flags = f, \ 238 + .muxdiv_offset = mo, \ 239 + .mux_shift = ms, \ 240 + .mux_width = mw, \ 241 + .mux_flags = mf, \ 242 + .div_shift = ds, \ 243 + .div_width = dw, \ 244 + .div_flags = df, \ 245 + .gate_offset = -1, \ 246 + } 247 + 248 + #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ 249 + { \ 250 + .id = _id, \ 251 + .branch_type = branch_fraction_divider, \ 252 + .name = cname, \ 253 + .parent_names = (const char *[]){ pname }, \ 254 + .num_parents = 1, \ 255 + .flags = f, \ 256 + .muxdiv_offset = mo, \ 257 + .div_shift = 16, \ 258 + .div_width = 16, \ 259 + .div_flags = df, \ 260 + .gate_offset = go, \ 261 + .gate_shift = gs, \ 262 + .gate_flags = gf, \ 263 + } 264 + 265 + #define MUX(_id, cname, pnames, f, o, s, w, mf) \ 266 + { \ 267 + .id = _id, \ 268 + .branch_type = branch_mux, \ 269 + .name = cname, \ 270 + .parent_names = pnames, \ 271 + .num_parents = ARRAY_SIZE(pnames), \ 272 + .flags = f, \ 273 + .muxdiv_offset = o, \ 274 + .mux_shift = s, \ 275 + .mux_width = w, \ 276 + .mux_flags = mf, \ 277 + .gate_offset = -1, \ 278 + } 279 + 280 + #define DIV(_id, cname, pname, f, o, s, w, df) \ 281 + { \ 282 + .id = _id, \ 283 + .branch_type = branch_divider, \ 284 + .name = cname, \ 285 + .parent_names = (const char *[]){ pname }, \ 286 + .num_parents = 1, \ 287 + .flags = f, \ 288 + .muxdiv_offset = o, \ 289 + .div_shift = s, \ 290 + .div_width = w, \ 291 + .div_flags = df, \ 292 + .gate_offset = -1, \ 293 + } 294 + 295 + #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ 296 + { \ 297 + .id = _id, \ 298 + .branch_type = branch_divider, \ 299 + .name = cname, \ 300 + .parent_names = (const char *[]){ pname }, \ 301 + .num_parents = 1, \ 302 + .flags = f, \ 303 + .muxdiv_offset = o, \ 304 + .div_shift = s, \ 305 + .div_width = w, \ 306 + .div_flags = df, \ 307 + .div_table = dt, \ 308 + } 309 + 310 + #define GATE(_id, cname, pname, f, o, b, gf) \ 311 + { \ 312 + .id = _id, \ 313 + .branch_type = branch_gate, \ 314 + .name = cname, \ 315 + .parent_names = (const char *[]){ pname }, \ 316 + .num_parents = 1, \ 317 + .flags = f, \ 318 + .gate_offset = o, \ 319 + .gate_shift = b, \ 320 + .gate_flags = gf, \ 321 + } 322 + 323 + 324 + void rockchip_clk_init(struct device_node *np, void __iomem *base, 325 + unsigned long nr_clks); 326 + struct regmap *rockchip_clk_get_grf(void); 327 + void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); 328 + void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, 329 + unsigned int nr_clk); 330 + void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 331 + unsigned int nr_pll, int grf_lock_offset); 332 + 333 + #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 334 + 335 + #ifdef CONFIG_RESET_CONTROLLER 336 + void rockchip_register_softrst(struct device_node *np, 337 + unsigned int num_regs, 338 + void __iomem *base, u8 flags); 339 + #else 340 + static inline void rockchip_register_softrst(struct device_node *np, 341 + unsigned int num_regs, 342 + void __iomem *base, u8 flags) 343 + { 344 + } 345 + #endif 346 + 347 + #endif
+118
drivers/clk/rockchip/softrst.c
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/slab.h> 17 + #include <linux/io.h> 18 + #include <linux/reset-controller.h> 19 + #include <linux/spinlock.h> 20 + #include "clk.h" 21 + 22 + struct rockchip_softrst { 23 + struct reset_controller_dev rcdev; 24 + void __iomem *reg_base; 25 + int num_regs; 26 + int num_per_reg; 27 + u8 flags; 28 + spinlock_t lock; 29 + }; 30 + 31 + static int rockchip_softrst_assert(struct reset_controller_dev *rcdev, 32 + unsigned long id) 33 + { 34 + struct rockchip_softrst *softrst = container_of(rcdev, 35 + struct rockchip_softrst, 36 + rcdev); 37 + int bank = id / softrst->num_per_reg; 38 + int offset = id % softrst->num_per_reg; 39 + 40 + if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) { 41 + writel(BIT(offset) | (BIT(offset) << 16), 42 + softrst->reg_base + (bank * 4)); 43 + } else { 44 + unsigned long flags; 45 + u32 reg; 46 + 47 + spin_lock_irqsave(&softrst->lock, flags); 48 + 49 + reg = readl(softrst->reg_base + (bank * 4)); 50 + writel(reg | BIT(offset), softrst->reg_base + (bank * 4)); 51 + 52 + spin_unlock_irqrestore(&softrst->lock, flags); 53 + } 54 + 55 + return 0; 56 + } 57 + 58 + static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev, 59 + unsigned long id) 60 + { 61 + struct rockchip_softrst *softrst = container_of(rcdev, 62 + struct rockchip_softrst, 63 + rcdev); 64 + int bank = id / softrst->num_per_reg; 65 + int offset = id % softrst->num_per_reg; 66 + 67 + if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) { 68 + writel((BIT(offset) << 16), softrst->reg_base + (bank * 4)); 69 + } else { 70 + unsigned long flags; 71 + u32 reg; 72 + 73 + spin_lock_irqsave(&softrst->lock, flags); 74 + 75 + reg = readl(softrst->reg_base + (bank * 4)); 76 + writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4)); 77 + 78 + spin_unlock_irqrestore(&softrst->lock, flags); 79 + } 80 + 81 + return 0; 82 + } 83 + 84 + static struct reset_control_ops rockchip_softrst_ops = { 85 + .assert = rockchip_softrst_assert, 86 + .deassert = rockchip_softrst_deassert, 87 + }; 88 + 89 + void __init rockchip_register_softrst(struct device_node *np, 90 + unsigned int num_regs, 91 + void __iomem *base, u8 flags) 92 + { 93 + struct rockchip_softrst *softrst; 94 + int ret; 95 + 96 + softrst = kzalloc(sizeof(*softrst), GFP_KERNEL); 97 + if (!softrst) 98 + return; 99 + 100 + spin_lock_init(&softrst->lock); 101 + 102 + softrst->reg_base = base; 103 + softrst->flags = flags; 104 + softrst->num_regs = num_regs; 105 + softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 106 + : 32; 107 + 108 + softrst->rcdev.owner = THIS_MODULE; 109 + softrst->rcdev.nr_resets = num_regs * softrst->num_per_reg; 110 + softrst->rcdev.ops = &rockchip_softrst_ops; 111 + softrst->rcdev.of_node = np; 112 + ret = reset_controller_register(&softrst->rcdev); 113 + if (ret) { 114 + pr_err("%s: could not register reset controller, %d\n", 115 + __func__, ret); 116 + kfree(softrst); 117 + } 118 + };
+35
include/dt-bindings/clock/rk3066a-cru.h
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <dt-bindings/clock/rk3188-cru-common.h> 17 + 18 + /* soft-reset indices */ 19 + #define SRST_SRST1 0 20 + #define SRST_SRST2 1 21 + 22 + #define SRST_L2MEM 18 23 + #define SRST_I2S0 23 24 + #define SRST_I2S1 24 25 + #define SRST_I2S2 25 26 + #define SRST_TIMER2 29 27 + 28 + #define SRST_GPIO4 36 29 + #define SRST_GPIO6 38 30 + 31 + #define SRST_TSADC 92 32 + 33 + #define SRST_HDMI 96 34 + #define SRST_HDMI_APB 97 35 + #define SRST_CIF1 111
+249
include/dt-bindings/clock/rk3188-cru-common.h
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + /* core clocks from */ 17 + #define PLL_APLL 1 18 + #define PLL_DPLL 2 19 + #define PLL_CPLL 3 20 + #define PLL_GPLL 4 21 + #define CORE_PERI 5 22 + #define CORE_L2C 6 23 + 24 + /* sclk gates (special clocks) */ 25 + #define SCLK_UART0 64 26 + #define SCLK_UART1 65 27 + #define SCLK_UART2 66 28 + #define SCLK_UART3 67 29 + #define SCLK_MAC 68 30 + #define SCLK_SPI0 69 31 + #define SCLK_SPI1 70 32 + #define SCLK_SARADC 71 33 + #define SCLK_SDMMC 72 34 + #define SCLK_SDIO 73 35 + #define SCLK_EMMC 74 36 + #define SCLK_I2S0 75 37 + #define SCLK_I2S1 76 38 + #define SCLK_I2S2 77 39 + #define SCLK_SPDIF 78 40 + #define SCLK_CIF0 79 41 + #define SCLK_CIF1 80 42 + #define SCLK_OTGPHY0 81 43 + #define SCLK_OTGPHY1 82 44 + #define SCLK_HSADC 83 45 + #define SCLK_TIMER0 84 46 + #define SCLK_TIMER1 85 47 + #define SCLK_TIMER2 86 48 + #define SCLK_TIMER3 87 49 + #define SCLK_TIMER4 88 50 + #define SCLK_TIMER5 89 51 + #define SCLK_TIMER6 90 52 + #define SCLK_JTAG 91 53 + #define SCLK_SMC 92 54 + 55 + #define DCLK_LCDC0 190 56 + #define DCLK_LCDC1 191 57 + 58 + /* aclk gates */ 59 + #define ACLK_DMA1 192 60 + #define ACLK_DMA2 193 61 + #define ACLK_GPS 194 62 + #define ACLK_LCDC0 195 63 + #define ACLK_LCDC1 196 64 + #define ACLK_GPU 197 65 + #define ACLK_SMC 198 66 + #define ACLK_CIF 199 67 + #define ACLK_IPP 200 68 + #define ACLK_RGA 201 69 + #define ACLK_CIF0 202 70 + 71 + /* pclk gates */ 72 + #define PCLK_GRF 320 73 + #define PCLK_PMU 321 74 + #define PCLK_TIMER0 322 75 + #define PCLK_TIMER1 323 76 + #define PCLK_TIMER2 324 77 + #define PCLK_TIMER3 325 78 + #define PCLK_PWM01 326 79 + #define PCLK_PWM23 327 80 + #define PCLK_SPI0 328 81 + #define PCLK_SPI1 329 82 + #define PCLK_SARADC 330 83 + #define PCLK_WDT 331 84 + #define PCLK_UART0 332 85 + #define PCLK_UART1 333 86 + #define PCLK_UART2 334 87 + #define PCLK_UART3 335 88 + #define PCLK_I2C0 336 89 + #define PCLK_I2C1 337 90 + #define PCLK_I2C2 338 91 + #define PCLK_I2C3 339 92 + #define PCLK_I2C4 340 93 + #define PCLK_GPIO0 341 94 + #define PCLK_GPIO1 342 95 + #define PCLK_GPIO2 343 96 + #define PCLK_GPIO3 344 97 + #define PCLK_GPIO4 345 98 + #define PCLK_GPIO6 346 99 + #define PCLK_EFUSE 347 100 + #define PCLK_TZPC 348 101 + #define PCLK_TSADC 349 102 + 103 + /* hclk gates */ 104 + #define HCLK_SDMMC 448 105 + #define HCLK_SDIO 449 106 + #define HCLK_EMMC 450 107 + #define HCLK_OTG0 451 108 + #define HCLK_EMAC 452 109 + #define HCLK_SPDIF 453 110 + #define HCLK_I2S0 454 111 + #define HCLK_I2S1 455 112 + #define HCLK_I2S2 456 113 + #define HCLK_OTG1 457 114 + #define HCLK_HSIC 458 115 + #define HCLK_HSADC 459 116 + #define HCLK_PIDF 460 117 + #define HCLK_LCDC0 461 118 + #define HCLK_LCDC1 462 119 + #define HCLK_ROM 463 120 + #define HCLK_CIF0 464 121 + #define HCLK_IPP 465 122 + #define HCLK_RGA 466 123 + #define HCLK_NANDC0 467 124 + 125 + #define CLK_NR_CLKS (HCLK_NANDC0 + 1) 126 + 127 + /* soft-reset indices */ 128 + #define SRST_MCORE 2 129 + #define SRST_CORE0 3 130 + #define SRST_CORE1 4 131 + #define SRST_MCORE_DBG 7 132 + #define SRST_CORE0_DBG 8 133 + #define SRST_CORE1_DBG 9 134 + #define SRST_CORE0_WDT 12 135 + #define SRST_CORE1_WDT 13 136 + #define SRST_STRC_SYS 14 137 + #define SRST_L2C 15 138 + 139 + #define SRST_CPU_AHB 17 140 + #define SRST_AHB2APB 19 141 + #define SRST_DMA1 20 142 + #define SRST_INTMEM 21 143 + #define SRST_ROM 22 144 + #define SRST_SPDIF 26 145 + #define SRST_TIMER0 27 146 + #define SRST_TIMER1 28 147 + #define SRST_EFUSE 30 148 + 149 + #define SRST_GPIO0 32 150 + #define SRST_GPIO1 33 151 + #define SRST_GPIO2 34 152 + #define SRST_GPIO3 35 153 + 154 + #define SRST_UART0 39 155 + #define SRST_UART1 40 156 + #define SRST_UART2 41 157 + #define SRST_UART3 42 158 + #define SRST_I2C0 43 159 + #define SRST_I2C1 44 160 + #define SRST_I2C2 45 161 + #define SRST_I2C3 46 162 + #define SRST_I2C4 47 163 + 164 + #define SRST_PWM0 48 165 + #define SRST_PWM1 49 166 + #define SRST_DAP_PO 50 167 + #define SRST_DAP 51 168 + #define SRST_DAP_SYS 52 169 + #define SRST_TPIU_ATB 53 170 + #define SRST_PMU_APB 54 171 + #define SRST_GRF 55 172 + #define SRST_PMU 56 173 + #define SRST_PERI_AXI 57 174 + #define SRST_PERI_AHB 58 175 + #define SRST_PERI_APB 59 176 + #define SRST_PERI_NIU 60 177 + #define SRST_CPU_PERI 61 178 + #define SRST_EMEM_PERI 62 179 + #define SRST_USB_PERI 63 180 + 181 + #define SRST_DMA2 64 182 + #define SRST_SMC 65 183 + #define SRST_MAC 66 184 + #define SRST_NANC0 68 185 + #define SRST_USBOTG0 69 186 + #define SRST_USBPHY0 70 187 + #define SRST_OTGC0 71 188 + #define SRST_USBOTG1 72 189 + #define SRST_USBPHY1 73 190 + #define SRST_OTGC1 74 191 + #define SRST_HSADC 76 192 + #define SRST_PIDFILTER 77 193 + #define SRST_DDR_MSCH 79 194 + 195 + #define SRST_TZPC 80 196 + #define SRST_SDMMC 81 197 + #define SRST_SDIO 82 198 + #define SRST_EMMC 83 199 + #define SRST_SPI0 84 200 + #define SRST_SPI1 85 201 + #define SRST_WDT 86 202 + #define SRST_SARADC 87 203 + #define SRST_DDRPHY 88 204 + #define SRST_DDRPHY_APB 89 205 + #define SRST_DDRCTL 90 206 + #define SRST_DDRCTL_APB 91 207 + #define SRST_DDRPUB 93 208 + 209 + #define SRST_VIO0_AXI 98 210 + #define SRST_VIO0_AHB 99 211 + #define SRST_LCDC0_AXI 100 212 + #define SRST_LCDC0_AHB 101 213 + #define SRST_LCDC0_DCLK 102 214 + #define SRST_LCDC1_AXI 103 215 + #define SRST_LCDC1_AHB 104 216 + #define SRST_LCDC1_DCLK 105 217 + #define SRST_IPP_AXI 106 218 + #define SRST_IPP_AHB 107 219 + #define SRST_RGA_AXI 108 220 + #define SRST_RGA_AHB 109 221 + #define SRST_CIF0 110 222 + 223 + #define SRST_VCODEC_AXI 112 224 + #define SRST_VCODEC_AHB 113 225 + #define SRST_VIO1_AXI 114 226 + #define SRST_VCODEC_CPU 115 227 + #define SRST_VCODEC_NIU 116 228 + #define SRST_GPU 120 229 + #define SRST_GPU_NIU 122 230 + #define SRST_TFUN_ATB 125 231 + #define SRST_TFUN_APB 126 232 + #define SRST_CTI4_APB 127 233 + 234 + #define SRST_TPIU_APB 128 235 + #define SRST_TRACE 129 236 + #define SRST_CORE_DBG 130 237 + #define SRST_DBG_APB 131 238 + #define SRST_CTI0 132 239 + #define SRST_CTI0_APB 133 240 + #define SRST_CTI1 134 241 + #define SRST_CTI1_APB 135 242 + #define SRST_PTM_CORE0 136 243 + #define SRST_PTM_CORE1 137 244 + #define SRST_PTM0 138 245 + #define SRST_PTM0_ATB 139 246 + #define SRST_PTM1 140 247 + #define SRST_PTM1_ATB 141 248 + #define SRST_CTM 142 249 + #define SRST_TS 143
+51
include/dt-bindings/clock/rk3188-cru.h
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <dt-bindings/clock/rk3188-cru-common.h> 17 + 18 + /* soft-reset indices */ 19 + #define SRST_PTM_CORE2 0 20 + #define SRST_PTM_CORE3 1 21 + #define SRST_CORE2 5 22 + #define SRST_CORE3 6 23 + #define SRST_CORE2_DBG 10 24 + #define SRST_CORE3_DBG 11 25 + 26 + #define SRST_TIMER2 16 27 + #define SRST_TIMER4 23 28 + #define SRST_I2S0 24 29 + #define SRST_TIMER5 25 30 + #define SRST_TIMER3 29 31 + #define SRST_TIMER6 31 32 + 33 + #define SRST_PTM3 36 34 + #define SRST_PTM3_ATB 37 35 + 36 + #define SRST_GPS 67 37 + #define SRST_HSICPHY 75 38 + #define SRST_TIMER 78 39 + 40 + #define SRST_PTM2 92 41 + #define SRST_CORE2_WDT 94 42 + #define SRST_CORE3_WDT 95 43 + 44 + #define SRST_PTM2_ATB 111 45 + 46 + #define SRST_HSIC 117 47 + #define SRST_CTI2 118 48 + #define SRST_CTI2_APB 119 49 + #define SRST_GPU_BRIDGE 121 50 + #define SRST_CTI3 123 51 + #define SRST_CTI3_APB 124
+278
include/dt-bindings/clock/rk3288-cru.h
··· 1 + /* 2 + * Copyright (c) 2014 MundoReader S.L. 3 + * Author: Heiko Stuebner <heiko@sntech.de> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + /* core clocks */ 17 + #define PLL_APLL 1 18 + #define PLL_DPLL 2 19 + #define PLL_CPLL 3 20 + #define PLL_GPLL 4 21 + #define PLL_NPLL 5 22 + 23 + /* sclk gates (special clocks) */ 24 + #define SCLK_GPU 64 25 + #define SCLK_SPI0 65 26 + #define SCLK_SPI1 66 27 + #define SCLK_SPI2 67 28 + #define SCLK_SDMMC 68 29 + #define SCLK_SDIO0 69 30 + #define SCLK_SDIO1 70 31 + #define SCLK_EMMC 71 32 + #define SCLK_TSADC 72 33 + #define SCLK_SARADC 73 34 + #define SCLK_PS2C 74 35 + #define SCLK_NANDC0 75 36 + #define SCLK_NANDC1 76 37 + #define SCLK_UART0 77 38 + #define SCLK_UART1 78 39 + #define SCLK_UART2 79 40 + #define SCLK_UART3 80 41 + #define SCLK_UART4 81 42 + #define SCLK_I2S0 82 43 + #define SCLK_SPDIF 83 44 + #define SCLK_SPDIF8CH 84 45 + #define SCLK_TIMER0 85 46 + #define SCLK_TIMER1 86 47 + #define SCLK_TIMER2 87 48 + #define SCLK_TIMER3 88 49 + #define SCLK_TIMER4 89 50 + #define SCLK_TIMER5 90 51 + #define SCLK_TIMER6 91 52 + #define SCLK_HSADC 92 53 + #define SCLK_OTGPHY0 93 54 + #define SCLK_OTGPHY1 94 55 + #define SCLK_OTGPHY2 95 56 + #define SCLK_OTG_ADP 96 57 + #define SCLK_HSICPHY480M 97 58 + #define SCLK_HSICPHY12M 98 59 + #define SCLK_MACREF 99 60 + #define SCLK_LCDC_PWM0 100 61 + #define SCLK_LCDC_PWM1 101 62 + #define SCLK_MAC_RX 102 63 + #define SCLK_MAC_TX 103 64 + 65 + #define DCLK_VOP0 190 66 + #define DCLK_VOP1 191 67 + 68 + /* aclk gates */ 69 + #define ACLK_GPU 192 70 + #define ACLK_DMAC1 193 71 + #define ACLK_DMAC2 194 72 + #define ACLK_MMU 195 73 + #define ACLK_GMAC 196 74 + #define ACLK_VOP0 197 75 + #define ACLK_VOP1 198 76 + #define ACLK_CRYPTO 199 77 + #define ACLK_RGA 200 78 + 79 + /* pclk gates */ 80 + #define PCLK_GPIO0 320 81 + #define PCLK_GPIO1 321 82 + #define PCLK_GPIO2 322 83 + #define PCLK_GPIO3 323 84 + #define PCLK_GPIO4 324 85 + #define PCLK_GPIO5 325 86 + #define PCLK_GPIO6 326 87 + #define PCLK_GPIO7 327 88 + #define PCLK_GPIO8 328 89 + #define PCLK_GRF 329 90 + #define PCLK_SGRF 330 91 + #define PCLK_PMU 331 92 + #define PCLK_I2C0 332 93 + #define PCLK_I2C1 333 94 + #define PCLK_I2C2 334 95 + #define PCLK_I2C3 335 96 + #define PCLK_I2C4 336 97 + #define PCLK_I2C5 337 98 + #define PCLK_SPI0 338 99 + #define PCLK_SPI1 339 100 + #define PCLK_SPI2 340 101 + #define PCLK_UART0 341 102 + #define PCLK_UART1 342 103 + #define PCLK_UART2 343 104 + #define PCLK_UART3 344 105 + #define PCLK_UART4 345 106 + #define PCLK_TSADC 346 107 + #define PCLK_SARADC 347 108 + #define PCLK_SIM 348 109 + #define PCLK_GMAC 349 110 + #define PCLK_PWM 350 111 + #define PCLK_RKPWM 351 112 + #define PCLK_PS2C 352 113 + #define PCLK_TIMER 353 114 + #define PCLK_TZPC 354 115 + 116 + /* hclk gates */ 117 + #define HCLK_GPS 448 118 + #define HCLK_OTG0 449 119 + #define HCLK_USBHOST0 450 120 + #define HCLK_USBHOST1 451 121 + #define HCLK_HSIC 452 122 + #define HCLK_NANDC0 453 123 + #define HCLK_NANDC1 454 124 + #define HCLK_TSP 455 125 + #define HCLK_SDMMC 456 126 + #define HCLK_SDIO0 457 127 + #define HCLK_SDIO1 458 128 + #define HCLK_EMMC 459 129 + #define HCLK_HSADC 460 130 + #define HCLK_CRYPTO 461 131 + #define HCLK_I2S0 462 132 + #define HCLK_SPDIF 463 133 + #define HCLK_SPDIF8CH 464 134 + #define HCLK_VOP0 465 135 + #define HCLK_VOP1 466 136 + #define HCLK_ROM 467 137 + #define HCLK_IEP 468 138 + #define HCLK_ISP 469 139 + #define HCLK_RGA 470 140 + 141 + #define CLK_NR_CLKS (HCLK_RGA + 1) 142 + 143 + /* soft-reset indices */ 144 + #define SRST_CORE0 0 145 + #define SRST_CORE1 1 146 + #define SRST_CORE2 2 147 + #define SRST_CORE3 3 148 + #define SRST_CORE0_PO 4 149 + #define SRST_CORE1_PO 5 150 + #define SRST_CORE2_PO 6 151 + #define SRST_CORE3_PO 7 152 + #define SRST_PDCORE_STRSYS 8 153 + #define SRST_PDBUS_STRSYS 9 154 + #define SRST_L2C 10 155 + #define SRST_TOPDBG 11 156 + #define SRST_CORE0_DBG 12 157 + #define SRST_CORE1_DBG 13 158 + #define SRST_CORE2_DBG 14 159 + #define SRST_CORE3_DBG 15 160 + 161 + #define SRST_PDBUG_AHB_ARBITOR 16 162 + #define SRST_EFUSE256 17 163 + #define SRST_DMAC1 18 164 + #define SRST_INTMEM 19 165 + #define SRST_ROM 20 166 + #define SRST_SPDIF8CH 21 167 + #define SRST_TIMER 22 168 + #define SRST_I2S0 23 169 + #define SRST_SPDIF 24 170 + #define SRST_TIMER0 25 171 + #define SRST_TIMER1 26 172 + #define SRST_TIMER2 27 173 + #define SRST_TIMER3 28 174 + #define SRST_TIMER4 29 175 + #define SRST_TIMER5 30 176 + #define SRST_EFUSE 31 177 + 178 + #define SRST_GPIO0 32 179 + #define SRST_GPIO1 33 180 + #define SRST_GPIO2 34 181 + #define SRST_GPIO3 35 182 + #define SRST_GPIO4 36 183 + #define SRST_GPIO5 37 184 + #define SRST_GPIO6 38 185 + #define SRST_GPIO7 39 186 + #define SRST_GPIO8 40 187 + #define SRST_I2C0 42 188 + #define SRST_I2C1 43 189 + #define SRST_I2C2 44 190 + #define SRST_I2C3 45 191 + #define SRST_I2C4 46 192 + #define SRST_I2C5 47 193 + 194 + #define SRST_DWPWM 48 195 + #define SRST_MMC_PERI 49 196 + #define SRST_PERIPH_MMU 50 197 + #define SRST_DAP 51 198 + #define SRST_DAP_SYS 52 199 + #define SRST_TPIU 53 200 + #define SRST_PMU_APB 54 201 + #define SRST_GRF 55 202 + #define SRST_PMU 56 203 + #define SRST_PERIPH_AXI 57 204 + #define SRST_PERIPH_AHB 58 205 + #define SRST_PERIPH_APB 59 206 + #define SRST_PERIPH_NIU 60 207 + #define SRST_PDPERI_AHB_ARBI 61 208 + #define SRST_EMEM 62 209 + #define SRST_USB_PERI 63 210 + 211 + #define SRST_DMAC2 64 212 + #define SRST_MAC 66 213 + #define SRST_GPS 67 214 + #define SRST_RKPWM 69 215 + #define SRST_CCP 71 216 + #define SRST_USBHOST0 72 217 + #define SRST_HSIC 73 218 + #define SRST_HSIC_AUX 74 219 + #define SRST_HSIC_PHY 75 220 + #define SRST_HSADC 76 221 + #define SRST_NANDC0 77 222 + #define SRST_NANDC1 78 223 + 224 + #define SRST_TZPC 80 225 + #define SRST_SPI0 83 226 + #define SRST_SPI1 84 227 + #define SRST_SPI2 85 228 + #define SRST_SARADC 87 229 + #define SRST_PDALIVE_NIU 88 230 + #define SRST_PDPMU_INTMEM 89 231 + #define SRST_PDPMU_NIU 90 232 + #define SRST_SGRF 91 233 + 234 + #define SRST_VIO_ARBI 96 235 + #define SRST_RGA_NIU 97 236 + #define SRST_VIO0_NIU_AXI 98 237 + #define SRST_VIO_NIU_AHB 99 238 + #define SRST_LCDC0_AXI 100 239 + #define SRST_LCDC0_AHB 101 240 + #define SRST_LCDC0_DCLK 102 241 + #define SRST_VIO1_NIU_AXI 103 242 + #define SRST_VIP 104 243 + #define SRST_RGA_CORE 105 244 + #define SRST_IEP_AXI 106 245 + #define SRST_IEP_AHB 107 246 + #define SRST_RGA_AXI 108 247 + #define SRST_RGA_AHB 109 248 + #define SRST_ISP 110 249 + #define SRST_EDP 111 250 + 251 + #define SRST_VCODEC_AXI 112 252 + #define SRST_VCODEC_AHB 113 253 + #define SRST_VIO_H2P 114 254 + #define SRST_MIPIDSI0 115 255 + #define SRST_MIPIDSI1 116 256 + #define SRST_MIPICSI 117 257 + #define SRST_LVDS_PHY 118 258 + #define SRST_LVDS_CON 119 259 + #define SRST_GPU 120 260 + #define SRST_HDMI 121 261 + #define SRST_CORE_PVTM 124 262 + #define SRST_GPU_PVTM 125 263 + 264 + #define SRST_MMC0 128 265 + #define SRST_SDIO0 129 266 + #define SRST_SDIO1 130 267 + #define SRST_EMMC 131 268 + #define SRST_USBOTG_AHB 132 269 + #define SRST_USBOTG_PHY 133 270 + #define SRST_USBOTG_CON 134 271 + #define SRST_USBHOST0_AHB 135 272 + #define SRST_USBHOST0_PHY 136 273 + #define SRST_USBHOST0_CON 137 274 + #define SRST_USBHOST1_AHB 138 275 + #define SRST_USBHOST1_PHY 139 276 + #define SRST_USBHOST1_CON 140 277 + #define SRST_USB_ADP 141 278 + #define SRST_ACC_EFUSE 142