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>
24088efd92SMagnus Damm #include <linux/platform_data/gpio-em.h>
253d5de271SMagnus Damm #include <linux/of_platform.h>
267f627f03SMagnus Damm #include <linux/delay.h>
277f627f03SMagnus Damm #include <linux/input.h>
287f627f03SMagnus Damm #include <linux/io.h>
29520f7bd7SRob Herring #include <linux/irqchip/arm-gic.h>
307f627f03SMagnus Damm #include <mach/hardware.h>
317f627f03SMagnus Damm #include <mach/common.h>
327f627f03SMagnus Damm #include <mach/emev2.h>
337f627f03SMagnus Damm #include <mach/irqs.h>
347f627f03SMagnus Damm #include <asm/mach-types.h>
357f627f03SMagnus Damm #include <asm/mach/arch.h>
367f627f03SMagnus Damm #include <asm/mach/map.h>
377f627f03SMagnus Damm #include <asm/mach/time.h>
387f627f03SMagnus Damm 
39bd5a875dSMagnus Damm static struct map_desc emev2_io_desc[] __initdata = {
40bd5a875dSMagnus Damm #ifdef CONFIG_SMP
41bd5a875dSMagnus Damm 	/* 128K entity map for 0xe0100000 (SMU) */
42bd5a875dSMagnus Damm 	{
43bd5a875dSMagnus Damm 		.virtual	= 0xe0100000,
44bd5a875dSMagnus Damm 		.pfn		= __phys_to_pfn(0xe0100000),
45bd5a875dSMagnus Damm 		.length		= SZ_128K,
46bd5a875dSMagnus Damm 		.type		= MT_DEVICE
47bd5a875dSMagnus Damm 	},
48bd5a875dSMagnus Damm 	/* 2M mapping for SCU + L2 controller */
49bd5a875dSMagnus Damm 	{
50bd5a875dSMagnus Damm 		.virtual	= 0xf0000000,
51bd5a875dSMagnus Damm 		.pfn		= __phys_to_pfn(0x1e000000),
52bd5a875dSMagnus Damm 		.length		= SZ_2M,
53bd5a875dSMagnus Damm 		.type		= MT_DEVICE
54bd5a875dSMagnus Damm 	},
55bd5a875dSMagnus Damm #endif
56bd5a875dSMagnus Damm };
57bd5a875dSMagnus Damm 
58bd5a875dSMagnus Damm void __init emev2_map_io(void)
59bd5a875dSMagnus Damm {
60bd5a875dSMagnus Damm 	iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
61bd5a875dSMagnus Damm }
62bd5a875dSMagnus Damm 
637f627f03SMagnus Damm /* UART */
647f627f03SMagnus Damm static struct resource uart0_resources[] = {
65210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1020000, 0x38),
66210e179dSMagnus Damm 	DEFINE_RES_IRQ(40),
677f627f03SMagnus Damm };
687f627f03SMagnus Damm 
697f627f03SMagnus Damm static struct resource uart1_resources[] = {
70210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1030000, 0x38),
71210e179dSMagnus Damm 	DEFINE_RES_IRQ(41),
727f627f03SMagnus Damm };
737f627f03SMagnus Damm 
747f627f03SMagnus Damm static struct resource uart2_resources[] = {
75210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1040000, 0x38),
76210e179dSMagnus Damm 	DEFINE_RES_IRQ(42),
777f627f03SMagnus Damm };
787f627f03SMagnus Damm 
797f627f03SMagnus Damm static struct resource uart3_resources[] = {
80210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1050000, 0x38),
81210e179dSMagnus Damm 	DEFINE_RES_IRQ(43),
827f627f03SMagnus Damm };
837f627f03SMagnus Damm 
84210e179dSMagnus Damm #define emev2_register_uart(idx)					\
85210e179dSMagnus Damm 	platform_device_register_simple("serial8250-em", idx,		\
86210e179dSMagnus Damm 					uart##idx##_resources,		\
87210e179dSMagnus Damm 					ARRAY_SIZE(uart##idx##_resources))
887f627f03SMagnus Damm 
897f627f03SMagnus Damm /* STI */
907f627f03SMagnus Damm static struct resource sti_resources[] = {
91210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0180000, 0x54),
92210e179dSMagnus Damm 	DEFINE_RES_IRQ(157),
937f627f03SMagnus Damm };
947f627f03SMagnus Damm 
95210e179dSMagnus Damm #define emev2_register_sti()					\
96210e179dSMagnus Damm 	platform_device_register_simple("em_sti", 0,		\
97210e179dSMagnus Damm 					sti_resources,		\
98210e179dSMagnus Damm 					ARRAY_SIZE(sti_resources))
99088efd92SMagnus Damm 
100088efd92SMagnus Damm /* GIO */
101088efd92SMagnus Damm static struct gpio_em_config gio0_config = {
102088efd92SMagnus Damm 	.gpio_base = 0,
103088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(0),
104088efd92SMagnus Damm 	.number_of_pins = 32,
105088efd92SMagnus Damm };
106088efd92SMagnus Damm 
107088efd92SMagnus Damm static struct resource gio0_resources[] = {
108210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050000, 0x2c),
109210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050040, 0x20),
110210e179dSMagnus Damm 	DEFINE_RES_IRQ(99),
111210e179dSMagnus Damm 	DEFINE_RES_IRQ(100),
112088efd92SMagnus Damm };
113088efd92SMagnus Damm 
114088efd92SMagnus Damm static struct gpio_em_config gio1_config = {
115088efd92SMagnus Damm 	.gpio_base = 32,
116088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(32),
117088efd92SMagnus Damm 	.number_of_pins = 32,
118088efd92SMagnus Damm };
119088efd92SMagnus Damm 
120088efd92SMagnus Damm static struct resource gio1_resources[] = {
121210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050080, 0x2c),
122210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe00500c0, 0x20),
123210e179dSMagnus Damm 	DEFINE_RES_IRQ(101),
124210e179dSMagnus Damm 	DEFINE_RES_IRQ(102),
125088efd92SMagnus Damm };
126088efd92SMagnus Damm 
127088efd92SMagnus Damm static struct gpio_em_config gio2_config = {
128088efd92SMagnus Damm 	.gpio_base = 64,
129088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(64),
130088efd92SMagnus Damm 	.number_of_pins = 32,
131088efd92SMagnus Damm };
132088efd92SMagnus Damm 
133088efd92SMagnus Damm static struct resource gio2_resources[] = {
134210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050100, 0x2c),
135210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050140, 0x20),
136210e179dSMagnus Damm 	DEFINE_RES_IRQ(103),
137210e179dSMagnus Damm 	DEFINE_RES_IRQ(104),
138088efd92SMagnus Damm };
139088efd92SMagnus Damm 
140088efd92SMagnus Damm static struct gpio_em_config gio3_config = {
141088efd92SMagnus Damm 	.gpio_base = 96,
142088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(96),
143088efd92SMagnus Damm 	.number_of_pins = 32,
144088efd92SMagnus Damm };
145088efd92SMagnus Damm 
146088efd92SMagnus Damm static struct resource gio3_resources[] = {
147210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050180, 0x2c),
148210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe00501c0, 0x20),
149210e179dSMagnus Damm 	DEFINE_RES_IRQ(105),
150210e179dSMagnus Damm 	DEFINE_RES_IRQ(106),
151088efd92SMagnus Damm };
152088efd92SMagnus Damm 
153088efd92SMagnus Damm static struct gpio_em_config gio4_config = {
154088efd92SMagnus Damm 	.gpio_base = 128,
155088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(128),
156088efd92SMagnus Damm 	.number_of_pins = 31,
157088efd92SMagnus Damm };
158088efd92SMagnus Damm 
159088efd92SMagnus Damm static struct resource gio4_resources[] = {
160210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050200, 0x2c),
161210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050240, 0x20),
162210e179dSMagnus Damm 	DEFINE_RES_IRQ(107),
163210e179dSMagnus Damm 	DEFINE_RES_IRQ(108),
164088efd92SMagnus Damm };
165088efd92SMagnus Damm 
166210e179dSMagnus Damm #define emev2_register_gio(idx)						\
167210e179dSMagnus Damm 	platform_device_register_resndata(&platform_bus, "em_gio",	\
168210e179dSMagnus Damm 					  idx, gio##idx##_resources,	\
169210e179dSMagnus Damm 					  ARRAY_SIZE(gio##idx##_resources), \
170210e179dSMagnus Damm 					  &gio##idx##_config,		\
171210e179dSMagnus Damm 					  sizeof(struct gpio_em_config))
172088efd92SMagnus Damm 
173e433d444STetsuyuki Kobayashi static struct resource pmu_resources[] = {
174210e179dSMagnus Damm 	DEFINE_RES_IRQ(152),
175210e179dSMagnus Damm 	DEFINE_RES_IRQ(153),
176e433d444STetsuyuki Kobayashi };
177e433d444STetsuyuki Kobayashi 
178210e179dSMagnus Damm #define emev2_register_pmu()					\
179210e179dSMagnus Damm 	platform_device_register_simple("arm-pmu", -1,		\
180210e179dSMagnus Damm 					pmu_resources,		\
181210e179dSMagnus Damm 					ARRAY_SIZE(pmu_resources))
1827f627f03SMagnus Damm 
1837f627f03SMagnus Damm void __init emev2_add_standard_devices(void)
1847f627f03SMagnus Damm {
1857f627f03SMagnus Damm 	emev2_clock_init();
1867f627f03SMagnus Damm 
187210e179dSMagnus Damm 	emev2_register_uart(0);
188210e179dSMagnus Damm 	emev2_register_uart(1);
189210e179dSMagnus Damm 	emev2_register_uart(2);
190210e179dSMagnus Damm 	emev2_register_uart(3);
191210e179dSMagnus Damm 	emev2_register_sti();
192210e179dSMagnus Damm 	emev2_register_gio(0);
193210e179dSMagnus Damm 	emev2_register_gio(1);
194210e179dSMagnus Damm 	emev2_register_gio(2);
195210e179dSMagnus Damm 	emev2_register_gio(3);
196210e179dSMagnus Damm 	emev2_register_gio(4);
197210e179dSMagnus Damm 	emev2_register_pmu();
1987f627f03SMagnus Damm }
1997f627f03SMagnus Damm 
2004146fa88SMagnus Damm void __init emev2_init_delay(void)
2017f627f03SMagnus Damm {
2027f627f03SMagnus Damm 	shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
2033d5de271SMagnus Damm }
2043d5de271SMagnus Damm 
2057f627f03SMagnus Damm void __init emev2_init_irq(void)
2067f627f03SMagnus Damm {
2077f627f03SMagnus Damm 	void __iomem *gic_dist_base;
2087f627f03SMagnus Damm 	void __iomem *gic_cpu_base;
2097f627f03SMagnus Damm 
2107f627f03SMagnus Damm 	/* Static mappings, never released */
2117f627f03SMagnus Damm 	gic_dist_base = ioremap(0xe0028000, PAGE_SIZE);
2127f627f03SMagnus Damm 	gic_cpu_base = ioremap(0xe0020000, PAGE_SIZE);
2137f627f03SMagnus Damm 	BUG_ON(!gic_dist_base || !gic_cpu_base);
2147f627f03SMagnus Damm 
2157f627f03SMagnus Damm 	/* Use GIC to handle interrupts */
2167f627f03SMagnus Damm 	gic_init(0, 29, gic_dist_base, gic_cpu_base);
2177f627f03SMagnus Damm }
2183d5de271SMagnus Damm 
2193d5de271SMagnus Damm #ifdef CONFIG_USE_OF
2203d5de271SMagnus Damm 
2213d5de271SMagnus Damm static const char *emev2_boards_compat_dt[] __initdata = {
2223d5de271SMagnus Damm 	"renesas,emev2",
2233d5de271SMagnus Damm 	NULL,
2243d5de271SMagnus Damm };
2253d5de271SMagnus Damm 
2263d5de271SMagnus Damm DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
227a62580e5SMarc Zyngier 	.smp		= smp_ops(emev2_smp_ops),
2283d5de271SMagnus Damm 	.init_early	= emev2_init_delay,
2293d5de271SMagnus Damm 	.nr_irqs	= NR_IRQS_LEGACY,
2303d5de271SMagnus Damm 	.dt_compat	= emev2_boards_compat_dt,
2313d5de271SMagnus Damm MACHINE_END
2323d5de271SMagnus Damm 
2333d5de271SMagnus Damm #endif /* CONFIG_USE_OF */
234