17f627f03SMagnus Damm /*
27f627f03SMagnus Damm  * Emma Mobile EV2 processor support
37f627f03SMagnus Damm  *
47f627f03SMagnus Damm  * Copyright (C) 2012  Magnus Damm
57f627f03SMagnus Damm  *
67f627f03SMagnus Damm  * This program is free software; you can redistribute it and/or modify
77f627f03SMagnus Damm  * it under the terms of the GNU General Public License as published by
87f627f03SMagnus Damm  * the Free Software Foundation; version 2 of the License.
97f627f03SMagnus Damm  *
107f627f03SMagnus Damm  * This program is distributed in the hope that it will be useful,
117f627f03SMagnus Damm  * but WITHOUT ANY WARRANTY; without even the implied warranty of
127f627f03SMagnus Damm  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
137f627f03SMagnus Damm  * GNU General Public License for more details.
147f627f03SMagnus Damm  *
157f627f03SMagnus Damm  * You should have received a copy of the GNU General Public License
167f627f03SMagnus Damm  * along with this program; if not, write to the Free Software
177f627f03SMagnus Damm  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
187f627f03SMagnus Damm  */
197f627f03SMagnus Damm #include <linux/kernel.h>
207f627f03SMagnus Damm #include <linux/init.h>
217f627f03SMagnus Damm #include <linux/interrupt.h>
227f627f03SMagnus Damm #include <linux/irq.h>
237f627f03SMagnus Damm #include <linux/platform_device.h>
247f627f03SMagnus Damm #include <linux/delay.h>
257f627f03SMagnus Damm #include <linux/input.h>
267f627f03SMagnus Damm #include <linux/io.h>
277f627f03SMagnus Damm #include <mach/hardware.h>
287f627f03SMagnus Damm #include <mach/common.h>
297f627f03SMagnus Damm #include <mach/emev2.h>
307f627f03SMagnus Damm #include <mach/irqs.h>
317f627f03SMagnus Damm #include <asm/mach-types.h>
327f627f03SMagnus Damm #include <asm/mach/arch.h>
337f627f03SMagnus Damm #include <asm/mach/map.h>
347f627f03SMagnus Damm #include <asm/mach/time.h>
357f627f03SMagnus Damm #include <asm/hardware/gic.h>
367f627f03SMagnus Damm 
377f627f03SMagnus Damm /* UART */
387f627f03SMagnus Damm static struct resource uart0_resources[] = {
397f627f03SMagnus Damm 	[0]	= {
407f627f03SMagnus Damm 		.start	= 0xe1020000,
417f627f03SMagnus Damm 		.end	= 0xe1020037,
427f627f03SMagnus Damm 		.flags	= IORESOURCE_MEM,
437f627f03SMagnus Damm 	},
447f627f03SMagnus Damm 	[1]	= {
457f627f03SMagnus Damm 		.start	= 40,
467f627f03SMagnus Damm 		.flags	= IORESOURCE_IRQ,
477f627f03SMagnus Damm 	}
487f627f03SMagnus Damm };
497f627f03SMagnus Damm 
507f627f03SMagnus Damm static struct platform_device uart0_device = {
517f627f03SMagnus Damm 	.name		= "serial8250-em",
527f627f03SMagnus Damm 	.id		= 0,
537f627f03SMagnus Damm 	.num_resources	= ARRAY_SIZE(uart0_resources),
547f627f03SMagnus Damm 	.resource	= uart0_resources,
557f627f03SMagnus Damm };
567f627f03SMagnus Damm 
577f627f03SMagnus Damm static struct resource uart1_resources[] = {
587f627f03SMagnus Damm 	[0]	= {
597f627f03SMagnus Damm 		.start	= 0xe1030000,
607f627f03SMagnus Damm 		.end	= 0xe1030037,
617f627f03SMagnus Damm 		.flags	= IORESOURCE_MEM,
627f627f03SMagnus Damm 	},
637f627f03SMagnus Damm 	[1]	= {
647f627f03SMagnus Damm 		.start	= 41,
657f627f03SMagnus Damm 		.flags	= IORESOURCE_IRQ,
667f627f03SMagnus Damm 	}
677f627f03SMagnus Damm };
687f627f03SMagnus Damm 
697f627f03SMagnus Damm static struct platform_device uart1_device = {
707f627f03SMagnus Damm 	.name		= "serial8250-em",
717f627f03SMagnus Damm 	.id		= 1,
727f627f03SMagnus Damm 	.num_resources	= ARRAY_SIZE(uart1_resources),
737f627f03SMagnus Damm 	.resource	= uart1_resources,
747f627f03SMagnus Damm };
757f627f03SMagnus Damm 
767f627f03SMagnus Damm static struct resource uart2_resources[] = {
777f627f03SMagnus Damm 	[0]	= {
787f627f03SMagnus Damm 		.start	= 0xe1040000,
797f627f03SMagnus Damm 		.end	= 0xe1040037,
807f627f03SMagnus Damm 		.flags	= IORESOURCE_MEM,
817f627f03SMagnus Damm 	},
827f627f03SMagnus Damm 	[1]	= {
837f627f03SMagnus Damm 		.start	= 42,
847f627f03SMagnus Damm 		.flags	= IORESOURCE_IRQ,
857f627f03SMagnus Damm 	}
867f627f03SMagnus Damm };
877f627f03SMagnus Damm 
887f627f03SMagnus Damm static struct platform_device uart2_device = {
897f627f03SMagnus Damm 	.name		= "serial8250-em",
907f627f03SMagnus Damm 	.id		= 2,
917f627f03SMagnus Damm 	.num_resources	= ARRAY_SIZE(uart2_resources),
927f627f03SMagnus Damm 	.resource	= uart2_resources,
937f627f03SMagnus Damm };
947f627f03SMagnus Damm 
957f627f03SMagnus Damm static struct resource uart3_resources[] = {
967f627f03SMagnus Damm 	[0]	= {
977f627f03SMagnus Damm 		.start	= 0xe1050000,
987f627f03SMagnus Damm 		.end	= 0xe1050037,
997f627f03SMagnus Damm 		.flags	= IORESOURCE_MEM,
1007f627f03SMagnus Damm 	},
1017f627f03SMagnus Damm 	[1]	= {
1027f627f03SMagnus Damm 		.start	= 43,
1037f627f03SMagnus Damm 		.flags	= IORESOURCE_IRQ,
1047f627f03SMagnus Damm 	}
1057f627f03SMagnus Damm };
1067f627f03SMagnus Damm 
1077f627f03SMagnus Damm static struct platform_device uart3_device = {
1087f627f03SMagnus Damm 	.name		= "serial8250-em",
1097f627f03SMagnus Damm 	.id		= 3,
1107f627f03SMagnus Damm 	.num_resources	= ARRAY_SIZE(uart3_resources),
1117f627f03SMagnus Damm 	.resource	= uart3_resources,
1127f627f03SMagnus Damm };
1137f627f03SMagnus Damm 
1147f627f03SMagnus Damm /* STI */
1157f627f03SMagnus Damm static struct resource sti_resources[] = {
1167f627f03SMagnus Damm 	[0] = {
1177f627f03SMagnus Damm 		.name	= "STI",
1187f627f03SMagnus Damm 		.start	= 0xe0180000,
1197f627f03SMagnus Damm 		.end	= 0xe0180053,
1207f627f03SMagnus Damm 		.flags	= IORESOURCE_MEM,
1217f627f03SMagnus Damm 	},
1227f627f03SMagnus Damm 	[1] = {
1237f627f03SMagnus Damm 		.start	= 157,
1247f627f03SMagnus Damm 		.flags	= IORESOURCE_IRQ,
1257f627f03SMagnus Damm 	},
1267f627f03SMagnus Damm };
1277f627f03SMagnus Damm 
1287f627f03SMagnus Damm static struct platform_device sti_device = {
1297f627f03SMagnus Damm 	.name		= "em_sti",
1307f627f03SMagnus Damm 	.id		= 0,
1317f627f03SMagnus Damm 	.resource	= sti_resources,
1327f627f03SMagnus Damm 	.num_resources	= ARRAY_SIZE(sti_resources),
1337f627f03SMagnus Damm };
1347f627f03SMagnus Damm 
1357f627f03SMagnus Damm static struct platform_device *emev2_early_devices[] __initdata = {
1367f627f03SMagnus Damm 	&uart0_device,
1377f627f03SMagnus Damm 	&uart1_device,
1387f627f03SMagnus Damm 	&uart2_device,
1397f627f03SMagnus Damm 	&uart3_device,
1407f627f03SMagnus Damm };
1417f627f03SMagnus Damm 
1427f627f03SMagnus Damm static struct platform_device *emev2_late_devices[] __initdata = {
1437f627f03SMagnus Damm 	&sti_device,
1447f627f03SMagnus Damm };
1457f627f03SMagnus Damm 
1467f627f03SMagnus Damm void __init emev2_add_standard_devices(void)
1477f627f03SMagnus Damm {
1487f627f03SMagnus Damm 	emev2_clock_init();
1497f627f03SMagnus Damm 
1507f627f03SMagnus Damm 	platform_add_devices(emev2_early_devices,
1517f627f03SMagnus Damm 			     ARRAY_SIZE(emev2_early_devices));
1527f627f03SMagnus Damm 
1537f627f03SMagnus Damm 	platform_add_devices(emev2_late_devices,
1547f627f03SMagnus Damm 			     ARRAY_SIZE(emev2_late_devices));
1557f627f03SMagnus Damm }
1567f627f03SMagnus Damm 
1577f627f03SMagnus Damm void __init emev2_add_early_devices(void)
1587f627f03SMagnus Damm {
1597f627f03SMagnus Damm 	shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
1607f627f03SMagnus Damm 
1617f627f03SMagnus Damm 	early_platform_add_devices(emev2_early_devices,
1627f627f03SMagnus Damm 				   ARRAY_SIZE(emev2_early_devices));
1637f627f03SMagnus Damm 
1647f627f03SMagnus Damm 	/* setup early console here as well */
1657f627f03SMagnus Damm 	shmobile_setup_console();
1667f627f03SMagnus Damm }
1677f627f03SMagnus Damm 
1687f627f03SMagnus Damm void __init emev2_init_irq(void)
1697f627f03SMagnus Damm {
1707f627f03SMagnus Damm 	void __iomem *gic_dist_base;
1717f627f03SMagnus Damm 	void __iomem *gic_cpu_base;
1727f627f03SMagnus Damm 
1737f627f03SMagnus Damm 	/* Static mappings, never released */
1747f627f03SMagnus Damm 	gic_dist_base = ioremap(0xe0028000, PAGE_SIZE);
1757f627f03SMagnus Damm 	gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE);
1767f627f03SMagnus Damm 	BUG_ON(!gic_dist_base || !gic_cpu_base);
1777f627f03SMagnus Damm 
1787f627f03SMagnus Damm 	/* Use GIC to handle interrupts */
1797f627f03SMagnus Damm 	gic_init(0, 29, gic_dist_base, gic_cpu_base);
1807f627f03SMagnus Damm }
181