diff options
-rw-r--r-- | arch/arm/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/mach-integrator/core.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-integrator/include/mach/clkdev.h | 26 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_cp.c | 63 | ||||
-rw-r--r-- | arch/arm/plat-versatile/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/plat-versatile/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/versatile/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/versatile/clk-integrator.c | 111 | ||||
-rw-r--r-- | include/linux/platform_data/clk-integrator.h | 1 |
10 files changed, 131 insertions, 136 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c59853738967..6f8cf405d3ec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -254,8 +254,8 @@ config ARCH_INTEGRATOR | |||
254 | bool "ARM Ltd. Integrator family" | 254 | bool "ARM Ltd. Integrator family" |
255 | select ARM_AMBA | 255 | select ARM_AMBA |
256 | select ARCH_HAS_CPUFREQ | 256 | select ARCH_HAS_CPUFREQ |
257 | select CLKDEV_LOOKUP | 257 | select COMMON_CLK |
258 | select HAVE_MACH_CLKDEV | 258 | select CLK_VERSATILE |
259 | select HAVE_TCM | 259 | select HAVE_TCM |
260 | select ICST | 260 | select ICST |
261 | select GENERIC_CLOCKEVENTS | 261 | select GENERIC_CLOCKEVENTS |
@@ -277,6 +277,7 @@ config ARCH_REALVIEW | |||
277 | select GENERIC_CLOCKEVENTS | 277 | select GENERIC_CLOCKEVENTS |
278 | select ARCH_WANT_OPTIONAL_GPIOLIB | 278 | select ARCH_WANT_OPTIONAL_GPIOLIB |
279 | select PLAT_VERSATILE | 279 | select PLAT_VERSATILE |
280 | select PLAT_VERSATILE_CLOCK | ||
280 | select PLAT_VERSATILE_CLCD | 281 | select PLAT_VERSATILE_CLCD |
281 | select ARM_TIMER_SP804 | 282 | select ARM_TIMER_SP804 |
282 | select GPIO_PL061 if GPIOLIB | 283 | select GPIO_PL061 if GPIOLIB |
@@ -295,6 +296,7 @@ config ARCH_VERSATILE | |||
295 | select ARCH_WANT_OPTIONAL_GPIOLIB | 296 | select ARCH_WANT_OPTIONAL_GPIOLIB |
296 | select NEED_MACH_IO_H if PCI | 297 | select NEED_MACH_IO_H if PCI |
297 | select PLAT_VERSATILE | 298 | select PLAT_VERSATILE |
299 | select PLAT_VERSATILE_CLOCK | ||
298 | select PLAT_VERSATILE_CLCD | 300 | select PLAT_VERSATILE_CLCD |
299 | select PLAT_VERSATILE_FPGA_IRQ | 301 | select PLAT_VERSATILE_FPGA_IRQ |
300 | select ARM_TIMER_SP804 | 302 | select ARM_TIMER_SP804 |
@@ -314,6 +316,7 @@ config ARCH_VEXPRESS | |||
314 | select ICST | 316 | select ICST |
315 | select NO_IOPORT | 317 | select NO_IOPORT |
316 | select PLAT_VERSATILE | 318 | select PLAT_VERSATILE |
319 | select PLAT_VERSATILE_CLOCK | ||
317 | select PLAT_VERSATILE_CLCD | 320 | select PLAT_VERSATILE_CLCD |
318 | help | 321 | help |
319 | This enables support for the ARM Ltd Versatile Express boards. | 322 | This enables support for the ARM Ltd Versatile Express boards. |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 2a20bba246fb..ebf680bebdf2 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/amba/bus.h> | 21 | #include <linux/amba/bus.h> |
22 | #include <linux/amba/serial.h> | 22 | #include <linux/amba/serial.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/clkdev.h> | ||
25 | 24 | ||
26 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
27 | #include <mach/platform.h> | 26 | #include <mach/platform.h> |
@@ -61,50 +60,6 @@ static struct amba_device *amba_devs[] __initdata = { | |||
61 | &kmi1_device, | 60 | &kmi1_device, |
62 | }; | 61 | }; |
63 | 62 | ||
64 | /* | ||
65 | * These are fixed clocks. | ||
66 | */ | ||
67 | static struct clk clk24mhz = { | ||
68 | .rate = 24000000, | ||
69 | }; | ||
70 | |||
71 | static struct clk uartclk = { | ||
72 | .rate = 14745600, | ||
73 | }; | ||
74 | |||
75 | static struct clk dummy_apb_pclk; | ||
76 | |||
77 | static struct clk_lookup lookups[] = { | ||
78 | { /* Bus clock */ | ||
79 | .con_id = "apb_pclk", | ||
80 | .clk = &dummy_apb_pclk, | ||
81 | }, { | ||
82 | /* Integrator/AP timer frequency */ | ||
83 | .dev_id = "ap_timer", | ||
84 | .clk = &clk24mhz, | ||
85 | }, { /* UART0 */ | ||
86 | .dev_id = "uart0", | ||
87 | .clk = &uartclk, | ||
88 | }, { /* UART1 */ | ||
89 | .dev_id = "uart1", | ||
90 | .clk = &uartclk, | ||
91 | }, { /* KMI0 */ | ||
92 | .dev_id = "kmi0", | ||
93 | .clk = &clk24mhz, | ||
94 | }, { /* KMI1 */ | ||
95 | .dev_id = "kmi1", | ||
96 | .clk = &clk24mhz, | ||
97 | }, { /* MMCI - IntegratorCP */ | ||
98 | .dev_id = "mmci", | ||
99 | .clk = &uartclk, | ||
100 | } | ||
101 | }; | ||
102 | |||
103 | void __init integrator_init_early(void) | ||
104 | { | ||
105 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
106 | } | ||
107 | |||
108 | static int __init integrator_init(void) | 63 | static int __init integrator_init(void) |
109 | { | 64 | { |
110 | int i; | 65 | int i; |
diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h deleted file mode 100644 index bfe07679faec..000000000000 --- a/arch/arm/mach-integrator/include/mach/clkdev.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | #ifndef __ASM_MACH_CLKDEV_H | ||
2 | #define __ASM_MACH_CLKDEV_H | ||
3 | |||
4 | #include <linux/module.h> | ||
5 | #include <plat/clock.h> | ||
6 | |||
7 | struct clk { | ||
8 | unsigned long rate; | ||
9 | const struct clk_ops *ops; | ||
10 | struct module *owner; | ||
11 | const struct icst_params *params; | ||
12 | void __iomem *vcoreg; | ||
13 | void *data; | ||
14 | }; | ||
15 | |||
16 | static inline int __clk_get(struct clk *clk) | ||
17 | { | ||
18 | return try_module_get(clk->owner); | ||
19 | } | ||
20 | |||
21 | static inline void __clk_put(struct clk *clk) | ||
22 | { | ||
23 | module_put(clk->owner); | ||
24 | } | ||
25 | |||
26 | #endif | ||
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index c857501c5783..7b1055c8e0b9 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/mtd/physmap.h> | 34 | #include <linux/mtd/physmap.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/platform_data/clk-integrator.h> | ||
36 | #include <video/vga.h> | 37 | #include <video/vga.h> |
37 | 38 | ||
38 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
@@ -174,6 +175,7 @@ static void __init ap_init_irq(void) | |||
174 | 175 | ||
175 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, | 176 | fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, |
176 | -1, INTEGRATOR_SC_VALID_INT, NULL); | 177 | -1, INTEGRATOR_SC_VALID_INT, NULL); |
178 | integrator_clk_init(false); | ||
177 | } | 179 | } |
178 | 180 | ||
179 | #ifdef CONFIG_PM | 181 | #ifdef CONFIG_PM |
@@ -440,6 +442,10 @@ static void integrator_clockevent_init(unsigned long inrate) | |||
440 | 0xffffU); | 442 | 0xffffU); |
441 | } | 443 | } |
442 | 444 | ||
445 | void __init ap_init_early(void) | ||
446 | { | ||
447 | } | ||
448 | |||
443 | /* | 449 | /* |
444 | * Set up timer(s). | 450 | * Set up timer(s). |
445 | */ | 451 | */ |
@@ -471,7 +477,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") | |||
471 | .reserve = integrator_reserve, | 477 | .reserve = integrator_reserve, |
472 | .map_io = ap_map_io, | 478 | .map_io = ap_map_io, |
473 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, | 479 | .nr_irqs = NR_IRQS_INTEGRATOR_AP, |
474 | .init_early = integrator_init_early, | 480 | .init_early = ap_init_early, |
475 | .init_irq = ap_init_irq, | 481 | .init_irq = ap_init_irq, |
476 | .handle_irq = fpga_handle_irq, | 482 | .handle_irq = fpga_handle_irq, |
477 | .timer = &ap_timer, | 483 | .timer = &ap_timer, |
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a8c6480babdd..82d5c837cc74 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c | |||
@@ -21,8 +21,8 @@ | |||
21 | #include <linux/amba/mmci.h> | 21 | #include <linux/amba/mmci.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/gfp.h> | 23 | #include <linux/gfp.h> |
24 | #include <linux/clkdev.h> | ||
25 | #include <linux/mtd/physmap.h> | 24 | #include <linux/mtd/physmap.h> |
25 | #include <linux/platform_data/clk-integrator.h> | ||
26 | 26 | ||
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/platform.h> | 28 | #include <mach/platform.h> |
@@ -171,65 +171,10 @@ static void __init intcp_init_irq(void) | |||
171 | 171 | ||
172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, | 172 | fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, |
173 | IRQ_CP_CPPLDINT, sic_mask, NULL); | 173 | IRQ_CP_CPPLDINT, sic_mask, NULL); |
174 | integrator_clk_init(true); | ||
174 | } | 175 | } |
175 | 176 | ||
176 | /* | 177 | /* |
177 | * Clock handling | ||
178 | */ | ||
179 | #define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) | ||
180 | #define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c) | ||
181 | |||
182 | static const struct icst_params cp_auxvco_params = { | ||
183 | .ref = 24000000, | ||
184 | .vco_max = ICST525_VCO_MAX_5V, | ||
185 | .vco_min = ICST525_VCO_MIN, | ||
186 | .vd_min = 8, | ||
187 | .vd_max = 263, | ||
188 | .rd_min = 3, | ||
189 | .rd_max = 65, | ||
190 | .s2div = icst525_s2div, | ||
191 | .idx2s = icst525_idx2s, | ||
192 | }; | ||
193 | |||
194 | static void cp_auxvco_set(struct clk *clk, struct icst_vco vco) | ||
195 | { | ||
196 | u32 val; | ||
197 | |||
198 | val = readl(clk->vcoreg) & ~0x7ffff; | ||
199 | val |= vco.v | (vco.r << 9) | (vco.s << 16); | ||
200 | |||
201 | writel(0xa05f, CM_LOCK); | ||
202 | writel(val, clk->vcoreg); | ||
203 | writel(0, CM_LOCK); | ||
204 | } | ||
205 | |||
206 | static const struct clk_ops cp_auxclk_ops = { | ||
207 | .round = icst_clk_round, | ||
208 | .set = icst_clk_set, | ||
209 | .setvco = cp_auxvco_set, | ||
210 | }; | ||
211 | |||
212 | static struct clk cp_auxclk = { | ||
213 | .ops = &cp_auxclk_ops, | ||
214 | .params = &cp_auxvco_params, | ||
215 | .vcoreg = CM_AUXOSC, | ||
216 | }; | ||
217 | |||
218 | static struct clk sp804_clk = { | ||
219 | .rate = 1000000, | ||
220 | }; | ||
221 | |||
222 | static struct clk_lookup cp_lookups[] = { | ||
223 | { /* CLCD */ | ||
224 | .dev_id = "clcd", | ||
225 | .clk = &cp_auxclk, | ||
226 | }, { /* SP804 timers */ | ||
227 | .dev_id = "sp804", | ||
228 | .clk = &sp804_clk, | ||
229 | }, | ||
230 | }; | ||
231 | |||
232 | /* | ||
233 | * Flash handling. | 178 | * Flash handling. |
234 | */ | 179 | */ |
235 | static int intcp_flash_init(struct platform_device *dev) | 180 | static int intcp_flash_init(struct platform_device *dev) |
@@ -406,10 +351,6 @@ static struct amba_device *amba_devs[] __initdata = { | |||
406 | 351 | ||
407 | static void __init intcp_init_early(void) | 352 | static void __init intcp_init_early(void) |
408 | { | 353 | { |
409 | clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups)); | ||
410 | |||
411 | integrator_init_early(); | ||
412 | |||
413 | #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK | 354 | #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK |
414 | versatile_sched_clock_init(REFCOUNTER, 24000000); | 355 | versatile_sched_clock_init(REFCOUNTER, 24000000); |
415 | #endif | 356 | #endif |
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 81ee7cc34457..8d5c10a5084d 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig | |||
@@ -1,5 +1,8 @@ | |||
1 | if PLAT_VERSATILE | 1 | if PLAT_VERSATILE |
2 | 2 | ||
3 | config PLAT_VERSATILE_CLOCK | ||
4 | bool | ||
5 | |||
3 | config PLAT_VERSATILE_CLCD | 6 | config PLAT_VERSATILE_CLCD |
4 | bool | 7 | bool |
5 | 8 | ||
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index a5cb1945bdcc..272769a8a7d6 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := clock.o | 1 | obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o |
2 | obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o | 2 | obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o |
3 | obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o | 3 | obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o |
4 | obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o | 4 | obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o |
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index a83539b41787..50cf6a2ee693 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | # Makefile for Versatile-specific clocks | 1 | # Makefile for Versatile-specific clocks |
2 | obj-$(CONFIG_ICST) += clk-icst.o | 2 | obj-$(CONFIG_ICST) += clk-icst.o |
3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o | ||
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c new file mode 100644 index 000000000000..a5053921bf7f --- /dev/null +++ b/drivers/clk/versatile/clk-integrator.c | |||
@@ -0,0 +1,111 @@ | |||
1 | #include <linux/clk.h> | ||
2 | #include <linux/clkdev.h> | ||
3 | #include <linux/err.h> | ||
4 | #include <linux/io.h> | ||
5 | #include <linux/clk-provider.h> | ||
6 | |||
7 | #include <mach/hardware.h> | ||
8 | #include <mach/platform.h> | ||
9 | |||
10 | #include "clk-icst.h" | ||
11 | |||
12 | /* | ||
13 | * Implementation of the ARM Integrator/AP and Integrator/CP clock tree. | ||
14 | * Inspired by portions of: | ||
15 | * plat-versatile/clock.c and plat-versatile/include/plat/clock.h | ||
16 | */ | ||
17 | #define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) | ||
18 | #define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c) | ||
19 | |||
20 | /** | ||
21 | * cp_auxvco_get() - get ICST VCO settings for the Integrator/CP | ||
22 | * @vco: ICST VCO parameters to update with hardware status | ||
23 | */ | ||
24 | static struct icst_vco cp_auxvco_get(void) | ||
25 | { | ||
26 | u32 val; | ||
27 | struct icst_vco vco; | ||
28 | |||
29 | val = readl(CM_AUXOSC); | ||
30 | vco.v = val & 0x1ff; | ||
31 | vco.r = (val >> 9) & 0x7f; | ||
32 | vco.s = (val >> 16) & 03; | ||
33 | return vco; | ||
34 | } | ||
35 | |||
36 | /** | ||
37 | * cp_auxvco_set() - commit changes to Integrator/CP ICST VCO | ||
38 | * @vco: ICST VCO parameters to commit | ||
39 | */ | ||
40 | static void cp_auxvco_set(struct icst_vco vco) | ||
41 | { | ||
42 | u32 val; | ||
43 | |||
44 | val = readl(CM_AUXOSC) & ~0x7ffff; | ||
45 | val |= vco.v | (vco.r << 9) | (vco.s << 16); | ||
46 | |||
47 | /* This magic unlocks the CM VCO so it can be controlled */ | ||
48 | writel(0xa05f, CM_LOCK); | ||
49 | writel(val, CM_AUXOSC); | ||
50 | /* This locks the CM again */ | ||
51 | writel(0, CM_LOCK); | ||
52 | } | ||
53 | |||
54 | static const struct icst_params cp_auxvco_params = { | ||
55 | .ref = 24000000, | ||
56 | .vco_max = ICST525_VCO_MAX_5V, | ||
57 | .vco_min = ICST525_VCO_MIN, | ||
58 | .vd_min = 8, | ||
59 | .vd_max = 263, | ||
60 | .rd_min = 3, | ||
61 | .rd_max = 65, | ||
62 | .s2div = icst525_s2div, | ||
63 | .idx2s = icst525_idx2s, | ||
64 | }; | ||
65 | |||
66 | static const struct clk_icst_desc __initdata cp_icst_desc = { | ||
67 | .params = &cp_auxvco_params, | ||
68 | .getvco = cp_auxvco_get, | ||
69 | .setvco = cp_auxvco_set, | ||
70 | }; | ||
71 | |||
72 | /* | ||
73 | * integrator_clk_init() - set up the integrator clock tree | ||
74 | * @is_cp: pass true if it's the Integrator/CP else AP is assumed | ||
75 | */ | ||
76 | void __init integrator_clk_init(bool is_cp) | ||
77 | { | ||
78 | struct clk *clk; | ||
79 | |||
80 | /* APB clock dummy */ | ||
81 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); | ||
82 | clk_register_clkdev(clk, "apb_pclk", NULL); | ||
83 | |||
84 | /* UART reference clock */ | ||
85 | clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, | ||
86 | 14745600); | ||
87 | clk_register_clkdev(clk, NULL, "uart0"); | ||
88 | clk_register_clkdev(clk, NULL, "uart1"); | ||
89 | if (is_cp) | ||
90 | clk_register_clkdev(clk, NULL, "mmci"); | ||
91 | |||
92 | /* 24 MHz clock */ | ||
93 | clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, | ||
94 | 24000000); | ||
95 | clk_register_clkdev(clk, NULL, "kmi0"); | ||
96 | clk_register_clkdev(clk, NULL, "kmi1"); | ||
97 | if (!is_cp) | ||
98 | clk_register_clkdev(clk, NULL, "ap_timer"); | ||
99 | |||
100 | if (!is_cp) | ||
101 | return; | ||
102 | |||
103 | /* 1 MHz clock */ | ||
104 | clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, | ||
105 | 1000000); | ||
106 | clk_register_clkdev(clk, NULL, "sp804"); | ||
107 | |||
108 | /* ICST VCO clock used on the Integrator/CP CLCD */ | ||
109 | clk = icst_clk_register(NULL, &cp_icst_desc); | ||
110 | clk_register_clkdev(clk, NULL, "clcd"); | ||
111 | } | ||
diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h new file mode 100644 index 000000000000..83fe9c283bb8 --- /dev/null +++ b/include/linux/platform_data/clk-integrator.h | |||
@@ -0,0 +1 @@ | |||
void integrator_clk_init(bool is_cp); | |||