Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / arm / mach-vexpress / v2m.c
1 /*
2  * Versatile Express V2M Motherboard Support
3  */
4 #include <linux/device.h>
5 #include <linux/amba/bus.h>
6 #include <linux/amba/mmci.h>
7 #include <linux/io.h>
8 #include <linux/smp.h>
9 #include <linux/init.h>
10 #include <linux/irqchip.h>
11 #include <linux/of_address.h>
12 #include <linux/of_fdt.h>
13 #include <linux/of_irq.h>
14 #include <linux/of_platform.h>
15 #include <linux/platform_device.h>
16 #include <linux/ata_platform.h>
17 #include <linux/smsc911x.h>
18 #include <linux/spinlock.h>
19 #include <linux/usb/isp1760.h>
20 #include <linux/mtd/physmap.h>
21 #include <linux/regulator/fixed.h>
22 #include <linux/regulator/machine.h>
23 #include <linux/vexpress.h>
24 #include <linux/clk-provider.h>
25 #include <linux/clkdev.h>
26
27 #include <asm/arch_timer.h>
28 #include <asm/mach-types.h>
29 #include <asm/sizes.h>
30 #include <asm/smp_twd.h>
31 #include <asm/mach/arch.h>
32 #include <asm/mach/map.h>
33 #include <asm/mach/time.h>
34 #include <asm/hardware/arm_timer.h>
35 #include <asm/hardware/cache-l2x0.h>
36 #include <asm/hardware/timer-sp.h>
37
38 #include <mach/ct-ca9x4.h>
39 #include <mach/motherboard.h>
40
41 #include <plat/sched_clock.h>
42 #include <plat/platsmp.h>
43
44 #include "core.h"
45
46 #define V2M_PA_CS0      0x40000000
47 #define V2M_PA_CS1      0x44000000
48 #define V2M_PA_CS2      0x48000000
49 #define V2M_PA_CS3      0x4c000000
50 #define V2M_PA_CS7      0x10000000
51
52 static struct map_desc v2m_io_desc[] __initdata = {
53         {
54                 .virtual        = V2M_PERIPH,
55                 .pfn            = __phys_to_pfn(V2M_PA_CS7),
56                 .length         = SZ_128K,
57                 .type           = MT_DEVICE,
58         },
59 };
60
61 static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
62 {
63         if (WARN_ON(!base || irq == NO_IRQ))
64                 return;
65
66         writel(0, base + TIMER_1_BASE + TIMER_CTRL);
67         writel(0, base + TIMER_2_BASE + TIMER_CTRL);
68
69         sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
70         sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
71 }
72
73
74 static struct resource v2m_pcie_i2c_resource = {
75         .start  = V2M_SERIAL_BUS_PCI,
76         .end    = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
77         .flags  = IORESOURCE_MEM,
78 };
79
80 static struct platform_device v2m_pcie_i2c_device = {
81         .name           = "versatile-i2c",
82         .id             = 0,
83         .num_resources  = 1,
84         .resource       = &v2m_pcie_i2c_resource,
85 };
86
87 static struct resource v2m_ddc_i2c_resource = {
88         .start  = V2M_SERIAL_BUS_DVI,
89         .end    = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
90         .flags  = IORESOURCE_MEM,
91 };
92
93 static struct platform_device v2m_ddc_i2c_device = {
94         .name           = "versatile-i2c",
95         .id             = 1,
96         .num_resources  = 1,
97         .resource       = &v2m_ddc_i2c_resource,
98 };
99
100 static struct resource v2m_eth_resources[] = {
101         {
102                 .start  = V2M_LAN9118,
103                 .end    = V2M_LAN9118 + SZ_64K - 1,
104                 .flags  = IORESOURCE_MEM,
105         }, {
106                 .start  = IRQ_V2M_LAN9118,
107                 .end    = IRQ_V2M_LAN9118,
108                 .flags  = IORESOURCE_IRQ,
109         },
110 };
111
112 static struct smsc911x_platform_config v2m_eth_config = {
113         .flags          = SMSC911X_USE_32BIT,
114         .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
115         .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
116         .phy_interface  = PHY_INTERFACE_MODE_MII,
117 };
118
119 static struct platform_device v2m_eth_device = {
120         .name           = "smsc911x",
121         .id             = -1,
122         .resource       = v2m_eth_resources,
123         .num_resources  = ARRAY_SIZE(v2m_eth_resources),
124         .dev.platform_data = &v2m_eth_config,
125 };
126
127 static struct regulator_consumer_supply v2m_eth_supplies[] = {
128         REGULATOR_SUPPLY("vddvario", "smsc911x"),
129         REGULATOR_SUPPLY("vdd33a", "smsc911x"),
130 };
131
132 static struct resource v2m_usb_resources[] = {
133         {
134                 .start  = V2M_ISP1761,
135                 .end    = V2M_ISP1761 + SZ_128K - 1,
136                 .flags  = IORESOURCE_MEM,
137         }, {
138                 .start  = IRQ_V2M_ISP1761,
139                 .end    = IRQ_V2M_ISP1761,
140                 .flags  = IORESOURCE_IRQ,
141         },
142 };
143
144 static struct isp1760_platform_data v2m_usb_config = {
145         .is_isp1761             = true,
146         .bus_width_16           = false,
147         .port1_otg              = true,
148         .analog_oc              = false,
149         .dack_polarity_high     = false,
150         .dreq_polarity_high     = false,
151 };
152
153 static struct platform_device v2m_usb_device = {
154         .name           = "isp1760",
155         .id             = -1,
156         .resource       = v2m_usb_resources,
157         .num_resources  = ARRAY_SIZE(v2m_usb_resources),
158         .dev.platform_data = &v2m_usb_config,
159 };
160
161 static struct physmap_flash_data v2m_flash_data = {
162         .width          = 4,
163 };
164
165 static struct resource v2m_flash_resources[] = {
166         {
167                 .start  = V2M_NOR0,
168                 .end    = V2M_NOR0 + SZ_64M - 1,
169                 .flags  = IORESOURCE_MEM,
170         }, {
171                 .start  = V2M_NOR1,
172                 .end    = V2M_NOR1 + SZ_64M - 1,
173                 .flags  = IORESOURCE_MEM,
174         },
175 };
176
177 static struct platform_device v2m_flash_device = {
178         .name           = "physmap-flash",
179         .id             = -1,
180         .resource       = v2m_flash_resources,
181         .num_resources  = ARRAY_SIZE(v2m_flash_resources),
182         .dev.platform_data = &v2m_flash_data,
183 };
184
185 static struct pata_platform_info v2m_pata_data = {
186         .ioport_shift   = 2,
187 };
188
189 static struct resource v2m_pata_resources[] = {
190         {
191                 .start  = V2M_CF,
192                 .end    = V2M_CF + 0xff,
193                 .flags  = IORESOURCE_MEM,
194         }, {
195                 .start  = V2M_CF + 0x100,
196                 .end    = V2M_CF + SZ_4K - 1,
197                 .flags  = IORESOURCE_MEM,
198         },
199 };
200
201 static struct platform_device v2m_cf_device = {
202         .name           = "pata_platform",
203         .id             = -1,
204         .resource       = v2m_pata_resources,
205         .num_resources  = ARRAY_SIZE(v2m_pata_resources),
206         .dev.platform_data = &v2m_pata_data,
207 };
208
209 static struct mmci_platform_data v2m_mmci_data = {
210         .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
211         .gpio_wp        = VEXPRESS_GPIO_MMC_WPROT,
212         .gpio_cd        = VEXPRESS_GPIO_MMC_CARDIN,
213 };
214
215 static struct resource v2m_sysreg_resources[] = {
216         {
217                 .start  = V2M_SYSREGS,
218                 .end    = V2M_SYSREGS + 0xfff,
219                 .flags  = IORESOURCE_MEM,
220         },
221 };
222
223 static struct platform_device v2m_sysreg_device = {
224         .name           = "vexpress-sysreg",
225         .id             = -1,
226         .resource       = v2m_sysreg_resources,
227         .num_resources  = ARRAY_SIZE(v2m_sysreg_resources),
228 };
229
230 static struct platform_device v2m_muxfpga_device = {
231         .name           = "vexpress-muxfpga",
232         .id             = 0,
233         .num_resources  = 1,
234         .resource       = (struct resource []) {
235                 VEXPRESS_RES_FUNC(0, 7),
236         }
237 };
238
239 static struct platform_device v2m_shutdown_device = {
240         .name           = "vexpress-shutdown",
241         .id             = 0,
242         .num_resources  = 1,
243         .resource       = (struct resource []) {
244                 VEXPRESS_RES_FUNC(0, 8),
245         }
246 };
247
248 static struct platform_device v2m_reboot_device = {
249         .name           = "vexpress-reboot",
250         .id             = 0,
251         .num_resources  = 1,
252         .resource       = (struct resource []) {
253                 VEXPRESS_RES_FUNC(0, 9),
254         }
255 };
256
257 static struct platform_device v2m_dvimode_device = {
258         .name           = "vexpress-dvimode",
259         .id             = 0,
260         .num_resources  = 1,
261         .resource       = (struct resource []) {
262                 VEXPRESS_RES_FUNC(0, 11),
263         }
264 };
265
266 static AMBA_APB_DEVICE(aaci,  "mb:aaci",  0, V2M_AACI, IRQ_V2M_AACI, NULL);
267 static AMBA_APB_DEVICE(mmci,  "mb:mmci",  0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data);
268 static AMBA_APB_DEVICE(kmi0,  "mb:kmi0",  0, V2M_KMI0, IRQ_V2M_KMI0, NULL);
269 static AMBA_APB_DEVICE(kmi1,  "mb:kmi1",  0, V2M_KMI1, IRQ_V2M_KMI1, NULL);
270 static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL);
271 static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL);
272 static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL);
273 static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL);
274 static AMBA_APB_DEVICE(wdt,   "mb:wdt",   0, V2M_WDT, IRQ_V2M_WDT, NULL);
275 static AMBA_APB_DEVICE(rtc,   "mb:rtc",   0, V2M_RTC, IRQ_V2M_RTC, NULL);
276
277 static struct amba_device *v2m_amba_devs[] __initdata = {
278         &aaci_device,
279         &mmci_device,
280         &kmi0_device,
281         &kmi1_device,
282         &uart0_device,
283         &uart1_device,
284         &uart2_device,
285         &uart3_device,
286         &wdt_device,
287         &rtc_device,
288 };
289
290 static void __init v2m_timer_init(void)
291 {
292         vexpress_clk_init(ioremap(V2M_SYSCTL, SZ_4K));
293         v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
294 }
295
296 static void __init v2m_init_early(void)
297 {
298         if (ct_desc->init_early)
299                 ct_desc->init_early();
300         versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
301 }
302
303 struct ct_desc *ct_desc;
304
305 static struct ct_desc *ct_descs[] __initdata = {
306 #ifdef CONFIG_ARCH_VEXPRESS_CA9X4
307         &ct_ca9x4_desc,
308 #endif
309 };
310
311 static void __init v2m_populate_ct_desc(void)
312 {
313         int i;
314         u32 current_tile_id;
315
316         ct_desc = NULL;
317         current_tile_id = vexpress_get_procid(VEXPRESS_SITE_MASTER)
318                                 & V2M_CT_ID_MASK;
319
320         for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
321                 if (ct_descs[i]->id == current_tile_id)
322                         ct_desc = ct_descs[i];
323
324         if (!ct_desc)
325                 panic("vexpress: this kernel does not support core tile ID 0x%08x when booting via ATAGs.\n"
326                       "You may need a device tree blob or a different kernel to boot on this board.\n",
327                       current_tile_id);
328 }
329
330 static void __init v2m_map_io(void)
331 {
332         iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
333         vexpress_sysreg_early_init(ioremap(V2M_SYSREGS, SZ_4K));
334         v2m_populate_ct_desc();
335         ct_desc->map_io();
336 }
337
338 static void __init v2m_init_irq(void)
339 {
340         ct_desc->init_irq();
341 }
342
343 static void __init v2m_init(void)
344 {
345         int i;
346
347         regulator_register_fixed(0, v2m_eth_supplies,
348                         ARRAY_SIZE(v2m_eth_supplies));
349
350         platform_device_register(&v2m_muxfpga_device);
351         platform_device_register(&v2m_shutdown_device);
352         platform_device_register(&v2m_reboot_device);
353         platform_device_register(&v2m_dvimode_device);
354
355         platform_device_register(&v2m_sysreg_device);
356         platform_device_register(&v2m_pcie_i2c_device);
357         platform_device_register(&v2m_ddc_i2c_device);
358         platform_device_register(&v2m_flash_device);
359         platform_device_register(&v2m_cf_device);
360         platform_device_register(&v2m_eth_device);
361         platform_device_register(&v2m_usb_device);
362
363         for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
364                 amba_device_register(v2m_amba_devs[i], &iomem_resource);
365
366         pm_power_off = vexpress_power_off;
367
368         ct_desc->init_tile();
369 }
370
371 MACHINE_START(VEXPRESS, "ARM-Versatile Express")
372         .atag_offset    = 0x100,
373         .smp            = smp_ops(vexpress_smp_ops),
374         .map_io         = v2m_map_io,
375         .init_early     = v2m_init_early,
376         .init_irq       = v2m_init_irq,
377         .init_time      = v2m_timer_init,
378         .init_machine   = v2m_init,
379         .restart        = vexpress_restart,
380 MACHINE_END
381
382 static struct map_desc v2m_rs1_io_desc __initdata = {
383         .virtual        = V2M_PERIPH,
384         .pfn            = __phys_to_pfn(0x1c000000),
385         .length         = SZ_2M,
386         .type           = MT_DEVICE,
387 };
388
389 static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname,
390                 int depth, void *data)
391 {
392         const char **map = data;
393
394         if (strcmp(uname, "motherboard") != 0)
395                 return 0;
396
397         *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL);
398
399         return 1;
400 }
401
402 void __init v2m_dt_map_io(void)
403 {
404         const char *map = NULL;
405
406         of_scan_flat_dt(v2m_dt_scan_memory_map, &map);
407
408         if (map && strcmp(map, "rs1") == 0)
409                 iotable_init(&v2m_rs1_io_desc, 1);
410         else
411                 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
412
413 #if defined(CONFIG_SMP)
414         vexpress_dt_smp_map_io();
415 #endif
416 }
417
418 void __init v2m_dt_init_early(void)
419 {
420         u32 dt_hbi;
421
422         vexpress_sysreg_of_early_init();
423
424         /* Confirm board type against DT property, if available */
425         if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
426                 u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
427
428                 if (WARN_ON(dt_hbi != hbi))
429                         pr_warning("vexpress: DT HBI (%x) is not matching "
430                                         "hardware (%x)!\n", dt_hbi, hbi);
431         }
432 }
433
434 static void __init v2m_dt_timer_init(void)
435 {
436         struct device_node *node = NULL;
437
438         of_clk_init(NULL);
439
440         do {
441                 node = of_find_compatible_node(node, NULL, "arm,sp804");
442         } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
443         if (node) {
444                 pr_info("Using SP804 '%s' as a clock & events source\n",
445                                 node->full_name);
446                 WARN_ON(clk_register_clkdev(of_clk_get_by_name(node,
447                                 "timclken1"), "v2m-timer0", "sp804"));
448                 WARN_ON(clk_register_clkdev(of_clk_get_by_name(node,
449                                 "timclken2"), "v2m-timer1", "sp804"));
450                 v2m_sp804_init(of_iomap(node, 0),
451                                 irq_of_parse_and_map(node, 0));
452         }
453
454         if (arch_timer_of_register() != 0)
455                 twd_local_timer_of_register();
456
457         if (arch_timer_sched_clock_init() != 0)
458                 versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
459                                 24000000);
460 }
461
462 static const struct of_device_id v2m_dt_bus_match[] __initconst = {
463         { .compatible = "simple-bus", },
464         { .compatible = "arm,amba-bus", },
465         { .compatible = "arm,vexpress,config-bus", },
466         {}
467 };
468
469 static void __init v2m_dt_init(void)
470 {
471         l2x0_of_init(0x00400000, 0xfe0fffff);
472         of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL);
473         pm_power_off = vexpress_power_off;
474 }
475
476 static const char * const v2m_dt_match[] __initconst = {
477         "arm,vexpress",
478         "xen,xenvm",
479         NULL,
480 };
481
482 DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
483         .dt_compat      = v2m_dt_match,
484         .smp            = smp_ops(vexpress_smp_ops),
485         .map_io         = v2m_dt_map_io,
486         .init_early     = v2m_dt_init_early,
487         .init_irq       = irqchip_init,
488         .init_time      = v2m_dt_timer_init,
489         .init_machine   = v2m_dt_init,
490         .restart        = vexpress_restart,
491 MACHINE_END