aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJun Nie <jun.nie@linaro.org>2015-06-03 23:21:01 -0400
committerKevin Hilman <khilman@linaro.org>2015-06-11 19:18:08 -0400
commit5a46580812266c85a2cd0ee530e4039ea5f76a19 (patch)
tree3e130c8954a644ebea33234c8de10294fe114b80
parentf3519dc6f090eb2315af58ab46857f0c6f45bae4 (diff)
clk: zx: add clock support to zx296702
It adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed. Signed-off-by: Jun Nie <jun.nie@linaro.org> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Kevin Hilman <khilman@linaro.org>
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/zte/Makefile2
-rw-r--r--drivers/clk/zte/clk-pll.c172
-rw-r--r--drivers/clk/zte/clk-zx296702.c657
-rw-r--r--drivers/clk/zte/clk.h32
5 files changed, 864 insertions, 0 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 3d00c25382c5..f4c68beafe0a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -72,4 +72,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
72obj-$(CONFIG_ARCH_U8500) += ux500/ 72obj-$(CONFIG_ARCH_U8500) += ux500/
73obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 73obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
74obj-$(CONFIG_X86) += x86/ 74obj-$(CONFIG_X86) += x86/
75obj-$(CONFIG_ARCH_ZX) += zte/
75obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 76obj-$(CONFIG_ARCH_ZYNQ) += zynq/
diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile
new file mode 100644
index 000000000000..95b707c18108
--- /dev/null
+++ b/drivers/clk/zte/Makefile
@@ -0,0 +1,2 @@
1obj-y := clk-pll.o
2obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o
diff --git a/drivers/clk/zte/clk-pll.c b/drivers/clk/zte/clk-pll.c
new file mode 100644
index 000000000000..c3b221ae6cd7
--- /dev/null
+++ b/drivers/clk/zte/clk-pll.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright 2014 Linaro Ltd.
3 * Copyright (C) 2014 ZTE Corporation.
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 version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/iopoll.h>
14#include <linux/slab.h>
15#include <linux/spinlock.h>
16
17#include "clk.h"
18
19#define to_clk_zx_pll(_hw) container_of(_hw, struct clk_zx_pll, hw)
20
21#define CFG0_CFG1_OFFSET 4
22#define LOCK_FLAG BIT(30)
23#define POWER_DOWN BIT(31)
24
25static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate)
26{
27 const struct zx_pll_config *config = zx_pll->lookup_table;
28 int i;
29
30 for (i = 0; i < zx_pll->count; i++) {
31 if (config[i].rate > rate)
32 return i > 0 ? i - 1 : 0;
33
34 if (config[i].rate == rate)
35 return i;
36 }
37
38 return i - 1;
39}
40
41static int hw_to_idx(struct clk_zx_pll *zx_pll)
42{
43 const struct zx_pll_config *config = zx_pll->lookup_table;
44 u32 hw_cfg0, hw_cfg1;
45 int i;
46
47 hw_cfg0 = readl_relaxed(zx_pll->reg_base);
48 hw_cfg1 = readl_relaxed(zx_pll->reg_base + CFG0_CFG1_OFFSET);
49
50 /* For matching the value in lookup table */
51 hw_cfg0 &= ~LOCK_FLAG;
52 hw_cfg0 |= POWER_DOWN;
53
54 for (i = 0; i < zx_pll->count; i++) {
55 if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1)
56 return i;
57 }
58
59 return -EINVAL;
60}
61
62static unsigned long zx_pll_recalc_rate(struct clk_hw *hw,
63 unsigned long parent_rate)
64{
65 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
66 int idx;
67
68 idx = hw_to_idx(zx_pll);
69 if (unlikely(idx == -EINVAL))
70 return 0;
71
72 return zx_pll->lookup_table[idx].rate;
73}
74
75static long zx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
76 unsigned long *prate)
77{
78 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
79 int idx;
80
81 idx = rate_to_idx(zx_pll, rate);
82
83 return zx_pll->lookup_table[idx].rate;
84}
85
86static int zx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
87 unsigned long parent_rate)
88{
89 /* Assume current cpu is not running on current PLL */
90 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
91 const struct zx_pll_config *config;
92 int idx;
93
94 idx = rate_to_idx(zx_pll, rate);
95 config = &zx_pll->lookup_table[idx];
96
97 writel_relaxed(config->cfg0, zx_pll->reg_base);
98 writel_relaxed(config->cfg1, zx_pll->reg_base + CFG0_CFG1_OFFSET);
99
100 return 0;
101}
102
103static int zx_pll_enable(struct clk_hw *hw)
104{
105 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
106 u32 reg;
107
108 reg = readl_relaxed(zx_pll->reg_base);
109 writel_relaxed(reg & ~POWER_DOWN, zx_pll->reg_base);
110
111 return readl_relaxed_poll_timeout(zx_pll->reg_base, reg,
112 reg & LOCK_FLAG, 0, 100);
113}
114
115static void zx_pll_disable(struct clk_hw *hw)
116{
117 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
118 u32 reg;
119
120 reg = readl_relaxed(zx_pll->reg_base);
121 writel_relaxed(reg | POWER_DOWN, zx_pll->reg_base);
122}
123
124static int zx_pll_is_enabled(struct clk_hw *hw)
125{
126 struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw);
127 u32 reg;
128
129 reg = readl_relaxed(zx_pll->reg_base);
130
131 return !(reg & POWER_DOWN);
132}
133
134static const struct clk_ops zx_pll_ops = {
135 .recalc_rate = zx_pll_recalc_rate,
136 .round_rate = zx_pll_round_rate,
137 .set_rate = zx_pll_set_rate,
138 .enable = zx_pll_enable,
139 .disable = zx_pll_disable,
140 .is_enabled = zx_pll_is_enabled,
141};
142
143struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
144 unsigned long flags, void __iomem *reg_base,
145 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock)
146{
147 struct clk_zx_pll *zx_pll;
148 struct clk *clk;
149 struct clk_init_data init;
150
151 zx_pll = kzalloc(sizeof(*zx_pll), GFP_KERNEL);
152 if (!zx_pll)
153 return ERR_PTR(-ENOMEM);
154
155 init.name = name;
156 init.ops = &zx_pll_ops;
157 init.flags = flags;
158 init.parent_names = parent_name ? &parent_name : NULL;
159 init.num_parents = parent_name ? 1 : 0;
160
161 zx_pll->reg_base = reg_base;
162 zx_pll->lookup_table = lookup_table;
163 zx_pll->count = count;
164 zx_pll->lock = lock;
165 zx_pll->hw.init = &init;
166
167 clk = clk_register(NULL, &zx_pll->hw);
168 if (IS_ERR(clk))
169 kfree(zx_pll);
170
171 return clk;
172}
diff --git a/drivers/clk/zte/clk-zx296702.c b/drivers/clk/zte/clk-zx296702.c
new file mode 100644
index 000000000000..929d033594af
--- /dev/null
+++ b/drivers/clk/zte/clk-zx296702.c
@@ -0,0 +1,657 @@
1/*
2 * Copyright 2014 Linaro Ltd.
3 * Copyright (C) 2014 ZTE Corporation.
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 version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/of_address.h>
12#include <dt-bindings/clock/zx296702-clock.h>
13#include "clk.h"
14
15static DEFINE_SPINLOCK(reg_lock);
16
17static void __iomem *topcrm_base;
18static void __iomem *lsp0crpm_base;
19static void __iomem *lsp1crpm_base;
20
21static struct clk *topclk[ZX296702_TOPCLK_END];
22static struct clk *lsp0clk[ZX296702_LSP0CLK_END];
23static struct clk *lsp1clk[ZX296702_LSP1CLK_END];
24
25static struct clk_onecell_data topclk_data;
26static struct clk_onecell_data lsp0clk_data;
27static struct clk_onecell_data lsp1clk_data;
28
29#define CLK_MUX (topcrm_base + 0x04)
30#define CLK_DIV (topcrm_base + 0x08)
31#define CLK_EN0 (topcrm_base + 0x0c)
32#define CLK_EN1 (topcrm_base + 0x10)
33#define VOU_LOCAL_CLKEN (topcrm_base + 0x68)
34#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70)
35#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74)
36#define CLK_MUX1 (topcrm_base + 0x8c)
37
38#define CLK_SDMMC1 (lsp0crpm_base + 0x0c)
39
40#define CLK_UART0 (lsp1crpm_base + 0x20)
41#define CLK_UART1 (lsp1crpm_base + 0x24)
42#define CLK_SDMMC0 (lsp1crpm_base + 0x2c)
43
44static const struct zx_pll_config pll_a9_config[] = {
45 { .rate = 700000000, .cfg0 = 0x800405d1, .cfg1 = 0x04555555 },
46 { .rate = 800000000, .cfg0 = 0x80040691, .cfg1 = 0x04aaaaaa },
47 { .rate = 900000000, .cfg0 = 0x80040791, .cfg1 = 0x04000000 },
48 { .rate = 1000000000, .cfg0 = 0x80040851, .cfg1 = 0x04555555 },
49 { .rate = 1100000000, .cfg0 = 0x80040911, .cfg1 = 0x04aaaaaa },
50 { .rate = 1200000000, .cfg0 = 0x80040a11, .cfg1 = 0x04000000 },
51};
52
53static const struct clk_div_table main_hlk_div[] = {
54 { .val = 1, .div = 2, },
55 { .val = 3, .div = 4, },
56 { /* sentinel */ }
57};
58
59static const struct clk_div_table a9_as1_aclk_divider[] = {
60 { .val = 0, .div = 1, },
61 { .val = 1, .div = 2, },
62 { .val = 3, .div = 4, },
63 { /* sentinel */ }
64};
65
66static const struct clk_div_table sec_wclk_divider[] = {
67 { .val = 0, .div = 1, },
68 { .val = 1, .div = 2, },
69 { .val = 3, .div = 4, },
70 { .val = 5, .div = 6, },
71 { .val = 7, .div = 8, },
72 { /* sentinel */ }
73};
74
75static const char * matrix_aclk_sel[] = {
76 "pll_mm0_198M",
77 "osc",
78 "clk_148M5",
79 "pll_lsp_104M",
80};
81
82static const char * a9_wclk_sel[] = {
83 "pll_a9",
84 "osc",
85 "clk_500",
86 "clk_250",
87};
88
89static const char * a9_as1_aclk_sel[] = {
90 "clk_250",
91 "osc",
92 "pll_mm0_396M",
93 "pll_mac_333M",
94};
95
96static const char * a9_trace_clkin_sel[] = {
97 "clk_74M25",
98 "pll_mm1_108M",
99 "clk_125",
100 "clk_148M5",
101};
102
103static const char * decppu_aclk_sel[] = {
104 "clk_250",
105 "pll_mm0_198M",
106 "pll_lsp_104M",
107 "pll_audio_294M912",
108};
109
110static const char * vou_main_wclk_sel[] = {
111 "clk_148M5",
112 "clk_74M25",
113 "clk_27",
114 "pll_mm1_54M",
115};
116
117static const char * vou_scaler_wclk_sel[] = {
118 "clk_250",
119 "pll_mac_333M",
120 "pll_audio_294M912",
121 "pll_mm0_198M",
122};
123
124static const char * r2d_wclk_sel[] = {
125 "pll_audio_294M912",
126 "pll_mac_333M",
127 "pll_a9_350M",
128 "pll_mm0_396M",
129};
130
131static const char * ddr_wclk_sel[] = {
132 "pll_mac_333M",
133 "pll_ddr_266M",
134 "pll_audio_294M912",
135 "pll_mm0_198M",
136};
137
138static const char * nand_wclk_sel[] = {
139 "pll_lsp_104M",
140 "osc",
141};
142
143static const char * lsp_26_wclk_sel[] = {
144 "pll_lsp_26M",
145 "osc",
146};
147
148static const char * vl0_sel[] = {
149 "vou_main_channel_div",
150 "vou_aux_channel_div",
151};
152
153static const char * hdmi_sel[] = {
154 "vou_main_channel_wclk",
155 "vou_aux_channel_wclk",
156};
157
158static const char * sdmmc0_wclk_sel[] = {
159 "lsp1_104M_wclk",
160 "lsp1_26M_wclk",
161};
162
163static const char * sdmmc1_wclk_sel[] = {
164 "lsp0_104M_wclk",
165 "lsp0_26M_wclk",
166};
167
168static const char * uart_wclk_sel[] = {
169 "lsp1_104M_wclk",
170 "lsp1_26M_wclk",
171};
172
173static inline struct clk *zx_divtbl(const char *name, const char *parent,
174 void __iomem *reg, u8 shift, u8 width,
175 const struct clk_div_table *table)
176{
177 return clk_register_divider_table(NULL, name, parent, 0, reg, shift,
178 width, 0, table, &reg_lock);
179}
180
181static inline struct clk *zx_div(const char *name, const char *parent,
182 void __iomem *reg, u8 shift, u8 width)
183{
184 return clk_register_divider(NULL, name, parent, 0,
185 reg, shift, width, 0, &reg_lock);
186}
187
188static inline struct clk *zx_mux(const char *name, const char **parents,
189 int num_parents, void __iomem *reg, u8 shift, u8 width)
190{
191 return clk_register_mux(NULL, name, parents, num_parents,
192 0, reg, shift, width, 0, &reg_lock);
193}
194
195static inline struct clk *zx_gate(const char *name, const char *parent,
196 void __iomem *reg, u8 shift)
197{
198 return clk_register_gate(NULL, name, parent, CLK_IGNORE_UNUSED,
199 reg, shift, 0, &reg_lock);
200}
201
202static void __init zx296702_top_clocks_init(struct device_node *np)
203{
204 struct clk **clk = topclk;
205 int i;
206
207 topcrm_base = of_iomap(np, 0);
208 WARN_ON(!topcrm_base);
209
210 clk[ZX296702_OSC] =
211 clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT,
212 30000000);
213 clk[ZX296702_PLL_A9] =
214 clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base
215 + 0x01c, pll_a9_config,
216 ARRAY_SIZE(pll_a9_config), &reg_lock);
217
218 /* TODO: pll_a9_350M look like changeble follow a9 pll */
219 clk[ZX296702_PLL_A9_350M] =
220 clk_register_fixed_rate(NULL, "pll_a9_350M", "osc", 0,
221 350000000);
222 clk[ZX296702_PLL_MAC_1000M] =
223 clk_register_fixed_rate(NULL, "pll_mac_1000M", "osc", 0,
224 1000000000);
225 clk[ZX296702_PLL_MAC_333M] =
226 clk_register_fixed_rate(NULL, "pll_mac_333M", "osc", 0,
227 333000000);
228 clk[ZX296702_PLL_MM0_1188M] =
229 clk_register_fixed_rate(NULL, "pll_mm0_1188M", "osc", 0,
230 1188000000);
231 clk[ZX296702_PLL_MM0_396M] =
232 clk_register_fixed_rate(NULL, "pll_mm0_396M", "osc", 0,
233 396000000);
234 clk[ZX296702_PLL_MM0_198M] =
235 clk_register_fixed_rate(NULL, "pll_mm0_198M", "osc", 0,
236 198000000);
237 clk[ZX296702_PLL_MM1_108M] =
238 clk_register_fixed_rate(NULL, "pll_mm1_108M", "osc", 0,
239 108000000);
240 clk[ZX296702_PLL_MM1_72M] =
241 clk_register_fixed_rate(NULL, "pll_mm1_72M", "osc", 0,
242 72000000);
243 clk[ZX296702_PLL_MM1_54M] =
244 clk_register_fixed_rate(NULL, "pll_mm1_54M", "osc", 0,
245 54000000);
246 clk[ZX296702_PLL_LSP_104M] =
247 clk_register_fixed_rate(NULL, "pll_lsp_104M", "osc", 0,
248 104000000);
249 clk[ZX296702_PLL_LSP_26M] =
250 clk_register_fixed_rate(NULL, "pll_lsp_26M", "osc", 0,
251 26000000);
252 clk[ZX296702_PLL_DDR_266M] =
253 clk_register_fixed_rate(NULL, "pll_ddr_266M", "osc", 0,
254 266000000);
255 clk[ZX296702_PLL_AUDIO_294M912] =
256 clk_register_fixed_rate(NULL, "pll_audio_294M912", "osc", 0,
257 294912000);
258
259 /* bus clock */
260 clk[ZX296702_MATRIX_ACLK] =
261 zx_mux("matrix_aclk", matrix_aclk_sel,
262 ARRAY_SIZE(matrix_aclk_sel), CLK_MUX, 2, 2);
263 clk[ZX296702_MAIN_HCLK] =
264 zx_divtbl("main_hclk", "matrix_aclk", CLK_DIV, 0, 2,
265 main_hlk_div);
266 clk[ZX296702_MAIN_PCLK] =
267 zx_divtbl("main_pclk", "matrix_aclk", CLK_DIV, 2, 2,
268 main_hlk_div);
269
270 /* cpu clock */
271 clk[ZX296702_CLK_500] =
272 clk_register_fixed_factor(NULL, "clk_500", "pll_mac_1000M", 0,
273 1, 2);
274 clk[ZX296702_CLK_250] =
275 clk_register_fixed_factor(NULL, "clk_250", "pll_mac_1000M", 0,
276 1, 4);
277 clk[ZX296702_CLK_125] =
278 clk_register_fixed_factor(NULL, "clk_125", "clk_250", 0, 1, 2);
279 clk[ZX296702_CLK_148M5] =
280 clk_register_fixed_factor(NULL, "clk_148M5", "pll_mm0_1188M", 0,
281 1, 8);
282 clk[ZX296702_CLK_74M25] =
283 clk_register_fixed_factor(NULL, "clk_74M25", "pll_mm0_1188M", 0,
284 1, 16);
285 clk[ZX296702_A9_WCLK] =
286 zx_mux("a9_wclk", a9_wclk_sel, ARRAY_SIZE(a9_wclk_sel), CLK_MUX,
287 0, 2);
288 clk[ZX296702_A9_AS1_ACLK_MUX] =
289 zx_mux("a9_as1_aclk_mux", a9_as1_aclk_sel,
290 ARRAY_SIZE(a9_as1_aclk_sel), CLK_MUX, 4, 2);
291 clk[ZX296702_A9_TRACE_CLKIN_MUX] =
292 zx_mux("a9_trace_clkin_mux", a9_trace_clkin_sel,
293 ARRAY_SIZE(a9_trace_clkin_sel), CLK_MUX1, 0, 2);
294 clk[ZX296702_A9_AS1_ACLK_DIV] =
295 zx_divtbl("a9_as1_aclk_div", "a9_as1_aclk_mux", CLK_DIV, 4, 2,
296 a9_as1_aclk_divider);
297
298 /* multi-media clock */
299 clk[ZX296702_CLK_2] =
300 clk_register_fixed_factor(NULL, "clk_2", "pll_mm1_72M", 0,
301 1, 36);
302 clk[ZX296702_CLK_27] =
303 clk_register_fixed_factor(NULL, "clk_27", "pll_mm1_54M", 0,
304 1, 2);
305 clk[ZX296702_DECPPU_ACLK_MUX] =
306 zx_mux("decppu_aclk_mux", decppu_aclk_sel,
307 ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 6, 2);
308 clk[ZX296702_PPU_ACLK_MUX] =
309 zx_mux("ppu_aclk_mux", decppu_aclk_sel,
310 ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 8, 2);
311 clk[ZX296702_MALI400_ACLK_MUX] =
312 zx_mux("mali400_aclk_mux", decppu_aclk_sel,
313 ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 12, 2);
314 clk[ZX296702_VOU_ACLK_MUX] =
315 zx_mux("vou_aclk_mux", decppu_aclk_sel,
316 ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 10, 2);
317 clk[ZX296702_VOU_MAIN_WCLK_MUX] =
318 zx_mux("vou_main_wclk_mux", vou_main_wclk_sel,
319 ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 14, 2);
320 clk[ZX296702_VOU_AUX_WCLK_MUX] =
321 zx_mux("vou_aux_wclk_mux", vou_main_wclk_sel,
322 ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 16, 2);
323 clk[ZX296702_VOU_SCALER_WCLK_MUX] =
324 zx_mux("vou_scaler_wclk_mux", vou_scaler_wclk_sel,
325 ARRAY_SIZE(vou_scaler_wclk_sel), CLK_MUX,
326 18, 2);
327 clk[ZX296702_R2D_ACLK_MUX] =
328 zx_mux("r2d_aclk_mux", decppu_aclk_sel,
329 ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 20, 2);
330 clk[ZX296702_R2D_WCLK_MUX] =
331 zx_mux("r2d_wclk_mux", r2d_wclk_sel,
332 ARRAY_SIZE(r2d_wclk_sel), CLK_MUX, 22, 2);
333
334 /* other clock */
335 clk[ZX296702_CLK_50] =
336 clk_register_fixed_factor(NULL, "clk_50", "pll_mac_1000M",
337 0, 1, 20);
338 clk[ZX296702_CLK_25] =
339 clk_register_fixed_factor(NULL, "clk_25", "pll_mac_1000M",
340 0, 1, 40);
341 clk[ZX296702_CLK_12] =
342 clk_register_fixed_factor(NULL, "clk_12", "pll_mm1_72M",
343 0, 1, 6);
344 clk[ZX296702_CLK_16M384] =
345 clk_register_fixed_factor(NULL, "clk_16M384",
346 "pll_audio_294M912", 0, 1, 18);
347 clk[ZX296702_CLK_32K768] =
348 clk_register_fixed_factor(NULL, "clk_32K768", "clk_16M384",
349 0, 1, 500);
350 clk[ZX296702_SEC_WCLK_DIV] =
351 zx_divtbl("sec_wclk_div", "pll_lsp_104M", CLK_DIV, 6, 3,
352 sec_wclk_divider);
353 clk[ZX296702_DDR_WCLK_MUX] =
354 zx_mux("ddr_wclk_mux", ddr_wclk_sel,
355 ARRAY_SIZE(ddr_wclk_sel), CLK_MUX, 24, 2);
356 clk[ZX296702_NAND_WCLK_MUX] =
357 zx_mux("nand_wclk_mux", nand_wclk_sel,
358 ARRAY_SIZE(nand_wclk_sel), CLK_MUX, 24, 2);
359 clk[ZX296702_LSP_26_WCLK_MUX] =
360 zx_mux("lsp_26_wclk_mux", lsp_26_wclk_sel,
361 ARRAY_SIZE(lsp_26_wclk_sel), CLK_MUX, 27, 1);
362
363 /* gates */
364 clk[ZX296702_A9_AS0_ACLK] =
365 zx_gate("a9_as0_aclk", "matrix_aclk", CLK_EN0, 0);
366 clk[ZX296702_A9_AS1_ACLK] =
367 zx_gate("a9_as1_aclk", "a9_as1_aclk_div", CLK_EN0, 1);
368 clk[ZX296702_A9_TRACE_CLKIN] =
369 zx_gate("a9_trace_clkin", "a9_trace_clkin_mux", CLK_EN0, 2);
370 clk[ZX296702_DECPPU_AXI_M_ACLK] =
371 zx_gate("decppu_axi_m_aclk", "decppu_aclk_mux", CLK_EN0, 3);
372 clk[ZX296702_DECPPU_AHB_S_HCLK] =
373 zx_gate("decppu_ahb_s_hclk", "main_hclk", CLK_EN0, 4);
374 clk[ZX296702_PPU_AXI_M_ACLK] =
375 zx_gate("ppu_axi_m_aclk", "ppu_aclk_mux", CLK_EN0, 5);
376 clk[ZX296702_PPU_AHB_S_HCLK] =
377 zx_gate("ppu_ahb_s_hclk", "main_hclk", CLK_EN0, 6);
378 clk[ZX296702_VOU_AXI_M_ACLK] =
379 zx_gate("vou_axi_m_aclk", "vou_aclk_mux", CLK_EN0, 7);
380 clk[ZX296702_VOU_APB_PCLK] =
381 zx_gate("vou_apb_pclk", "main_pclk", CLK_EN0, 8);
382 clk[ZX296702_VOU_MAIN_CHANNEL_WCLK] =
383 zx_gate("vou_main_channel_wclk", "vou_main_wclk_mux",
384 CLK_EN0, 9);
385 clk[ZX296702_VOU_AUX_CHANNEL_WCLK] =
386 zx_gate("vou_aux_channel_wclk", "vou_aux_wclk_mux",
387 CLK_EN0, 10);
388 clk[ZX296702_VOU_HDMI_OSCLK_CEC] =
389 zx_gate("vou_hdmi_osclk_cec", "clk_2", CLK_EN0, 11);
390 clk[ZX296702_VOU_SCALER_WCLK] =
391 zx_gate("vou_scaler_wclk", "vou_scaler_wclk_mux", CLK_EN0, 12);
392 clk[ZX296702_MALI400_AXI_M_ACLK] =
393 zx_gate("mali400_axi_m_aclk", "mali400_aclk_mux", CLK_EN0, 13);
394 clk[ZX296702_MALI400_APB_PCLK] =
395 zx_gate("mali400_apb_pclk", "main_pclk", CLK_EN0, 14);
396 clk[ZX296702_R2D_WCLK] =
397 zx_gate("r2d_wclk", "r2d_wclk_mux", CLK_EN0, 15);
398 clk[ZX296702_R2D_AXI_M_ACLK] =
399 zx_gate("r2d_axi_m_aclk", "r2d_aclk_mux", CLK_EN0, 16);
400 clk[ZX296702_R2D_AHB_HCLK] =
401 zx_gate("r2d_ahb_hclk", "main_hclk", CLK_EN0, 17);
402 clk[ZX296702_DDR3_AXI_S0_ACLK] =
403 zx_gate("ddr3_axi_s0_aclk", "matrix_aclk", CLK_EN0, 18);
404 clk[ZX296702_DDR3_APB_PCLK] =
405 zx_gate("ddr3_apb_pclk", "main_pclk", CLK_EN0, 19);
406 clk[ZX296702_DDR3_WCLK] =
407 zx_gate("ddr3_wclk", "ddr_wclk_mux", CLK_EN0, 20);
408 clk[ZX296702_USB20_0_AHB_HCLK] =
409 zx_gate("usb20_0_ahb_hclk", "main_hclk", CLK_EN0, 21);
410 clk[ZX296702_USB20_0_EXTREFCLK] =
411 zx_gate("usb20_0_extrefclk", "clk_12", CLK_EN0, 22);
412 clk[ZX296702_USB20_1_AHB_HCLK] =
413 zx_gate("usb20_1_ahb_hclk", "main_hclk", CLK_EN0, 23);
414 clk[ZX296702_USB20_1_EXTREFCLK] =
415 zx_gate("usb20_1_extrefclk", "clk_12", CLK_EN0, 24);
416 clk[ZX296702_USB20_2_AHB_HCLK] =
417 zx_gate("usb20_2_ahb_hclk", "main_hclk", CLK_EN0, 25);
418 clk[ZX296702_USB20_2_EXTREFCLK] =
419 zx_gate("usb20_2_extrefclk", "clk_12", CLK_EN0, 26);
420 clk[ZX296702_GMAC_AXI_M_ACLK] =
421 zx_gate("gmac_axi_m_aclk", "matrix_aclk", CLK_EN0, 27);
422 clk[ZX296702_GMAC_APB_PCLK] =
423 zx_gate("gmac_apb_pclk", "main_pclk", CLK_EN0, 28);
424 clk[ZX296702_GMAC_125_CLKIN] =
425 zx_gate("gmac_125_clkin", "clk_125", CLK_EN0, 29);
426 clk[ZX296702_GMAC_RMII_CLKIN] =
427 zx_gate("gmac_rmii_clkin", "clk_50", CLK_EN0, 30);
428 clk[ZX296702_GMAC_25M_CLK] =
429 zx_gate("gmac_25M_clk", "clk_25", CLK_EN0, 31);
430 clk[ZX296702_NANDFLASH_AHB_HCLK] =
431 zx_gate("nandflash_ahb_hclk", "main_hclk", CLK_EN1, 0);
432 clk[ZX296702_NANDFLASH_WCLK] =
433 zx_gate("nandflash_wclk", "nand_wclk_mux", CLK_EN1, 1);
434 clk[ZX296702_LSP0_APB_PCLK] =
435 zx_gate("lsp0_apb_pclk", "main_pclk", CLK_EN1, 2);
436 clk[ZX296702_LSP0_AHB_HCLK] =
437 zx_gate("lsp0_ahb_hclk", "main_hclk", CLK_EN1, 3);
438 clk[ZX296702_LSP0_26M_WCLK] =
439 zx_gate("lsp0_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 4);
440 clk[ZX296702_LSP0_104M_WCLK] =
441 zx_gate("lsp0_104M_wclk", "pll_lsp_104M", CLK_EN1, 5);
442 clk[ZX296702_LSP0_16M384_WCLK] =
443 zx_gate("lsp0_16M384_wclk", "clk_16M384", CLK_EN1, 6);
444 clk[ZX296702_LSP1_APB_PCLK] =
445 zx_gate("lsp1_apb_pclk", "main_pclk", CLK_EN1, 7);
446 /* FIXME: wclk enable bit is bit8. We hack it as reserved 31 for
447 * UART does not work after parent clk is disabled/enabled */
448 clk[ZX296702_LSP1_26M_WCLK] =
449 zx_gate("lsp1_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 31);
450 clk[ZX296702_LSP1_104M_WCLK] =
451 zx_gate("lsp1_104M_wclk", "pll_lsp_104M", CLK_EN1, 9);
452 clk[ZX296702_LSP1_32K_CLK] =
453 zx_gate("lsp1_32K_clk", "clk_32K768", CLK_EN1, 10);
454 clk[ZX296702_AON_HCLK] =
455 zx_gate("aon_hclk", "main_hclk", CLK_EN1, 11);
456 clk[ZX296702_SYS_CTRL_PCLK] =
457 zx_gate("sys_ctrl_pclk", "main_pclk", CLK_EN1, 12);
458 clk[ZX296702_DMA_PCLK] =
459 zx_gate("dma_pclk", "main_pclk", CLK_EN1, 13);
460 clk[ZX296702_DMA_ACLK] =
461 zx_gate("dma_aclk", "matrix_aclk", CLK_EN1, 14);
462 clk[ZX296702_SEC_HCLK] =
463 zx_gate("sec_hclk", "main_hclk", CLK_EN1, 15);
464 clk[ZX296702_AES_WCLK] =
465 zx_gate("aes_wclk", "sec_wclk_div", CLK_EN1, 16);
466 clk[ZX296702_DES_WCLK] =
467 zx_gate("des_wclk", "sec_wclk_div", CLK_EN1, 17);
468 clk[ZX296702_IRAM_ACLK] =
469 zx_gate("iram_aclk", "matrix_aclk", CLK_EN1, 18);
470 clk[ZX296702_IROM_ACLK] =
471 zx_gate("irom_aclk", "matrix_aclk", CLK_EN1, 19);
472 clk[ZX296702_BOOT_CTRL_HCLK] =
473 zx_gate("boot_ctrl_hclk", "main_hclk", CLK_EN1, 20);
474 clk[ZX296702_EFUSE_CLK_30] =
475 zx_gate("efuse_clk_30", "osc", CLK_EN1, 21);
476
477 /* TODO: add VOU Local clocks */
478 clk[ZX296702_VOU_MAIN_CHANNEL_DIV] =
479 zx_div("vou_main_channel_div", "vou_main_channel_wclk",
480 VOU_LOCAL_DIV2_SET, 1, 1);
481 clk[ZX296702_VOU_AUX_CHANNEL_DIV] =
482 zx_div("vou_aux_channel_div", "vou_aux_channel_wclk",
483 VOU_LOCAL_DIV2_SET, 0, 1);
484 clk[ZX296702_VOU_TV_ENC_HD_DIV] =
485 zx_div("vou_tv_enc_hd_div", "vou_tv_enc_hd_mux",
486 VOU_LOCAL_DIV2_SET, 3, 1);
487 clk[ZX296702_VOU_TV_ENC_SD_DIV] =
488 zx_div("vou_tv_enc_sd_div", "vou_tv_enc_sd_mux",
489 VOU_LOCAL_DIV2_SET, 2, 1);
490 clk[ZX296702_VL0_MUX] =
491 zx_mux("vl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
492 VOU_LOCAL_CLKSEL, 8, 1);
493 clk[ZX296702_VL1_MUX] =
494 zx_mux("vl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
495 VOU_LOCAL_CLKSEL, 9, 1);
496 clk[ZX296702_VL2_MUX] =
497 zx_mux("vl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
498 VOU_LOCAL_CLKSEL, 10, 1);
499 clk[ZX296702_GL0_MUX] =
500 zx_mux("gl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
501 VOU_LOCAL_CLKSEL, 5, 1);
502 clk[ZX296702_GL1_MUX] =
503 zx_mux("gl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
504 VOU_LOCAL_CLKSEL, 6, 1);
505 clk[ZX296702_GL2_MUX] =
506 zx_mux("gl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
507 VOU_LOCAL_CLKSEL, 7, 1);
508 clk[ZX296702_WB_MUX] =
509 zx_mux("wb_mux", vl0_sel, ARRAY_SIZE(vl0_sel),
510 VOU_LOCAL_CLKSEL, 11, 1);
511 clk[ZX296702_HDMI_MUX] =
512 zx_mux("hdmi_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
513 VOU_LOCAL_CLKSEL, 4, 1);
514 clk[ZX296702_VOU_TV_ENC_HD_MUX] =
515 zx_mux("vou_tv_enc_hd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
516 VOU_LOCAL_CLKSEL, 3, 1);
517 clk[ZX296702_VOU_TV_ENC_SD_MUX] =
518 zx_mux("vou_tv_enc_sd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel),
519 VOU_LOCAL_CLKSEL, 2, 1);
520 clk[ZX296702_VL0_CLK] =
521 zx_gate("vl0_clk", "vl0_mux", VOU_LOCAL_CLKEN, 8);
522 clk[ZX296702_VL1_CLK] =
523 zx_gate("vl1_clk", "vl1_mux", VOU_LOCAL_CLKEN, 9);
524 clk[ZX296702_VL2_CLK] =
525 zx_gate("vl2_clk", "vl2_mux", VOU_LOCAL_CLKEN, 10);
526 clk[ZX296702_GL0_CLK] =
527 zx_gate("gl0_clk", "gl0_mux", VOU_LOCAL_CLKEN, 5);
528 clk[ZX296702_GL1_CLK] =
529 zx_gate("gl1_clk", "gl1_mux", VOU_LOCAL_CLKEN, 6);
530 clk[ZX296702_GL2_CLK] =
531 zx_gate("gl2_clk", "gl2_mux", VOU_LOCAL_CLKEN, 7);
532 clk[ZX296702_WB_CLK] =
533 zx_gate("wb_clk", "wb_mux", VOU_LOCAL_CLKEN, 11);
534 clk[ZX296702_CL_CLK] =
535 zx_gate("cl_clk", "vou_main_channel_div", VOU_LOCAL_CLKEN, 12);
536 clk[ZX296702_MAIN_MIX_CLK] =
537 zx_gate("main_mix_clk", "vou_main_channel_div",
538 VOU_LOCAL_CLKEN, 4);
539 clk[ZX296702_AUX_MIX_CLK] =
540 zx_gate("aux_mix_clk", "vou_aux_channel_div",
541 VOU_LOCAL_CLKEN, 3);
542 clk[ZX296702_HDMI_CLK] =
543 zx_gate("hdmi_clk", "hdmi_mux", VOU_LOCAL_CLKEN, 2);
544 clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK] =
545 zx_gate("vou_tv_enc_hd_dac_clk", "vou_tv_enc_hd_div",
546 VOU_LOCAL_CLKEN, 1);
547 clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK] =
548 zx_gate("vou_tv_enc_sd_dac_clk", "vou_tv_enc_sd_div",
549 VOU_LOCAL_CLKEN, 0);
550
551 /* CA9 PERIPHCLK = a9_wclk / 2 */
552 clk[ZX296702_A9_PERIPHCLK] =
553 clk_register_fixed_factor(NULL, "a9_periphclk", "a9_wclk",
554 0, 1, 2);
555
556 for (i = 0; i < ARRAY_SIZE(topclk); i++) {
557 if (IS_ERR(clk[i])) {
558 pr_err("zx296702 clk %d: register failed with %ld\n",
559 i, PTR_ERR(clk[i]));
560 return;
561 }
562 }
563
564 topclk_data.clks = topclk;
565 topclk_data.clk_num = ARRAY_SIZE(topclk);
566 of_clk_add_provider(np, of_clk_src_onecell_get, &topclk_data);
567}
568CLK_OF_DECLARE(zx296702_top_clk, "zte,zx296702-topcrm-clk",
569 zx296702_top_clocks_init);
570
571static void __init zx296702_lsp0_clocks_init(struct device_node *np)
572{
573 struct clk **clk = lsp0clk;
574 int i;
575
576 lsp0crpm_base = of_iomap(np, 0);
577 WARN_ON(!lsp0crpm_base);
578
579 /* SDMMC1 */
580 clk[ZX296702_SDMMC1_WCLK_MUX] =
581 zx_mux("sdmmc1_wclk_mux", sdmmc1_wclk_sel,
582 ARRAY_SIZE(sdmmc1_wclk_sel), CLK_SDMMC1, 4, 1);
583 clk[ZX296702_SDMMC1_WCLK_DIV] =
584 zx_div("sdmmc1_wclk_div", "sdmmc1_wclk_mux", CLK_SDMMC1, 12, 4);
585 clk[ZX296702_SDMMC1_WCLK] =
586 zx_gate("sdmmc1_wclk", "sdmmc1_wclk_div", CLK_SDMMC1, 1);
587 clk[ZX296702_SDMMC1_PCLK] =
588 zx_gate("sdmmc1_pclk", "lsp1_apb_pclk", CLK_SDMMC1, 0);
589
590 for (i = 0; i < ARRAY_SIZE(lsp0clk); i++) {
591 if (IS_ERR(clk[i])) {
592 pr_err("zx296702 clk %d: register failed with %ld\n",
593 i, PTR_ERR(clk[i]));
594 return;
595 }
596 }
597
598 lsp0clk_data.clks = lsp0clk;
599 lsp0clk_data.clk_num = ARRAY_SIZE(lsp0clk);
600 of_clk_add_provider(np, of_clk_src_onecell_get, &lsp0clk_data);
601}
602CLK_OF_DECLARE(zx296702_lsp0_clk, "zte,zx296702-lsp0crpm-clk",
603 zx296702_lsp0_clocks_init);
604
605static void __init zx296702_lsp1_clocks_init(struct device_node *np)
606{
607 struct clk **clk = lsp1clk;
608 int i;
609
610 lsp1crpm_base = of_iomap(np, 0);
611 WARN_ON(!lsp1crpm_base);
612
613 /* UART0 */
614 clk[ZX296702_UART0_WCLK_MUX] =
615 zx_mux("uart0_wclk_mux", uart_wclk_sel,
616 ARRAY_SIZE(uart_wclk_sel), CLK_UART0, 4, 1);
617 /* FIXME: uart wclk enable bit is bit1 in. We hack it as reserved 31 for
618 * UART does not work after parent clk is disabled/enabled */
619 clk[ZX296702_UART0_WCLK] =
620 zx_gate("uart0_wclk", "uart0_wclk_mux", CLK_UART0, 31);
621 clk[ZX296702_UART0_PCLK] =
622 zx_gate("uart0_pclk", "lsp1_apb_pclk", CLK_UART0, 0);
623
624 /* UART1 */
625 clk[ZX296702_UART1_WCLK_MUX] =
626 zx_mux("uart1_wclk_mux", uart_wclk_sel,
627 ARRAY_SIZE(uart_wclk_sel), CLK_UART1, 4, 1);
628 clk[ZX296702_UART1_WCLK] =
629 zx_gate("uart1_wclk", "uart1_wclk_mux", CLK_UART1, 1);
630 clk[ZX296702_UART1_PCLK] =
631 zx_gate("uart1_pclk", "lsp1_apb_pclk", CLK_UART1, 0);
632
633 /* SDMMC0 */
634 clk[ZX296702_SDMMC0_WCLK_MUX] =
635 zx_mux("sdmmc0_wclk_mux", sdmmc0_wclk_sel,
636 ARRAY_SIZE(sdmmc0_wclk_sel), CLK_SDMMC0, 4, 1);
637 clk[ZX296702_SDMMC0_WCLK_DIV] =
638 zx_div("sdmmc0_wclk_div", "sdmmc0_wclk_mux", CLK_SDMMC0, 12, 4);
639 clk[ZX296702_SDMMC0_WCLK] =
640 zx_gate("sdmmc0_wclk", "sdmmc0_wclk_div", CLK_SDMMC0, 1);
641 clk[ZX296702_SDMMC0_PCLK] =
642 zx_gate("sdmmc0_pclk", "lsp1_apb_pclk", CLK_SDMMC0, 0);
643
644 for (i = 0; i < ARRAY_SIZE(lsp1clk); i++) {
645 if (IS_ERR(clk[i])) {
646 pr_err("zx296702 clk %d: register failed with %ld\n",
647 i, PTR_ERR(clk[i]));
648 return;
649 }
650 }
651
652 lsp1clk_data.clks = lsp1clk;
653 lsp1clk_data.clk_num = ARRAY_SIZE(lsp1clk);
654 of_clk_add_provider(np, of_clk_src_onecell_get, &lsp1clk_data);
655}
656CLK_OF_DECLARE(zx296702_lsp1_clk, "zte,zx296702-lsp1crpm-clk",
657 zx296702_lsp1_clocks_init);
diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h
new file mode 100644
index 000000000000..0914a82d0535
--- /dev/null
+++ b/drivers/clk/zte/clk.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2015 Linaro Ltd.
3 * Copyright (C) 2014 ZTE Corporation.
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 version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef __ZTE_CLK_H
11#define __ZTE_CLK_H
12#include <linux/clk-provider.h>
13#include <linux/spinlock.h>
14
15struct zx_pll_config {
16 unsigned long rate;
17 u32 cfg0;
18 u32 cfg1;
19};
20
21struct clk_zx_pll {
22 struct clk_hw hw;
23 void __iomem *reg_base;
24 const struct zx_pll_config *lookup_table; /* order by rate asc */
25 int count;
26 spinlock_t *lock;
27};
28
29struct clk *clk_register_zx_pll(const char *name, const char *parent_name,
30 unsigned long flags, void __iomem *reg_base,
31 const struct zx_pll_config *lookup_table, int count, spinlock_t *lock);
32#endif