aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBarry Song <Baohua.Song@csr.com>2014-01-15 01:11:34 -0500
committerMike Turquette <mturquette@linaro.org>2014-01-16 15:00:53 -0500
commit7bf21bc81f28cefa61250cfd9de2c884bbe1f3db (patch)
tree4ebe55e17d9a341ae339deb92bca1a83d5a129fc
parent5d2043fbe4ddc6cc16ba71b49c2c13f4cb2fe932 (diff)
clk: sirf: re-arch to make the codes support both prima2 and atlas6
sirfprima2 and sirfatlas6 are two different SoCs in CSR SiRF series. for prima2 and atlas6, there are many shared clocks but there are still some different register layout and hardware clocks, then result in different clock table. here we re-arch the driver to 1. clk-common.c provides common clocks for prima2 and atlas6, 2. clk-prima2.h describles registers of prima2 and clk-prima2.c provides prima2 specific clocks and clock table. 3. clk-atlas6.h describles registers of atlas6 and clk-atlas6.c provides atlas6 specific clocks and clock table. 4. clk.h and clk.c expose external interfaces and provide uniform entry for both prima2 and atlas6. so both prima2 and atlas6 will get support by drivers/clk/sirf. Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Rongjun Ying <Rongjun.Ying@csr.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/sirf/Makefile5
-rw-r--r--drivers/clk/sirf/atlas6.h31
-rw-r--r--drivers/clk/sirf/clk-atlas6.c152
-rw-r--r--drivers/clk/sirf/clk-common.c (renamed from drivers/clk/clk-prima2.c)264
-rw-r--r--drivers/clk/sirf/clk-prima2.c151
-rw-r--r--drivers/clk/sirf/prima2.h25
7 files changed, 458 insertions, 172 deletions
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 6705d9a82cbc..fcaa5b8d4e62 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
21obj-$(CONFIG_PLAT_SPEAR) += spear/ 21obj-$(CONFIG_PLAT_SPEAR) += spear/
22obj-$(CONFIG_ARCH_U300) += clk-u300.o 22obj-$(CONFIG_ARCH_U300) += clk-u300.o
23obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ 23obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
24obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o
25obj-$(CONFIG_PLAT_ORION) += mvebu/ 24obj-$(CONFIG_PLAT_ORION) += mvebu/
26ifeq ($(CONFIG_COMMON_CLK), y) 25ifeq ($(CONFIG_COMMON_CLK), y)
27obj-$(CONFIG_ARCH_MMP) += mmp/ 26obj-$(CONFIG_ARCH_MMP) += mmp/
@@ -31,6 +30,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
31obj-$(CONFIG_ARCH_SUNXI) += sunxi/ 30obj-$(CONFIG_ARCH_SUNXI) += sunxi/
32obj-$(CONFIG_ARCH_U8500) += ux500/ 31obj-$(CONFIG_ARCH_U8500) += ux500/
33obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 32obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
33obj-$(CONFIG_ARCH_SIRF) += sirf/
34obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 34obj-$(CONFIG_ARCH_ZYNQ) += zynq/
35obj-$(CONFIG_ARCH_TEGRA) += tegra/ 35obj-$(CONFIG_ARCH_TEGRA) += tegra/
36obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ 36obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
diff --git a/drivers/clk/sirf/Makefile b/drivers/clk/sirf/Makefile
new file mode 100644
index 000000000000..36b8e203f6e7
--- /dev/null
+++ b/drivers/clk/sirf/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for sirf specific clk
3#
4
5obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o
diff --git a/drivers/clk/sirf/atlas6.h b/drivers/clk/sirf/atlas6.h
new file mode 100644
index 000000000000..376217f3bf8f
--- /dev/null
+++ b/drivers/clk/sirf/atlas6.h
@@ -0,0 +1,31 @@
1#define SIRFSOC_CLKC_CLK_EN0 0x0000
2#define SIRFSOC_CLKC_CLK_EN1 0x0004
3#define SIRFSOC_CLKC_REF_CFG 0x0020
4#define SIRFSOC_CLKC_CPU_CFG 0x0024
5#define SIRFSOC_CLKC_MEM_CFG 0x0028
6#define SIRFSOC_CLKC_MEMDIV_CFG 0x002C
7#define SIRFSOC_CLKC_SYS_CFG 0x0030
8#define SIRFSOC_CLKC_IO_CFG 0x0034
9#define SIRFSOC_CLKC_DSP_CFG 0x0038
10#define SIRFSOC_CLKC_GFX_CFG 0x003c
11#define SIRFSOC_CLKC_MM_CFG 0x0040
12#define SIRFSOC_CLKC_GFX2D_CFG 0x0040
13#define SIRFSOC_CLKC_LCD_CFG 0x0044
14#define SIRFSOC_CLKC_MMC01_CFG 0x0048
15#define SIRFSOC_CLKC_MMC23_CFG 0x004C
16#define SIRFSOC_CLKC_MMC45_CFG 0x0050
17#define SIRFSOC_CLKC_NAND_CFG 0x0054
18#define SIRFSOC_CLKC_NANDDIV_CFG 0x0058
19#define SIRFSOC_CLKC_PLL1_CFG0 0x0080
20#define SIRFSOC_CLKC_PLL2_CFG0 0x0084
21#define SIRFSOC_CLKC_PLL3_CFG0 0x0088
22#define SIRFSOC_CLKC_PLL1_CFG1 0x008c
23#define SIRFSOC_CLKC_PLL2_CFG1 0x0090
24#define SIRFSOC_CLKC_PLL3_CFG1 0x0094
25#define SIRFSOC_CLKC_PLL1_CFG2 0x0098
26#define SIRFSOC_CLKC_PLL2_CFG2 0x009c
27#define SIRFSOC_CLKC_PLL3_CFG2 0x00A0
28#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
29#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
30#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
31#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
diff --git a/drivers/clk/sirf/clk-atlas6.c b/drivers/clk/sirf/clk-atlas6.c
new file mode 100644
index 000000000000..f9f4a15a64ab
--- /dev/null
+++ b/drivers/clk/sirf/clk-atlas6.c
@@ -0,0 +1,152 @@
1/*
2 * Clock tree for CSR SiRFatlasVI
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
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>
17
18#include "atlas6.h"
19#include "clk-common.c"
20
21static struct clk_dmn clk_mmc01 = {
22 .regofs = SIRFSOC_CLKC_MMC01_CFG,
23 .enable_bit = 59,
24 .hw = {
25 .init = &clk_mmc01_init,
26 },
27};
28
29static struct clk_dmn clk_mmc23 = {
30 .regofs = SIRFSOC_CLKC_MMC23_CFG,
31 .enable_bit = 60,
32 .hw = {
33 .init = &clk_mmc23_init,
34 },
35};
36
37static struct clk_dmn clk_mmc45 = {
38 .regofs = SIRFSOC_CLKC_MMC45_CFG,
39 .enable_bit = 61,
40 .hw = {
41 .init = &clk_mmc45_init,
42 },
43};
44
45static struct clk_init_data clk_nand_init = {
46 .name = "nand",
47 .ops = &dmn_ops,
48 .parent_names = dmn_clk_parents,
49 .num_parents = ARRAY_SIZE(dmn_clk_parents),
50};
51
52static struct clk_dmn clk_nand = {
53 .regofs = SIRFSOC_CLKC_NAND_CFG,
54 .enable_bit = 34,
55 .hw = {
56 .init = &clk_nand_init,
57 },
58};
59
60enum atlas6_clk_index {
61 /* 0 1 2 3 4 5 6 7 8 9 */
62 rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
63 mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
64 spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
65 usp2, vip, gfx, gfx2d, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
66 usb0, usb1, cphif, maxclk,
67};
68
69static __initdata struct clk_hw *atlas6_clk_hw_array[maxclk] = {
70 NULL, /* dummy */
71 NULL,
72 &clk_pll1.hw,
73 &clk_pll2.hw,
74 &clk_pll3.hw,
75 &clk_mem.hw,
76 &clk_sys.hw,
77 &clk_security.hw,
78 &clk_dsp.hw,
79 &clk_gps.hw,
80 &clk_mf.hw,
81 &clk_io.hw,
82 &clk_cpu.hw,
83 &clk_uart0.hw,
84 &clk_uart1.hw,
85 &clk_uart2.hw,
86 &clk_tsc.hw,
87 &clk_i2c0.hw,
88 &clk_i2c1.hw,
89 &clk_spi0.hw,
90 &clk_spi1.hw,
91 &clk_pwmc.hw,
92 &clk_efuse.hw,
93 &clk_pulse.hw,
94 &clk_dmac0.hw,
95 &clk_dmac1.hw,
96 &clk_nand.hw,
97 &clk_audio.hw,
98 &clk_usp0.hw,
99 &clk_usp1.hw,
100 &clk_usp2.hw,
101 &clk_vip.hw,
102 &clk_gfx.hw,
103 &clk_gfx2d.hw,
104 &clk_lcd.hw,
105 &clk_vpp.hw,
106 &clk_mmc01.hw,
107 &clk_mmc23.hw,
108 &clk_mmc45.hw,
109 &usb_pll_clk_hw,
110 &clk_usb0.hw,
111 &clk_usb1.hw,
112 &clk_cphif.hw,
113};
114
115static struct clk *atlas6_clks[maxclk];
116
117static void __init atlas6_clk_init(struct device_node *np)
118{
119 struct device_node *rscnp;
120 int i;
121
122 rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
123 sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
124 if (!sirfsoc_rsc_vbase)
125 panic("unable to map rsc registers\n");
126 of_node_put(rscnp);
127
128 sirfsoc_clk_vbase = of_iomap(np, 0);
129 if (!sirfsoc_clk_vbase)
130 panic("unable to map clkc registers\n");
131
132 /* These are always available (RTC and 26MHz OSC)*/
133 atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
134 CLK_IS_ROOT, 32768);
135 atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
136 CLK_IS_ROOT, 26000000);
137
138 for (i = pll1; i < maxclk; i++) {
139 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
140 BUG_ON(!atlas6_clks[i]);
141 }
142 clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
143 clk_register_clkdev(atlas6_clks[io], NULL, "io");
144 clk_register_clkdev(atlas6_clks[mem], NULL, "mem");
145 clk_register_clkdev(atlas6_clks[mem], NULL, "osc");
146
147 clk_data.clks = atlas6_clks;
148 clk_data.clk_num = maxclk;
149
150 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
151}
152CLK_OF_DECLARE(atlas6_clk, "sirf,atlas6-clkc", atlas6_clk_init);
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/sirf/clk-common.c
index 6c15e3316137..7dde6a82f514 100644
--- a/drivers/clk/clk-prima2.c
+++ b/drivers/clk/sirf/clk-common.c
@@ -1,51 +1,18 @@
1/* 1/*
2 * Clock tree for CSR SiRFprimaII 2 * common clks module for all SiRF SoCs
3 * 3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 * 5 *
6 * Licensed under GPLv2 or later. 6 * Licensed under GPLv2 or later.
7 */ 7 */
8 8
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>
17
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)
43
44static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
45
46#define KHZ 1000 9#define KHZ 1000
47#define MHZ (KHZ * KHZ) 10#define MHZ (KHZ * KHZ)
48 11
12static void *sirfsoc_clk_vbase;
13static void *sirfsoc_rsc_vbase;
14static struct clk_onecell_data clk_data;
15
49/* 16/*
50 * SiRFprimaII clock controller 17 * SiRFprimaII clock controller
51 * - 2 oscillators: osc-26MHz, rtc-32.768KHz 18 * - 2 oscillators: osc-26MHz, rtc-32.768KHz
@@ -127,6 +94,7 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
127 unsigned long *parent_rate) 94 unsigned long *parent_rate)
128{ 95{
129 unsigned long fin, nf, nr, od; 96 unsigned long fin, nf, nr, od;
97 u64 dividend;
130 98
131 /* 99 /*
132 * fout = fin * nf / (nr * od); 100 * fout = fin * nf / (nr * od);
@@ -147,7 +115,10 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
147 nr = BIT(6); 115 nr = BIT(6);
148 od = 1; 116 od = 1;
149 117
150 return fin * nf / (nr * od); 118 dividend = (u64)fin * nf;
119 do_div(dividend, nr * od);
120
121 return (long)dividend;
151} 122}
152 123
153static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, 124static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -186,6 +157,30 @@ static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
186 return 0; 157 return 0;
187} 158}
188 159
160static long cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
161 unsigned long *parent_rate)
162{
163 /*
164 * SiRF SoC has not cpu clock control,
165 * So bypass to it's parent pll.
166 */
167 struct clk *parent_clk = clk_get_parent(hw->clk);
168 struct clk *pll_parent_clk = clk_get_parent(parent_clk);
169 unsigned long pll_parent_rate = clk_get_rate(pll_parent_clk);
170 return pll_clk_round_rate(__clk_get_hw(parent_clk), rate, &pll_parent_rate);
171}
172
173static unsigned long cpu_clk_recalc_rate(struct clk_hw *hw,
174 unsigned long parent_rate)
175{
176 /*
177 * SiRF SoC has not cpu clock control,
178 * So return the parent pll rate.
179 */
180 struct clk *parent_clk = clk_get_parent(hw->clk);
181 return __clk_get_rate(parent_clk);
182}
183
189static struct clk_ops std_pll_ops = { 184static struct clk_ops std_pll_ops = {
190 .recalc_rate = pll_clk_recalc_rate, 185 .recalc_rate = pll_clk_recalc_rate,
191 .round_rate = pll_clk_round_rate, 186 .round_rate = pll_clk_round_rate,
@@ -403,6 +398,42 @@ static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
403 return 0; 398 return 0;
404} 399}
405 400
401static int cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
402 unsigned long parent_rate)
403{
404 int ret1, ret2;
405 struct clk *cur_parent;
406
407 if (rate == clk_get_rate(clk_pll1.hw.clk)) {
408 ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
409 return ret1;
410 }
411
412 if (rate == clk_get_rate(clk_pll2.hw.clk)) {
413 ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
414 return ret1;
415 }
416
417 if (rate == clk_get_rate(clk_pll3.hw.clk)) {
418 ret1 = clk_set_parent(hw->clk, clk_pll3.hw.clk);
419 return ret1;
420 }
421
422 cur_parent = clk_get_parent(hw->clk);
423
424 /* switch to tmp pll before setting parent clock's rate */
425 if (cur_parent == clk_pll1.hw.clk) {
426 ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
427 BUG_ON(ret1);
428 }
429
430 ret2 = clk_set_rate(clk_pll1.hw.clk, rate);
431
432 ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
433
434 return ret2 ? ret2 : ret1;
435}
436
406static struct clk_ops msi_ops = { 437static struct clk_ops msi_ops = {
407 .set_rate = dmn_clk_set_rate, 438 .set_rate = dmn_clk_set_rate,
408 .round_rate = dmn_clk_round_rate, 439 .round_rate = dmn_clk_round_rate,
@@ -457,6 +488,9 @@ static struct clk_dmn clk_io = {
457static struct clk_ops cpu_ops = { 488static struct clk_ops cpu_ops = {
458 .set_parent = dmn_clk_set_parent, 489 .set_parent = dmn_clk_set_parent,
459 .get_parent = dmn_clk_get_parent, 490 .get_parent = dmn_clk_get_parent,
491 .set_rate = cpu_clk_set_rate,
492 .round_rate = cpu_clk_round_rate,
493 .recalc_rate = cpu_clk_recalc_rate,
460}; 494};
461 495
462static struct clk_init_data clk_cpu_init = { 496static struct clk_init_data clk_cpu_init = {
@@ -532,6 +566,11 @@ static struct clk_dmn clk_mm = {
532 }, 566 },
533}; 567};
534 568
569/*
570 * for atlas6, gfx2d holds the bit of prima2's clk_mm
571 */
572#define clk_gfx2d clk_mm
573
535static struct clk_init_data clk_lcd_init = { 574static struct clk_init_data clk_lcd_init = {
536 .name = "lcd", 575 .name = "lcd",
537 .ops = &dmn_ops, 576 .ops = &dmn_ops,
@@ -569,14 +608,6 @@ static struct clk_init_data clk_mmc01_init = {
569 .num_parents = ARRAY_SIZE(dmn_clk_parents), 608 .num_parents = ARRAY_SIZE(dmn_clk_parents),
570}; 609};
571 610
572static struct clk_dmn clk_mmc01 = {
573 .regofs = SIRFSOC_CLKC_MMC_CFG,
574 .enable_bit = 59,
575 .hw = {
576 .init = &clk_mmc01_init,
577 },
578};
579
580static struct clk_init_data clk_mmc23_init = { 611static struct clk_init_data clk_mmc23_init = {
581 .name = "mmc23", 612 .name = "mmc23",
582 .ops = &dmn_ops, 613 .ops = &dmn_ops,
@@ -584,14 +615,6 @@ static struct clk_init_data clk_mmc23_init = {
584 .num_parents = ARRAY_SIZE(dmn_clk_parents), 615 .num_parents = ARRAY_SIZE(dmn_clk_parents),
585}; 616};
586 617
587static struct clk_dmn clk_mmc23 = {
588 .regofs = SIRFSOC_CLKC_MMC_CFG,
589 .enable_bit = 60,
590 .hw = {
591 .init = &clk_mmc23_init,
592 },
593};
594
595static struct clk_init_data clk_mmc45_init = { 618static struct clk_init_data clk_mmc45_init = {
596 .name = "mmc45", 619 .name = "mmc45",
597 .ops = &dmn_ops, 620 .ops = &dmn_ops,
@@ -599,14 +622,6 @@ static struct clk_init_data clk_mmc45_init = {
599 .num_parents = ARRAY_SIZE(dmn_clk_parents), 622 .num_parents = ARRAY_SIZE(dmn_clk_parents),
600}; 623};
601 624
602static struct clk_dmn clk_mmc45 = {
603 .regofs = SIRFSOC_CLKC_MMC_CFG,
604 .enable_bit = 61,
605 .hw = {
606 .init = &clk_mmc45_init,
607 },
608};
609
610/* 625/*
611 * peripheral controllers in io domain 626 * peripheral controllers in io domain
612 */ 627 */
@@ -667,6 +682,20 @@ static struct clk_ops ios_ops = {
667 .disable = std_clk_disable, 682 .disable = std_clk_disable,
668}; 683};
669 684
685static struct clk_init_data clk_cphif_init = {
686 .name = "cphif",
687 .ops = &ios_ops,
688 .parent_names = std_clk_io_parents,
689 .num_parents = ARRAY_SIZE(std_clk_io_parents),
690};
691
692static struct clk_std clk_cphif = {
693 .enable_bit = 20,
694 .hw = {
695 .init = &clk_cphif_init,
696 },
697};
698
670static struct clk_init_data clk_dmac0_init = { 699static struct clk_init_data clk_dmac0_init = {
671 .name = "dmac0", 700 .name = "dmac0",
672 .ops = &ios_ops, 701 .ops = &ios_ops,
@@ -695,20 +724,6 @@ static struct clk_std clk_dmac1 = {
695 }, 724 },
696}; 725};
697 726
698static 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),
703};
704
705static struct clk_std clk_nand = {
706 .enable_bit = 34,
707 .hw = {
708 .init = &clk_nand_init,
709 },
710};
711
712static struct clk_init_data clk_audio_init = { 727static struct clk_init_data clk_audio_init = {
713 .name = "audio", 728 .name = "audio",
714 .ops = &ios_ops, 729 .ops = &ios_ops,
@@ -970,7 +985,7 @@ static const char *std_clk_sys_parents[] = {
970}; 985};
971 986
972static struct clk_init_data clk_security_init = { 987static struct clk_init_data clk_security_init = {
973 .name = "mf", 988 .name = "security",
974 .ops = &ios_ops, 989 .ops = &ios_ops,
975 .parent_names = std_clk_sys_parents, 990 .parent_names = std_clk_sys_parents,
976 .num_parents = ARRAY_SIZE(std_clk_sys_parents), 991 .num_parents = ARRAY_SIZE(std_clk_sys_parents),
@@ -1014,96 +1029,3 @@ static struct clk_std clk_usb1 = {
1014 .init = &clk_usb1_init, 1029 .init = &clk_usb1_init,
1015 }, 1030 },
1016}; 1031};
1017
1018enum prima2_clk_index {
1019 /* 0 1 2 3 4 5 6 7 8 9 */
1020 rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
1021 mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
1022 spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
1023 usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
1024 usb0, usb1, maxclk,
1025};
1026
1027static struct clk_hw *prima2_clk_hw_array[maxclk] __initdata = {
1028 NULL, /* dummy */
1029 NULL,
1030 &clk_pll1.hw,
1031 &clk_pll2.hw,
1032 &clk_pll3.hw,
1033 &clk_mem.hw,
1034 &clk_sys.hw,
1035 &clk_security.hw,
1036 &clk_dsp.hw,
1037 &clk_gps.hw,
1038 &clk_mf.hw,
1039 &clk_io.hw,
1040 &clk_cpu.hw,
1041 &clk_uart0.hw,
1042 &clk_uart1.hw,
1043 &clk_uart2.hw,
1044 &clk_tsc.hw,
1045 &clk_i2c0.hw,
1046 &clk_i2c1.hw,
1047 &clk_spi0.hw,
1048 &clk_spi1.hw,
1049 &clk_pwmc.hw,
1050 &clk_efuse.hw,
1051 &clk_pulse.hw,
1052 &clk_dmac0.hw,
1053 &clk_dmac1.hw,
1054 &clk_nand.hw,
1055 &clk_audio.hw,
1056 &clk_usp0.hw,
1057 &clk_usp1.hw,
1058 &clk_usp2.hw,
1059 &clk_vip.hw,
1060 &clk_gfx.hw,
1061 &clk_mm.hw,
1062 &clk_lcd.hw,
1063 &clk_vpp.hw,
1064 &clk_mmc01.hw,
1065 &clk_mmc23.hw,
1066 &clk_mmc45.hw,
1067 &usb_pll_clk_hw,
1068 &clk_usb0.hw,
1069 &clk_usb1.hw,
1070};
1071
1072static struct clk *prima2_clks[maxclk];
1073static struct clk_onecell_data clk_data;
1074
1075static void __init sirfsoc_clk_init(struct device_node *np)
1076{
1077 struct device_node *rscnp;
1078 int i;
1079
1080 rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
1081 sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
1082 if (!sirfsoc_rsc_vbase)
1083 panic("unable to map rsc registers\n");
1084 of_node_put(rscnp);
1085
1086 sirfsoc_clk_vbase = of_iomap(np, 0);
1087 if (!sirfsoc_clk_vbase)
1088 panic("unable to map clkc registers\n");
1089
1090 /* These are always available (RTC and 26MHz OSC)*/
1091 prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
1092 CLK_IS_ROOT, 32768);
1093 prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL,
1094 CLK_IS_ROOT, 26000000);
1095
1096 for (i = pll1; i < maxclk; i++) {
1097 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
1098 BUG_ON(IS_ERR(prima2_clks[i]));
1099 }
1100 clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
1101 clk_register_clkdev(prima2_clks[io], NULL, "io");
1102 clk_register_clkdev(prima2_clks[mem], NULL, "mem");
1103
1104 clk_data.clks = prima2_clks;
1105 clk_data.clk_num = maxclk;
1106
1107 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
1108}
1109CLK_OF_DECLARE(sirfsoc_clk, "sirf,prima2-clkc", sirfsoc_clk_init);
diff --git a/drivers/clk/sirf/clk-prima2.c b/drivers/clk/sirf/clk-prima2.c
new file mode 100644
index 000000000000..7adc5c70c7ff
--- /dev/null
+++ b/drivers/clk/sirf/clk-prima2.c
@@ -0,0 +1,151 @@
1/*
2 * Clock tree for CSR SiRFprimaII
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
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>
17
18#include "prima2.h"
19#include "clk-common.c"
20
21static struct clk_dmn clk_mmc01 = {
22 .regofs = SIRFSOC_CLKC_MMC_CFG,
23 .enable_bit = 59,
24 .hw = {
25 .init = &clk_mmc01_init,
26 },
27};
28
29static struct clk_dmn clk_mmc23 = {
30 .regofs = SIRFSOC_CLKC_MMC_CFG,
31 .enable_bit = 60,
32 .hw = {
33 .init = &clk_mmc23_init,
34 },
35};
36
37static struct clk_dmn clk_mmc45 = {
38 .regofs = SIRFSOC_CLKC_MMC_CFG,
39 .enable_bit = 61,
40 .hw = {
41 .init = &clk_mmc45_init,
42 },
43};
44
45static struct clk_init_data clk_nand_init = {
46 .name = "nand",
47 .ops = &ios_ops,
48 .parent_names = std_clk_io_parents,
49 .num_parents = ARRAY_SIZE(std_clk_io_parents),
50};
51
52static struct clk_std clk_nand = {
53 .enable_bit = 34,
54 .hw = {
55 .init = &clk_nand_init,
56 },
57};
58
59enum prima2_clk_index {
60 /* 0 1 2 3 4 5 6 7 8 9 */
61 rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
62 mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
63 spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
64 usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
65 usb0, usb1, cphif, maxclk,
66};
67
68static __initdata struct clk_hw *prima2_clk_hw_array[maxclk] = {
69 NULL, /* dummy */
70 NULL,
71 &clk_pll1.hw,
72 &clk_pll2.hw,
73 &clk_pll3.hw,
74 &clk_mem.hw,
75 &clk_sys.hw,
76 &clk_security.hw,
77 &clk_dsp.hw,
78 &clk_gps.hw,
79 &clk_mf.hw,
80 &clk_io.hw,
81 &clk_cpu.hw,
82 &clk_uart0.hw,
83 &clk_uart1.hw,
84 &clk_uart2.hw,
85 &clk_tsc.hw,
86 &clk_i2c0.hw,
87 &clk_i2c1.hw,
88 &clk_spi0.hw,
89 &clk_spi1.hw,
90 &clk_pwmc.hw,
91 &clk_efuse.hw,
92 &clk_pulse.hw,
93 &clk_dmac0.hw,
94 &clk_dmac1.hw,
95 &clk_nand.hw,
96 &clk_audio.hw,
97 &clk_usp0.hw,
98 &clk_usp1.hw,
99 &clk_usp2.hw,
100 &clk_vip.hw,
101 &clk_gfx.hw,
102 &clk_mm.hw,
103 &clk_lcd.hw,
104 &clk_vpp.hw,
105 &clk_mmc01.hw,
106 &clk_mmc23.hw,
107 &clk_mmc45.hw,
108 &usb_pll_clk_hw,
109 &clk_usb0.hw,
110 &clk_usb1.hw,
111 &clk_cphif.hw,
112};
113
114static struct clk *prima2_clks[maxclk];
115
116static void __init prima2_clk_init(struct device_node *np)
117{
118 struct device_node *rscnp;
119 int i;
120
121 rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
122 sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
123 if (!sirfsoc_rsc_vbase)
124 panic("unable to map rsc registers\n");
125 of_node_put(rscnp);
126
127 sirfsoc_clk_vbase = of_iomap(np, 0);
128 if (!sirfsoc_clk_vbase)
129 panic("unable to map clkc registers\n");
130
131 /* These are always available (RTC and 26MHz OSC)*/
132 prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
133 CLK_IS_ROOT, 32768);
134 prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
135 CLK_IS_ROOT, 26000000);
136
137 for (i = pll1; i < maxclk; i++) {
138 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
139 BUG_ON(!prima2_clks[i]);
140 }
141 clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
142 clk_register_clkdev(prima2_clks[io], NULL, "io");
143 clk_register_clkdev(prima2_clks[mem], NULL, "mem");
144 clk_register_clkdev(prima2_clks[mem], NULL, "osc");
145
146 clk_data.clks = prima2_clks;
147 clk_data.clk_num = maxclk;
148
149 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
150}
151CLK_OF_DECLARE(prima2_clk, "sirf,prima2-clkc", prima2_clk_init);
diff --git a/drivers/clk/sirf/prima2.h b/drivers/clk/sirf/prima2.h
new file mode 100644
index 000000000000..01bc3854a058
--- /dev/null
+++ b/drivers/clk/sirf/prima2.h
@@ -0,0 +1,25 @@
1#define SIRFSOC_CLKC_CLK_EN0 0x0000
2#define SIRFSOC_CLKC_CLK_EN1 0x0004
3#define SIRFSOC_CLKC_REF_CFG 0x0014
4#define SIRFSOC_CLKC_CPU_CFG 0x0018
5#define SIRFSOC_CLKC_MEM_CFG 0x001c
6#define SIRFSOC_CLKC_SYS_CFG 0x0020
7#define SIRFSOC_CLKC_IO_CFG 0x0024
8#define SIRFSOC_CLKC_DSP_CFG 0x0028
9#define SIRFSOC_CLKC_GFX_CFG 0x002c
10#define SIRFSOC_CLKC_MM_CFG 0x0030
11#define SIRFSOC_CLKC_LCD_CFG 0x0034
12#define SIRFSOC_CLKC_MMC_CFG 0x0038
13#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
14#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
15#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
16#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
17#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
18#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
19#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
20#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
21#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
22#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
23#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
24#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
25#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)