clk: convert ARM RealView to common clk
authorLinus Walleij <linus.walleij@linaro.org>
Mon, 6 Aug 2012 16:32:08 +0000 (18:32 +0200)
committerMike Turquette <mturquette@linaro.org>
Sat, 25 Aug 2012 00:42:10 +0000 (17:42 -0700)
This converts the ARM RealView machine over to using the common
clock. The approach is similar to the one used for the Integrator,
and we're reusing the ICST wrapper code.

We have to put the clock intialization in the timer init function
for the clocks to be available when initializing the timer,
keeping them in early_init() is too early for the common clk.

Since we now have to go down and compile drivers/clk/versatile
a CONFIG_COMMON_CLK_VERSATILE symbol has been added so the proper
code gets compiled into the kernel for either machine. A leftover
CLK_VERSATILE in the Integrator Kconfig was fixed up to use
the new symbol as well.

Tested on ARM RealView PB1176.

Cc: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
13 files changed:
arch/arm/Kconfig
arch/arm/mach-realview/core.c
arch/arm/mach-realview/include/mach/clkdev.h [deleted file]
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/versatile/Makefile
drivers/clk/versatile/clk-realview.c [new file with mode: 0644]
include/linux/platform_data/clk-realview.h [new file with mode: 0644]

index fb6014868d33e9e0b8b85be2e9a1f634975765bc..1a01ffa331d04d1fe9c2fa41295aa5eb9fe4b0db 100644 (file)
@@ -273,7 +273,7 @@ config ARCH_INTEGRATOR
        select ARM_AMBA
        select ARCH_HAS_CPUFREQ
        select COMMON_CLK
-       select CLK_VERSATILE
+       select COMMON_CLK_VERSATILE
        select HAVE_TCM
        select ICST
        select GENERIC_CLOCKEVENTS
@@ -289,13 +289,12 @@ config ARCH_INTEGRATOR
 config ARCH_REALVIEW
        bool "ARM Ltd. RealView family"
        select ARM_AMBA
-       select CLKDEV_LOOKUP
-       select HAVE_MACH_CLKDEV
+       select COMMON_CLK
+       select COMMON_CLK_VERSATILE
        select ICST
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select PLAT_VERSATILE
-       select PLAT_VERSATILE_CLOCK
        select PLAT_VERSATILE_CLCD
        select ARM_TIMER_SP804
        select GPIO_PL061 if GPIOLIB
index 45868bb43cbd2fbcbfcdfff638dc15f1cbd7d38b..ff007d15e0ec99b165e540e4d5eefee40ceb8f86 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/ata_platform.h>
 #include <linux/amba/mmci.h>
 #include <linux/gfp.h>
-#include <linux/clkdev.h>
 #include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
@@ -226,115 +225,10 @@ struct mmci_platform_data realview_mmc1_plat_data = {
        .cd_invert      = true,
 };
 
