aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-07-28 08:02:13 -0400
committerArnd Bergmann <arnd@arndb.de>2014-07-28 08:15:25 -0400
commit3fdef7e3bc6da0519eb1d76fa528ca088e12530e (patch)
tree01c26f9b119f85d5986e55ca2d847b0e5c63c9f2
parent55be3cf836ff295efe8968710654a31e18b88a28 (diff)
parent1fe69496cf463b654d2d6e1a9a10fb8d99f10831 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt61
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt61
-rw-r--r--Documentation/devicetree/bindings/clock/rockchip.txt3
-rw-r--r--arch/arm/mach-rockchip/Kconfig1
-rw-r--r--drivers/clk/clk-composite.c79
-rw-r--r--drivers/clk/rockchip/Makefile6
-rw-r--r--drivers/clk/rockchip/clk-pll.c431
-rw-r--r--drivers/clk/rockchip/clk-rk3188.c672
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c717
-rw-r--r--drivers/clk/rockchip/clk.c244
-rw-r--r--drivers/clk/rockchip/clk.h347
-rw-r--r--drivers/clk/rockchip/softrst.c118
-rw-r--r--include/dt-bindings/clock/rk3066a-cru.h35
-rw-r--r--include/dt-bindings/clock/rk3188-cru-common.h249
-rw-r--r--include/dt-bindings/clock/rk3188-cru.h51
-rw-r--r--include/dt-bindings/clock/rk3288-cru.h278
16 files changed, 3338 insertions, 15 deletions
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt
new file mode 100644
index 000000000000..0c2bf5eba43e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3188-cru.txt
@@ -0,0 +1,61 @@
1* Rockchip RK3188/RK3066 Clock and Reset Unit
2
3The RK3188/RK3066 clock controller generates and supplies clock to various
4controllers within the SoC and also implements a reset controller for SoC
5peripherals.
6
7Required 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
16Optional 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
21Each clock is assigned an identifier and client nodes can use this identifier
22to specify the clock which they consume. All available clocks are defined as
23preprocessor macros in the dt-bindings/clock/rk3188-cru.h and
24dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources.
25Similar macros exist for the reset sources in these files.
26
27External clocks:
28
29There are several clocks that are generated outside the SoC. It is expected
30that they are defined using standard clock bindings with following
31clock-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
40Example: 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
51Example: 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 };
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
new file mode 100644
index 000000000000..c9fbb76573e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3288-cru.txt
@@ -0,0 +1,61 @@
1* Rockchip RK3288 Clock and Reset Unit
2
3The RK3288 clock controller generates and supplies clock to various
4controllers within the SoC and also implements a reset controller for SoC
5peripherals.
6
7Required 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
15Optional 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
20Each clock is assigned an identifier and client nodes can use this identifier
21to specify the clock which they consume. All available clocks are defined as
22preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be
23used in device tree sources. Similar macros exist for the reset sources in
24these files.
25
26External clocks:
27
28There are several clocks that are generated outside the SoC. It is expected
29that they are defined using standard clock bindings with following
30clock-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
40Example: 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
51Example: 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 };
diff --git a/Documentation/devicetree/bindings/clock/rockchip.txt b/Documentation/devicetree/bindings/clock/rockchip.txt
index a891c823ed44..22f6769e5d4a 100644
--- a/Documentation/devicetree/bindings/clock/rockchip.txt
+++ b/Documentation/devicetree/bindings/clock/rockchip.txt
@@ -6,6 +6,9 @@ This binding uses the common clock binding[1].
6 6
7== Gate clocks == 7== Gate clocks ==
8 8
9These bindings are deprecated!
10Please use the soc specific CRU bindings instead.
11
9The gate registers form a continuos block which makes the dt node 12The gate registers form a continuos block which makes the dt node
10structure a matter of taste, as either all gates can be put into 13structure a matter of taste, as either all gates can be put into
11one gate clock spanning all registers or they can be divided into 14one gate clock spanning all registers or they can be divided into
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 1caee6d548b8..e4564c259ed1 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -2,6 +2,7 @@ config ARCH_ROCKCHIP
2 bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7 2 bool "Rockchip RK2928 and RK3xxx SOCs" if ARCH_MULTI_V7
3 select PINCTRL 3 select PINCTRL
4 select PINCTRL_ROCKCHIP 4 select PINCTRL_ROCKCHIP
5 select ARCH_HAS_RESET_CONTROLLER
5 select ARCH_REQUIRE_GPIOLIB 6 select ARCH_REQUIRE_GPIOLIB
6 select ARM_GIC 7 select ARM_GIC
7 select CACHE_L2X0 8 select CACHE_L2X0
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 57a078e06efe..b9355daf8065 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -64,11 +64,56 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
64 const struct clk_ops *mux_ops = composite->mux_ops; 64 const struct clk_ops *mux_ops = composite->mux_ops;
65 struct clk_hw *rate_hw = composite->rate_hw; 65 struct clk_hw *rate_hw = composite->rate_hw;
66 struct clk_hw *mux_hw = composite->mux_hw; 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 if (rate_hw && rate_ops && rate_ops->determine_rate) { 74 if (rate_hw && rate_ops && rate_ops->determine_rate) {
69 rate_hw->clk = hw->clk; 75 rate_hw->clk = hw->clk;
70 return rate_ops->determine_rate(rate_hw, rate, best_parent_rate, 76 return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
71 best_parent_p); 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 } else if (mux_hw && mux_ops && mux_ops->determine_rate) { 117 } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
73 mux_hw->clk = hw->clk; 118 mux_hw->clk = hw->clk;
74 return mux_ops->determine_rate(mux_hw, rate, best_parent_rate, 119 return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
@@ -162,7 +207,7 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
162 clk_composite_ops = &composite->ops; 207 clk_composite_ops = &composite->ops;
163 208
164 if (mux_hw && mux_ops) { 209 if (mux_hw && mux_ops) {
165 if (!mux_ops->get_parent || !mux_ops->set_parent) { 210 if (!mux_ops->get_parent) {
166 clk = ERR_PTR(-EINVAL); 211 clk = ERR_PTR(-EINVAL);
167 goto err; 212 goto err;
168 } 213 }
@@ -170,7 +215,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
170 composite->mux_hw = mux_hw; 215 composite->mux_hw = mux_hw;
171 composite->mux_ops = mux_ops; 216 composite->mux_ops = mux_ops;
172 clk_composite_ops->get_parent = clk_composite_get_parent; 217 clk_composite_ops->get_parent = clk_composite_get_parent;
173 clk_composite_ops->set_parent = clk_composite_set_parent; 218 if (mux_ops->set_parent)
219 clk_composite_ops->set_parent = clk_composite_set_parent;
174 if (mux_ops->determine_rate) 220 if (mux_ops->determine_rate)
175 clk_composite_ops->determine_rate = clk_composite_determine_rate; 221 clk_composite_ops->determine_rate = clk_composite_determine_rate;
176 } 222 }
@@ -180,24 +226,27 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
180 clk = ERR_PTR(-EINVAL); 226 clk = ERR_PTR(-EINVAL);
181 goto err; 227 goto err;
182 } 228 }
229 clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
183 230
184 /* .round_rate is a prerequisite for .set_rate */ 231 if (rate_ops->determine_rate)
185 if (rate_ops->round_rate) { 232 clk_composite_ops->determine_rate =
186 clk_composite_ops->round_rate = clk_composite_round_rate; 233 clk_composite_determine_rate;
187 if (rate_ops->set_rate) { 234 else if (rate_ops->round_rate)
188 clk_composite_ops->set_rate = clk_composite_set_rate; 235 clk_composite_ops->round_rate =
189 } 236 clk_composite_round_rate;
190 } else { 237
191 WARN(rate_ops->set_rate, 238 /* .set_rate requires either .round_rate or .determine_rate */
192 "%s: missing round_rate op is required\n", 239 if (rate_ops->set_rate) {
193 __func__); 240 if (rate_ops->determine_rate || rate_ops->round_rate)
241 clk_composite_ops->set_rate =
242 clk_composite_set_rate;
243 else
244 WARN(1, "%s: missing round_rate op is required\n",
245 __func__);
194 } 246 }
195 247
196 composite->rate_hw = rate_hw; 248 composite->rate_hw = rate_hw;
197 composite->rate_ops = rate_ops; 249 composite->rate_ops = rate_ops;
198 clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
199 if (rate_ops->determine_rate)
200 clk_composite_ops->determine_rate = clk_composite_determine_rate;
201 } 250 }
202 251
203 if (gate_hw && gate_ops) { 252 if (gate_hw && gate_ops) {
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 8d3aefad2e73..ee6b077381e1 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -3,3 +3,9 @@
3# 3#
4 4
5obj-y += clk-rockchip.o 5obj-y += clk-rockchip.o
6obj-y += clk.o
7obj-y += clk-pll.o
8obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
9
10obj-y += clk-rk3188.o
11obj-y += clk-rk3288.o
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
new file mode 100644
index 000000000000..f2a1c7abf4d9
--- /dev/null
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -0,0 +1,431 @@
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
30struct 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
52static 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
66static 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 */
88static 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 */
116static 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
162static 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
190static 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
253static 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
263static 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
272static 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
280static 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
287static 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
300struct 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
419err_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 }
426err_pll_notifier:
427 clk_unregister(pll_clk);
428err_pll:
429 kfree(pll);
430 return mux_clk;
431}
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
new file mode 100644
index 000000000000..a83a6d8d0fb6
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -0,0 +1,672 @@
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
24enum rk3188_plls {
25 apll, cpll, dpll, gpll,
26};
27
28struct 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
103PNAME(mux_pll_p) = { "xin24m", "xin32k" };
104PNAME(mux_armclk_p) = { "apll", "gpll_armclk" };
105PNAME(mux_ddrphy_p) = { "dpll", "gpll_ddr" };
106PNAME(mux_pll_src_gpll_cpll_p) = { "gpll", "cpll" };
107PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
108PNAME(mux_aclk_cpu_p) = { "apll", "gpll" };
109PNAME(mux_sclk_cif0_p) = { "cif0_pre", "xin24m" };
110PNAME(mux_sclk_i2s0_p) = { "i2s0_pre", "i2s0_frac", "xin12m" };
111PNAME(mux_sclk_spdif_p) = { "spdif_src", "spdif_frac", "xin12m" };
112PNAME(mux_sclk_uart0_p) = { "uart0_pre", "uart0_frac", "xin24m" };
113PNAME(mux_sclk_uart1_p) = { "uart1_pre", "uart1_frac", "xin24m" };
114PNAME(mux_sclk_uart2_p) = { "uart2_pre", "uart2_frac", "xin24m" };
115PNAME(mux_sclk_uart3_p) = { "uart3_pre", "uart3_frac", "xin24m" };
116PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" };
117PNAME(mux_mac_p) = { "gpll", "dpll" };
118PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" };
119
120static 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) */
136static 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
144static 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
399PNAME(mux_rk3066_lcdc0_p) = { "dclk_lcdc0_src", "xin27m" };
400PNAME(mux_rk3066_lcdc1_p) = { "dclk_lcdc1_src", "xin27m" };
401PNAME(mux_sclk_cif1_p) = { "cif1_pre", "xin24m" };
402PNAME(mux_sclk_i2s1_p) = { "i2s1_pre", "i2s1_frac", "xin12m" };
403PNAME(mux_sclk_i2s2_p) = { "i2s2_pre", "i2s2_frac", "xin12m" };
404
405static 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
414static 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
514static 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
523PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1",
524 "gpll", "cpll" };
525
526static 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
602static 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
636static 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}
642CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
643
644static 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}
650CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
651
652static 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}
672CLK_OF_DECLARE(rk3188_cru, "rockchip,rk3188-cru", rk3188_clk_init);
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
new file mode 100644
index 000000000000..0d8c6c59a75e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -0,0 +1,717 @@
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
25enum rk3288_plls {
26 apll, dpll, cpll, gpll, npll,
27};
28
29struct 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
104PNAME(mux_pll_p) = { "xin24m", "xin32k" };
105PNAME(mux_armclk_p) = { "apll_core", "gpll_core" };
106PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" };
107PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
108
109PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" };
110PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" };
111PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" };
112PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" };
113
114PNAME(mux_mmc_src_p) = { "cpll", "gpll", "xin24m", "xin24m" };
115PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
116PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
117PNAME(mux_spdif_p) = { "spdif_pre", "spdif_frac", "xin12m" };
118PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" };
119PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" };
120PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
121PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
122PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
123PNAME(mux_uart3_p) = { "uart3_src", "uart3_frac", "xin24m" };
124PNAME(mux_uart4_p) = { "uart4_src", "uart4_frac", "xin24m" };
125PNAME(mux_cif_out_p) = { "cif_src", "xin24m" };
126PNAME(mux_macref_p) = { "mac_src", "ext_gmac" };
127PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" };
128PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" };
129PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" };
130
131PNAME(mux_usbphy480m_p) = { "sclk_otgphy0", "sclk_otgphy1",
132 "sclk_otgphy2" };
133PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" };
134PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" };
135
136static 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
149static 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
160static 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
683static 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}
717CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
new file mode 100644
index 000000000000..278cf9dd1e23
--- /dev/null
+++ b/drivers/clk/rockchip/clk.c
@@ -0,0 +1,244 @@
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 */
40struct 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
106static DEFINE_SPINLOCK(clk_lock);
107static struct clk **clk_table;
108static void __iomem *reg_base;
109static struct clk_onecell_data clk_data;
110static struct device_node *cru_node;
111static struct regmap *grf;
112
113void __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
129struct 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
136void rockchip_clk_add_lookup(struct clk *clk, unsigned int id)
137{
138 if (clk_table && id)
139 clk_table[id] = clk;
140}
141
142void __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
164void __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}
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
new file mode 100644
index 000000000000..887cbdeca2aa
--- /dev/null
+++ b/drivers/clk/rockchip/clk.h
@@ -0,0 +1,347 @@
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
52enum 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
65struct 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 */
86struct 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
116struct 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
125enum rockchip_clk_branch_type {
126 branch_composite,
127 branch_mux,
128 branch_divider,
129 branch_fraction_divider,
130 branch_gate,
131};
132
133struct 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
324void rockchip_clk_init(struct device_node *np, void __iomem *base,
325 unsigned long nr_clks);
326struct regmap *rockchip_clk_get_grf(void);
327void rockchip_clk_add_lookup(struct clk *clk, unsigned int id);
328void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list,
329 unsigned int nr_clk);
330void 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
336void rockchip_register_softrst(struct device_node *np,
337 unsigned int num_regs,
338 void __iomem *base, u8 flags);
339#else
340static 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
diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c
new file mode 100644
index 000000000000..552f7bb15bc5
--- /dev/null
+++ b/drivers/clk/rockchip/softrst.c
@@ -0,0 +1,118 @@
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
22struct 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
31static 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
58static 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
84static struct reset_control_ops rockchip_softrst_ops = {
85 .assert = rockchip_softrst_assert,
86 .deassert = rockchip_softrst_deassert,
87};
88
89void __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};
diff --git a/include/dt-bindings/clock/rk3066a-cru.h b/include/dt-bindings/clock/rk3066a-cru.h
new file mode 100644
index 000000000000..bc1ed1dbd855
--- /dev/null
+++ b/include/dt-bindings/clock/rk3066a-cru.h
@@ -0,0 +1,35 @@
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
diff --git a/include/dt-bindings/clock/rk3188-cru-common.h b/include/dt-bindings/clock/rk3188-cru-common.h
new file mode 100644
index 000000000000..750ee60e75fb
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru-common.h
@@ -0,0 +1,249 @@
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
diff --git a/include/dt-bindings/clock/rk3188-cru.h b/include/dt-bindings/clock/rk3188-cru.h
new file mode 100644
index 000000000000..9fac8edd3f9d
--- /dev/null
+++ b/include/dt-bindings/clock/rk3188-cru.h
@@ -0,0 +1,51 @@
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
diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h
new file mode 100644
index 000000000000..ebcb460ea4ad
--- /dev/null
+++ b/include/dt-bindings/clock/rk3288-cru.h
@@ -0,0 +1,278 @@
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