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
254 bool "ARM Ltd. Integrator family"254 bool "ARM Ltd. Integrator family"
255 select ARM_AMBA255 select ARM_AMBA
256 select ARCH_HAS_CPUFREQ256 select ARCH_HAS_CPUFREQ
257 select CLKDEV_LOOKUP257 select COMMON_CLK
258 select HAVE_MACH_CLKDEV258 select CLK_VERSATILE
259 select HAVE_TCM259 select HAVE_TCM
260 select ICST260 select ICST
261 select GENERIC_CLOCKEVENTS261 select GENERIC_CLOCKEVENTS
@@ -277,6 +277,7 @@ config ARCH_REALVIEW · 15 unmodified lines
277 select GENERIC_CLOCKEVENTS277 select GENERIC_CLOCKEVENTS
278 select ARCH_WANT_OPTIONAL_GPIOLIB278 select ARCH_WANT_OPTIONAL_GPIOLIB
279 select PLAT_VERSATILE279 select PLAT_VERSATILE
280 select PLAT_VERSATILE_CLOCK
280 select PLAT_VERSATILE_CLCD281 select PLAT_VERSATILE_CLCD
281 select ARM_TIMER_SP804282 select ARM_TIMER_SP804
282 select GPIO_PL061 if GPIOLIB283 select GPIO_PL061 if GPIOLIB
@@ -295,6 +296,7 @@ config ARCH_VERSATILE · 12 unmodified lines
295 select ARCH_WANT_OPTIONAL_GPIOLIB296 select ARCH_WANT_OPTIONAL_GPIOLIB
296 select NEED_MACH_IO_H if PCI297 select NEED_MACH_IO_H if PCI
297 select PLAT_VERSATILE298 select PLAT_VERSATILE
299 select PLAT_VERSATILE_CLOCK
298 select PLAT_VERSATILE_CLCD300 select PLAT_VERSATILE_CLCD
299 select PLAT_VERSATILE_FPGA_IRQ301 select PLAT_VERSATILE_FPGA_IRQ
300 select ARM_TIMER_SP804302 select ARM_TIMER_SP804
@@ -314,6 +316,7 @@ config ARCH_VEXPRESS · 13 unmodified lines
314 select ICST316 select ICST
315 select NO_IOPORT317 select NO_IOPORT
316 select PLAT_VERSATILE318 select PLAT_VERSATILE
319 select PLAT_VERSATILE_CLOCK
317 select PLAT_VERSATILE_CLCD320 select PLAT_VERSATILE_CLCD
318 help321 help
319 This enables support for the ARM Ltd Versatile Express boards.322 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
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 = { · 33 unmodified lines
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;
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
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
arch/arm/mach-integrator/integrator_ap.c+7−1
@@ -33,6 +33,7 @@ · 32 unmodified lines
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) · 135 unmodified lines
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_PM181#ifdef CONFIG_PM
@@ -440,6 +442,10 @@ static void integrator_clockevent_init(unsigned long inrate) · 260 unmodified lines
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") · 25 unmodified lines
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,
arch/arm/mach-integrator/integrator_cp.c+2−61
@@ -21,8 +21,8 @@ · 20 unmodified lines
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,64 +171,9 @@ static void __init intcp_init_irq(void) · 142 unmodified lines
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 * 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/*177/*
233 * Flash handling.178 * Flash handling.
234 */179 */
@@ -406,10 +351,6 @@ static struct amba_device *amba_devs[] __initdata = { · 171 unmodified lines
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_CLOCK354#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
414 versatile_sched_clock_init(REFCOUNTER, 24000000);355 versatile_sched_clock_init(REFCOUNTER, 24000000);
415#endif356#endif
arch/arm/plat-versatile/Kconfig+3−0
@@ -1,5 +1,8 @@
1if PLAT_VERSATILE1if PLAT_VERSATILE
2 2
3config PLAT_VERSATILE_CLOCK
4 bool
5
3config PLAT_VERSATILE_CLCD6config PLAT_VERSATILE_CLCD
4 bool7 bool
5 8
arch/arm/plat-versatile/Makefile+1−1
@@ -1,4 +1,4 @@
1obj-y := clock.o1obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o
2obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o2obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
3obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o3obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
4obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o4obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
drivers/clk/versatile/Makefile+1−0
@@ -1,2 +1,3 @@
1# Makefile for Versatile-specific clocks1# Makefile for Versatile-specific clocks
2obj-$(CONFIG_ICST) += clk-icst.o2obj-$(CONFIG_ICST) += clk-icst.o
3obj-$(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 */
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}
include/linux/platform_data/clk-integrator.h+1−0
@@ -0,0 +1 @@
1void 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