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