zynq: Provide a framework to read clock frequencies
[oweals/u-boot.git] / arch / arm / cpu / armv7 / 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 clk_ops:
51  * @set_rate:   Function pointer to set_rate() implementation
52  * @get_rate:   Function pointer to get_rate() implementation
53  */
54 struct 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 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
165 static void init_cpu_clocks(void)
166 {
167         int clk_621;
168         u32 reg, div, srcsel;
169         enum zynq_clk parent;
170
171         reg = readl(&slcr_base->arm_clk_ctrl);
172         clk_621 = readl(&slcr_base->clk_621_true) & 1;
173         div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
174         srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
175         parent = __zynq_clk_cpu_get_parent(srcsel);
176
177         /* cpu clocks */
178         clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
179         clks[cpu_6or4x_clk].parent = parent;
180         clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
181                         zynq_clk_get_rate(parent), div);
182         clks[cpu_6or4x_clk].name = "cpu_6or4x";
183
184         clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
185         clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
186         clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
187         clks[cpu_3or2x_clk].name = "cpu_3or2x";
188
189         clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
190         clks[cpu_2x_clk].parent = cpu_6or4x_clk;
191         clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
192                         (2 + clk_621);
193         clks[cpu_2x_clk].name = "cpu_2x";
194
195         clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
196         clks[cpu_1x_clk].parent = cpu_6or4x_clk;
197         clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
198                         (4 + 2 * clk_621);
199         clks[cpu_1x_clk].name = "cpu_1x";
200 }
201
202 /**
203  * periph_calc_two_divs() - Calculate clock dividers
204  * @cur_rate:   Current clock rate
205  * @tgt_rate:   Target clock rate
206  * @prate:      Parent clock rate
207  * @div0:       First divider (output)
208  * @div1:       Second divider (output)
209  * Returns the actual clock rate possible.
210  *
211  * Calculates clock dividers for clocks with two 6-bit dividers.
212  */
213 static unsigned long periph_calc_two_divs(unsigned long cur_rate,
214                 unsigned long tgt_rate, unsigned long prate, u32 *div0,
215                 u32 *div1)
216 {
217         long err, best_err = (long)(~0UL >> 1);
218         unsigned long rate, best_rate = 0;
219         u32 d0, d1;
220
221         for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
222                 for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
223                         rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
224                                         d1);
225                         err = abs(rate - tgt_rate);
226
227                         if (err < best_err) {
228                                 *div0 = d0;
229                                 *div1 = d1;
230                                 best_err = err;
231                                 best_rate = rate;
232                         }
233                 }
234         }
235
236         return best_rate;
237 }
238
239 /**
240  * zynq_clk_periph_set_rate() - Set clock rate
241  * @clk:        Handle of the peripheral clock
242  * @rate:       New clock rate
243  * Sets the clock frequency of @clk to @rate. Returns zero on success.
244  */
245 static int zynq_clk_periph_set_rate(struct clk *clk,
246                 unsigned long rate)
247 {
248         u32 ctrl, div0 = 0, div1 = 0;
249         unsigned long prate, new_rate, cur_rate = clk->frequency;
250
251         ctrl = readl(clk->reg);
252         prate = zynq_clk_get_rate(clk->parent);
253         ctrl &= ~CLK_CTRL_DIV0_MASK;
254
255         if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
256                 ctrl &= ~CLK_CTRL_DIV1_MASK;
257                 new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
258                                 &div1);
259                 ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
260         } else {
261                 div0 = DIV_ROUND_CLOSEST(prate, rate);
262                 div0 &= ZYNQ_CLK_MAXDIV;
263                 new_rate = DIV_ROUND_CLOSEST(rate, div0);
264         }
265
266         /* write new divs to hardware */
267         ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
268         writel(ctrl, clk->reg);
269
270         /* update frequency in clk framework */
271         clk->frequency = new_rate;
272
273         return 0;
274 }
275
276 /**
277  * zynq_clk_periph_get_rate() - Get clock rate
278  * @clk:        Handle of the peripheral clock
279  * Returns the current clock rate of @clk.
280  */
281 static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
282 {
283         u32 clk_ctrl = readl(clk->reg);
284         u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
285         u32 div1 = 1;
286
287         if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
288                 div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
289
290         /* a register value of zero == division by 1 */
291         if (!div0)
292                 div0 = 1;
293         if (!div1)
294                 div1 = 1;
295
296         return
297                 DIV_ROUND_CLOSEST(
298                         DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
299                         div1);
300 }
301
302 /**
303  * __zynq_clk_periph_get_parent() - Decode clock multiplexer
304  * @srcsel:     Mux select value
305  * Returns the clock identifier associated with the selected mux input.
306  */
307 static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
308 {
309         switch (srcsel) {
310         case ZYNQ_CLKMUX_SEL_0:
311         case ZYNQ_CLKMUX_SEL_1:
312                 return iopll_clk;
313         case ZYNQ_CLKMUX_SEL_2:
314                 return armpll_clk;
315         case ZYNQ_CLKMUX_SEL_3:
316                 return ddrpll_clk;
317         default:
318                 return 0;
319         }
320 }
321
322 /**
323  * zynq_clk_periph_get_parent() - Decode clock multiplexer
324  * @clk:        Clock handle
325  * Returns the clock identifier associated with the selected mux input.
326  */
327 static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
328 {
329         u32 clk_ctrl = readl(clk->reg);
330         u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
331
332         return __zynq_clk_periph_get_parent(srcsel);
333 }
334
335 /**
336  * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
337  * @clk:        Pointer to struct clk for the clock
338  * @ctrl:       Clock control register
339  * @name:       PLL name
340  * @two_divs:   Indicates whether the clock features one or two dividers
341  */
342 static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
343                 bool two_divs)
344 {
345         clk->name = name;
346         clk->reg = ctrl;
347         if (two_divs)
348                 clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
349         clk->parent = zynq_clk_periph_get_parent(clk);
350         clk->frequency = zynq_clk_periph_get_rate(clk);
351         clk->ops.get_rate = zynq_clk_periph_get_rate;
352         clk->ops.set_rate = zynq_clk_periph_set_rate;
353
354         return 0;
355 }
356
357 static void init_periph_clocks(void)
358 {
359         zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
360                                      "gem0", 1);
361         zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
362                                      "gem1", 1);
363
364         zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
365                                      "smc", 0);
366
367         zynq_clk_register_periph_clk(&clks[lqspi_clk],
368                                      &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
369
370         zynq_clk_register_periph_clk(&clks[sdio0_clk],
371                                      &slcr_base->sdio_clk_ctrl, "sdio0", 0);
372         zynq_clk_register_periph_clk(&clks[sdio1_clk],
373                                      &slcr_base->sdio_clk_ctrl, "sdio1", 0);
374
375         zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
376                                      "spi0", 0);
377         zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
378                                      "spi1", 0);
379
380         zynq_clk_register_periph_clk(&clks[uart0_clk],
381                                      &slcr_base->uart_clk_ctrl, "uart0", 0);
382         zynq_clk_register_periph_clk(&clks[uart1_clk],
383                                      &slcr_base->uart_clk_ctrl, "uart1", 0);
384
385         zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
386                                      &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
387         zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
388                                      &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
389
390         zynq_clk_register_periph_clk(&clks[pcap_clk],
391                                      &slcr_base->pcap_clk_ctrl, "pcap", 0);
392
393         zynq_clk_register_periph_clk(&clks[fclk0_clk],
394                                      &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
395         zynq_clk_register_periph_clk(&clks[fclk1_clk],
396                                      &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
397         zynq_clk_register_periph_clk(&clks[fclk2_clk],
398                                      &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
399         zynq_clk_register_periph_clk(&clks[fclk3_clk],
400                                      &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
401 }
402
403 /**
404  * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
405  * @clk:        Pointer to struct clk for the clock
406  * @ctrl:       Clock control register
407  * @name:       PLL name
408  */
409 static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
410 {
411         clk->name = name;
412         clk->reg = ctrl;
413         clk->parent = cpu_1x_clk;
414         clk->frequency = zynq_clk_get_rate(clk->parent);
415 }
416
417 static void init_aper_clocks(void)
418 {
419         zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
420                                    &slcr_base->aper_clk_ctrl, "usb0_aper");
421         zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
422                                    &slcr_base->aper_clk_ctrl, "usb1_aper");
423
424         zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
425                                    &slcr_base->aper_clk_ctrl, "gem0_aper");
426         zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
427                                    &slcr_base->aper_clk_ctrl, "gem1_aper");
428
429         zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
430                                    &slcr_base->aper_clk_ctrl, "sdio0_aper");
431         zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
432                                    &slcr_base->aper_clk_ctrl, "sdio1_aper");
433
434         zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
435                                    &slcr_base->aper_clk_ctrl, "spi0_aper");
436         zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
437                                    &slcr_base->aper_clk_ctrl, "spi1_aper");
438
439         zynq_clk_register_aper_clk(&clks[can0_aper_clk],
440                                    &slcr_base->aper_clk_ctrl, "can0_aper");
441         zynq_clk_register_aper_clk(&clks[can1_aper_clk],
442                                    &slcr_base->aper_clk_ctrl, "can1_aper");
443
444         zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
445                                    &slcr_base->aper_clk_ctrl, "i2c0_aper");
446         zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
447                                    &slcr_base->aper_clk_ctrl, "i2c1_aper");
448
449         zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
450                                    &slcr_base->aper_clk_ctrl, "uart0_aper");
451         zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
452                                    &slcr_base->aper_clk_ctrl, "uart1_aper");
453
454         zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
455                                    &slcr_base->aper_clk_ctrl, "gpio_aper");
456
457         zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
458                                    &slcr_base->aper_clk_ctrl, "lqspi_aper");
459
460         zynq_clk_register_aper_clk(&clks[smc_aper_clk],
461                                    &slcr_base->aper_clk_ctrl, "smc_aper");
462 }
463
464 /**
465  * __zynq_clk_pll_get_rate() - Get PLL rate
466  * @addr:       Address of the PLL's control register
467  * Returns the current PLL output rate.
468  */
469 static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
470 {
471         u32 reg, mul, bypass;
472
473         reg = readl(addr);
474         bypass = reg & PLLCTRL_BPFORCE_MASK;
475         if (bypass)
476                 mul = 1;
477         else
478                 mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
479
480         return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
481 }
482
483 /**
484  * zynq_clk_pll_get_rate() - Get PLL rate
485  * @pll:        Handle of the PLL
486  * Returns the current clock rate of @pll.
487  */
488 static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
489 {
490         return __zynq_clk_pll_get_rate(pll->reg);
491 }
492
493 /**
494  * zynq_clk_register_pll() - Set up a PLL with the framework
495  * @clk:        Pointer to struct clk for the PLL
496  * @ctrl:       PLL control register
497  * @name:       PLL name
498  * @prate:      PLL input clock rate
499  */
500 static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
501                 unsigned long prate)
502 {
503         clk->name = name;
504         clk->reg = ctrl;
505         clk->frequency = zynq_clk_pll_get_rate(clk);
506         clk->ops.get_rate = zynq_clk_pll_get_rate;
507 }
508
509 /**
510  * clkid_2_register() - Get clock control register
511  * @id: Clock identifier of one of the PLLs
512  * Returns the address of the requested PLL's control register.
513  */
514 static u32 *clkid_2_register(enum zynq_clk id)
515 {
516         switch (id) {
517         case armpll_clk:
518                 return &slcr_base->arm_pll_ctrl;
519         case ddrpll_clk:
520                 return &slcr_base->ddr_pll_ctrl;
521         case iopll_clk:
522                 return &slcr_base->io_pll_ctrl;
523         default:
524                 return &slcr_base->io_pll_ctrl;
525         }
526 }
527
528 /* API */
529 /**
530  * zynq_clk_early_init() - Early init for the clock framework
531  *
532  * This function is called from before relocation and sets up the CPU clock
533  * frequency in the global data struct.
534  */
535 void zynq_clk_early_init(void)
536 {
537         u32 reg = readl(&slcr_base->arm_clk_ctrl);
538         u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
539         u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
540         enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
541         u32 *pllreg = clkid_2_register(parent);
542         unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
543
544         if (!div)
545                 div = 1;
546
547         gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
548 }
549
550 /**
551  * get_uart_clk() - Get UART input frequency
552  * @dev_index:  UART ID
553  * Returns UART input clock frequency in Hz.
554  *
555  * Compared to zynq_clk_get_rate() this function is designed to work before
556  * relocation and can be called when the serial UART is set up.
557  */
558 unsigned long get_uart_clk(int dev_index)
559 {
560         u32 reg = readl(&slcr_base->uart_clk_ctrl);
561         u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
562         u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
563         enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
564         u32 *pllreg = clkid_2_register(parent);
565         unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
566
567         if (!div)
568                 div = 1;
569
570         return DIV_ROUND_CLOSEST(prate, div);
571 }
572
573 /**
574  * set_cpu_clk_info() - Initialize clock framework
575  * Always returns zero.
576  *
577  * This function is called from common code after relocation and sets up the
578  * clock framework. The framework must not be used before this function had been
579  * called.
580  */
581 int set_cpu_clk_info(void)
582 {
583         zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
584                               "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
585         zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
586                               "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
587         zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
588                               "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
589
590         init_ddr_clocks();
591         init_cpu_clocks();
592         init_periph_clocks();
593         init_aper_clocks();
594
595         return 0;
596 }
597
598 /**
599  * zynq_clk_get_rate() - Get clock rate
600  * @clk:        Clock identifier
601  * Returns the current clock rate of @clk on success or zero for an invalid
602  * clock id.
603  */
604 unsigned long zynq_clk_get_rate(enum zynq_clk clk)
605 {
606         if (clk < 0 || clk >= clk_max)
607                 return 0;
608
609         return clks[clk].frequency;
610 }
611
612 /**
613  * zynq_clk_set_rate() - Set clock rate
614  * @clk:        Clock identifier
615  * @rate:       Requested clock rate
616  * Passes on the return value from the clock's set_rate() function or negative
617  * errno.
618  */
619 int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
620 {
621         if (clk < 0 || clk >= clk_max)
622                 return -ENODEV;
623
624         if (clks[clk].ops.set_rate)
625                 return clks[clk].ops.set_rate(&clks[clk], rate);
626
627         return -ENXIO;
628 }
629
630 /**
631  * zynq_clk_get_name() - Get clock name
632  * @clk:        Clock identifier
633  * Returns the name of @clk.
634  */
635 const char *zynq_clk_get_name(enum zynq_clk clk)
636 {
637         return clks[clk].name;
638 }