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