ARM: 6751/1: vexpress: select applicable errata workarounds in Kconfig
[sfrench/cifs-2.6.git] / arch / arm / mach-vexpress / ct-ca9x4.c
1 /*
2  * Versatile Express Core Tile Cortex A9x4 Support
3  */
4 #include <linux/init.h>
5 #include <linux/gfp.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>
12
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>
18 #include <asm/pmu.h>
19 #include <asm/smp_twd.h>
20
21 #include <mach/ct-ca9x4.h>
22
23 #include <asm/hardware/timer-sp.h>
24
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
27 #include <asm/mach/time.h>
28
29 #include "core.h"
30
31 #include <mach/motherboard.h>
32
33 #include <plat/clcd.h>
34
35 #define V2M_PA_CS7      0x10000000
36
37 static struct map_desc ct_ca9x4_io_desc[] __initdata = {
38         {
39                 .virtual        = __MMIO_P2V(CT_CA9X4_MPIC),
40                 .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
41                 .length         = SZ_16K,
42                 .type           = MT_DEVICE,
43         }, {
44                 .virtual        = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
45                 .pfn            = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
46                 .length         = SZ_4K,
47                 .type           = MT_DEVICE,
48         }, {
49                 .virtual        = __MMIO_P2V(CT_CA9X4_L2CC),
50                 .pfn            = __phys_to_pfn(CT_CA9X4_L2CC),
51                 .length         = SZ_4K,
52                 .type           = MT_DEVICE,
53         },
54 };
55
56 static void __init ct_ca9x4_map_io(void)
57 {
58 #ifdef CONFIG_LOCAL_TIMERS
59         twd_base = MMIO_P2V(A9_MPCORE_TWD);
60 #endif
61         v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
62 }
63
64 static void __init ct_ca9x4_init_irq(void)
65 {
66         gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
67                  MMIO_P2V(A9_MPCORE_GIC_CPU));
68 }
69
70 #if 0
71 static void __init ct_ca9x4_timer_init(void)
72 {
73         writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
74         writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
75
76         sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1));
77         sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0);
78 }
79
80 static struct sys_timer ct_ca9x4_timer = {
81         .init   = ct_ca9x4_timer_init,
82 };
83 #endif
84
85 static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
86 {
87         v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
88         v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
89 }
90
91 static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
92 {
93         unsigned long framesize = 1024 * 768 * 2;
94
95         fb->panel = versatile_clcd_get_panel("XVGA");
96         if (!fb->panel)
97                 return -EINVAL;
98
99         return versatile_clcd_setup_dma(fb, framesize);
100 }
101
102 static struct clcd_board ct_ca9x4_clcd_data = {
103         .name           = "CT-CA9X4",
104         .caps           = CLCD_CAP_5551 | CLCD_CAP_565,
105         .check          = clcdfb_check,
106         .decode         = clcdfb_decode,
107         .enable         = ct_ca9x4_clcd_enable,
108         .setup          = ct_ca9x4_clcd_setup,
109         .mmap           = versatile_clcd_mmap_dma,
110         .remove         = versatile_clcd_remove_dma,
111 };
112
113 static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
114 static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
115 static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
116 static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
117
118 static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
119         &clcd_device,
120         &dmc_device,
121         &smc_device,
122         &gpio_device,
123 };
124
125
126 static long ct_round(struct clk *clk, unsigned long rate)
127 {
128         return rate;
129 }
130
131 static int ct_set(struct clk *clk, unsigned long rate)
132 {
133         return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
134 }
135
136 static const struct clk_ops osc1_clk_ops = {
137         .round  = ct_round,
138         .set    = ct_set,
139 };
140
141 static struct clk osc1_clk = {
142         .ops    = &osc1_clk_ops,
143         .rate   = 24000000,
144 };
145
146 static struct clk_lookup lookups[] = {
147         {       /* CLCD */
148                 .dev_id         = "ct:clcd",
149                 .clk            = &osc1_clk,
150         },
151 };
152
153 static struct resource pmu_resources[] = {
154         [0] = {
155                 .start  = IRQ_CT_CA9X4_PMU_CPU0,
156                 .end    = IRQ_CT_CA9X4_PMU_CPU0,
157                 .flags  = IORESOURCE_IRQ,
158         },
159         [1] = {
160                 .start  = IRQ_CT_CA9X4_PMU_CPU1,
161                 .end    = IRQ_CT_CA9X4_PMU_CPU1,
162                 .flags  = IORESOURCE_IRQ,
163         },
164         [2] = {
165                 .start  = IRQ_CT_CA9X4_PMU_CPU2,
166                 .end    = IRQ_CT_CA9X4_PMU_CPU2,
167                 .flags  = IORESOURCE_IRQ,
168         },
169         [3] = {
170                 .start  = IRQ_CT_CA9X4_PMU_CPU3,
171                 .end    = IRQ_CT_CA9X4_PMU_CPU3,
172                 .flags  = IORESOURCE_IRQ,
173         },
174 };
175
176 static struct platform_device pmu_device = {
177         .name           = "arm-pmu",
178         .id             = ARM_PMU_DEVICE_CPU,
179         .num_resources  = ARRAY_SIZE(pmu_resources),
180         .resource       = pmu_resources,
181 };
182
183 static void __init ct_ca9x4_init_early(void)
184 {
185         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
186
187         v2m_init_early();
188 }
189
190 static void __init ct_ca9x4_init(void)
191 {
192         int i;
193
194 #ifdef CONFIG_CACHE_L2X0
195         void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
196
197         /* set RAM latencies to 1 cycle for this core tile. */
198         writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
199         writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
200
201         l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
202 #endif
203
204         for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
205                 amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
206
207         platform_device_register(&pmu_device);
208 }
209
210 MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
211         .boot_params    = PHYS_OFFSET + 0x00000100,
212         .map_io         = ct_ca9x4_map_io,
213         .init_irq       = ct_ca9x4_init_irq,
214         .init_early     = ct_ca9x4_init_early,
215 #if 0
216         .timer          = &ct_ca9x4_timer,
217 #else
218         .timer          = &v2m_timer,
219 #endif
220         .init_machine   = ct_ca9x4_init,
221 MACHINE_END