]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-zynq/clk.c
Merge git://git.denx.de/u-boot-dm
[u-boot] / arch / arm / mach-zynq / clk.c
1 /*
2  * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
3  * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 #include <common.h>
8 #include <errno.h>
9 #include <asm/io.h>
10 #include <asm/arch/hardware.h>
11 #include <asm/arch/clk.h>
12
13 /* Board oscillator frequency */
14 #ifndef CONFIG_ZYNQ_PS_CLK_FREQ
15 # define CONFIG_ZYNQ_PS_CLK_FREQ        33333333UL
16 #endif
17
18 /* Register bitfield defines */
19 #define PLLCTRL_FBDIV_MASK      0x7f000
20 #define PLLCTRL_FBDIV_SHIFT     12
21 #define PLLCTRL_BPFORCE_MASK    (1 << 4)
22 #define PLLCTRL_PWRDWN_MASK     2
23 #define PLLCTRL_PWRDWN_SHIFT    1
24 #define PLLCTRL_RESET_MASK      1
25 #define PLLCTRL_RESET_SHIFT     0
26
27 #define ZYNQ_CLK_MAXDIV         0x3f
28 #define CLK_CTRL_DIV1_SHIFT     20
29 #define CLK_CTRL_DIV1_MASK      (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
30 #define CLK_CTRL_DIV0_SHIFT     8
31 #define CLK_CTRL_DIV0_MASK      (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
32 #define CLK_CTRL_SRCSEL_SHIFT   4
33 #define CLK_CTRL_SRCSEL_MASK    (0x3 << CLK_CTRL_SRCSEL_SHIFT)
34
35 #define CLK_CTRL_DIV2X_SHIFT    26
36 #define CLK_CTRL_DIV2X_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
37 #define CLK_CTRL_DIV3X_SHIFT    20
38 #define CLK_CTRL_DIV3X_MASK     (ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
39
40 #define ZYNQ_CLKMUX_SEL_0       0
41 #define ZYNQ_CLKMUX_SEL_1       1
42 #define ZYNQ_CLKMUX_SEL_2       2
43 #define ZYNQ_CLKMUX_SEL_3       3
44
45 DECLARE_GLOBAL_DATA_PTR;
46
47 struct clk;
48
49 /**
50  * struct zynq_clk_ops:
51  * @set_rate:   Function pointer to set_rate() implementation
52  * @get_rate:   Function pointer to get_rate() implementation
53  */
54 struct zynq_clk_ops {
55         int (*set_rate)(struct clk *clk, unsigned long rate);
56         unsigned long (*get_rate)(struct clk *clk);
57 };
58
59 /**
60  * struct clk:
61  * @name:       Clock name
62  * @frequency:  Currenct frequency
63  * @parent:     Parent clock
64  * @flags:      Clock flags
65  * @reg:        Clock control register
66  * @ops:        Clock operations
67  */
68 struct clk {
69         char            *name;
70         unsigned long   frequency;
71         enum zynq_clk   parent;
72         unsigned int    flags;
73         u32             *reg;
74         struct zynq_clk_ops     ops;
75 };
76 #define ZYNQ_CLK_FLAGS_HAS_2_DIVS       1
77
78 static struct clk clks[clk_max];
79
80 /**
81  * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
82  * @srcsel:     Mux select value
83  * Returns the clock identifier associated with the selected mux input.
84  */
85 static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
86 {
87         unsigned int ret;
88
89         switch (srcsel) {
90         case ZYNQ_CLKMUX_SEL_0:
91         case ZYNQ_CLKMUX_SEL_1:
92                 ret = armpll_clk;
93                 break;
94         case ZYNQ_CLKMUX_SEL_2:
95                 ret = ddrpll_clk;
96                 break;
97         case ZYNQ_CLKMUX_SEL_3:
98                 ret = iopll_clk;
99                 break;
100         default:
101                 ret = armpll_clk;
102                 break;
103         }
104
105         return ret;
106 }
107
108 /**
109  * ddr2x_get_rate() - Get clock rate of DDR2x clock
110  * @clk:        Clock handle
111  * Returns the current clock rate of @clk.
112  */
113 static unsigned long ddr2x_get_rate(struct clk *clk)
114 {
115         u32 clk_ctrl = readl(clk->reg);
116         u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
117
118         return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
119 }
120
121 /**
122  * ddr3x_get_rate() - Get clock rate of DDR3x clock
123  * @clk:        Clock handle
124  * Returns the current clock rate of @clk.
125  */
126 static unsigned long ddr3x_get_rate(struct clk *clk)
127 {
128         u32 clk_ctrl = readl(clk->reg);
129         u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
130
131         return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
132 }
133
134 static void init_ddr_clocks(void)
135 {
136         u32 div0, div1;
137         unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
138         u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
139
140         /* DDR2x */
141         clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
142         clks[ddr2x_clk].parent = ddrpll_clk;
143         clks[ddr2x_clk].name = "ddr_2x";
144         clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
145         clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
146
147         /* DDR3x */
148         clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
149         clks[ddr3x_clk].parent = ddrpll_clk;
150         clks[ddr3x_clk].name = "ddr_3x";
151         clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
152         clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
153
154         /* DCI */
155         clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
156         div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
157         div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
158         clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
159         clks[dci_clk].parent = ddrpll_clk;
160         clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
161                         DIV_ROUND_CLOSEST(prate, div0), div1);
162         clks[dci_clk].name = "dci";
163
164         gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
165 }
166
167 static void init_cpu_clocks(void)
168 {
169         int clk_621;
170         u32 reg, div, srcsel;
171         enum zynq_clk parent;
172
173         reg = readl(&slcr_base->arm_clk_ctrl);
174         clk_621 = readl(&slcr_base->clk_621_true) & 1;
175         div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
176         srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
177         parent = __zynq_clk_cpu_get_parent(srcsel);
178
179         /* cpu clocks */
180         clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
181         clks[cpu_6or4x_clk].parent = parent;
182         clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
183                         zynq_clk_get_rate(parent), div);
184         clks[cpu_6or4x_clk].name = "cpu_6or4x";
185
186         clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
187         clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
188         clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
189         clks[cpu_3or2x_clk].name = "cpu_3or2x";
190
191         clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
192         clks[cpu_2x_clk].parent = cpu_6or4x_clk;
193         clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
194                         (2 + clk_621);
195         clks[cpu_2x_clk].name = "cpu_2x";
196
197         clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
198         clks[cpu_1x_clk].parent = cpu_6or4x_clk;
199         clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
200                         (4 + 2 * clk_621);
201         clks[cpu_1x_clk].name = "cpu_1x";
202 }
203
204 /**
205  * periph_calc_two_divs() - Calculate clock dividers
206  * @cur_rate:   Current clock rate
207  * @tgt_rate:   Target clock rate
208  * @prate:      Parent clock rate
209  * @div0:       First divider (output)
210  * @div1:       Second divider (output)
211  * Returns the actual clock rate possible.
212  *
213  * Calculates clock dividers for clocks with two 6-bit dividers.
214  */
215 static unsigned long periph_calc_two_divs(unsigned long cur_rate,
216                 unsigned long tgt_rate, unsigned long prate, u32 *div0,
217                 u32 *div1)
218 {
219         long err, best_err = (long)(~0UL >> 1);
220         unsigned long rate, best_rate = 0;
221         u32 d0, d1;
222
223         for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
224                 for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
225                         rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
226                                         d1);
227                         err = abs(rate - tgt_rate);
228
229                         if (err < best_err) {
230                                 *div0 = d0;
231                                 *div1 = d1;
232                                 best_err = err;
233                                 best_rate = rate;
234                         }
235                 }
236         }
237
238         return best_rate;
239 }
240
241 /**
242  * zynq_clk_periph_set_rate() - Set clock rate
243  * @clk:        Handle of the peripheral clock
244  * @rate:       New clock rate
245  * Sets the clock frequency of @clk to @rate. Returns zero on success.
246  */
247 static int zynq_clk_periph_set_rate(struct clk *clk,
248                 unsigned long rate)
249 {
250         u32 ctrl, div0 = 0, div1 = 0;
251         unsigned long prate, new_rate, cur_rate = clk->frequency;
252
253         ctrl = readl(clk->reg);
254         prate = zynq_clk_get_rate(clk->parent);
255         ctrl &= ~CLK_CTRL_DIV0_MASK;
256
257         if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
258                 ctrl &= ~CLK_CTRL_DIV1_MASK;
259                 new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
260                                 &div1);
261                 ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
262         } else {
263                 div0 = DIV_ROUND_CLOSEST(prate, rate);
264                 div0 &= ZYNQ_CLK_MAXDIV;
265                 new_rate = DIV_ROUND_CLOSEST(rate, div0);
266         }
267
268         /* write new divs to hardware */
269         ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
270         writel(ctrl, clk->reg);
271
272         /* update frequency in clk framework */
273         clk->frequency = new_rate;
274
275         return 0;
276 }
277
278 /**
279  * zynq_clk_periph_get_rate() - Get clock rate
280  * @clk:        Handle of the peripheral clock
281  * Returns the current clock rate of @clk.
282  */
283 static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
284 {
285         u32 clk_ctrl = readl(clk->reg);
286         u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
287         u32 div1 = 1;
288
289         if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
290                 div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
291
292         /* a register value of zero == division by 1 */
293         if (!div0)
294                 div0 = 1;
295         if (!div1)
296                 div1 = 1;
297
298         return
299                 DIV_ROUND_CLOSEST(
300                         DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
301                         div1);
302 }
303
304 /**
305  * __zynq_clk_periph_get_parent() - Decode clock multiplexer
306  * @srcsel:     Mux select value
307  * Returns the clock identifier associated with the selected mux input.
308  */
309 static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
310 {
311         switch (srcsel) {
312         case ZYNQ_CLKMUX_SEL_0:
313         case ZYNQ_CLKMUX_SEL_1:
314                 return iopll_clk;
315         case ZYNQ_CLKMUX_SEL_2:
316                 return armpll_clk;
317         case ZYNQ_CLKMUX_SEL_3:
318                 return ddrpll_clk;
319         default:
320                 return 0;
321         }
322 }
323
324 /**
325  * zynq_clk_periph_get_parent() - Decode clock multiplexer
326  * @clk:        Clock handle
327  * Returns the clock identifier associated with the selected mux input.
328  */
329 static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
330 {
331         u32 clk_ctrl = readl(clk->reg);
332         u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
333
334         return __zynq_clk_periph_get_parent(srcsel);
335 }
336
337 /**
338  * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
339  * @clk:        Pointer to struct clk for the clock
340  * @ctrl:       Clock control register
341  * @name:       PLL name
342  * @two_divs:   Indicates whether the clock features one or two dividers
343  */
344 static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
345                 bool two_divs)
346 {
347         clk->name = name;
348         clk->reg = ctrl;
349         if (two_divs)
350                 clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
351         clk->parent = zynq_clk_periph_get_parent(clk);
352         clk->frequency = zynq_clk_periph_get_rate(clk);
353         clk->ops.get_rate = zynq_clk_periph_get_rate;
354         clk->ops.set_rate = zynq_clk_periph_set_rate;
355
356         return 0;
357 }
358
359 static void init_periph_clocks(void)
360 {
361         zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
362                                      "gem0", 1);
363         zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
364                                      "gem1", 1);
365
366         zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
367                                      "smc", 0);
368
369         zynq_clk_register_periph_clk(&clks[lqspi_clk],
370                                      &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
371
372         zynq_clk_register_periph_clk(&clks[sdio0_clk],
373                                      &slcr_base->sdio_clk_ctrl, "sdio0", 0);
374         zynq_clk_register_periph_clk(&clks[sdio1_clk],
375                                      &slcr_base->sdio_clk_ctrl, "sdio1", 0);
376
377         zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
378                                      "spi0", 0);
379         zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
380                                      "spi1", 0);
381
382         zynq_clk_register_periph_clk(&clks[uart0_clk],
383                                      &slcr_base->uart_clk_ctrl, "uart0", 0);
384         zynq_clk_register_periph_clk(&clks[uart1_clk],
385                                      &slcr_base->uart_clk_ctrl, "uart1", 0);
386
387         zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
388                                      &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
389         zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
390                                      &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
391
392         zynq_clk_register_periph_clk(&clks[pcap_clk],
393                                      &slcr_base->pcap_clk_ctrl, "pcap", 0);
394
395         zynq_clk_register_periph_clk(&clks[fclk0_clk],
396                                      &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
397         zynq_clk_register_periph_clk(&clks[fclk1_clk],
398                                      &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
399         zynq_clk_register_periph_clk(&clks[fclk2_clk],
400                                      &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
401         zynq_clk_register_periph_clk(&clks[fclk3_clk],
402                                      &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
403 }
404
405 /**
406  * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
407  * @clk:        Pointer to struct clk for the clock
408  * @ctrl:       Clock control register
409  * @name:       PLL name
410  */
411 static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
412 {
413         clk->name = name;
414         clk->reg = ctrl;
415         clk->parent = cpu_1x_clk;
416         clk->frequency = zynq_clk_get_rate(clk->parent);
417 }
418
419 static void init_aper_clocks(void)
420 {
421         zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
422                                    &slcr_base->aper_clk_ctrl, "usb0_aper");
423         zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
424                                    &slcr_base->aper_clk_ctrl, "usb1_aper");
425
426         zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
427                                    &slcr_base->aper_clk_ctrl, "gem0_aper");
428         zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
429                                    &slcr_base->aper_clk_ctrl, "gem1_aper");
430
431         zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
432                                    &slcr_base->aper_clk_ctrl, "sdio0_aper");
433         zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
434                                    &slcr_base->aper_clk_ctrl, "sdio1_aper");
435
436         zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
437                                    &slcr_base->aper_clk_ctrl, "spi0_aper");
438         zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
439                                    &slcr_base->aper_clk_ctrl, "spi1_aper");
440
441         zynq_clk_register_aper_clk(&clks[can0_aper_clk],
442                                    &slcr_base->aper_clk_ctrl, "can0_aper");
443         zynq_clk_register_aper_clk(&clks[can1_aper_clk],
444                                    &slcr_base->aper_clk_ctrl, "can1_aper");
445
446         zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
447                                    &slcr_base->aper_clk_ctrl, "i2c0_aper");
448         zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
449                                    &slcr_base->aper_clk_ctrl, "i2c1_aper");
450
451         zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
452                                    &slcr_base->aper_clk_ctrl, "uart0_aper");
453         zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
454                                    &slcr_base->aper_clk_ctrl, "uart1_aper");
455
456         zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
457                                    &slcr_base->aper_clk_ctrl, "gpio_aper");
458
459         zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
460                                    &slcr_base->aper_clk_ctrl, "lqspi_aper");
461
462         zynq_clk_register_aper_clk(&clks[smc_aper_clk],
463                                    &slcr_base->aper_clk_ctrl, "smc_aper");
464 }
465
466 /**
467  * __zynq_clk_pll_get_rate() - Get PLL rate
468  * @addr:       Address of the PLL's control register
469  * Returns the current PLL output rate.
470  */
471 static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
472 {
473         u32 reg, mul, bypass;
474
475         reg = readl(addr);
476         bypass = reg & PLLCTRL_BPFORCE_MASK;
477         if (bypass)
478                 mul = 1;
479         else
480                 mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
481
482         return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
483 }
484
485 /**
486  * zynq_clk_pll_get_rate() - Get PLL rate
487  * @pll:        Handle of the PLL
488  * Returns the current clock rate of @pll.
489  */
490 static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
491 {
492         return __zynq_clk_pll_get_rate(pll->reg);
493 }
494
495 /**
496  * zynq_clk_register_pll() - Set up a PLL with the framework
497  * @clk:        Pointer to struct clk for the PLL
498  * @ctrl:       PLL control register
499  * @name:       PLL name
500  * @prate:      PLL input clock rate
501  */
502 static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
503                 unsigned long prate)
504 {
505         clk->name = name;
506         clk->reg = ctrl;
507         clk->frequency = zynq_clk_pll_get_rate(clk);
508         clk->ops.get_rate = zynq_clk_pll_get_rate;
509 }
510
511 /**
512  * clkid_2_register() - Get clock control register
513  * @id: Clock identifier of one of the PLLs
514  * Returns the address of the requested PLL's control register.
515  */
516 static u32 *clkid_2_register(enum zynq_clk id)
517 {
518         switch (id) {
519         case armpll_clk:
520                 return &slcr_base->arm_pll_ctrl;
521         case ddrpll_clk:
522                 return &slcr_base->ddr_pll_ctrl;
523         case iopll_clk:
524                 return &slcr_base->io_pll_ctrl;
525         default:
526                 return &slcr_base->io_pll_ctrl;
527         }
528 }
529
530 /* API */
531 /**
532  * zynq_clk_early_init() - Early init for the clock framework
533  *
534  * This function is called from before relocation and sets up the CPU clock
535  * frequency in the global data struct.
536  */
537 void zynq_clk_early_init(void)
538 {
539         u32 reg = readl(&slcr_base->arm_clk_ctrl);
540         u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
541         u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
542         enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
543         u32 *pllreg = clkid_2_register(parent);
544         unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
545
546         if (!div)
547                 div = 1;
548
549         gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
550 }
551
552 /**
553  * get_uart_clk() - Get UART input frequency
554  * @dev_index:  UART ID
555  * Returns UART input clock frequency in Hz.
556  *
557  * Compared to zynq_clk_get_rate() this function is designed to work before
558  * relocation and can be called when the serial UART is set up.
559  */
560 unsigned long get_uart_clk(int dev_index)
561 {
562         u32 reg = readl(&slcr_base->uart_clk_ctrl);
563         u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
564         u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
565         enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
566         u32 *pllreg = clkid_2_register(parent);
567         unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
568
569         if (!div)
570                 div = 1;
571
572         return DIV_ROUND_CLOSEST(prate, div);
573 }
574
575 /**
576  * set_cpu_clk_info() - Initialize clock framework
577  * Always returns zero.
578  *
579  * This function is called from common code after relocation and sets up the
580  * clock framework. The framework must not be used before this function had been
581  * called.
582  */
583 int set_cpu_clk_info(void)
584 {
585         zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
586                               "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
587         zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
588                               "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
589         zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
590                               "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
591
592         init_ddr_clocks();
593         init_cpu_clocks();
594         init_periph_clocks();
595         init_aper_clocks();
596
597         gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
598         gd->bd->bi_dsp_freq = 0;
599
600         return 0;
601 }
602
603 /**
604  * zynq_clk_get_rate() - Get clock rate
605  * @clk:        Clock identifier
606  * Returns the current clock rate of @clk on success or zero for an invalid
607  * clock id.
608  */
609 unsigned long zynq_clk_get_rate(enum zynq_clk clk)
610 {
611         if (clk < 0 || clk >= clk_max)
612                 return 0;
613
614         return clks[clk].frequency;
615 }
616
617 /**
618  * zynq_clk_set_rate() - Set clock rate
619  * @clk:        Clock identifier
620  * @rate:       Requested clock rate
621  * Passes on the return value from the clock's set_rate() function or negative
622  * errno.
623  */
624 int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
625 {
626         if (clk < 0 || clk >= clk_max)
627                 return -ENODEV;
628
629         if (clks[clk].ops.set_rate)
630                 return clks[clk].ops.set_rate(&clks[clk], rate);
631
632         return -ENXIO;
633 }
634
635 /**
636  * zynq_clk_get_name() - Get clock name
637  * @clk:        Clock identifier
638  * Returns the name of @clk.
639  */
640 const char *zynq_clk_get_name(enum zynq_clk clk)
641 {
642         return clks[clk].name;
643 }
644
645 /**
646  * soc_clk_dump() - Print clock frequencies
647  * Returns zero on success
648  *
649  * Implementation for the clk dump command.
650  */
651 int soc_clk_dump(void)
652 {
653         int i;
654
655         printf("clk\t\tfrequency\n");
656         for (i = 0; i < clk_max; i++) {
657                 const char *name = zynq_clk_get_name(i);
658                 if (name)
659                         printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
660         }
661
662         return 0;
663 }