Merge tag 'multi-platform-for-3.7' of git://sources.calxeda.com/kernel/linux into...
[linux-3.10.git] / arch / arm / mach-vexpress / ct-ca9x4.c
index 1b1d2e4..4f471fa 100644 (file)
@@ -13,7 +13,6 @@
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
-#include <asm/pmu.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 
 #include "core.h"
 
 #include <mach/motherboard.h>
+#include <mach/irqs.h>
 
 #include <plat/clcd.h>
 
-#define V2M_PA_CS7     0x10000000
-
 static struct map_desc ct_ca9x4_io_desc[] __initdata = {
        {
-               .virtual        = __MMIO_P2V(CT_CA9X4_MPIC),
-               .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
-               .length         = SZ_16K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
-               .pfn            = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
-       }, {
-               .virtual        = __MMIO_P2V(CT_CA9X4_L2CC),
-               .pfn            = __phys_to_pfn(CT_CA9X4_L2CC),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
+               .virtual        = V2T_PERIPH,
+               .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
+               .length         = SZ_8K,
+               .type           = MT_DEVICE,
        },
 };
 
 static void __init ct_ca9x4_map_io(void)
 {
-#ifdef CONFIG_LOCAL_TIMERS
-       twd_base = MMIO_P2V(A9_MPCORE_TWD);
-#endif
        iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
-static void __init ct_ca9x4_init_irq(void)
+#ifdef CONFIG_HAVE_ARM_TWD
+static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
+
+static void __init ca9x4_twd_init(void)
 {
-       gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
-                MMIO_P2V(A9_MPCORE_GIC_CPU));
+       int err = twd_local_timer_register(&twd_local_timer);
+       if (err)
+               pr_err("twd_local_timer_register failed %d\n", err);
 }
+#else
+#define ca9x4_twd_init()       do {} while(0)
+#endif
 
-#if 0
-static void __init ct_ca9x4_timer_init(void)
+static void __init ct_ca9x4_init_irq(void)
 {
-       writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
-       writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
-
-       sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1");
-       sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0,
-               "ct-timer0");
+       gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
+                ioremap(A9_MPCORE_GIC_CPU, SZ_256));
+       ca9x4_twd_init();
 }
 
-static struct sys_timer ct_ca9x4_timer = {
-       .init   = ct_ca9x4_timer_init,
-};
-#endif
-
 static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
 {
-       v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
-       v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
+       u32 site = v2m_get_master_site();
+
+       /*
+        * Old firmware was using the "site" component of the command
+        * to control the DVI muxer (while it should be always 0 ie. MB).
+        * Newer firmware uses the data register. Keep both for compatibility.
+        */
+       v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE(site), site);
+       v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE(SYS_CFG_SITE_MB), 2);
 }
 
 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
@@ -122,43 +112,11 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
 };
 
 
-static long ct_round(struct clk *clk, unsigned long rate)
-{
-       return rate;
-}
-
-static int ct_set(struct clk *clk, unsigned long rate)
-{
-       return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
-}
-
-static const struct clk_ops osc1_clk_ops = {
-       .round  = ct_round,
-       .set    = ct_set,
-};
-
-static struct clk osc1_clk = {
-       .ops    = &osc1_clk_ops,
-       .rate   = 24000000,
-};
-
-static struct clk ct_sp804_clk = {
-       .rate   = 1000000,
-};
-
-static struct clk_lookup lookups[] = {
-       {       /* CLCD */
-               .dev_id         = "ct:clcd",
-               .clk            = &osc1_clk,
-       }, {    /* SP804 timers */
-               .dev_id         = "sp804",
-               .con_id         = "ct-timer0",
-               .clk            = &ct_sp804_clk,
-       }, {    /* SP804 timers */
-               .dev_id         = "sp804",
-               .con_id         = "ct-timer1",
-               .clk            = &ct_sp804_clk,
-       },
+static struct v2m_osc ct_osc1 = {
+       .osc = 1,
+       .rate_min = 10000000,
+       .rate_max = 80000000,
+       .rate_default = 23750000,
 };
 
 static struct resource pmu_resources[] = {
@@ -186,22 +144,18 @@ static struct resource pmu_resources[] = {
 
 static struct platform_device pmu_device = {
        .name           = "arm-pmu",
-       .id             = ARM_PMU_DEVICE_CPU,
+       .id             = -1,
        .num_resources  = ARRAY_SIZE(pmu_resources),
        .resource       = pmu_resources,
 };
 
-static void __init ct_ca9x4_init_early(void)
-{
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-}
-
 static void __init ct_ca9x4_init(void)
 {
        int i;
+       struct clk *clk;
 
 #ifdef CONFIG_CACHE_L2X0
-       void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
+       void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
 
        /* set RAM latencies to 1 cycle for this core tile. */
        writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
@@ -210,6 +164,10 @@ static void __init ct_ca9x4_init(void)
        l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
 #endif
 
+       ct_osc1.site = v2m_get_master_site();
+       clk = v2m_osc_register("ct:osc1", &ct_osc1);
+       clk_register_clkdev(clk, NULL, "ct:clcd");
+
        for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
                amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
 
@@ -217,9 +175,17 @@ static void __init ct_ca9x4_init(void)
 }
 
 #ifdef CONFIG_SMP
+static void *ct_ca9x4_scu_base __initdata;
+
 static void __init ct_ca9x4_init_cpu_map(void)
 {
-       int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
+       int i, ncores;
+
+       ct_ca9x4_scu_base = ioremap(A9_MPCORE_SCU, SZ_128);
+       if (WARN_ON(!ct_ca9x4_scu_base))
+               return;
+
+       ncores = scu_get_core_count(ct_ca9x4_scu_base);
 
        if (ncores > nr_cpu_ids) {
                pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
@@ -235,7 +201,7 @@ static void __init ct_ca9x4_init_cpu_map(void)
 
 static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
-       scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+       scu_enable(ct_ca9x4_scu_base);
 }
 #endif
 
@@ -243,7 +209,6 @@ struct ct_desc ct_ca9x4_desc __initdata = {
        .id             = V2M_CT_ID_CA9,
        .name           = "CA9x4",
        .map_io         = ct_ca9x4_map_io,
-       .init_early     = ct_ca9x4_init_early,
        .init_irq       = ct_ca9x4_init_irq,
        .init_tile      = ct_ca9x4_init,
 #ifdef CONFIG_SMP