1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/clk/zynq.h>
22#include <linux/clk.h>
23#include <linux/clk-provider.h>
24#include <linux/of.h>
25#include <linux/of_address.h>
26#include <linux/slab.h>
27#include <linux/string.h>
28#include <linux/io.h>
29
30static void __iomem *zynq_clkc_base;
31
32#define SLCR_ARMPLL_CTRL (zynq_clkc_base + 0x00)
33#define SLCR_DDRPLL_CTRL (zynq_clkc_base + 0x04)
34#define SLCR_IOPLL_CTRL (zynq_clkc_base + 0x08)
35#define SLCR_PLL_STATUS (zynq_clkc_base + 0x0c)
36#define SLCR_ARM_CLK_CTRL (zynq_clkc_base + 0x20)
37#define SLCR_DDR_CLK_CTRL (zynq_clkc_base + 0x24)
38#define SLCR_DCI_CLK_CTRL (zynq_clkc_base + 0x28)
39#define SLCR_APER_CLK_CTRL (zynq_clkc_base + 0x2c)
40#define SLCR_GEM0_CLK_CTRL (zynq_clkc_base + 0x40)
41#define SLCR_GEM1_CLK_CTRL (zynq_clkc_base + 0x44)
42#define SLCR_SMC_CLK_CTRL (zynq_clkc_base + 0x48)
43#define SLCR_LQSPI_CLK_CTRL (zynq_clkc_base + 0x4c)
44#define SLCR_SDIO_CLK_CTRL (zynq_clkc_base + 0x50)
45#define SLCR_UART_CLK_CTRL (zynq_clkc_base + 0x54)
46#define SLCR_SPI_CLK_CTRL (zynq_clkc_base + 0x58)
47#define SLCR_CAN_CLK_CTRL (zynq_clkc_base + 0x5c)
48#define SLCR_CAN_MIOCLK_CTRL (zynq_clkc_base + 0x60)
49#define SLCR_DBG_CLK_CTRL (zynq_clkc_base + 0x64)
50#define SLCR_PCAP_CLK_CTRL (zynq_clkc_base + 0x68)
51#define SLCR_TOPSW_CLK_CTRL (zynq_clkc_base + 0x6c)
52#define SLCR_FPGA0_CLK_CTRL (zynq_clkc_base + 0x70)
53#define SLCR_621_TRUE (zynq_clkc_base + 0xc4)
54#define SLCR_SWDT_CLK_SEL (zynq_clkc_base + 0x204)
55
56#define NUM_MIO_PINS 54
57
58#define DBG_CLK_CTRL_CLKACT_TRC BIT(0)
59#define DBG_CLK_CTRL_CPU_1XCLKACT BIT(1)
60
61enum zynq_clk {
62 armpll, ddrpll, iopll,
63 cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x,
64 ddr2x, ddr3x, dci,
65 lqspi, smc, pcap, gem0, gem1, fclk0, fclk1, fclk2, fclk3, can0, can1,
66 sdio0, sdio1, uart0, uart1, spi0, spi1, dma,
67 usb0_aper, usb1_aper, gem0_aper, gem1_aper,
68 sdio0_aper, sdio1_aper, spi0_aper, spi1_aper, can0_aper, can1_aper,
69 i2c0_aper, i2c1_aper, uart0_aper, uart1_aper, gpio_aper, lqspi_aper,
70 smc_aper, swdt, dbg_trc, dbg_apb, clk_max};
71
72static struct clk *ps_clk;
73static struct clk *clks[clk_max];
74static struct clk_onecell_data clk_data;
75
76static DEFINE_SPINLOCK(armpll_lock);
77static DEFINE_SPINLOCK(ddrpll_lock);
78static DEFINE_SPINLOCK(iopll_lock);
79static DEFINE_SPINLOCK(armclk_lock);
80static DEFINE_SPINLOCK(swdtclk_lock);
81static DEFINE_SPINLOCK(ddrclk_lock);
82static DEFINE_SPINLOCK(dciclk_lock);
83static DEFINE_SPINLOCK(gem0clk_lock);
84static DEFINE_SPINLOCK(gem1clk_lock);
85static DEFINE_SPINLOCK(canclk_lock);
86static DEFINE_SPINLOCK(canmioclk_lock);
87static DEFINE_SPINLOCK(dbgclk_lock);
88static DEFINE_SPINLOCK(aperclk_lock);
89
90static const char *const armpll_parents[] __initconst = {"armpll_int",
91 "ps_clk"};
92static const char *const ddrpll_parents[] __initconst = {"ddrpll_int",
93 "ps_clk"};
94static const char *const iopll_parents[] __initconst = {"iopll_int",
95 "ps_clk"};
96static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"};
97static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"};
98static const char *const can0_mio_mux2_parents[] __initconst = {"can0_gate",
99 "can0_mio_mux"};
100static const char *const can1_mio_mux2_parents[] __initconst = {"can1_gate",
101 "can1_mio_mux"};
102static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div",
103 "dummy_name"};
104
105static const char *const dbgtrc_emio_input_names[] __initconst = {
106 "trace_emio_clk"};
107static const char *const gem0_emio_input_names[] __initconst = {
108 "gem0_emio_clk"};
109static const char *const gem1_emio_input_names[] __initconst = {
110 "gem1_emio_clk"};
111static const char *const swdt_ext_clk_input_names[] __initconst = {
112 "swdt_ext_clk"};
113
114#ifdef CONFIG_SUSPEND
115static struct clk *iopll_save_parent;
116
117#define TOPSW_CLK_CTRL_DIS_MASK BIT(0)
118
119int zynq_clk_suspend_early(void)
120{
121 int ret;
122
123 iopll_save_parent = clk_get_parent(clks[iopll]);
124
125 ret = clk_set_parent(clks[iopll], ps_clk);
126 if (ret)
127 pr_info("%s: reparent iopll failed %d\n", __func__, ret);
128
129 return 0;
130}
131
132void zynq_clk_resume_late(void)
133{
134 clk_set_parent(clks[iopll], iopll_save_parent);
135}
136
137void zynq_clk_topswitch_enable(void)
138{
139 u32 reg;
140
141 reg = readl(SLCR_TOPSW_CLK_CTRL);
142 reg &= ~TOPSW_CLK_CTRL_DIS_MASK;
143 writel(reg, SLCR_TOPSW_CLK_CTRL);
144}
145
146void zynq_clk_topswitch_disable(void)
147{
148 u32 reg;
149
150 reg = readl(SLCR_TOPSW_CLK_CTRL);
151 reg |= TOPSW_CLK_CTRL_DIS_MASK;
152 writel(reg, SLCR_TOPSW_CLK_CTRL);
153}
154#endif
155
156static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
157 const char *clk_name, void __iomem *fclk_ctrl_reg,
158 const char **parents, int enable)
159{
160 struct clk *clk;
161 u32 enable_reg;
162 char *mux_name;
163 char *div0_name;
164 char *div1_name;
165 spinlock_t *fclk_lock;
166 spinlock_t *fclk_gate_lock;
167 void __iomem *fclk_gate_reg = fclk_ctrl_reg + 8;
168
169 fclk_lock = kmalloc(sizeof(*fclk_lock), GFP_KERNEL);
170 if (!fclk_lock)
171 goto err;
172 fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL);
173 if (!fclk_gate_lock)
174 goto err_fclk_gate_lock;
175 spin_lock_init(fclk_lock);
176 spin_lock_init(fclk_gate_lock);
177
178 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
179 if (!mux_name)
180 goto err_mux_name;
181 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
182 if (!div0_name)
183 goto err_div0_name;
184 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
185 if (!div1_name)
186 goto err_div1_name;
187
188 clk = clk_register_mux(NULL, mux_name, parents, 4,
189 CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0,
190 fclk_lock);
191
192 clk = clk_register_divider(NULL, div0_name, mux_name,
193 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED |
194 CLK_DIVIDER_ALLOW_ZERO, fclk_lock);
195
196 clk = clk_register_divider(NULL, div1_name, div0_name,
197 CLK_SET_RATE_PARENT, fclk_ctrl_reg, 20, 6,
198 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
199 fclk_lock);
200
201 clks[fclk] = clk_register_gate(NULL, clk_name,
202 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
203 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
204 enable_reg = clk_readl(fclk_gate_reg) & 1;
205 if (enable && !enable_reg) {
206 if (clk_prepare_enable(clks[fclk]))
207 pr_warn("%s: FCLK%u enable failed\n", __func__,
208 fclk - fclk0);
209 }
210 kfree(mux_name);
211 kfree(div0_name);
212 kfree(div1_name);
213
214 return;
215
216err_div1_name:
217 kfree(div0_name);
218err_div0_name:
219 kfree(mux_name);
220err_mux_name:
221 kfree(fclk_gate_lock);
222err_fclk_gate_lock:
223 kfree(fclk_lock);
224err:
225 clks[fclk] = ERR_PTR(-ENOMEM);
226}
227
228static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
229 enum zynq_clk clk1, const char *clk_name0,
230 const char *clk_name1, void __iomem *clk_ctrl,
231 const char **parents, unsigned int two_gates)
232{
233 struct clk *clk;
234 char *mux_name;
235 char *div_name;
236 spinlock_t *lock;
237
238 lock = kmalloc(sizeof(*lock), GFP_KERNEL);
239 if (!lock)
240 goto err;
241 spin_lock_init(lock);
242
243 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
244 div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
245
246 clk = clk_register_mux(NULL, mux_name, parents, 4,
247 CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock);
248
249 clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6,
250 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock);
251
252 clks[clk0] = clk_register_gate(NULL, clk_name0, div_name,
253 CLK_SET_RATE_PARENT, clk_ctrl, 0, 0, lock);
254 if (two_gates)
255 clks[clk1] = clk_register_gate(NULL, clk_name1, div_name,
256 CLK_SET_RATE_PARENT, clk_ctrl, 1, 0, lock);
257
258 kfree(mux_name);
259 kfree(div_name);
260
261 return;
262
263err:
264 clks[clk0] = ERR_PTR(-ENOMEM);
265 if (two_gates)
266 clks[clk1] = ERR_PTR(-ENOMEM);
267}
268
269static void __init zynq_clk_setup(struct device_node *np)
270{
271 int i;
272 u32 tmp;
273 int ret;
274 struct clk *clk;
275 char *clk_name;
276 unsigned int fclk_enable = 0;
277 const char *clk_output_name[clk_max];
278 const char *cpu_parents[4];
279 const char *periph_parents[4];
280 const char *swdt_ext_clk_mux_parents[2];
281 const char *can_mio_mux_parents[NUM_MIO_PINS];
282 const char *dummy_nm = "dummy_name";
283
284 pr_info("Zynq clock init\n");
285
286
287 for (i = 0; i < clk_max; i++) {
288 if (of_property_read_string_index(np, "clock-output-names",
289 i, &clk_output_name[i])) {
290 pr_err("%s: clock output name not in DT\n", __func__);
291 BUG();
292 }
293 }
294 cpu_parents[0] = clk_output_name[armpll];
295 cpu_parents[1] = clk_output_name[armpll];
296 cpu_parents[2] = clk_output_name[ddrpll];
297 cpu_parents[3] = clk_output_name[iopll];
298 periph_parents[0] = clk_output_name[iopll];
299 periph_parents[1] = clk_output_name[iopll];
300 periph_parents[2] = clk_output_name[armpll];
301 periph_parents[3] = clk_output_name[ddrpll];
302
303 of_property_read_u32(np, "fclk-enable", &fclk_enable);
304
305
306 ret = of_property_read_u32(np, "ps-clk-frequency", &tmp);
307 if (ret) {
308 pr_warn("ps_clk frequency not specified, using 33 MHz.\n");
309 tmp = 33333333;
310 }
311 ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, 0, tmp);
312
313
314 clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
315 SLCR_PLL_STATUS, 0, &armpll_lock);
316 clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll],
317 armpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
318 SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock);
319
320 clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL,
321 SLCR_PLL_STATUS, 1, &ddrpll_lock);
322 clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll],
323 ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
324 SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock);
325
326 clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL,
327 SLCR_PLL_STATUS, 2, &iopll_lock);
328 clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll],
329 iopll_parents, 2, CLK_SET_RATE_NO_REPARENT,
330 SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);
331
332
333 tmp = clk_readl(SLCR_621_TRUE) & 1;
334 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
335 CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
336 &armclk_lock);
337 clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0,
338 SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
339 CLK_DIVIDER_ALLOW_ZERO, &armclk_lock);
340
341 clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x],
342 "cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
343 SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock);
344
345 clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0,
346 1, 2);
347 clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x],
348 "cpu_3or2x_div", CLK_IGNORE_UNUSED,
349 SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock);
350
351 clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1,
352 2 + tmp);
353 clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x],
354 "cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL,
355 26, 0, &armclk_lock);
356 clk_prepare_enable(clks[cpu_2x]);
357
358 clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1,
359 4 + 2 * tmp);
360 clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x],
361 "cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27,
362 0, &armclk_lock);
363
364
365 swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x];
366 for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
367 int idx = of_property_match_string(np, "clock-names",
368 swdt_ext_clk_input_names[i]);
369 if (idx >= 0)
370 swdt_ext_clk_mux_parents[i + 1] =
371 of_clk_get_parent_name(np, idx);
372 else
373 swdt_ext_clk_mux_parents[i + 1] = dummy_nm;
374 }
375 clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt],
376 swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT |
377 CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0,
378 &swdtclk_lock);
379
380
381 clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0,
382 SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED |
383 CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
384 clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x],
385 "ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock);
386 clk_prepare_enable(clks[ddr2x]);
387 clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0,
388 SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED |
389 CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
390 clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x],
391 "ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock);
392 clk_prepare_enable(clks[ddr3x]);
393
394 clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0,
395 SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
396 CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock);
397 clk = clk_register_divider(NULL, "dci_div1", "dci_div0",
398 CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6,
399 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
400 &dciclk_lock);
401 clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1",
402 CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0,
403 &dciclk_lock);
404 clk_prepare_enable(clks[dci]);
405
406
407 for (i = fclk0; i <= fclk3; i++) {
408 int enable = !!(fclk_enable & BIT(i - fclk0));
409 zynq_clk_register_fclk(i, clk_output_name[i],
410 SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
411 periph_parents, enable);
412 }
413
414 zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
415 SLCR_LQSPI_CLK_CTRL, periph_parents, 0);
416
417 zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL,
418 SLCR_SMC_CLK_CTRL, periph_parents, 0);
419
420 zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL,
421 SLCR_PCAP_CLK_CTRL, periph_parents, 0);
422
423 zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0],
424 clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL,
425 periph_parents, 1);
426
427 zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0],
428 clk_output_name[uart1], SLCR_UART_CLK_CTRL,
429 periph_parents, 1);
430
431 zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0],
432 clk_output_name[spi1], SLCR_SPI_CLK_CTRL,
433 periph_parents, 1);
434
435 for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
436 int idx = of_property_match_string(np, "clock-names",
437 gem0_emio_input_names[i]);
438 if (idx >= 0)
439 gem0_mux_parents[i + 1] = of_clk_get_parent_name(np,
440 idx);
441 }
442 clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4,
443 CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0,
444 &gem0clk_lock);
445 clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0,
446 SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
447 CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock);
448 clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0",
449 CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6,
450 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
451 &gem0clk_lock);
452 clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2,
453 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
454 SLCR_GEM0_CLK_CTRL, 6, 1, 0,
455 &gem0clk_lock);
456 clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0],
457 "gem0_emio_mux", CLK_SET_RATE_PARENT,
458 SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock);
459
460 for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
461 int idx = of_property_match_string(np, "clock-names",
462 gem1_emio_input_names[i]);
463 if (idx >= 0)
464 gem1_mux_parents[i + 1] = of_clk_get_parent_name(np,
465 idx);
466 }
467 clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4,
468 CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0,
469 &gem1clk_lock);
470 clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0,
471 SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
472 CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock);
473 clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0",
474 CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6,
475 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
476 &gem1clk_lock);
477 clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2,
478 CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
479 SLCR_GEM1_CLK_CTRL, 6, 1, 0,
480 &gem1clk_lock);
481 clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1],
482 "gem1_emio_mux", CLK_SET_RATE_PARENT,
483 SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
484
485 tmp = strlen("mio_clk_00x");
486 clk_name = kmalloc(tmp, GFP_KERNEL);
487 for (i = 0; i < NUM_MIO_PINS; i++) {
488 int idx;
489
490 snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
491 idx = of_property_match_string(np, "clock-names", clk_name);
492 if (idx >= 0)
493 can_mio_mux_parents[i] = of_clk_get_parent_name(np,
494 idx);
495 else
496 can_mio_mux_parents[i] = dummy_nm;
497 }
498 kfree(clk_name);
499 clk = clk_register_mux(NULL, "can_mux", periph_parents, 4,
500 CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0,
501 &canclk_lock);
502 clk = clk_register_divider(NULL, "can_div0", "can_mux", 0,
503 SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
504 CLK_DIVIDER_ALLOW_ZERO, &canclk_lock);
505 clk = clk_register_divider(NULL, "can_div1", "can_div0",
506 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6,
507 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
508 &canclk_lock);
509 clk = clk_register_gate(NULL, "can0_gate", "can_div1",
510 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0,
511 &canclk_lock);
512 clk = clk_register_gate(NULL, "can1_gate", "can_div1",
513 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0,
514 &canclk_lock);
515 clk = clk_register_mux(NULL, "can0_mio_mux",
516 can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
517 CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0,
518 &canmioclk_lock);
519 clk = clk_register_mux(NULL, "can1_mio_mux",
520 can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
521 CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6,
522 0, &canmioclk_lock);
523 clks[can0] = clk_register_mux(NULL, clk_output_name[can0],
524 can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
525 CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0,
526 &canmioclk_lock);
527 clks[can1] = clk_register_mux(NULL, clk_output_name[can1],
528 can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
529 CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1,
530 0, &canmioclk_lock);
531
532 for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) {
533 int idx = of_property_match_string(np, "clock-names",
534 dbgtrc_emio_input_names[i]);
535 if (idx >= 0)
536 dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np,
537 idx);
538 }
539 clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4,
540 CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0,
541 &dbgclk_lock);
542 clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0,
543 SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
544 CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock);
545 clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2,
546 CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0,
547 &dbgclk_lock);
548 clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc],
549 "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL,
550 0, 0, &dbgclk_lock);
551 clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb],
552 clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0,
553 &dbgclk_lock);
554
555
556 tmp = clk_readl(SLCR_DBG_CLK_CTRL);
557 if (tmp & DBG_CLK_CTRL_CLKACT_TRC)
558 if (clk_prepare_enable(clks[dbg_trc]))
559 pr_warn("%s: trace clk enable failed\n", __func__);
560 if (tmp & DBG_CLK_CTRL_CPU_1XCLKACT)
561 if (clk_prepare_enable(clks[dbg_apb]))
562 pr_warn("%s: debug APB clk enable failed\n", __func__);
563
564
565 clks[dma] = clk_register_gate(NULL, clk_output_name[dma],
566 clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0,
567 &aperclk_lock);
568 clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper],
569 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0,
570 &aperclk_lock);
571 clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper],
572 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0,
573 &aperclk_lock);
574 clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper],
575 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0,
576 &aperclk_lock);
577 clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper],
578 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0,
579 &aperclk_lock);
580 clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper],
581 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0,
582 &aperclk_lock);
583 clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper],
584 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0,
585 &aperclk_lock);
586 clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper],
587 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0,
588 &aperclk_lock);
589 clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper],
590 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0,
591 &aperclk_lock);
592 clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper],
593 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0,
594 &aperclk_lock);
595 clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper],
596 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0,
597 &aperclk_lock);
598 clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper],
599 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0,
600 &aperclk_lock);
601 clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper],
602 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0,
603 &aperclk_lock);
604 clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper],
605 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0,
606 &aperclk_lock);
607 clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper],
608 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0,
609 &aperclk_lock);
610 clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper],
611 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0,
612 &aperclk_lock);
613 clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper],
614 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0,
615 &aperclk_lock);
616 clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper],
617 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0,
618 &aperclk_lock);
619
620 for (i = 0; i < ARRAY_SIZE(clks); i++) {
621 if (IS_ERR(clks[i])) {
622 pr_err("Zynq clk %d: register failed with %ld\n",
623 i, PTR_ERR(clks[i]));
624 BUG();
625 }
626 }
627
628 clk_data.clks = clks;
629 clk_data.clk_num = ARRAY_SIZE(clks);
630 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
631}
632
633CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup);
634
635void __init zynq_clock_init(void)
636{
637 struct device_node *np;
638 struct device_node *slcr;
639 struct resource res;
640
641 np = of_find_compatible_node(NULL, NULL, "xlnx,ps7-clkc");
642 if (!np) {
643 pr_err("%s: clkc node not found\n", __func__);
644 goto np_err;
645 }
646
647 if (of_address_to_resource(np, 0, &res)) {
648 pr_err("%s: failed to get resource\n", np->name);
649 goto np_err;
650 }
651
652 slcr = of_get_parent(np);
653
654 if (slcr->data) {
655 zynq_clkc_base = (__force void __iomem *)slcr->data + res.start;
656 } else {
657 pr_err("%s: Unable to get I/O memory\n", np->name);
658 of_node_put(slcr);
659 goto np_err;
660 }
661
662 pr_info("%s: clkc starts at %p\n", __func__, zynq_clkc_base);
663
664 of_node_put(slcr);
665 of_node_put(np);
666
667 return;
668
669np_err:
670 of_node_put(np);
671 BUG();
672}
673