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 2023a9e..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)
@@ -109,10 +99,10 @@ static struct clcd_board ct_ca9x4_clcd_data = {
        .remove         = versatile_clcd_remove_dma,
 };
 
-static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
-static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
-static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
-static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL);
+static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL);
+static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL);
 
 static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
        &clcd_device,
@@ -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,21 +175,33 @@ static void __init ct_ca9x4_init(void)
 }
 
 #ifdef CONFIG_SMP
-static void ct_ca9x4_init_cpu_map(void)
+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",
+                       ncores, nr_cpu_ids);
+               ncores = nr_cpu_ids;
+       }
 
        for (i = 0; i < ncores; ++i)
                set_cpu_possible(i, true);
+
+       set_smp_cross_call(gic_raise_softirq);
 }
 
-static void ct_ca9x4_smp_enable(unsigned int max_cpus)
+static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
-       int i;
-       for (i = 0; i < max_cpus; i++)
-               set_cpu_present(i, true);
-
-       scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+       scu_enable(ct_ca9x4_scu_base);
 }
 #endif
 
@@ -239,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