Linux 3.9-rc4
[linux-2.6/cjktty.git] / drivers / clk / clk-prima2.c
blobf8e9d0c27be27252f53aeb0ecec904c9caabc99a
1 /*
2 * Clock tree for CSR SiRFprimaII
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
7 */
9 #include <linux/module.h>
10 #include <linux/bitops.h>
11 #include <linux/io.h>
12 #include <linux/clk.h>
13 #include <linux/clkdev.h>
14 #include <linux/clk-provider.h>
15 #include <linux/of_address.h>
16 #include <linux/syscore_ops.h>
18 #define SIRFSOC_CLKC_CLK_EN0 0x0000
19 #define SIRFSOC_CLKC_CLK_EN1 0x0004
20 #define SIRFSOC_CLKC_REF_CFG 0x0014
21 #define SIRFSOC_CLKC_CPU_CFG 0x0018
22 #define SIRFSOC_CLKC_MEM_CFG 0x001c
23 #define SIRFSOC_CLKC_SYS_CFG 0x0020
24 #define SIRFSOC_CLKC_IO_CFG 0x0024
25 #define SIRFSOC_CLKC_DSP_CFG 0x0028
26 #define SIRFSOC_CLKC_GFX_CFG 0x002c
27 #define SIRFSOC_CLKC_MM_CFG 0x0030
28 #define SIRFSOC_CLKC_LCD_CFG 0x0034
29 #define SIRFSOC_CLKC_MMC_CFG 0x0038
30 #define SIRFSOC_CLKC_PLL1_CFG0 0x0040
31 #define SIRFSOC_CLKC_PLL2_CFG0 0x0044
32 #define SIRFSOC_CLKC_PLL3_CFG0 0x0048
33 #define SIRFSOC_CLKC_PLL1_CFG1 0x004c
34 #define SIRFSOC_CLKC_PLL2_CFG1 0x0050
35 #define SIRFSOC_CLKC_PLL3_CFG1 0x0054
36 #define SIRFSOC_CLKC_PLL1_CFG2 0x0058
37 #define SIRFSOC_CLKC_PLL2_CFG2 0x005c
38 #define SIRFSOC_CLKC_PLL3_CFG2 0x0060
39 #define SIRFSOC_USBPHY_PLL_CTRL 0x0008
40 #define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
41 #define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
42 #define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
44 static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
46 #define KHZ 1000
47 #define MHZ (KHZ * KHZ)
50 * SiRFprimaII clock controller
51 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
52 * - 3 standard configurable plls: pll1, pll2 & pll3
53 * - 2 exclusive plls: usb phy pll and sata phy pll
54 * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia,
55 * display and sdphy.
56 * Each clock domain can select its own clock source from five clock sources,
57 * X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source
58 * clock of the group clock.
59 * - dsp domain: gps, mf
60 * - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse
61 * - sys domain: security
64 struct clk_pll {
65 struct clk_hw hw;
66 unsigned short regofs; /* register offset */
69 #define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw)
71 struct clk_dmn {
72 struct clk_hw hw;
73 signed char enable_bit; /* enable bit: 0 ~ 63 */
74 unsigned short regofs; /* register offset */
77 #define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw)
79 struct clk_std {
80 struct clk_hw hw;
81 signed char enable_bit; /* enable bit: 0 ~ 63 */
84 #define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
86 static int std_clk_is_enabled(struct clk_hw *hw);
87 static int std_clk_enable(struct clk_hw *hw);
88 static void std_clk_disable(struct clk_hw *hw);
90 static inline unsigned long clkc_readl(unsigned reg)
92 return readl(sirfsoc_clk_vbase + reg);
95 static inline void clkc_writel(u32 val, unsigned reg)
97 writel(val, sirfsoc_clk_vbase + reg);
101 * std pll
104 static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
105 unsigned long parent_rate)
107 unsigned long fin = parent_rate;
108 struct clk_pll *clk = to_pllclk(hw);
109 u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 -
110 SIRFSOC_CLKC_PLL1_CFG0;
112 if (clkc_readl(regcfg2) & BIT(2)) {
113 /* pll bypass mode */
114 return fin;
115 } else {
116 /* fout = fin * nf / nr / od */
117 u32 cfg0 = clkc_readl(clk->regofs);
118 u32 nf = (cfg0 & (BIT(13) - 1)) + 1;
119 u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1;
120 u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1;
121 WARN_ON(fin % MHZ);
122 return fin / MHZ * nf / nr / od * MHZ;
126 static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
127 unsigned long *parent_rate)
129 unsigned long fin, nf, nr, od;
132 * fout = fin * nf / (nr * od);
133 * set od = 1, nr = fin/MHz, so fout = nf * MHz
135 rate = rate - rate % MHZ;
137 nf = rate / MHZ;
138 if (nf > BIT(13))
139 nf = BIT(13);
140 if (nf < 1)
141 nf = 1;
143 fin = *parent_rate;
145 nr = fin / MHZ;
146 if (nr > BIT(6))
147 nr = BIT(6);
148 od = 1;
150 return fin * nf / (nr * od);
153 static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
154 unsigned long parent_rate)
156 struct clk_pll *clk = to_pllclk(hw);
157 unsigned long fin, nf, nr, od, reg;
160 * fout = fin * nf / (nr * od);
161 * set od = 1, nr = fin/MHz, so fout = nf * MHz
164 nf = rate / MHZ;
165 if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1))
166 return -EINVAL;
168 fin = parent_rate;
169 BUG_ON(fin < MHZ);
171 nr = fin / MHZ;
172 BUG_ON((fin % MHZ) || nr > BIT(6));
174 od = 1;
176 reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19);
177 clkc_writel(reg, clk->regofs);
179 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0;
180 clkc_writel((nf >> 1) - 1, reg);
182 reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0;
183 while (!(clkc_readl(reg) & BIT(6)))
184 cpu_relax();
186 return 0;
189 static struct clk_ops std_pll_ops = {
190 .recalc_rate = pll_clk_recalc_rate,
191 .round_rate = pll_clk_round_rate,
192 .set_rate = pll_clk_set_rate,
195 static const char *pll_clk_parents[] = {
196 "osc",
199 static struct clk_init_data clk_pll1_init = {
200 .name = "pll1",
201 .ops = &std_pll_ops,
202 .parent_names = pll_clk_parents,
203 .num_parents = ARRAY_SIZE(pll_clk_parents),
206 static struct clk_init_data clk_pll2_init = {
207 .name = "pll2",
208 .ops = &std_pll_ops,
209 .parent_names = pll_clk_parents,
210 .num_parents = ARRAY_SIZE(pll_clk_parents),
213 static struct clk_init_data clk_pll3_init = {
214 .name = "pll3",
215 .ops = &std_pll_ops,
216 .parent_names = pll_clk_parents,
217 .num_parents = ARRAY_SIZE(pll_clk_parents),
220 static struct clk_pll clk_pll1 = {
221 .regofs = SIRFSOC_CLKC_PLL1_CFG0,
222 .hw = {
223 .init = &clk_pll1_init,
227 static struct clk_pll clk_pll2 = {
228 .regofs = SIRFSOC_CLKC_PLL2_CFG0,
229 .hw = {
230 .init = &clk_pll2_init,
234 static struct clk_pll clk_pll3 = {
235 .regofs = SIRFSOC_CLKC_PLL3_CFG0,
236 .hw = {
237 .init = &clk_pll3_init,
242 * usb uses specified pll
245 static int usb_pll_clk_enable(struct clk_hw *hw)
247 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
248 reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
249 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
250 while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) &
251 SIRFSOC_USBPHY_PLL_LOCK))
252 cpu_relax();
254 return 0;
257 static void usb_pll_clk_disable(struct clk_hw *clk)
259 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
260 reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS);
261 writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
264 static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
266 u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL);
267 return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ;
270 static struct clk_ops usb_pll_ops = {
271 .enable = usb_pll_clk_enable,
272 .disable = usb_pll_clk_disable,
273 .recalc_rate = usb_pll_clk_recalc_rate,
276 static struct clk_init_data clk_usb_pll_init = {
277 .name = "usb_pll",
278 .ops = &usb_pll_ops,
279 .parent_names = pll_clk_parents,
280 .num_parents = ARRAY_SIZE(pll_clk_parents),
283 static struct clk_hw usb_pll_clk_hw = {
284 .init = &clk_usb_pll_init,
288 * clock domains - cpu, mem, sys/io, dsp, gfx
291 static const char *dmn_clk_parents[] = {
292 "rtc",
293 "osc",
294 "pll1",
295 "pll2",
296 "pll3",
299 static u8 dmn_clk_get_parent(struct clk_hw *hw)
301 struct clk_dmn *clk = to_dmnclk(hw);
302 u32 cfg = clkc_readl(clk->regofs);
304 /* parent of io domain can only be pll3 */
305 if (strcmp(hw->init->name, "io") == 0)
306 return 4;
308 WARN_ON((cfg & (BIT(3) - 1)) > 4);
310 return cfg & (BIT(3) - 1);
313 static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent)
315 struct clk_dmn *clk = to_dmnclk(hw);
316 u32 cfg = clkc_readl(clk->regofs);
318 /* parent of io domain can only be pll3 */
319 if (strcmp(hw->init->name, "io") == 0)
320 return -EINVAL;
322 cfg &= ~(BIT(3) - 1);
323 clkc_writel(cfg | parent, clk->regofs);
324 /* BIT(3) - switching status: 1 - busy, 0 - done */
325 while (clkc_readl(clk->regofs) & BIT(3))
326 cpu_relax();
328 return 0;
331 static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw,
332 unsigned long parent_rate)
335 unsigned long fin = parent_rate;
336 struct clk_dmn *clk = to_dmnclk(hw);
338 u32 cfg = clkc_readl(clk->regofs);
340 if (cfg & BIT(24)) {
341 /* fcd bypass mode */
342 return fin;
343 } else {
345 * wait count: bit[19:16], hold count: bit[23:20]
347 u32 wait = (cfg >> 16) & (BIT(4) - 1);
348 u32 hold = (cfg >> 20) & (BIT(4) - 1);
350 return fin / (wait + hold + 2);
354 static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate,
355 unsigned long *parent_rate)
357 unsigned long fin;
358 unsigned ratio, wait, hold;
359 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
361 fin = *parent_rate;
362 ratio = fin / rate;
364 if (ratio < 2)
365 ratio = 2;
366 if (ratio > BIT(bits + 1))
367 ratio = BIT(bits + 1);
369 wait = (ratio >> 1) - 1;
370 hold = ratio - wait - 2;
372 return fin / (wait + hold + 2);
375 static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
376 unsigned long parent_rate)
378 struct clk_dmn *clk = to_dmnclk(hw);
379 unsigned long fin;
380 unsigned ratio, wait, hold, reg;
381 unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4;
383 fin = parent_rate;
384 ratio = fin / rate;
386 if (unlikely(ratio < 2 || ratio > BIT(bits + 1)))
387 return -EINVAL;
389 WARN_ON(fin % rate);
391 wait = (ratio >> 1) - 1;
392 hold = ratio - wait - 2;
394 reg = clkc_readl(clk->regofs);
395 reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20));
396 reg |= (wait << 16) | (hold << 20) | BIT(25);
397 clkc_writel(reg, clk->regofs);
399 /* waiting FCD been effective */
400 while (clkc_readl(clk->regofs) & BIT(25))
401 cpu_relax();
403 return 0;
406 static struct clk_ops msi_ops = {
407 .set_rate = dmn_clk_set_rate,
408 .round_rate = dmn_clk_round_rate,
409 .recalc_rate = dmn_clk_recalc_rate,
410 .set_parent = dmn_clk_set_parent,
411 .get_parent = dmn_clk_get_parent,
414 static struct clk_init_data clk_mem_init = {
415 .name = "mem",
416 .ops = &msi_ops,
417 .parent_names = dmn_clk_parents,
418 .num_parents = ARRAY_SIZE(dmn_clk_parents),
421 static struct clk_dmn clk_mem = {
422 .regofs = SIRFSOC_CLKC_MEM_CFG,
423 .hw = {
424 .init = &clk_mem_init,
428 static struct clk_init_data clk_sys_init = {
429 .name = "sys",
430 .ops = &msi_ops,
431 .parent_names = dmn_clk_parents,
432 .num_parents = ARRAY_SIZE(dmn_clk_parents),
433 .flags = CLK_SET_RATE_GATE,
436 static struct clk_dmn clk_sys = {
437 .regofs = SIRFSOC_CLKC_SYS_CFG,
438 .hw = {
439 .init = &clk_sys_init,
443 static struct clk_init_data clk_io_init = {
444 .name = "io",
445 .ops = &msi_ops,
446 .parent_names = dmn_clk_parents,
447 .num_parents = ARRAY_SIZE(dmn_clk_parents),
450 static struct clk_dmn clk_io = {
451 .regofs = SIRFSOC_CLKC_IO_CFG,
452 .hw = {
453 .init = &clk_io_init,
457 static struct clk_ops cpu_ops = {
458 .set_parent = dmn_clk_set_parent,
459 .get_parent = dmn_clk_get_parent,
462 static struct clk_init_data clk_cpu_init = {
463 .name = "cpu",
464 .ops = &cpu_ops,
465 .parent_names = dmn_clk_parents,
466 .num_parents = ARRAY_SIZE(dmn_clk_parents),
467 .flags = CLK_SET_RATE_PARENT,
470 static struct clk_dmn clk_cpu = {
471 .regofs = SIRFSOC_CLKC_CPU_CFG,
472 .hw = {
473 .init = &clk_cpu_init,
477 static struct clk_ops dmn_ops = {
478 .is_enabled = std_clk_is_enabled,
479 .enable = std_clk_enable,
480 .disable = std_clk_disable,
481 .set_rate = dmn_clk_set_rate,
482 .round_rate = dmn_clk_round_rate,
483 .recalc_rate = dmn_clk_recalc_rate,
484 .set_parent = dmn_clk_set_parent,
485 .get_parent = dmn_clk_get_parent,
488 /* dsp, gfx, mm, lcd and vpp domain */
490 static struct clk_init_data clk_dsp_init = {
491 .name = "dsp",
492 .ops = &dmn_ops,
493 .parent_names = dmn_clk_parents,
494 .num_parents = ARRAY_SIZE(dmn_clk_parents),
497 static struct clk_dmn clk_dsp = {
498 .regofs = SIRFSOC_CLKC_DSP_CFG,
499 .enable_bit = 0,
500 .hw = {
501 .init = &clk_dsp_init,
505 static struct clk_init_data clk_gfx_init = {
506 .name = "gfx",
507 .ops = &dmn_ops,
508 .parent_names = dmn_clk_parents,
509 .num_parents = ARRAY_SIZE(dmn_clk_parents),
512 static struct clk_dmn clk_gfx = {
513 .regofs = SIRFSOC_CLKC_GFX_CFG,
514 .enable_bit = 8,
515 .hw = {
516 .init = &clk_gfx_init,
520 static struct clk_init_data clk_mm_init = {
521 .name = "mm",
522 .ops = &dmn_ops,
523 .parent_names = dmn_clk_parents,
524 .num_parents = ARRAY_SIZE(dmn_clk_parents),
527 static struct clk_dmn clk_mm = {
528 .regofs = SIRFSOC_CLKC_MM_CFG,
529 .enable_bit = 9,
530 .hw = {
531 .init = &clk_mm_init,
535 static struct clk_init_data clk_lcd_init = {
536 .name = "lcd",
537 .ops = &dmn_ops,
538 .parent_names = dmn_clk_parents,
539 .num_parents = ARRAY_SIZE(dmn_clk_parents),
542 static struct clk_dmn clk_lcd = {
543 .regofs = SIRFSOC_CLKC_LCD_CFG,
544 .enable_bit = 10,
545 .hw = {
546 .init = &clk_lcd_init,
550 static struct clk_init_data clk_vpp_init = {
551 .name = "vpp",
552 .ops = &dmn_ops,
553 .parent_names = dmn_clk_parents,
554 .num_parents = ARRAY_SIZE(dmn_clk_parents),
557 static struct clk_dmn clk_vpp = {
558 .regofs = SIRFSOC_CLKC_LCD_CFG,
559 .enable_bit = 11,
560 .hw = {
561 .init = &clk_vpp_init,
565 static struct clk_init_data clk_mmc01_init = {
566 .name = "mmc01",
567 .ops = &dmn_ops,
568 .parent_names = dmn_clk_parents,
569 .num_parents = ARRAY_SIZE(dmn_clk_parents),
572 static struct clk_dmn clk_mmc01 = {
573 .regofs = SIRFSOC_CLKC_MMC_CFG,
574 .enable_bit = 59,
575 .hw = {
576 .init = &clk_mmc01_init,
580 static struct clk_init_data clk_mmc23_init = {
581 .name = "mmc23",
582 .ops = &dmn_ops,
583 .parent_names = dmn_clk_parents,
584 .num_parents = ARRAY_SIZE(dmn_clk_parents),
587 static struct clk_dmn clk_mmc23 = {
588 .regofs = SIRFSOC_CLKC_MMC_CFG,
589 .enable_bit = 60,
590 .hw = {
591 .init = &clk_mmc23_init,
595 static struct clk_init_data clk_mmc45_init = {
596 .name = "mmc45",
597 .ops = &dmn_ops,
598 .parent_names = dmn_clk_parents,
599 .num_parents = ARRAY_SIZE(dmn_clk_parents),
602 static struct clk_dmn clk_mmc45 = {
603 .regofs = SIRFSOC_CLKC_MMC_CFG,
604 .enable_bit = 61,
605 .hw = {
606 .init = &clk_mmc45_init,
611 * peripheral controllers in io domain
614 static int std_clk_is_enabled(struct clk_hw *hw)
616 u32 reg;
617 int bit;
618 struct clk_std *clk = to_stdclk(hw);
620 bit = clk->enable_bit % 32;
621 reg = clk->enable_bit / 32;
622 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
624 return !!(clkc_readl(reg) & BIT(bit));
627 static int std_clk_enable(struct clk_hw *hw)
629 u32 val, reg;
630 int bit;
631 struct clk_std *clk = to_stdclk(hw);
633 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
635 bit = clk->enable_bit % 32;
636 reg = clk->enable_bit / 32;
637 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
639 val = clkc_readl(reg) | BIT(bit);
640 clkc_writel(val, reg);
641 return 0;
644 static void std_clk_disable(struct clk_hw *hw)
646 u32 val, reg;
647 int bit;
648 struct clk_std *clk = to_stdclk(hw);
650 BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63);
652 bit = clk->enable_bit % 32;
653 reg = clk->enable_bit / 32;
654 reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg);
656 val = clkc_readl(reg) & ~BIT(bit);
657 clkc_writel(val, reg);
660 static const char *std_clk_io_parents[] = {
661 "io",
664 static struct clk_ops ios_ops = {
665 .is_enabled = std_clk_is_enabled,
666 .enable = std_clk_enable,
667 .disable = std_clk_disable,
670 static struct clk_init_data clk_dmac0_init = {
671 .name = "dmac0",
672 .ops = &ios_ops,
673 .parent_names = std_clk_io_parents,
674 .num_parents = ARRAY_SIZE(std_clk_io_parents),
677 static struct clk_std clk_dmac0 = {
678 .enable_bit = 32,
679 .hw = {
680 .init = &clk_dmac0_init,
684 static struct clk_init_data clk_dmac1_init = {
685 .name = "dmac1",
686 .ops = &ios_ops,
687 .parent_names = std_clk_io_parents,
688 .num_parents = ARRAY_SIZE(std_clk_io_parents),
691 static struct clk_std clk_dmac1 = {
692 .enable_bit = 33,
693 .hw = {
694 .init = &clk_dmac1_init,
698 static struct clk_init_data clk_nand_init = {
699 .name = "nand",
700 .ops = &ios_ops,
701 .parent_names = std_clk_io_parents,
702 .num_parents = ARRAY_SIZE(std_clk_io_parents),
705 static struct clk_std clk_nand = {
706 .enable_bit = 34,
707 .hw = {
708 .init = &clk_nand_init,
712 static struct clk_init_data clk_audio_init = {
713 .name = "audio",
714 .ops = &ios_ops,
715 .parent_names = std_clk_io_parents,
716 .num_parents = ARRAY_SIZE(std_clk_io_parents),
719 static struct clk_std clk_audio = {
720 .enable_bit = 35,
721 .hw = {
722 .init = &clk_audio_init,
726 static struct clk_init_data clk_uart0_init = {
727 .name = "uart0",
728 .ops = &ios_ops,
729 .parent_names = std_clk_io_parents,
730 .num_parents = ARRAY_SIZE(std_clk_io_parents),
733 static struct clk_std clk_uart0 = {
734 .enable_bit = 36,
735 .hw = {
736 .init = &clk_uart0_init,
740 static struct clk_init_data clk_uart1_init = {
741 .name = "uart1",
742 .ops = &ios_ops,
743 .parent_names = std_clk_io_parents,
744 .num_parents = ARRAY_SIZE(std_clk_io_parents),
747 static struct clk_std clk_uart1 = {
748 .enable_bit = 37,
749 .hw = {
750 .init = &clk_uart1_init,
754 static struct clk_init_data clk_uart2_init = {
755 .name = "uart2",
756 .ops = &ios_ops,
757 .parent_names = std_clk_io_parents,
758 .num_parents = ARRAY_SIZE(std_clk_io_parents),
761 static struct clk_std clk_uart2 = {
762 .enable_bit = 38,
763 .hw = {
764 .init = &clk_uart2_init,
768 static struct clk_init_data clk_usp0_init = {
769 .name = "usp0",
770 .ops = &ios_ops,
771 .parent_names = std_clk_io_parents,
772 .num_parents = ARRAY_SIZE(std_clk_io_parents),
775 static struct clk_std clk_usp0 = {
776 .enable_bit = 39,
777 .hw = {
778 .init = &clk_usp0_init,
782 static struct clk_init_data clk_usp1_init = {
783 .name = "usp1",
784 .ops = &ios_ops,
785 .parent_names = std_clk_io_parents,
786 .num_parents = ARRAY_SIZE(std_clk_io_parents),
789 static struct clk_std clk_usp1 = {
790 .enable_bit = 40,
791 .hw = {
792 .init = &clk_usp1_init,
796 static struct clk_init_data clk_usp2_init = {
797 .name = "usp2",
798 .ops = &ios_ops,
799 .parent_names = std_clk_io_parents,
800 .num_parents = ARRAY_SIZE(std_clk_io_parents),
803 static struct clk_std clk_usp2 = {
804 .enable_bit = 41,
805 .hw = {
806 .init = &clk_usp2_init,
810 static struct clk_init_data clk_vip_init = {
811 .name = "vip",
812 .ops = &ios_ops,
813 .parent_names = std_clk_io_parents,
814 .num_parents = ARRAY_SIZE(std_clk_io_parents),
817 static struct clk_std clk_vip = {
818 .enable_bit = 42,
819 .hw = {
820 .init = &clk_vip_init,
824 static struct clk_init_data clk_spi0_init = {
825 .name = "spi0",
826 .ops = &ios_ops,
827 .parent_names = std_clk_io_parents,
828 .num_parents = ARRAY_SIZE(std_clk_io_parents),
831 static struct clk_std clk_spi0 = {
832 .enable_bit = 43,
833 .hw = {
834 .init = &clk_spi0_init,
838 static struct clk_init_data clk_spi1_init = {
839 .name = "spi1",
840 .ops = &ios_ops,
841 .parent_names = std_clk_io_parents,
842 .num_parents = ARRAY_SIZE(std_clk_io_parents),
845 static struct clk_std clk_spi1 = {
846 .enable_bit = 44,
847 .hw = {
848 .init = &clk_spi1_init,
852 static struct clk_init_data clk_tsc_init = {
853 .name = "tsc",
854 .ops = &ios_ops,
855 .parent_names = std_clk_io_parents,
856 .num_parents = ARRAY_SIZE(std_clk_io_parents),
859 static struct clk_std clk_tsc = {
860 .enable_bit = 45,
861 .hw = {
862 .init = &clk_tsc_init,
866 static struct clk_init_data clk_i2c0_init = {
867 .name = "i2c0",
868 .ops = &ios_ops,
869 .parent_names = std_clk_io_parents,
870 .num_parents = ARRAY_SIZE(std_clk_io_parents),
873 static struct clk_std clk_i2c0 = {
874 .enable_bit = 46,
875 .hw = {
876 .init = &clk_i2c0_init,
880 static struct clk_init_data clk_i2c1_init = {
881 .name = "i2c1",
882 .ops = &ios_ops,
883 .parent_names = std_clk_io_parents,
884 .num_parents = ARRAY_SIZE(std_clk_io_parents),
887 static struct clk_std clk_i2c1 = {
888 .enable_bit = 47,
889 .hw = {
890 .init = &clk_i2c1_init,
894 static struct clk_init_data clk_pwmc_init = {
895 .name = "pwmc",
896 .ops = &ios_ops,
897 .parent_names = std_clk_io_parents,
898 .num_parents = ARRAY_SIZE(std_clk_io_parents),
901 static struct clk_std clk_pwmc = {
902 .enable_bit = 48,
903 .hw = {
904 .init = &clk_pwmc_init,
908 static struct clk_init_data clk_efuse_init = {
909 .name = "efuse",
910 .ops = &ios_ops,
911 .parent_names = std_clk_io_parents,
912 .num_parents = ARRAY_SIZE(std_clk_io_parents),
915 static struct clk_std clk_efuse = {
916 .enable_bit = 49,
917 .hw = {
918 .init = &clk_efuse_init,
922 static struct clk_init_data clk_pulse_init = {
923 .name = "pulse",
924 .ops = &ios_ops,
925 .parent_names = std_clk_io_parents,
926 .num_parents = ARRAY_SIZE(std_clk_io_parents),
929 static struct clk_std clk_pulse = {
930 .enable_bit = 50,
931 .hw = {
932 .init = &clk_pulse_init,
936 static const char *std_clk_dsp_parents[] = {
937 "dsp",
940 static struct clk_init_data clk_gps_init = {
941 .name = "gps",
942 .ops = &ios_ops,
943 .parent_names = std_clk_dsp_parents,
944 .num_parents = ARRAY_SIZE(std_clk_dsp_parents),
947 static struct clk_std clk_gps = {
948 .enable_bit = 1,
949 .hw = {
950 .init = &clk_gps_init,
954 static struct clk_init_data clk_mf_init = {
955 .name = "mf",
956 .ops = &ios_ops,
957 .parent_names = std_clk_io_parents,
958 .num_parents = ARRAY_SIZE(std_clk_io_parents),
961 static struct clk_std clk_mf = {
962 .enable_bit = 2,
963 .hw = {
964 .init = &clk_mf_init,
968 static const char *std_clk_sys_parents[] = {
969 "sys",
972 static struct clk_init_data clk_security_init = {
973 .name = "mf",
974 .ops = &ios_ops,
975 .parent_names = std_clk_sys_parents,
976 .num_parents = ARRAY_SIZE(std_clk_sys_parents),
979 static struct clk_std clk_security = {
980 .enable_bit = 19,
981 .hw = {
982 .init = &clk_security_init,
986 static const char *std_clk_usb_parents[] = {
987 "usb_pll",
990 static struct clk_init_data clk_usb0_init = {
991 .name = "usb0",
992 .ops = &ios_ops,
993 .parent_names = std_clk_usb_parents,
994 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
997 static struct clk_std clk_usb0 = {
998 .enable_bit = 16,
999 .hw = {
1000 .init = &clk_usb0_init,
1004 static struct clk_init_data clk_usb1_init = {
1005 .name = "usb1",
1006 .ops = &ios_ops,
1007 .parent_names = std_clk_usb_parents,
1008 .num_parents = ARRAY_SIZE(std_clk_usb_parents),
1011 static struct clk_std clk_usb1 = {
1012 .enable_bit = 17,
1013 .hw = {
1014 .init = &clk_usb1_init,
1018 static struct of_device_id clkc_ids[] = {
1019 { .compatible = "sirf,prima2-clkc" },
1023 static struct of_device_id rsc_ids[] = {
1024 { .compatible = "sirf,prima2-rsc" },
1028 enum prima2_clk_index {
1029 /* 0 1 2 3 4 5 6 7 8 9 */
1030 rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
1031 mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
1032 spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
1033 usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
1034 usb0, usb1, maxclk,
1037 static __initdata struct clk_hw* prima2_clk_hw_array[maxclk] = {
1038 NULL, /* dummy */
1039 NULL,
1040 &clk_pll1.hw,
1041 &clk_pll2.hw,
1042 &clk_pll3.hw,
1043 &clk_mem.hw,
1044 &clk_sys.hw,
1045 &clk_security.hw,
1046 &clk_dsp.hw,
1047 &clk_gps.hw,
1048 &clk_mf.hw,
1049 &clk_io.hw,
1050 &clk_cpu.hw,
1051 &clk_uart0.hw,
1052 &clk_uart1.hw,
1053 &clk_uart2.hw,
1054 &clk_tsc.hw,
1055 &clk_i2c0.hw,
1056 &clk_i2c1.hw,
1057 &clk_spi0.hw,
1058 &clk_spi1.hw,
1059 &clk_pwmc.hw,
1060 &clk_efuse.hw,
1061 &clk_pulse.hw,
1062 &clk_dmac0.hw,
1063 &clk_dmac1.hw,
1064 &clk_nand.hw,
1065 &clk_audio.hw,
1066 &clk_usp0.hw,
1067 &clk_usp1.hw,
1068 &clk_usp2.hw,
1069 &clk_vip.hw,
1070 &clk_gfx.hw,
1071 &clk_mm.hw,
1072 &clk_lcd.hw,
1073 &clk_vpp.hw,
1074 &clk_mmc01.hw,
1075 &clk_mmc23.hw,
1076 &clk_mmc45.hw,
1077 &usb_pll_clk_hw,
1078 &clk_usb0.hw,
1079 &clk_usb1.hw,
1082 static struct clk *prima2_clks[maxclk];
1083 static struct clk_onecell_data clk_data;
1085 void __init sirfsoc_of_clk_init(void)
1087 struct device_node *np;
1088 int i;
1090 np = of_find_matching_node(NULL, rsc_ids);
1091 if (!np)
1092 panic("unable to find compatible rsc node in dtb\n");
1094 sirfsoc_rsc_vbase = of_iomap(np, 0);
1095 if (!sirfsoc_rsc_vbase)
1096 panic("unable to map rsc registers\n");
1098 of_node_put(np);
1100 np = of_find_matching_node(NULL, clkc_ids);
1101 if (!np)
1102 return;
1104 sirfsoc_clk_vbase = of_iomap(np, 0);
1105 if (!sirfsoc_clk_vbase)
1106 panic("unable to map clkc registers\n");
1108 /* These are always available (RTC and 26MHz OSC)*/
1109 prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
1110 CLK_IS_ROOT, 32768);
1111 prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL,
1112 CLK_IS_ROOT, 26000000);
1114 for (i = pll1; i < maxclk; i++) {
1115 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
1116 BUG_ON(!prima2_clks[i]);
1118 clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
1119 clk_register_clkdev(prima2_clks[io], NULL, "io");
1120 clk_register_clkdev(prima2_clks[mem], NULL, "mem");
1122 clk_data.clks = prima2_clks;
1123 clk_data.clk_num = maxclk;
1125 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);