History

ARM: integrator: convert to common clock

This converts the Integrator platform to use common clock and the ICST driver. Since from this point not all ARM reference platforms use the clock, we define CONFIG_PLAT_VERSATILE_CLOCK and select it for all platforms except the Integrator. Open issue: I could not use the .init_early() field of the machine descriptor to initialize the clocks, but had to move them to .init_irq(), so presumably .init_early() is so early that common clock is not up, and .init_machine() is too late since it's needed for the clockevent/clocksource initialization. Any suggestions on how to solve this is very welcome.

Linus Walleij committed 14 years ago

Commit a6131631 parent 91b87a410 files · +131 −136Browse files

Unified · Split

10 files
  1. arch/arm/Kconfig +5 −2
  2. arch/arm/mach-integrator/core.c +0 −45
  3. arch/arm/mach-integrator/include/mach/clkdev.h +0 −26
  4. arch/arm/mach-integrator/integrator_ap.c +7 −1
  5. arch/arm/mach-integrator/integrator_cp.c +2 −61
  6. arch/arm/plat-versatile/Kconfig +3 −0
  7. arch/arm/plat-versatile/Makefile +1 −1
  8. drivers/clk/versatile/Makefile +1 −0
  9. drivers/clk/versatile/clk-integrator.c +111 −0
  10. include/linux/platform_data/clk-integrator.h +1 −0
arch/arm/Kconfig+5−2
@@ -254,8 +254,8 @@ config ARCH_INTEGRATOR · 253 unmodified lines
254254 bool "ARM Ltd. Integrator family"
255255 select ARM_AMBA
256256 select ARCH_HAS_CPUFREQ
257− select CLKDEV_LOOKUP
258− select HAVE_MACH_CLKDEV
257+ select COMMON_CLK
258+ select CLK_VERSATILE
259259 select HAVE_TCM
260260 select ICST
261261 select GENERIC_CLOCKEVENTS
@@ -277,6 +277,7 @@ config ARCH_REALVIEW · 15 unmodified lines
277277 select GENERIC_CLOCKEVENTS
278278 select ARCH_WANT_OPTIONAL_GPIOLIB
279279 select PLAT_VERSATILE
280+ select PLAT_VERSATILE_CLOCK
280281 select PLAT_VERSATILE_CLCD
281282 select ARM_TIMER_SP804
282283 select GPIO_PL061 if GPIOLIB
@@ -295,6 +296,7 @@ config ARCH_VERSATILE · 12 unmodified lines
295296 select ARCH_WANT_OPTIONAL_GPIOLIB
296297 select NEED_MACH_IO_H if PCI
297298 select PLAT_VERSATILE
299+ select PLAT_VERSATILE_CLOCK
298300 select PLAT_VERSATILE_CLCD
299301 select PLAT_VERSATILE_FPGA_IRQ
300302 select ARM_TIMER_SP804
@@ -314,6 +316,7 @@ config ARCH_VEXPRESS · 13 unmodified lines
314316 select ICST
315317 select NO_IOPORT
316318 select PLAT_VERSATILE
319+ select PLAT_VERSATILE_CLOCK
317320 select PLAT_VERSATILE_CLCD
318321 help
319322 This enables support for the ARM Ltd Versatile Express boards.
arch/arm/mach-integrator/core.c+0−45
@@ -21,7 +21,6 @@ · 20 unmodified lines
2121 #include <linux/amba/bus.h>
2222 #include <linux/amba/serial.h>
2323 #include <linux/io.h>
24−#include <linux/clkdev.h>
2524
2625 #include <mach/hardware.h>
2726 #include <mach/platform.h>
@@ -61,50 +60,6 @@ static struct amba_device *amba_devs[] __initdata = { · 33 unmodified lines
6160 &kmi1_device,
6261 };
6362
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−
10863 static int __init integrator_init(void)
10964 {
11065 int i;
arch/arm/mach-integrator/include/mach/clkdev.h+0−26
@@ -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
arch/arm/mach-integrator/integrator_ap.c+7−1
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 #include <linux/io.h>
3434 #include <linux/mtd/physmap.h>
3535 #include <linux/clk.h>
36+#include <linux/platform_data/clk-integrator.h>
3637 #include <video/vga.h>
3738
3839 #include <mach/hardware.h>
@@ -174,6 +175,7 @@ static void __init ap_init_irq(void) · 135 unmodified lines
174175
175176 fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
176177 -1, INTEGRATOR_SC_VALID_INT, NULL);
178+ integrator_clk_init(false);
177179 }
178180
179181 #ifdef CONFIG_PM
@@ -440,6 +442,10 @@ static void integrator_clockevent_init(unsigned long inrate) · 260 unmodified lines
440442 0xffffU);
441443 }
442444
445+void __init ap_init_early(void)
446+{
447+}
448+
443449 /*
444450 * Set up timer(s).
445451 */
@@ -471,7 +477,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") · 25 unmodified lines
471477 .reserve = integrator_reserve,
472478 .map_io = ap_map_io,
473479 .nr_irqs = NR_IRQS_INTEGRATOR_AP,
474− .init_early = integrator_init_early,
480+ .init_early = ap_init_early,
475481 .init_irq = ap_init_irq,
476482 .handle_irq = fpga_handle_irq,
477483 .timer = &ap_timer,
arch/arm/mach-integrator/integrator_cp.c+2−61
@@ -21,8 +21,8 @@ · 20 unmodified lines
2121 #include <linux/amba/mmci.h>
2222 #include <linux/io.h>
2323 #include <linux/gfp.h>
24−#include <linux/clkdev.h>
2524 #include <linux/mtd/physmap.h>
25+#include <linux/platform_data/clk-integrator.h>
2626
2727 #include <mach/hardware.h>
2828 #include <mach/platform.h>
@@ -171,64 +171,9 @@ static void __init intcp_init_irq(void) · 142 unmodified lines
171171
172172 fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
173173 IRQ_CP_CPPLDINT, sic_mask, NULL);
174+ integrator_clk_init(true);
174175 }
175176
176−/*
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−
232177 /*
233178 * Flash handling.
234179 */
@@ -406,10 +351,6 @@ static struct amba_device *amba_devs[] __initdata = { · 171 unmodified lines
406351
407352 static void __init intcp_init_early(void)
408353 {
409− clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
410−
411− integrator_init_early();
412−
413354 #ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
414355 versatile_sched_clock_init(REFCOUNTER, 24000000);
415356 #endif
arch/arm/plat-versatile/Kconfig+3−0
@@ -1,5 +1,8 @@
11 if PLAT_VERSATILE
22
3+config PLAT_VERSATILE_CLOCK
4+ bool
5+
36 config PLAT_VERSATILE_CLCD
47 bool
58
arch/arm/plat-versatile/Makefile+1−1
@@ -1,4 +1,4 @@
1−obj-y := clock.o
1+obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
22 obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
33 obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
44 obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
drivers/clk/versatile/Makefile+1−0
@@ -1,2 +1,3 @@
11 # Makefile for Versatile-specific clocks
22 obj-$(CONFIG_ICST) += clk-icst.o
3+obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o
drivers/clk/versatile/clk-integrator.c+111−0
@@ -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+}
include/linux/platform_data/clk-integrator.h+1−0
@@ -0,0 +1 @@
1+void integrator_clk_init(bool is_cp);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t