-/*
- * Clock handling
- */
-static const struct icst_params realview_oscvco_params = {
-       .ref            = 24000000,
-       .vco_max        = ICST307_VCO_MAX,
-       .vco_min        = ICST307_VCO_MIN,
-       .vd_min         = 4 + 8,
-       .vd_max         = 511 + 8,
-       .rd_min         = 1 + 2,
-       .rd_max         = 127 + 2,
-       .s2div          = icst307_s2div,
-       .idx2s          = icst307_idx2s,
-};
-
-static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
-{
-       void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-       u32 val;
-
-       val = readl(clk->vcoreg) & ~0x7ffff;
-       val |= vco.v | (vco.r << 9) | (vco.s << 16);
-
-       writel(0xa05f, sys_lock);
-       writel(val, clk->vcoreg);
-       writel(0, sys_lock);
-}
-
-static const struct clk_ops oscvco_clk_ops = {
-       .round  = icst_clk_round,
-       .set    = icst_clk_set,
-       .setvco = realview_oscvco_set,
-};
-
-static struct clk oscvco_clk = {
-       .ops    = &oscvco_clk_ops,
-       .params = &realview_oscvco_params,
-};
-
-/*
- * These are fixed clocks.
- */
-static struct clk ref24_clk = {
-       .rate   = 24000000,
-};
-
-static struct clk sp804_clk = {
-       .rate   = 1000000,
-};
-
-static struct clk dummy_apb_pclk;
-
-static struct clk_lookup lookups[] = {
-       {       /* Bus clock */
-               .con_id         = "apb_pclk",
-               .clk            = &dummy_apb_pclk,
-       }, {    /* UART0 */
-               .dev_id         = "dev:uart0",
-               .clk            = &ref24_clk,
-       }, {    /* UART1 */
-               .dev_id         = "dev:uart1",
-               .clk            = &ref24_clk,
-       }, {    /* UART2 */
-               .dev_id         = "dev:uart2",
-               .clk            = &ref24_clk,
-       }, {    /* UART3 */
-               .dev_id         = "fpga:uart3",
-               .clk            = &ref24_clk,
-       }, {    /* UART3 is on the dev chip in PB1176 */
-               .dev_id         = "dev:uart3",
-               .clk            = &ref24_clk,
-       }, {    /* UART4 only exists in PB1176 */
-               .dev_id         = "fpga:uart4",
-               .clk            = &ref24_clk,
-       }, {    /* KMI0 */
-               .dev_id         = "fpga:kmi0",
-               .clk            = &ref24_clk,
-       }, {    /* KMI1 */
-               .dev_id         = "fpga:kmi1",
-               .clk            = &ref24_clk,
-       }, {    /* MMC0 */
-               .dev_id         = "fpga:mmc0",
-               .clk            = &ref24_clk,
-       }, {    /* CLCD is in the PB1176 and EB DevChip */
-               .dev_id         = "dev:clcd",
-               .clk            = &oscvco_clk,
-       }, {    /* PB:CLCD */
-               .dev_id         = "issp:clcd",
-               .clk            = &oscvco_clk,
-       }, {    /* SSP */
-               .dev_id         = "dev:ssp0",
-               .clk            = &ref24_clk,
-       }, {    /* SP804 timers */
-               .dev_id         = "sp804",
-               .clk            = &sp804_clk,
-       },
-};
-
 void __init realview_init_early(void)
 {
        void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
 
-       if (machine_is_realview_pb1176())
-               oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
-       else
-               oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
-
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
        versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
 }
 
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
deleted file mode 100644 (file)
index e58d077..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#include <plat/clock.h>
-
-struct clk {
-       unsigned long           rate;
-       const struct clk_ops    *ops;
-       const struct icst_params *params;
-       void __iomem            *vcoreg;
-};
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do { } while (0)
-
-#endif
index baf382c5e77601957b2ef8982ccdd61552f9b2f2..a33e33b76733100ccf7872dd1f7d3929c39359ab 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -414,6 +415,7 @@ static void __init realview_eb_timer_init(void)
        else
                timer_irq = IRQ_EB_TIMER0_1;
 
+       realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
        realview_timer_init(timer_irq);
        realview_eb_twd_init();
 }
index b1d7cafa1a6d2e295c2f95529b1d556df4b85db1..f0298cbc203e98fffda9f0908c87a8d95397d307 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -326,6 +327,7 @@ static void __init realview_pb1176_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20;
 
+       realview_clk_init(__io_address(REALVIEW_SYS_BASE), true);
        realview_timer_init(IRQ_DC1176_TIMER0);
 }
 
index a98c536e3327afa9823a2b29ffd081258be2ae5a..1f019f76f7b5e8c4ad2f4622cdda8f46b1dfe546 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -312,6 +313,7 @@ static void __init realview_pb11mp_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
 
+       realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
        realview_timer_init(IRQ_TC11MP_TIMER0_1);
        realview_pb11mp_twd_init();
 }
index 59650174e6ed39e9c3bc9e44441beb48b22a4214..5032775dbfeefb51bb07bfce6d1e34fc9819127c 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
 
 #include <asm/irq.h>
 #include <asm/leds.h>
@@ -261,6 +262,7 @@ static void __init realview_pba8_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
 
+       realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
        realview_timer_init(IRQ_PBA8_TIMER0_1);
 }
 
index 3f2f605624e95270fd1039e64a3a0a2d2180cd06..de64ba0ddb956822a27e0b4b7c77f2d04e45e699 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
+#include <linux/platform_data/clk-realview.h>
 
 #include <asm/irq.h>
 #include <asm/leds.h>
@@ -320,6 +321,7 @@ static void __init realview_pbx_timer_init(void)
        timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
        timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
 
+       realview_clk_init(__io_address(REALVIEW_SYS_BASE), false);
        realview_timer_init(IRQ_PBX_TIMER0_1);
        realview_pbx_twd_init();
 }
index 7f0b5ca785160733839e6652cf7d67b410fe32e9..89b726d1afe509cff3067d7c217fd725832bbf8b 100644 (file)
@@ -40,4 +40,11 @@ config COMMON_CLK_WM831X
           Supports the clocking subsystem of the WM831x/2x series of
          PMICs from Wolfson Microlectronics.
 
+config COMMON_CLK_VERSATILE
+       tristate "Clock driver for ARM Reference designs"
+       depends on ARCH_INTEGRATOR || ARCH_REALVIEW
+       ---help---
+          Supports clocking on ARM Reference designs Integrator/AP,
+         Integrator/CP, RealView PB1176, EB, PB11MP and PBX.
+
 endmenu
