ARM: Add Versatile Express CA9x4 processor support
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 28 Feb 2010 17:26:25 +0000 (17:26 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 2 May 2010 08:35:39 +0000 (09:35 +0100)
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-vexpress/Kconfig
arch/arm/mach-vexpress/Makefile
arch/arm/mach-vexpress/ct-ca9x4.c [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/ct-ca9x4.h [new file with mode: 0644]
arch/arm/mm/Kconfig

index 751858c..3f19b66 100644 (file)
@@ -1,4 +1,9 @@
 menu "Versatile Express platform type"
        depends on ARCH_VEXPRESS
 
+config ARCH_VEXPRESS_CA9X4
+       bool "Versatile Express Cortex-A9x4 tile"
+       select CPU_V7
+       select ARM_GIC
+
 endmenu
index b47cf73..3c5e160 100644 (file)
@@ -3,3 +3,4 @@
 #
 
 obj-y                                  := v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)      += ct-ca9x4.o
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
new file mode 100644 (file)
index 0000000..5a0449c
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Versatile Express Core Tile Cortex A9x4 Support
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/clkdev.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+
+#include <mach/clkdev.h>
+#include <mach/ct-ca9x4.h>
+
+#include <plat/timer-sp.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "core.h"
+
+#include <mach/motherboard.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,
+       },
+};
+
+static void __init ct_ca9x4_map_io(void)
+{
+       v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+}
+
+void __iomem *gic_cpu_base_addr;
+
+static void __init ct_ca9x4_init_irq(void)
+{
+       gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU);
+       gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29);
+       gic_cpu_init(0, gic_cpu_base_addr);
+}
+
+#if 0
+static void ct_ca9x4_timer_init(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));
+       sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0);
+}
+
+static struct sys_timer ct_ca9x4_timer = {
+       .init   = ct_ca9x4_timer_init,
+};
+#endif
+
+static struct clcd_panel xvga_panel = {
+       .mode           = {
+               .name           = "XVGA",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15384,
+               .left_margin    = 168,
+               .right_margin   = 8,
+               .upper_margin   = 29,
+               .lower_margin   = 3,
+               .hsync_len      = 144,
+               .vsync_len      = 6,
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       .width          = -1,
+       .height         = -1,
+       .tim2           = TIM2_BCD | TIM2_IPC,
+       .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+       .bpp            = 16,
+};
+
+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);
+}
+
+static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
+{
+       unsigned long framesize = 1024 * 768 * 2;
+       dma_addr_t dma;
+
+       fb->panel = &xvga_panel;
+
+       fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+                               &dma, GFP_KERNEL);
+       if (!fb->fb.screen_base) {
+               printk(KERN_ERR "CLCD: unable to map frame buffer\n");
+               return -ENOMEM;
+       }
+       fb->fb.fix.smem_start = dma;
+       fb->fb.fix.smem_len = framesize;
+
+       return 0;
+}
+
+static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+       return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+               fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void ct_ca9x4_clcd_remove(struct clcd_fb *fb)
+{
+       dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+               fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board ct_ca9x4_clcd_data = {
+       .name           = "CT-CA9X4",
+       .check          = clcdfb_check,
+       .decode         = clcdfb_decode,
+       .enable         = ct_ca9x4_clcd_enable,
+       .setup          = ct_ca9x4_clcd_setup,
+       .mmap           = ct_ca9x4_clcd_mmap,
+       .remove         = ct_ca9x4_clcd_remove,
+};
+
+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 struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
+       &clcd_device,
+       &dmc_device,
+       &smc_device,
+       &gpio_device,
+};
+
+
+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_lookup lookups[] = {
+       {       /* CLCD */
+               .dev_id         = "ct:clcd",
+               .clk            = &osc1_clk,
+       },
+};
+
+static void ct_ca9x4_init(void)
+{
+       int i;
+
+#ifdef CONFIG_CACHE_L2X0
+       l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff);
+#endif
+
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+       for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
+               amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
+       .phys_io        = V2M_UART0,
+       .io_pg_offst    = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
+       .boot_params    = PHYS_OFFSET + 0x00000100,
+       .map_io         = ct_ca9x4_map_io,
+       .init_irq       = ct_ca9x4_init_irq,
+#if 0
+       .timer          = &ct_ca9x4_timer,
+#else
+       .timer          = &v2m_timer,
+#endif
+       .init_machine   = ct_ca9x4_init,
+MACHINE_END
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
new file mode 100644 (file)
index 0000000..10718e6
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __MACH_CT_CA9X4_H
+#define __MACH_CT_CA9X4_H
+
+/*
+ * Physical base addresses
+ */
+#define CT_CA9X4_CLCDC         (0x10020000)
+#define CT_CA9X4_AXIRAM                (0x10060000)
+#define CT_CA9X4_DMC           (0x100e0000)
+#define CT_CA9X4_SMC           (0x100e1000)
+#define CT_CA9X4_SCC           (0x100e2000)
+#define CT_CA9X4_SP804_TIMER   (0x100e4000)
+#define CT_CA9X4_SP805_WDT     (0x100e5000)
+#define CT_CA9X4_TZPC          (0x100e6000)
+#define CT_CA9X4_GPIO          (0x100e8000)
+#define CT_CA9X4_FASTAXI       (0x100e9000)
+#define CT_CA9X4_SLOWAXI       (0x100ea000)
+#define CT_CA9X4_TZASC         (0x100ec000)
+#define CT_CA9X4_CORESIGHT     (0x10200000)
+#define CT_CA9X4_MPIC          (0x1e000000)
+#define CT_CA9X4_SYSTIMER      (0x1e004000)
+#define CT_CA9X4_SYSWDT                (0x1e007000)
+#define CT_CA9X4_L2CC          (0x1e00a000)
+
+#define CT_CA9X4_TIMER0                (CT_CA9X4_SP804_TIMER + 0x000)
+#define CT_CA9X4_TIMER1                (CT_CA9X4_SP804_TIMER + 0x020)
+
+#define A9_MPCORE_SCU          (CT_CA9X4_MPIC + 0x0000)
+#define A9_MPCORE_GIC_CPU      (CT_CA9X4_MPIC + 0x0100)
+#define A9_MPCORE_GIT          (CT_CA9X4_MPIC + 0x0200)
+#define A9_MPCORE_GIC_DIST     (CT_CA9X4_MPIC + 0x1000)
+
+/*
+ * Interrupts.  Those in {} are for AMBA devices
+ */
+#define IRQ_CT_CA9X4_CLCDC     { 76 }
+#define IRQ_CT_CA9X4_DMC       { -1 }
+#define IRQ_CT_CA9X4_SMC       { 77, 78 }
+#define IRQ_CT_CA9X4_TIMER0    80
+#define IRQ_CT_CA9X4_TIMER1    81
+#define IRQ_CT_CA9X4_GPIO      { 82 }
+
+#endif
index c4ed9f9..270c8e2 100644 (file)
@@ -754,7 +754,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 config CACHE_L2X0
        bool "Enable the L2x0 outer cache controller"
        depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
-                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
+                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
+                  ARCH_NOMADIK || ARCH_OMAP4 || ARCH_VEXPRESS_CA9X4
        default y
        select OUTER_CACHE
        help