aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/mach-integrator/core.c45
-rw-r--r--arch/arm/mach-integrator/include/mach/clkdev.h26
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c8
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c63
-rw-r--r--arch/arm/plat-versatile/Kconfig3
-rw-r--r--arch/arm/plat-versatile/Makefile2
-rw-r--r--drivers/clk/versatile/Makefile1
-rw-r--r--drivers/clk/versatile/clk-integrator.c111
-rw-r--r--include/linux/platform_data/clk-integrator.h1
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 */
67static struct clk clk24mhz = {
68 .rate = 24000000,
69};
70
71static struct clk uartclk = {
72 .rate = 14745600,
73};
74
75static struct clk dummy_apb_pclk;
76
77static 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
103void __init integrator_init_early(void)
104{
105 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
106}
107
108static int __init integrator_init(void) 63static 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
7struct 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
16static inline int __clk_get(struct clk *clk)
17{
18 return try_module_get(clk->owner);
19}
20
21static 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
445void __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
182static 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
194static 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
206static const struct clk_ops cp_auxclk_ops = {
207 .round = icst_clk_round,
208 .set = icst_clk_set,
209 .setvco = cp_auxvco_set,
210};
211
212static struct clk cp_auxclk = {
213 .ops = &cp_auxclk_ops,
214 .params = &cp_auxvco_params,
215 .vcoreg = CM_AUXOSC,
216};
217
218static struct clk sp804_clk = {
219 .rate = 1000000,
220};
221
222static 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 */
235static int intcp_flash_init(struct platform_device *dev) 180static int intcp_flash_init(struct platform_device *dev)
@@ -406,10 +351,6 @@ static struct amba_device *amba_devs[] __initdata = {
406 351
407static void __init intcp_init_early(void) 352static 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 @@
1if PLAT_VERSATILE 1if PLAT_VERSATILE
2 2
3config PLAT_VERSATILE_CLOCK
4 bool
5
3config PLAT_VERSATILE_CLCD 6config 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 @@
1obj-y := clock.o 1obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
2obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o 2obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
3obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o 3obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
4obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o 4obj-$(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
2obj-$(CONFIG_ICST) += clk-icst.o 2obj-$(CONFIG_ICST) += clk-icst.o
3obj-$(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 */
24static 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 */
40static 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
54static 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
66static 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 */
76void __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);