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  */
19a3153e6cSMagnus Damm #include <linux/clk-provider.h>
207f627f03SMagnus Damm #include <linux/kernel.h>
217f627f03SMagnus Damm #include <linux/init.h>
227f627f03SMagnus Damm #include <linux/interrupt.h>
237f627f03SMagnus Damm #include <linux/irq.h>
247f627f03SMagnus Damm #include <linux/platform_device.h>
25088efd92SMagnus Damm #include <linux/platform_data/gpio-em.h>
263d5de271SMagnus Damm #include <linux/of_platform.h>
277f627f03SMagnus Damm #include <linux/delay.h>
287f627f03SMagnus Damm #include <linux/input.h>
297f627f03SMagnus Damm #include <linux/io.h>
30520f7bd7SRob Herring #include <linux/irqchip/arm-gic.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 	/* 2M mapping for SCU + L2 controller */
42bd5a875dSMagnus Damm 	{
43bd5a875dSMagnus Damm 		.virtual	= 0xf0000000,
44bd5a875dSMagnus Damm 		.pfn		= __phys_to_pfn(0x1e000000),
45bd5a875dSMagnus Damm 		.length		= SZ_2M,
46bd5a875dSMagnus Damm 		.type		= MT_DEVICE
47bd5a875dSMagnus Damm 	},
48bd5a875dSMagnus Damm #endif
49bd5a875dSMagnus Damm };
50bd5a875dSMagnus Damm 
51bd5a875dSMagnus Damm void __init emev2_map_io(void)
52bd5a875dSMagnus Damm {
53bd5a875dSMagnus Damm 	iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc));
54bd5a875dSMagnus Damm }
55bd5a875dSMagnus Damm 
567f627f03SMagnus Damm /* UART */
577f627f03SMagnus Damm static struct resource uart0_resources[] = {
58210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1020000, 0x38),
59210e179dSMagnus Damm 	DEFINE_RES_IRQ(40),
607f627f03SMagnus Damm };
617f627f03SMagnus Damm 
627f627f03SMagnus Damm static struct resource uart1_resources[] = {
63210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1030000, 0x38),
64210e179dSMagnus Damm 	DEFINE_RES_IRQ(41),
657f627f03SMagnus Damm };
667f627f03SMagnus Damm 
677f627f03SMagnus Damm static struct resource uart2_resources[] = {
68210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1040000, 0x38),
69210e179dSMagnus Damm 	DEFINE_RES_IRQ(42),
707f627f03SMagnus Damm };
717f627f03SMagnus Damm 
727f627f03SMagnus Damm static struct resource uart3_resources[] = {
73210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe1050000, 0x38),
74210e179dSMagnus Damm 	DEFINE_RES_IRQ(43),
757f627f03SMagnus Damm };
767f627f03SMagnus Damm 
77210e179dSMagnus Damm #define emev2_register_uart(idx)					\
78210e179dSMagnus Damm 	platform_device_register_simple("serial8250-em", idx,		\
79210e179dSMagnus Damm 					uart##idx##_resources,		\
80210e179dSMagnus Damm 					ARRAY_SIZE(uart##idx##_resources))
817f627f03SMagnus Damm 
827f627f03SMagnus Damm /* STI */
837f627f03SMagnus Damm static struct resource sti_resources[] = {
84210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0180000, 0x54),
85210e179dSMagnus Damm 	DEFINE_RES_IRQ(157),
867f627f03SMagnus Damm };
877f627f03SMagnus Damm 
88210e179dSMagnus Damm #define emev2_register_sti()					\
89210e179dSMagnus Damm 	platform_device_register_simple("em_sti", 0,		\
90210e179dSMagnus Damm 					sti_resources,		\
91210e179dSMagnus Damm 					ARRAY_SIZE(sti_resources))
92088efd92SMagnus Damm 
93088efd92SMagnus Damm /* GIO */
94088efd92SMagnus Damm static struct gpio_em_config gio0_config = {
95088efd92SMagnus Damm 	.gpio_base = 0,
96088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(0),
97088efd92SMagnus Damm 	.number_of_pins = 32,
98088efd92SMagnus Damm };
99088efd92SMagnus Damm 
100088efd92SMagnus Damm static struct resource gio0_resources[] = {
101210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050000, 0x2c),
102210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050040, 0x20),
103210e179dSMagnus Damm 	DEFINE_RES_IRQ(99),
104210e179dSMagnus Damm 	DEFINE_RES_IRQ(100),
105088efd92SMagnus Damm };
106088efd92SMagnus Damm 
107088efd92SMagnus Damm static struct gpio_em_config gio1_config = {
108088efd92SMagnus Damm 	.gpio_base = 32,
109088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(32),
110088efd92SMagnus Damm 	.number_of_pins = 32,
111088efd92SMagnus Damm };
112088efd92SMagnus Damm 
113088efd92SMagnus Damm static struct resource gio1_resources[] = {
114210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050080, 0x2c),
115210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe00500c0, 0x20),
116210e179dSMagnus Damm 	DEFINE_RES_IRQ(101),
117210e179dSMagnus Damm 	DEFINE_RES_IRQ(102),
118088efd92SMagnus Damm };
119088efd92SMagnus Damm 
120088efd92SMagnus Damm static struct gpio_em_config gio2_config = {
121088efd92SMagnus Damm 	.gpio_base = 64,
122088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(64),
123088efd92SMagnus Damm 	.number_of_pins = 32,
124088efd92SMagnus Damm };
125088efd92SMagnus Damm 
126088efd92SMagnus Damm static struct resource gio2_resources[] = {
127210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050100, 0x2c),
128210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050140, 0x20),
129210e179dSMagnus Damm 	DEFINE_RES_IRQ(103),
130210e179dSMagnus Damm 	DEFINE_RES_IRQ(104),
131088efd92SMagnus Damm };
132088efd92SMagnus Damm 
133088efd92SMagnus Damm static struct gpio_em_config gio3_config = {
134088efd92SMagnus Damm 	.gpio_base = 96,
135088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(96),
136088efd92SMagnus Damm 	.number_of_pins = 32,
137088efd92SMagnus Damm };
138088efd92SMagnus Damm 
139088efd92SMagnus Damm static struct resource gio3_resources[] = {
140210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050180, 0x2c),
141210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe00501c0, 0x20),
142210e179dSMagnus Damm 	DEFINE_RES_IRQ(105),
143210e179dSMagnus Damm 	DEFINE_RES_IRQ(106),
144088efd92SMagnus Damm };
145088efd92SMagnus Damm 
146088efd92SMagnus Damm static struct gpio_em_config gio4_config = {
147088efd92SMagnus Damm 	.gpio_base = 128,
148088efd92SMagnus Damm 	.irq_base = EMEV2_GPIO_IRQ(128),
149088efd92SMagnus Damm 	.number_of_pins = 31,
150088efd92SMagnus Damm };
151088efd92SMagnus Damm 
152088efd92SMagnus Damm static struct resource gio4_resources[] = {
153210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050200, 0x2c),
154210e179dSMagnus Damm 	DEFINE_RES_MEM(0xe0050240, 0x20),
155210e179dSMagnus Damm 	DEFINE_RES_IRQ(107),
156210e179dSMagnus Damm 	DEFINE_RES_IRQ(108),
157088efd92SMagnus Damm };
158088efd92SMagnus Damm 
159210e179dSMagnus Damm #define emev2_register_gio(idx)						\
160210e179dSMagnus Damm 	platform_device_register_resndata(&platform_bus, "em_gio",	\
161210e179dSMagnus Damm 					  idx, gio##idx##_resources,	\
162210e179dSMagnus Damm 					  ARRAY_SIZE(gio##idx##_resources), \
163210e179dSMagnus Damm 					  &gio##idx##_config,		\
164210e179dSMagnus Damm 					  sizeof(struct gpio_em_config))
165088efd92SMagnus Damm 
166e433d444STetsuyuki Kobayashi static struct resource pmu_resources[] = {
167210e179dSMagnus Damm 	DEFINE_RES_IRQ(152),
168210e179dSMagnus Damm 	DEFINE_RES_IRQ(153),
169e433d444STetsuyuki Kobayashi };
170e433d444STetsuyuki Kobayashi 
171210e179dSMagnus Damm #define emev2_register_pmu()					\
172210e179dSMagnus Damm 	platform_device_register_simple("arm-pmu", -1,		\
173210e179dSMagnus Damm 					pmu_resources,		\
174210e179dSMagnus Damm 					ARRAY_SIZE(pmu_resources))
1757f627f03SMagnus Damm 
1767f627f03SMagnus Damm void __init emev2_add_standard_devices(void)
1777f627f03SMagnus Damm {
178cbc60e7cSMagnus Damm 	if (!IS_ENABLED(CONFIG_COMMON_CLK))
1797f627f03SMagnus Damm 		emev2_clock_init();
1807f627f03SMagnus Damm 
181210e179dSMagnus Damm 	emev2_register_uart(0);
182210e179dSMagnus Damm 	emev2_register_uart(1);
183210e179dSMagnus Damm 	emev2_register_uart(2);
184210e179dSMagnus Damm 	emev2_register_uart(3);
185210e179dSMagnus Damm 	emev2_register_sti();
186210e179dSMagnus Damm 	emev2_register_gio(0);
187210e179dSMagnus Damm 	emev2_register_gio(1);
188210e179dSMagnus Damm 	emev2_register_gio(2);
189210e179dSMagnus Damm 	emev2_register_gio(3);
190210e179dSMagnus Damm 	emev2_register_gio(4);
191210e179dSMagnus Damm 	emev2_register_pmu();
1927f627f03SMagnus Damm }
1937f627f03SMagnus Damm 
1944146fa88SMagnus Damm void __init emev2_init_delay(void)
1957f627f03SMagnus Damm {
1967f627f03SMagnus Damm 	shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
1973d5de271SMagnus Damm }
1983d5de271SMagnus Damm 
1993d5de271SMagnus Damm #ifdef CONFIG_USE_OF
2003d5de271SMagnus Damm 
201a3153e6cSMagnus Damm static void __init emev2_add_standard_devices_dt(void)
202a3153e6cSMagnus Damm {
203a3153e6cSMagnus Damm #ifdef CONFIG_COMMON_CLK
204a3153e6cSMagnus Damm 	of_clk_init(NULL);
205a3153e6cSMagnus Damm #else
206a3153e6cSMagnus Damm 	emev2_clock_init();
207a3153e6cSMagnus Damm #endif
208a3153e6cSMagnus Damm 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
209a3153e6cSMagnus Damm }
210a3153e6cSMagnus Damm 
2113d5de271SMagnus Damm static const char *emev2_boards_compat_dt[] __initdata = {
2123d5de271SMagnus Damm 	"renesas,emev2",
2133d5de271SMagnus Damm 	NULL,
2143d5de271SMagnus Damm };
2153d5de271SMagnus Damm 
2163d5de271SMagnus Damm DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)")
217a62580e5SMarc Zyngier 	.smp		= smp_ops(emev2_smp_ops),
2180ea2b538SMagnus Damm 	.map_io		= emev2_map_io,
2193d5de271SMagnus Damm 	.init_early	= emev2_init_delay,
220a3153e6cSMagnus Damm 	.init_machine	= emev2_add_standard_devices_dt,
2213f348e1cSMagnus Damm 	.init_late	= shmobile_init_late,
2223d5de271SMagnus Damm 	.dt_compat	= emev2_boards_compat_dt,
2233d5de271SMagnus Damm MACHINE_END
2243d5de271SMagnus Damm 
2253d5de271SMagnus Damm #endif /* CONFIG_USE_OF */
226