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>
11 #include <linux/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/ct-ca9x4.h>
23 #include <asm/hardware/timer-sp.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
27 #include <asm/mach/time.h>
31 #include <mach/motherboard.h>
33 #define V2M_PA_CS7 0x10000000
35 static struct map_desc ct_ca9x4_io_desc
[] __initdata
= {
37 .virtual = __MMIO_P2V(CT_CA9X4_MPIC
),
38 .pfn
= __phys_to_pfn(CT_CA9X4_MPIC
),
42 .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER
),
43 .pfn
= __phys_to_pfn(CT_CA9X4_SP804_TIMER
),
47 .virtual = __MMIO_P2V(CT_CA9X4_L2CC
),
48 .pfn
= __phys_to_pfn(CT_CA9X4_L2CC
),
54 static void __init
ct_ca9x4_map_io(void)
56 #ifdef CONFIG_LOCAL_TIMERS
57 twd_base
= MMIO_P2V(A9_MPCORE_TWD
);
59 v2m_map_io(ct_ca9x4_io_desc
, ARRAY_SIZE(ct_ca9x4_io_desc
));
62 static void __init
ct_ca9x4_init_irq(void)
64 gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST
),
65 MMIO_P2V(A9_MPCORE_GIC_CPU
));
69 static void __init
ct_ca9x4_timer_init(void)
71 writel(0, MMIO_P2V(CT_CA9X4_TIMER0
) + TIMER_CTRL
);
72 writel(0, MMIO_P2V(CT_CA9X4_TIMER1
) + TIMER_CTRL
);
74 sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1
));
75 sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0
), IRQ_CT_CA9X4_TIMER0
);
78 static struct sys_timer ct_ca9x4_timer
= {
79 .init
= ct_ca9x4_timer_init
,
83 static struct clcd_panel xvga_panel
= {
97 .vmode
= FB_VMODE_NONINTERLACED
,
101 .tim2
= TIM2_BCD
| TIM2_IPC
,
102 .cntl
= CNTL_LCDTFT
| CNTL_BGR
| CNTL_LCDVCOMP(1),
106 static void ct_ca9x4_clcd_enable(struct clcd_fb
*fb
)
108 v2m_cfg_write(SYS_CFG_MUXFPGA
| SYS_CFG_SITE_DB1
, 0);
109 v2m_cfg_write(SYS_CFG_DVIMODE
| SYS_CFG_SITE_DB1
, 2);
112 static int ct_ca9x4_clcd_setup(struct clcd_fb
*fb
)
114 unsigned long framesize
= 1024 * 768 * 2;
117 fb
->panel
= &xvga_panel
;
119 fb
->fb
.screen_base
= dma_alloc_writecombine(&fb
->dev
->dev
, framesize
,
121 if (!fb
->fb
.screen_base
) {
122 printk(KERN_ERR
"CLCD: unable to map frame buffer\n");
125 fb
->fb
.fix
.smem_start
= dma
;
126 fb
->fb
.fix
.smem_len
= framesize
;
131 static int ct_ca9x4_clcd_mmap(struct clcd_fb
*fb
, struct vm_area_struct
*vma
)
133 return dma_mmap_writecombine(&fb
->dev
->dev
, vma
, fb
->fb
.screen_base
,
134 fb
->fb
.fix
.smem_start
, fb
->fb
.fix
.smem_len
);
137 static void ct_ca9x4_clcd_remove(struct clcd_fb
*fb
)
139 dma_free_writecombine(&fb
->dev
->dev
, fb
->fb
.fix
.smem_len
,
140 fb
->fb
.screen_base
, fb
->fb
.fix
.smem_start
);
143 static struct clcd_board ct_ca9x4_clcd_data
= {
145 .check
= clcdfb_check
,
146 .decode
= clcdfb_decode
,
147 .enable
= ct_ca9x4_clcd_enable
,
148 .setup
= ct_ca9x4_clcd_setup
,
149 .mmap
= ct_ca9x4_clcd_mmap
,
150 .remove
= ct_ca9x4_clcd_remove
,
153 static AMBA_DEVICE(clcd
, "ct:clcd", CT_CA9X4_CLCDC
, &ct_ca9x4_clcd_data
);
154 static AMBA_DEVICE(dmc
, "ct:dmc", CT_CA9X4_DMC
, NULL
);
155 static AMBA_DEVICE(smc
, "ct:smc", CT_CA9X4_SMC
, NULL
);
156 static AMBA_DEVICE(gpio
, "ct:gpio", CT_CA9X4_GPIO
, NULL
);
158 static struct amba_device
*ct_ca9x4_amba_devs
[] __initdata
= {
166 static long ct_round(struct clk
*clk
, unsigned long rate
)
171 static int ct_set(struct clk
*clk
, unsigned long rate
)
173 return v2m_cfg_write(SYS_CFG_OSC
| SYS_CFG_SITE_DB1
| 1, rate
);
176 static const struct clk_ops osc1_clk_ops
= {
181 static struct clk osc1_clk
= {
182 .ops
= &osc1_clk_ops
,
186 static struct clk_lookup lookups
[] = {
193 static struct resource pmu_resources
[] = {
195 .start
= IRQ_CT_CA9X4_PMU_CPU0
,
196 .end
= IRQ_CT_CA9X4_PMU_CPU0
,
197 .flags
= IORESOURCE_IRQ
,
200 .start
= IRQ_CT_CA9X4_PMU_CPU1
,
201 .end
= IRQ_CT_CA9X4_PMU_CPU1
,
202 .flags
= IORESOURCE_IRQ
,
205 .start
= IRQ_CT_CA9X4_PMU_CPU2
,
206 .end
= IRQ_CT_CA9X4_PMU_CPU2
,
207 .flags
= IORESOURCE_IRQ
,
210 .start
= IRQ_CT_CA9X4_PMU_CPU3
,
211 .end
= IRQ_CT_CA9X4_PMU_CPU3
,
212 .flags
= IORESOURCE_IRQ
,
216 static struct platform_device pmu_device
= {
218 .id
= ARM_PMU_DEVICE_CPU
,
219 .num_resources
= ARRAY_SIZE(pmu_resources
),
220 .resource
= pmu_resources
,
223 static void __init
ct_ca9x4_init(void)
227 #ifdef CONFIG_CACHE_L2X0
228 void __iomem
*l2x0_base
= MMIO_P2V(CT_CA9X4_L2CC
);
230 /* set RAM latencies to 1 cycle for this core tile. */
231 writel(0, l2x0_base
+ L2X0_TAG_LATENCY_CTRL
);
232 writel(0, l2x0_base
+ L2X0_DATA_LATENCY_CTRL
);
234 l2x0_init(l2x0_base
, 0x00400000, 0xfe0fffff);
237 clkdev_add_table(lookups
, ARRAY_SIZE(lookups
));
239 for (i
= 0; i
< ARRAY_SIZE(ct_ca9x4_amba_devs
); i
++)
240 amba_device_register(ct_ca9x4_amba_devs
[i
], &iomem_resource
);
242 platform_device_register(&pmu_device
);
245 MACHINE_START(VEXPRESS
, "ARM-Versatile Express CA9x4")
246 .boot_params
= PHYS_OFFSET
+ 0x00000100,
247 .map_io
= ct_ca9x4_map_io
,
248 .init_irq
= ct_ca9x4_init_irq
,
250 .timer
= &ct_ca9x4_timer
,
254 .init_machine
= ct_ca9x4_init
,