2 * Versatile Express Core Tile Cortex A9x4 Support
4 #include <linux/init.h>
6 #include <linux/device.h>
7 #include <linux/dma-mapping.h>
8 #include <linux/platform_device.h>
9 #include <linux/amba/bus.h>
10 #include <linux/amba/clcd.h>
12 #include <asm/clkdev.h>
13 #include <asm/pgtable.h>
14 #include <asm/hardware/arm_timer.h>
15 #include <asm/hardware/cache-l2x0.h>
16 #include <asm/hardware/gic.h>
17 #include <asm/mach-types.h>
19 #include <asm/smp_twd.h>
21 #include <mach/clkdev.h>
22 #include <mach/ct-ca9x4.h>
24 #include <plat/timer-sp.h>
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <asm/mach/time.h>
32 #include <mach/motherboard.h>
34 #define V2M_PA_CS7 0x10000000
36 static struct map_desc ct_ca9x4_io_desc
[] __initdata
= {
38 .virtual = __MMIO_P2V(CT_CA9X4_MPIC
),
39 .pfn
= __phys_to_pfn(CT_CA9X4_MPIC
),
43 .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER
),
44 .pfn
= __phys_to_pfn(CT_CA9X4_SP804_TIMER
),
48 .virtual = __MMIO_P2V(CT_CA9X4_L2CC
),
49 .pfn
= __phys_to_pfn(CT_CA9X4_L2CC
),
55 static void __init
ct_ca9x4_map_io(void)
57 twd_base
= MMIO_P2V(A9_MPCORE_TWD
);
58 v2m_map_io(ct_ca9x4_io_desc
, ARRAY_SIZE(ct_ca9x4_io_desc
));
61 void __iomem
*gic_cpu_base_addr
;
63 static void __init
ct_ca9x4_init_irq(void)
65 gic_cpu_base_addr
= MMIO_P2V(A9_MPCORE_GIC_CPU
);
66 gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST
), 29);
67 gic_cpu_init(0, gic_cpu_base_addr
);
71 static void __init
ct_ca9x4_timer_init(void)
73 writel(0, MMIO_P2V(CT_CA9X4_TIMER0
) + TIMER_CTRL
);
74 writel(0, MMIO_P2V(CT_CA9X4_TIMER1
) + TIMER_CTRL
);
76 sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1
));
77 sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0
), IRQ_CT_CA9X4_TIMER0
);
80 static struct sys_timer ct_ca9x4_timer
= {
81 .init
= ct_ca9x4_timer_init
,
85 static struct clcd_panel xvga_panel
= {
99 .vmode
= FB_VMODE_NONINTERLACED
,
103 .tim2
= TIM2_BCD
| TIM2_IPC
,
104 .cntl
= CNTL_LCDTFT
| CNTL_BGR
| CNTL_LCDVCOMP(1),
108 static void ct_ca9x4_clcd_enable(struct clcd_fb
*fb
)
110 v2m_cfg_write(SYS_CFG_MUXFPGA
| SYS_CFG_SITE_DB1
, 0);
111 v2m_cfg_write(SYS_CFG_DVIMODE
| SYS_CFG_SITE_DB1
, 2);
114 static int ct_ca9x4_clcd_setup(struct clcd_fb
*fb
)
116 unsigned long framesize
= 1024 * 768 * 2;
119 fb
->panel
= &xvga_panel
;
121 fb
->fb
.screen_base
= dma_alloc_writecombine(&fb
->dev
->dev
, framesize
,
123 if (!fb
->fb
.screen_base
) {
124 printk(KERN_ERR
"CLCD: unable to map frame buffer\n");
127 fb
->fb
.fix
.smem_start
= dma
;
128 fb
->fb
.fix
.smem_len
= framesize
;
133 static int ct_ca9x4_clcd_mmap(struct clcd_fb
*fb
, struct vm_area_struct
*vma
)
135 return dma_mmap_writecombine(&fb
->dev
->dev
, vma
, fb
->fb
.screen_base
,
136 fb
->fb
.fix
.smem_start
, fb
->fb
.fix
.smem_len
);
139 static void ct_ca9x4_clcd_remove(struct clcd_fb
*fb
)
141 dma_free_writecombine(&fb
->dev
->dev
, fb
->fb
.fix
.smem_len
,
142 fb
->fb
.screen_base
, fb
->fb
.fix
.smem_start
);
145 static struct clcd_board ct_ca9x4_clcd_data
= {
147 .check
= clcdfb_check
,
148 .decode
= clcdfb_decode
,
149 .enable
= ct_ca9x4_clcd_enable
,
150 .setup
= ct_ca9x4_clcd_setup
,
151 .mmap
= ct_ca9x4_clcd_mmap
,
152 .remove
= ct_ca9x4_clcd_remove
,
155 static AMBA_DEVICE(clcd
, "ct:clcd", CT_CA9X4_CLCDC
, &ct_ca9x4_clcd_data
);
156 static AMBA_DEVICE(dmc
, "ct:dmc", CT_CA9X4_DMC
, NULL
);
157 static AMBA_DEVICE(smc
, "ct:smc", CT_CA9X4_SMC
, NULL
);
158 static AMBA_DEVICE(gpio
, "ct:gpio", CT_CA9X4_GPIO
, NULL
);
160 static struct amba_device
*ct_ca9x4_amba_devs
[] __initdata
= {
168 static long ct_round(struct clk
*clk
, unsigned long rate
)
173 static int ct_set(struct clk
*clk
, unsigned long rate
)
175 return v2m_cfg_write(SYS_CFG_OSC
| SYS_CFG_SITE_DB1
| 1, rate
);
178 static const struct clk_ops osc1_clk_ops
= {
183 static struct clk osc1_clk
= {
184 .ops
= &osc1_clk_ops
,
188 static struct clk_lookup lookups
[] = {
195 static struct resource pmu_resources
[] = {
197 .start
= IRQ_CT_CA9X4_PMU_CPU0
,
198 .end
= IRQ_CT_CA9X4_PMU_CPU0
,
199 .flags
= IORESOURCE_IRQ
,
202 .start
= IRQ_CT_CA9X4_PMU_CPU1
,
203 .end
= IRQ_CT_CA9X4_PMU_CPU1
,
204 .flags
= IORESOURCE_IRQ
,
207 .start
= IRQ_CT_CA9X4_PMU_CPU2
,
208 .end
= IRQ_CT_CA9X4_PMU_CPU2
,
209 .flags
= IORESOURCE_IRQ
,
212 .start
= IRQ_CT_CA9X4_PMU_CPU3
,
213 .end
= IRQ_CT_CA9X4_PMU_CPU3
,
214 .flags
= IORESOURCE_IRQ
,
218 static struct platform_device pmu_device
= {
220 .id
= ARM_PMU_DEVICE_CPU
,
221 .num_resources
= ARRAY_SIZE(pmu_resources
),
222 .resource
= pmu_resources
,
225 static void __init
ct_ca9x4_init(void)
229 #ifdef CONFIG_CACHE_L2X0
230 void __iomem
*l2x0_base
= MMIO_P2V(CT_CA9X4_L2CC
);
232 /* set RAM latencies to 1 cycle for this core tile. */
233 writel(0, l2x0_base
+ L2X0_TAG_LATENCY_CTRL
);
234 writel(0, l2x0_base
+ L2X0_DATA_LATENCY_CTRL
);
236 l2x0_init(l2x0_base
, 0x00400000, 0xfe0fffff);
239 clkdev_add_table(lookups
, ARRAY_SIZE(lookups
));
241 for (i
= 0; i
< ARRAY_SIZE(ct_ca9x4_amba_devs
); i
++)
242 amba_device_register(ct_ca9x4_amba_devs
[i
], &iomem_resource
);
244 platform_device_register(&pmu_device
);
247 MACHINE_START(VEXPRESS
, "ARM-Versatile Express CA9x4")
248 .boot_params
= PHYS_OFFSET
+ 0x00000100,
249 .map_io
= ct_ca9x4_map_io
,
250 .init_irq
= ct_ca9x4_init_irq
,
252 .timer
= &ct_ca9x4_timer
,
256 .init_machine
= ct_ca9x4_init
,