diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-28 12:26:25 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-05-02 04:35:39 -0400 |
commit | fef88f10767cfd9f9b4eebb5d5490214c5e13ad5 (patch) | |
tree | cf4a8cb7d8e3959a0d1692314ec41282eeeff6c3 /arch/arm | |
parent | ceade897f31b8bb66f378cc35859fcfd0d46aaa2 (diff) |
ARM: Add Versatile Express CA9x4 processor support
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-vexpress/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/ct-ca9x4.c | 215 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | 43 | ||||
-rw-r--r-- | arch/arm/mm/Kconfig | 3 |
5 files changed, 266 insertions, 1 deletions
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 751858c97e6a..3f19b660a165 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig | |||
@@ -1,4 +1,9 @@ | |||
1 | menu "Versatile Express platform type" | 1 | menu "Versatile Express platform type" |
2 | depends on ARCH_VEXPRESS | 2 | depends on ARCH_VEXPRESS |
3 | 3 | ||
4 | config ARCH_VEXPRESS_CA9X4 | ||
5 | bool "Versatile Express Cortex-A9x4 tile" | ||
6 | select CPU_V7 | ||
7 | select ARM_GIC | ||
8 | |||
4 | endmenu | 9 | endmenu |
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index b47cf732981f..3c5e1609fc4f 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile | |||
@@ -3,3 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := v2m.o | 5 | obj-y := v2m.o |
6 | 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 index 000000000000..5a0449c6f50d --- /dev/null +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Versatile Express Core Tile Cortex A9x4 Support | ||
3 | */ | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/device.h> | ||
6 | #include <linux/dma-mapping.h> | ||
7 | #include <linux/amba/bus.h> | ||
8 | #include <linux/amba/clcd.h> | ||
9 | |||
10 | #include <asm/clkdev.h> | ||
11 | #include <asm/hardware/arm_timer.h> | ||
12 | #include <asm/hardware/cache-l2x0.h> | ||
13 | #include <asm/hardware/gic.h> | ||
14 | #include <asm/mach-types.h> | ||
15 | |||
16 | #include <mach/clkdev.h> | ||
17 | #include <mach/ct-ca9x4.h> | ||
18 | |||
19 | #include <plat/timer-sp.h> | ||
20 | |||
21 | #include <asm/mach/arch.h> | ||
22 | #include <asm/mach/map.h> | ||
23 | #include <asm/mach/time.h> | ||
24 | |||
25 | #include "core.h" | ||
26 | |||
27 | #include <mach/motherboard.h> | ||
28 | |||
29 | #define V2M_PA_CS7 0x10000000 | ||
30 | |||
31 | static struct map_desc ct_ca9x4_io_desc[] __initdata = { | ||
32 | { | ||
33 | .virtual = __MMIO_P2V(CT_CA9X4_MPIC), | ||
34 | .pfn = __phys_to_pfn(CT_CA9X4_MPIC), | ||
35 | .length = SZ_16K, | ||
36 | .type = MT_DEVICE, | ||
37 | }, { | ||
38 | .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER), | ||
39 | .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER), | ||
40 | .length = SZ_4K, | ||
41 | .type = MT_DEVICE, | ||
42 | }, { | ||
43 | .virtual = __MMIO_P2V(CT_CA9X4_L2CC), | ||
44 | .pfn = __phys_to_pfn(CT_CA9X4_L2CC), | ||
45 | .length = SZ_4K, | ||
46 | .type = MT_DEVICE, | ||
47 | }, | ||
48 | }; | ||
49 | |||
50 | static void __init ct_ca9x4_map_io(void) | ||
51 | { | ||
52 | v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); | ||
53 | } | ||
54 | |||
55 | void __iomem *gic_cpu_base_addr; | ||
56 | |||
57 | static void __init ct_ca9x4_init_irq(void) | ||
58 | { | ||
59 | gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU); | ||
60 | gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29); | ||
61 | gic_cpu_init(0, gic_cpu_base_addr); | ||
62 | } | ||
63 | |||
64 | #if 0 | ||
65 | static void ct_ca9x4_timer_init(void) | ||
66 | { | ||
67 | writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); | ||
68 | writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); | ||
69 | |||
70 | sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1)); | ||
71 | sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0); | ||
72 | } | ||
73 | |||
74 | static struct sys_timer ct_ca9x4_timer = { | ||
75 | .init = ct_ca9x4_timer_init, | ||
76 | }; | ||
77 | #endif | ||
78 | |||
79 | static struct clcd_panel xvga_panel = { | ||
80 | .mode = { | ||
81 | .name = "XVGA", | ||
82 | .refresh = 60, | ||
83 | .xres = 1024, | ||
84 | .yres = 768, | ||
85 | .pixclock = 15384, | ||
86 | .left_margin = 168, | ||
87 | .right_margin = 8, | ||
88 | .upper_margin = 29, | ||
89 | .lower_margin = 3, | ||
90 | .hsync_len = 144, | ||
91 | .vsync_len = 6, | ||
92 | .sync = 0, | ||
93 | .vmode = FB_VMODE_NONINTERLACED, | ||
94 | }, | ||
95 | .width = -1, | ||
96 | .height = -1, | ||
97 | .tim2 = TIM2_BCD | TIM2_IPC, | ||
98 | .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1), | ||
99 | .bpp = 16, | ||
100 | }; | ||
101 | |||
102 | static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) | ||
103 | { | ||
104 | v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); | ||
105 | v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2); | ||
106 | } | ||
107 | |||
108 | static int ct_ca9x4_clcd_setup(struct clcd_fb *fb) | ||
109 | { | ||
110 | unsigned long framesize = 1024 * 768 * 2; | ||
111 | dma_addr_t dma; | ||
112 | |||
113 | fb->panel = &xvga_panel; | ||
114 | |||
115 | fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize, | ||
116 | &dma, GFP_KERNEL); | ||
117 | if (!fb->fb.screen_base) { | ||
118 | printk(KERN_ERR "CLCD: unable to map frame buffer\n"); | ||
119 | return -ENOMEM; | ||
120 | } | ||
121 | fb->fb.fix.smem_start = dma; | ||
122 | fb->fb.fix.smem_len = framesize; | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma) | ||
128 | { | ||
129 | return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base, | ||
130 | fb->fb.fix.smem_start, fb->fb.fix.smem_len); | ||
131 | } | ||
132 | |||
133 | static void ct_ca9x4_clcd_remove(struct clcd_fb *fb) | ||
134 | { | ||
135 | dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len, | ||
136 | fb->fb.screen_base, fb->fb.fix.smem_start); | ||
137 | } | ||
138 | |||
139 | static struct clcd_board ct_ca9x4_clcd_data = { | ||
140 | .name = "CT-CA9X4", | ||
141 | .check = clcdfb_check, | ||
142 | .decode = clcdfb_decode, | ||
143 | .enable = ct_ca9x4_clcd_enable, | ||
144 | .setup = ct_ca9x4_clcd_setup, | ||
145 | .mmap = ct_ca9x4_clcd_mmap, | ||
146 | .remove = ct_ca9x4_clcd_remove, | ||
147 | }; | ||
148 | |||
149 | static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data); | ||
150 | static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL); | ||
151 | static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL); | ||
152 | static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL); | ||
153 | |||
154 | static struct amba_device *ct_ca9x4_amba_devs[] __initdata = { | ||
155 | &clcd_device, | ||
156 | &dmc_device, | ||
157 | &smc_device, | ||
158 | &gpio_device, | ||
159 | }; | ||
160 | |||
161 | |||
162 | static long ct_round(struct clk *clk, unsigned long rate) | ||
163 | { | ||
164 | return rate; | ||
165 | } | ||
166 | |||
167 | static int ct_set(struct clk *clk, unsigned long rate) | ||
168 | { | ||
169 | return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate); | ||
170 | } | ||
171 | |||
172 | static const struct clk_ops osc1_clk_ops = { | ||
173 | .round = ct_round, | ||
174 | .set = ct_set, | ||
175 | }; | ||
176 | |||
177 | static struct clk osc1_clk = { | ||
178 | .ops = &osc1_clk_ops, | ||
179 | .rate = 24000000, | ||
180 | }; | ||
181 | |||
182 | static struct clk_lookup lookups[] = { | ||
183 | { /* CLCD */ | ||
184 | .dev_id = "ct:clcd", | ||
185 | .clk = &osc1_clk, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static void ct_ca9x4_init(void) | ||
190 | { | ||
191 | int i; | ||
192 | |||
193 | #ifdef CONFIG_CACHE_L2X0 | ||
194 | l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); | ||
195 | #endif | ||
196 | |||
197 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | ||
198 | |||
199 | for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++) | ||
200 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); | ||
201 | } | ||
202 | |||
203 | MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") | ||
204 | .phys_io = V2M_UART0, | ||
205 | .io_pg_offst = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc, | ||
206 | .boot_params = PHYS_OFFSET + 0x00000100, | ||
207 | .map_io = ct_ca9x4_map_io, | ||
208 | .init_irq = ct_ca9x4_init_irq, | ||
209 | #if 0 | ||
210 | .timer = &ct_ca9x4_timer, | ||
211 | #else | ||
212 | .timer = &v2m_timer, | ||
213 | #endif | ||
214 | .init_machine = ct_ca9x4_init, | ||
215 | 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 index 000000000000..10718e654c6a --- /dev/null +++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h | |||
@@ -0,0 +1,43 @@ | |||
1 | #ifndef __MACH_CT_CA9X4_H | ||
2 | #define __MACH_CT_CA9X4_H | ||
3 | |||
4 | /* | ||
5 | * Physical base addresses | ||
6 | */ | ||
7 | #define CT_CA9X4_CLCDC (0x10020000) | ||
8 | #define CT_CA9X4_AXIRAM (0x10060000) | ||
9 | #define CT_CA9X4_DMC (0x100e0000) | ||
10 | #define CT_CA9X4_SMC (0x100e1000) | ||
11 | #define CT_CA9X4_SCC (0x100e2000) | ||
12 | #define CT_CA9X4_SP804_TIMER (0x100e4000) | ||
13 | #define CT_CA9X4_SP805_WDT (0x100e5000) | ||
14 | #define CT_CA9X4_TZPC (0x100e6000) | ||
15 | #define CT_CA9X4_GPIO (0x100e8000) | ||
16 | #define CT_CA9X4_FASTAXI (0x100e9000) | ||
17 | #define CT_CA9X4_SLOWAXI (0x100ea000) | ||
18 | #define CT_CA9X4_TZASC (0x100ec000) | ||
19 | #define CT_CA9X4_CORESIGHT (0x10200000) | ||
20 | #define CT_CA9X4_MPIC (0x1e000000) | ||
21 | #define CT_CA9X4_SYSTIMER (0x1e004000) | ||
22 | #define CT_CA9X4_SYSWDT (0x1e007000) | ||
23 | #define CT_CA9X4_L2CC (0x1e00a000) | ||
24 | |||
25 | #define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000) | ||
26 | #define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020) | ||
27 | |||
28 | #define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000) | ||
29 | #define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100) | ||
30 | #define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200) | ||
31 | #define A9_MPCORE_GIC_DIST (CT_CA9X4_MPIC + 0x1000) | ||
32 | |||
33 | /* | ||
34 | * Interrupts. Those in {} are for AMBA devices | ||
35 | */ | ||
36 | #define IRQ_CT_CA9X4_CLCDC { 76 } | ||
37 | #define IRQ_CT_CA9X4_DMC { -1 } | ||
38 | #define IRQ_CT_CA9X4_SMC { 77, 78 } | ||
39 | #define IRQ_CT_CA9X4_TIMER0 80 | ||
40 | #define IRQ_CT_CA9X4_TIMER1 81 | ||
41 | #define IRQ_CT_CA9X4_GPIO { 82 } | ||
42 | |||
43 | #endif | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c4ed9f93f646..270c8e2a4490 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -754,7 +754,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH | |||
754 | config CACHE_L2X0 | 754 | config CACHE_L2X0 |
755 | bool "Enable the L2x0 outer cache controller" | 755 | bool "Enable the L2x0 outer cache controller" |
756 | depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ | 756 | depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \ |
757 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4 | 757 | REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \ |
758 | ARCH_NOMADIK || ARCH_OMAP4 || ARCH_VEXPRESS_CA9X4 | ||
758 | default y | 759 | default y |
759 | select OUTER_CACHE | 760 | select OUTER_CACHE |
760 | help | 761 | help |