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 37bd5a875dSMagnus Damm static struct map_desc emev2_io_desc[] __initdata = { 38bd5a875dSMagnus Damm #ifdef CONFIG_SMP 39bd5a875dSMagnus Damm /* 128K entity map for 0xe0100000 (SMU) */ 40bd5a875dSMagnus Damm { 41bd5a875dSMagnus Damm .virtual = 0xe0100000, 42bd5a875dSMagnus Damm .pfn = __phys_to_pfn(0xe0100000), 43bd5a875dSMagnus Damm .length = SZ_128K, 44bd5a875dSMagnus Damm .type = MT_DEVICE 45bd5a875dSMagnus Damm }, 46bd5a875dSMagnus Damm /* 2M mapping for SCU + L2 controller */ 47bd5a875dSMagnus Damm { 48bd5a875dSMagnus Damm .virtual = 0xf0000000, 49bd5a875dSMagnus Damm .pfn = __phys_to_pfn(0x1e000000), 50bd5a875dSMagnus Damm .length = SZ_2M, 51bd5a875dSMagnus Damm .type = MT_DEVICE 52bd5a875dSMagnus Damm }, 53bd5a875dSMagnus Damm #endif 54bd5a875dSMagnus Damm }; 55bd5a875dSMagnus Damm 56bd5a875dSMagnus Damm void __init emev2_map_io(void) 57bd5a875dSMagnus Damm { 58bd5a875dSMagnus Damm iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc)); 59bd5a875dSMagnus Damm } 60bd5a875dSMagnus Damm 617f627f03SMagnus Damm /* UART */ 627f627f03SMagnus Damm static struct resource uart0_resources[] = { 637f627f03SMagnus Damm [0] = { 647f627f03SMagnus Damm .start = 0xe1020000, 657f627f03SMagnus Damm .end = 0xe1020037, 667f627f03SMagnus Damm .flags = IORESOURCE_MEM, 677f627f03SMagnus Damm }, 687f627f03SMagnus Damm [1] = { 697f627f03SMagnus Damm .start = 40, 707f627f03SMagnus Damm .flags = IORESOURCE_IRQ, 717f627f03SMagnus Damm } 727f627f03SMagnus Damm }; 737f627f03SMagnus Damm 747f627f03SMagnus Damm static struct platform_device uart0_device = { 757f627f03SMagnus Damm .name = "serial8250-em", 767f627f03SMagnus Damm .id = 0, 777f627f03SMagnus Damm .num_resources = ARRAY_SIZE(uart0_resources), 787f627f03SMagnus Damm .resource = uart0_resources, 797f627f03SMagnus Damm }; 807f627f03SMagnus Damm 817f627f03SMagnus Damm static struct resource uart1_resources[] = { 827f627f03SMagnus Damm [0] = { 837f627f03SMagnus Damm .start = 0xe1030000, 847f627f03SMagnus Damm .end = 0xe1030037, 857f627f03SMagnus Damm .flags = IORESOURCE_MEM, 867f627f03SMagnus Damm }, 877f627f03SMagnus Damm [1] = { 887f627f03SMagnus Damm .start = 41, 897f627f03SMagnus Damm .flags = IORESOURCE_IRQ, 907f627f03SMagnus Damm } 917f627f03SMagnus Damm }; 927f627f03SMagnus Damm 937f627f03SMagnus Damm static struct platform_device uart1_device = { 947f627f03SMagnus Damm .name = "serial8250-em", 957f627f03SMagnus Damm .id = 1, 967f627f03SMagnus Damm .num_resources = ARRAY_SIZE(uart1_resources), 977f627f03SMagnus Damm .resource = uart1_resources, 987f627f03SMagnus Damm }; 997f627f03SMagnus Damm 1007f627f03SMagnus Damm static struct resource uart2_resources[] = { 1017f627f03SMagnus Damm [0] = { 1027f627f03SMagnus Damm .start = 0xe1040000, 1037f627f03SMagnus Damm .end = 0xe1040037, 1047f627f03SMagnus Damm .flags = IORESOURCE_MEM, 1057f627f03SMagnus Damm }, 1067f627f03SMagnus Damm [1] = { 1077f627f03SMagnus Damm .start = 42, 1087f627f03SMagnus Damm .flags = IORESOURCE_IRQ, 1097f627f03SMagnus Damm } 1107f627f03SMagnus Damm }; 1117f627f03SMagnus Damm 1127f627f03SMagnus Damm static struct platform_device uart2_device = { 1137f627f03SMagnus Damm .name = "serial8250-em", 1147f627f03SMagnus Damm .id = 2, 1157f627f03SMagnus Damm .num_resources = ARRAY_SIZE(uart2_resources), 1167f627f03SMagnus Damm .resource = uart2_resources, 1177f627f03SMagnus Damm }; 1187f627f03SMagnus Damm 1197f627f03SMagnus Damm static struct resource uart3_resources[] = { 1207f627f03SMagnus Damm [0] = { 1217f627f03SMagnus Damm .start = 0xe1050000, 1227f627f03SMagnus Damm .end = 0xe1050037, 1237f627f03SMagnus Damm .flags = IORESOURCE_MEM, 1247f627f03SMagnus Damm }, 1257f627f03SMagnus Damm [1] = { 1267f627f03SMagnus Damm .start = 43, 1277f627f03SMagnus Damm .flags = IORESOURCE_IRQ, 1287f627f03SMagnus Damm } 1297f627f03SMagnus Damm }; 1307f627f03SMagnus Damm 1317f627f03SMagnus Damm static struct platform_device uart3_device = { 1327f627f03SMagnus Damm .name = "serial8250-em", 1337f627f03SMagnus Damm .id = 3, 1347f627f03SMagnus Damm .num_resources = ARRAY_SIZE(uart3_resources), 1357f627f03SMagnus Damm .resource = uart3_resources, 1367f627f03SMagnus Damm }; 1377f627f03SMagnus Damm 1387f627f03SMagnus Damm /* STI */ 1397f627f03SMagnus Damm static struct resource sti_resources[] = { 1407f627f03SMagnus Damm [0] = { 1417f627f03SMagnus Damm .name = "STI", 1427f627f03SMagnus Damm .start = 0xe0180000, 1437f627f03SMagnus Damm .end = 0xe0180053, 1447f627f03SMagnus Damm .flags = IORESOURCE_MEM, 1457f627f03SMagnus Damm }, 1467f627f03SMagnus Damm [1] = { 1477f627f03SMagnus Damm .start = 157, 1487f627f03SMagnus Damm .flags = IORESOURCE_IRQ, 1497f627f03SMagnus Damm }, 1507f627f03SMagnus Damm }; 1517f627f03SMagnus Damm 1527f627f03SMagnus Damm static struct platform_device sti_device = { 1537f627f03SMagnus Damm .name = "em_sti", 1547f627f03SMagnus Damm .id = 0, 1557f627f03SMagnus Damm .resource = sti_resources, 1567f627f03SMagnus Damm .num_resources = ARRAY_SIZE(sti_resources), 1577f627f03SMagnus Damm }; 1587f627f03SMagnus Damm 1597f627f03SMagnus Damm static struct platform_device *emev2_early_devices[] __initdata = { 1607f627f03SMagnus Damm &uart0_device, 1617f627f03SMagnus Damm &uart1_device, 1627f627f03SMagnus Damm &uart2_device, 1637f627f03SMagnus Damm &uart3_device, 1647f627f03SMagnus Damm }; 1657f627f03SMagnus Damm 1667f627f03SMagnus Damm static struct platform_device *emev2_late_devices[] __initdata = { 1677f627f03SMagnus Damm &sti_device, 1687f627f03SMagnus Damm }; 1697f627f03SMagnus Damm 1707f627f03SMagnus Damm void __init emev2_add_standard_devices(void) 1717f627f03SMagnus Damm { 1727f627f03SMagnus Damm emev2_clock_init(); 1737f627f03SMagnus Damm 1747f627f03SMagnus Damm platform_add_devices(emev2_early_devices, 1757f627f03SMagnus Damm ARRAY_SIZE(emev2_early_devices)); 1767f627f03SMagnus Damm 1777f627f03SMagnus Damm platform_add_devices(emev2_late_devices, 1787f627f03SMagnus Damm ARRAY_SIZE(emev2_late_devices)); 1797f627f03SMagnus Damm } 1807f627f03SMagnus Damm 1817f627f03SMagnus Damm void __init emev2_add_early_devices(void) 1827f627f03SMagnus Damm { 1837f627f03SMagnus Damm shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */ 1847f627f03SMagnus Damm 1857f627f03SMagnus Damm early_platform_add_devices(emev2_early_devices, 1867f627f03SMagnus Damm ARRAY_SIZE(emev2_early_devices)); 1877f627f03SMagnus Damm 1887f627f03SMagnus Damm /* setup early console here as well */ 1897f627f03SMagnus Damm shmobile_setup_console(); 1907f627f03SMagnus Damm } 1917f627f03SMagnus Damm 1927f627f03SMagnus Damm void __init emev2_init_irq(void) 1937f627f03SMagnus Damm { 1947f627f03SMagnus Damm void __iomem *gic_dist_base; 1957f627f03SMagnus Damm void __iomem *gic_cpu_base; 1967f627f03SMagnus Damm 1977f627f03SMagnus Damm /* Static mappings, never released */ 1987f627f03SMagnus Damm gic_dist_base = ioremap(0xe0028000, PAGE_SIZE); 1997f627f03SMagnus Damm gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE); 2007f627f03SMagnus Damm BUG_ON(!gic_dist_base || !gic_cpu_base); 2017f627f03SMagnus Damm 2027f627f03SMagnus Damm /* Use GIC to handle interrupts */ 2037f627f03SMagnus Damm gic_init(0, 29, gic_dist_base, gic_cpu_base); 2047f627f03SMagnus Damm } 205