index d4c7253eb30779d126a4b349622ae99ac505f281..e30376c4ff5d95dc308d0f3020148f90d95b35a6 100644 (file)
@@ -9,7 +9,7 @@ obj-$(CONFIG_ARCH_MXS)          += mxs/
 obj-$(CONFIG_ARCH_SOCFPGA)     += socfpga/
 obj-$(CONFIG_PLAT_SPEAR)       += spear/
 obj-$(CONFIG_ARCH_U300)                += clk-u300.o
-obj-$(CONFIG_ARCH_INTEGRATOR)  += versatile/
+obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
 obj-$(CONFIG_ARCH_PRIMA2)      += clk-prima2.o
 
 # Chip specific
index 50cf6a2ee693ce1d8d8d032047e8718a77963a7e..c0a0f647879848ff245db88cd7ef0306796b85f9 100644 (file)
@@ -1,3 +1,4 @@
 # Makefile for Versatile-specific clocks
 obj-$(CONFIG_ICST)             += clk-icst.o
 obj-$(CONFIG_ARCH_INTEGRATOR)  += clk-integrator.o
+obj-$(CONFIG_ARCH_REALVIEW)    += clk-realview.o
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
new file mode 100644 (file)
index 0000000..e21a99c
--- /dev/null
@@ -0,0 +1,114 @@
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#include "clk-icst.h"
+
+/*
+ * Implementation of the ARM RealView clock trees.
+ */
+
+static void __iomem *sys_lock;
+static void __iomem *sys_vcoreg;
+
+/**
+ * realview_oscvco_get() - get ICST OSC settings for the RealView
+ */
+static struct icst_vco realview_oscvco_get(void)
+{
+       u32 val;
+       struct icst_vco vco;
+
+       val = readl(sys_vcoreg);
+       vco.v = val & 0x1ff;
+       vco.r = (val >> 9) & 0x7f;
+       vco.s = (val >> 16) & 03;
+       return vco;
+}
+
+static void realview_oscvco_set(struct icst_vco vco)
+{
+       u32 val;
+
+       val = readl(sys_vcoreg) & ~0x7ffff;
+       val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+       /* This magic unlocks the CM VCO so it can be controlled */
+       writel(0xa05f, sys_lock);
+       writel(val, sys_vcoreg);
+       /* This locks the CM again */
+       writel(0, sys_lock);
+}
+
+static const struct icst_params realview_oscvco_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST307_VCO_MAX,
+       .vco_min        = ICST307_VCO_MIN,
+       .vd_min         = 4 + 8,
+       .vd_max         = 511 + 8,
+       .rd_min         = 1 + 2,
+       .rd_max         = 127 + 2,
+       .s2div          = icst307_s2div,
+       .idx2s          = icst307_idx2s,
+};
+
+static const struct clk_icst_desc __initdata realview_icst_desc = {
+       .params = &realview_oscvco_params,
+       .getvco = realview_oscvco_get,
+       .setvco = realview_oscvco_set,
+};
+
+/*
+ * realview_clk_init() - set up the RealView clock tree
+ */
+void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
+{
+       struct clk *clk;
+
+       sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET;
+       if (is_pb1176)
+               sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET;
+       else
+               sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET;
+
+
+       /* APB clock dummy */
+       clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0);
+       clk_register_clkdev(clk, "apb_pclk", NULL);
+
+       /* 24 MHz clock */
+       clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT,
+                               24000000);
+       clk_register_clkdev(clk, NULL, "dev:uart0");
+       clk_register_clkdev(clk, NULL, "dev:uart1");
+       clk_register_clkdev(clk, NULL, "dev:uart2");
+       clk_register_clkdev(clk, NULL, "fpga:kmi0");
+       clk_register_clkdev(clk, NULL, "fpga:kmi1");
+       clk_register_clkdev(clk, NULL, "fpga:mmc0");
+       clk_register_clkdev(clk, NULL, "dev:ssp0");
+       if (is_pb1176) {
+               /*
+                * UART3 is on the dev chip in PB1176
+                * UART4 only exists in PB1176
+                */
+               clk_register_clkdev(clk, NULL, "dev:uart3");
+               clk_register_clkdev(clk, NULL, "dev:uart4");
+       } else
+               clk_register_clkdev(clk, NULL, "fpga:uart3");
+
+
+       /* 1 MHz clock */
+       clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT,
+                                     1000000);
+       clk_register_clkdev(clk, NULL, "sp804");
+
+       /* ICST VCO clock */
+       clk = icst_clk_register(NULL, &realview_icst_desc);
+       clk_register_clkdev(clk, NULL, "dev:clcd");
+       clk_register_clkdev(clk, NULL, "issp:clcd");
+}
diff --git a/include/linux/platform_data/clk-realview.h b/include/linux/platform_data/clk-realview.h
new file mode 100644 (file)
index 0000000..2e426a7
--- /dev/null
@@ -0,0 +1 @@
+void realview_clk_init(void __iomem *sysbase, bool is_pb1176);