diff options
-rw-r--r-- | drivers/clk/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/sirf/Makefile | 5 | ||||
-rw-r--r-- | drivers/clk/sirf/atlas6.h | 31 | ||||
-rw-r--r-- | drivers/clk/sirf/clk-atlas6.c | 152 | ||||
-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.c | 151 | ||||
-rw-r--r-- | drivers/clk/sirf/prima2.h | 25 |
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/ | |||
21 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 21 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
22 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 22 | obj-$(CONFIG_ARCH_U300) += clk-u300.o |
23 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ | 23 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ |
24 | obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o | ||
25 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | 24 | obj-$(CONFIG_PLAT_ORION) += mvebu/ |
26 | ifeq ($(CONFIG_COMMON_CLK), y) | 25 | ifeq ($(CONFIG_COMMON_CLK), y) |
27 | obj-$(CONFIG_ARCH_MMP) += mmp/ | 26 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
@@ -31,6 +30,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ | |||
31 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ | 30 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ |
32 | obj-$(CONFIG_ARCH_U8500) += ux500/ | 31 | obj-$(CONFIG_ARCH_U8500) += ux500/ |
33 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 32 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
33 | obj-$(CONFIG_ARCH_SIRF) += sirf/ | ||
34 | obj-$(CONFIG_ARCH_ZYNQ) += zynq/ | 34 | obj-$(CONFIG_ARCH_ZYNQ) += zynq/ |
35 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | 35 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ |
36 | obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ | 36 | obj-$(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 | |||
5 | obj-$(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 | |||
21 | static 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 | |||
29 | static 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 | |||
37 | static 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 | |||
45 | static 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 | |||
52 | static 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 | |||
60 | enum 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 | |||
69 | static __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 | |||
115 | static struct clk *atlas6_clks[maxclk]; | ||
116 | |||
117 | static 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 | } | ||
152 | CLK_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 | |||
44 | static 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 | ||
12 | static void *sirfsoc_clk_vbase; | ||
13 | static void *sirfsoc_rsc_vbase; | ||
14 | static 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 | ||
153 | static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | 124 | static 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 | ||
160 | static 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 | |||
173 | static 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 | |||
189 | static struct clk_ops std_pll_ops = { | 184 | static 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 | ||
401 | static 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 | |||
406 | static struct clk_ops msi_ops = { | 437 | static 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 = { | |||
457 | static struct clk_ops cpu_ops = { | 488 | static 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 | ||
462 | static struct clk_init_data clk_cpu_init = { | 496 | static 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 | |||
535 | static struct clk_init_data clk_lcd_init = { | 574 | static 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 | ||
572 | static 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 | |||
580 | static struct clk_init_data clk_mmc23_init = { | 611 | static 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 | ||
587 | static 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 | |||
595 | static struct clk_init_data clk_mmc45_init = { | 618 | static 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 | ||
602 | static 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 | ||
685 | static 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 | |||
692 | static struct clk_std clk_cphif = { | ||
693 | .enable_bit = 20, | ||
694 | .hw = { | ||
695 | .init = &clk_cphif_init, | ||
696 | }, | ||
697 | }; | ||
698 | |||
670 | static struct clk_init_data clk_dmac0_init = { | 699 | static 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 | ||
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), | ||
703 | }; | ||
704 | |||
705 | static struct clk_std clk_nand = { | ||
706 | .enable_bit = 34, | ||
707 | .hw = { | ||
708 | .init = &clk_nand_init, | ||
709 | }, | ||
710 | }; | ||
711 | |||
712 | static struct clk_init_data clk_audio_init = { | 727 | static 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 | ||
972 | static struct clk_init_data clk_security_init = { | 987 | static 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 | |||
1018 | enum 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 | |||
1027 | static 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 | |||
1072 | static struct clk *prima2_clks[maxclk]; | ||
1073 | static struct clk_onecell_data clk_data; | ||
1074 | |||
1075 | static 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 | } | ||
1109 | CLK_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 | |||
21 | static 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 | |||
29 | static 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 | |||
37 | static 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 | |||
45 | static 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 | |||
52 | static struct clk_std clk_nand = { | ||
53 | .enable_bit = 34, | ||
54 | .hw = { | ||
55 | .init = &clk_nand_init, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | enum 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 | |||
68 | static __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 | |||
114 | static struct clk *prima2_clks[maxclk]; | ||
115 | |||
116 | static 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 | } | ||
151 | CLK_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) | ||