18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * arch/sh/boards/mach-x3proto/setup.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Renesas SH-X3 Prototype Board Support.
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2007 - 2010  Paul Mundt
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci#include <linux/init.h>
108c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/io.h>
138c2ecf20Sopenharmony_ci#include <linux/smc91x.h>
148c2ecf20Sopenharmony_ci#include <linux/irq.h>
158c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
168c2ecf20Sopenharmony_ci#include <linux/input.h>
178c2ecf20Sopenharmony_ci#include <linux/usb/r8a66597.h>
188c2ecf20Sopenharmony_ci#include <linux/usb/m66592.h>
198c2ecf20Sopenharmony_ci#include <linux/gpio.h>
208c2ecf20Sopenharmony_ci#include <linux/gpio_keys.h>
218c2ecf20Sopenharmony_ci#include <mach/ilsel.h>
228c2ecf20Sopenharmony_ci#include <mach/hardware.h>
238c2ecf20Sopenharmony_ci#include <asm/smp-ops.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic struct resource heartbeat_resources[] = {
268c2ecf20Sopenharmony_ci	[0] = {
278c2ecf20Sopenharmony_ci		.start	= 0xb8140020,
288c2ecf20Sopenharmony_ci		.end	= 0xb8140020,
298c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
308c2ecf20Sopenharmony_ci	},
318c2ecf20Sopenharmony_ci};
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic struct platform_device heartbeat_device = {
348c2ecf20Sopenharmony_ci	.name		= "heartbeat",
358c2ecf20Sopenharmony_ci	.id		= -1,
368c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(heartbeat_resources),
378c2ecf20Sopenharmony_ci	.resource	= heartbeat_resources,
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistatic struct smc91x_platdata smc91x_info = {
418c2ecf20Sopenharmony_ci	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistatic struct resource smc91x_resources[] = {
458c2ecf20Sopenharmony_ci	[0] = {
468c2ecf20Sopenharmony_ci		.start		= 0x18000300,
478c2ecf20Sopenharmony_ci		.end		= 0x18000300 + 0x10 - 1,
488c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_MEM,
498c2ecf20Sopenharmony_ci	},
508c2ecf20Sopenharmony_ci	[1] = {
518c2ecf20Sopenharmony_ci		/* Filled in by ilsel */
528c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
538c2ecf20Sopenharmony_ci	},
548c2ecf20Sopenharmony_ci};
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic struct platform_device smc91x_device = {
578c2ecf20Sopenharmony_ci	.name		= "smc91x",
588c2ecf20Sopenharmony_ci	.id		= -1,
598c2ecf20Sopenharmony_ci	.resource	= smc91x_resources,
608c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(smc91x_resources),
618c2ecf20Sopenharmony_ci	.dev	= {
628c2ecf20Sopenharmony_ci		.platform_data = &smc91x_info,
638c2ecf20Sopenharmony_ci	},
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic struct r8a66597_platdata r8a66597_data = {
678c2ecf20Sopenharmony_ci	.xtal = R8A66597_PLATDATA_XTAL_12MHZ,
688c2ecf20Sopenharmony_ci	.vif = 1,
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic struct resource r8a66597_usb_host_resources[] = {
728c2ecf20Sopenharmony_ci	[0] = {
738c2ecf20Sopenharmony_ci		.start	= 0x18040000,
748c2ecf20Sopenharmony_ci		.end	= 0x18080000 - 1,
758c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
768c2ecf20Sopenharmony_ci	},
778c2ecf20Sopenharmony_ci	[1] = {
788c2ecf20Sopenharmony_ci		/* Filled in by ilsel */
798c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
808c2ecf20Sopenharmony_ci	},
818c2ecf20Sopenharmony_ci};
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic struct platform_device r8a66597_usb_host_device = {
848c2ecf20Sopenharmony_ci	.name		= "r8a66597_hcd",
858c2ecf20Sopenharmony_ci	.id		= -1,
868c2ecf20Sopenharmony_ci	.dev = {
878c2ecf20Sopenharmony_ci		.dma_mask		= NULL,		/* don't use dma */
888c2ecf20Sopenharmony_ci		.coherent_dma_mask	= 0xffffffff,
898c2ecf20Sopenharmony_ci		.platform_data		= &r8a66597_data,
908c2ecf20Sopenharmony_ci	},
918c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(r8a66597_usb_host_resources),
928c2ecf20Sopenharmony_ci	.resource	= r8a66597_usb_host_resources,
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic struct m66592_platdata usbf_platdata = {
968c2ecf20Sopenharmony_ci	.xtal = M66592_PLATDATA_XTAL_24MHZ,
978c2ecf20Sopenharmony_ci	.vif = 1,
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic struct resource m66592_usb_peripheral_resources[] = {
1018c2ecf20Sopenharmony_ci	[0] = {
1028c2ecf20Sopenharmony_ci		.name	= "m66592_udc",
1038c2ecf20Sopenharmony_ci		.start	= 0x18080000,
1048c2ecf20Sopenharmony_ci		.end	= 0x180c0000 - 1,
1058c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1068c2ecf20Sopenharmony_ci	},
1078c2ecf20Sopenharmony_ci	[1] = {
1088c2ecf20Sopenharmony_ci		.name	= "m66592_udc",
1098c2ecf20Sopenharmony_ci		/* Filled in by ilsel */
1108c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
1118c2ecf20Sopenharmony_ci	},
1128c2ecf20Sopenharmony_ci};
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistatic struct platform_device m66592_usb_peripheral_device = {
1158c2ecf20Sopenharmony_ci	.name		= "m66592_udc",
1168c2ecf20Sopenharmony_ci	.id		= -1,
1178c2ecf20Sopenharmony_ci	.dev = {
1188c2ecf20Sopenharmony_ci		.dma_mask		= NULL,		/* don't use dma */
1198c2ecf20Sopenharmony_ci		.coherent_dma_mask	= 0xffffffff,
1208c2ecf20Sopenharmony_ci		.platform_data		= &usbf_platdata,
1218c2ecf20Sopenharmony_ci	},
1228c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
1238c2ecf20Sopenharmony_ci	.resource	= m66592_usb_peripheral_resources,
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic struct gpio_keys_button baseboard_buttons[NR_BASEBOARD_GPIOS] = {
1278c2ecf20Sopenharmony_ci	{
1288c2ecf20Sopenharmony_ci		.desc		= "key44",
1298c2ecf20Sopenharmony_ci		.code		= KEY_POWER,
1308c2ecf20Sopenharmony_ci		.active_low	= 1,
1318c2ecf20Sopenharmony_ci		.wakeup		= 1,
1328c2ecf20Sopenharmony_ci	}, {
1338c2ecf20Sopenharmony_ci		.desc		= "key43",
1348c2ecf20Sopenharmony_ci		.code		= KEY_SUSPEND,
1358c2ecf20Sopenharmony_ci		.active_low	= 1,
1368c2ecf20Sopenharmony_ci		.wakeup		= 1,
1378c2ecf20Sopenharmony_ci	}, {
1388c2ecf20Sopenharmony_ci		.desc		= "key42",
1398c2ecf20Sopenharmony_ci		.code		= KEY_KATAKANAHIRAGANA,
1408c2ecf20Sopenharmony_ci		.active_low	= 1,
1418c2ecf20Sopenharmony_ci	}, {
1428c2ecf20Sopenharmony_ci		.desc		= "key41",
1438c2ecf20Sopenharmony_ci		.code		= KEY_SWITCHVIDEOMODE,
1448c2ecf20Sopenharmony_ci		.active_low	= 1,
1458c2ecf20Sopenharmony_ci	}, {
1468c2ecf20Sopenharmony_ci		.desc		= "key34",
1478c2ecf20Sopenharmony_ci		.code		= KEY_F12,
1488c2ecf20Sopenharmony_ci		.active_low	= 1,
1498c2ecf20Sopenharmony_ci	}, {
1508c2ecf20Sopenharmony_ci		.desc		= "key33",
1518c2ecf20Sopenharmony_ci		.code		= KEY_F11,
1528c2ecf20Sopenharmony_ci		.active_low	= 1,
1538c2ecf20Sopenharmony_ci	}, {
1548c2ecf20Sopenharmony_ci		.desc		= "key32",
1558c2ecf20Sopenharmony_ci		.code		= KEY_F10,
1568c2ecf20Sopenharmony_ci		.active_low	= 1,
1578c2ecf20Sopenharmony_ci	}, {
1588c2ecf20Sopenharmony_ci		.desc		= "key31",
1598c2ecf20Sopenharmony_ci		.code		= KEY_F9,
1608c2ecf20Sopenharmony_ci		.active_low	= 1,
1618c2ecf20Sopenharmony_ci	}, {
1628c2ecf20Sopenharmony_ci		.desc		= "key24",
1638c2ecf20Sopenharmony_ci		.code		= KEY_F8,
1648c2ecf20Sopenharmony_ci		.active_low	= 1,
1658c2ecf20Sopenharmony_ci	}, {
1668c2ecf20Sopenharmony_ci		.desc		= "key23",
1678c2ecf20Sopenharmony_ci		.code		= KEY_F7,
1688c2ecf20Sopenharmony_ci		.active_low	= 1,
1698c2ecf20Sopenharmony_ci	}, {
1708c2ecf20Sopenharmony_ci		.desc		= "key22",
1718c2ecf20Sopenharmony_ci		.code		= KEY_F6,
1728c2ecf20Sopenharmony_ci		.active_low	= 1,
1738c2ecf20Sopenharmony_ci	}, {
1748c2ecf20Sopenharmony_ci		.desc		= "key21",
1758c2ecf20Sopenharmony_ci		.code		= KEY_F5,
1768c2ecf20Sopenharmony_ci		.active_low	= 1,
1778c2ecf20Sopenharmony_ci	}, {
1788c2ecf20Sopenharmony_ci		.desc		= "key14",
1798c2ecf20Sopenharmony_ci		.code		= KEY_F4,
1808c2ecf20Sopenharmony_ci		.active_low	= 1,
1818c2ecf20Sopenharmony_ci	}, {
1828c2ecf20Sopenharmony_ci		.desc		= "key13",
1838c2ecf20Sopenharmony_ci		.code		= KEY_F3,
1848c2ecf20Sopenharmony_ci		.active_low	= 1,
1858c2ecf20Sopenharmony_ci	}, {
1868c2ecf20Sopenharmony_ci		.desc		= "key12",
1878c2ecf20Sopenharmony_ci		.code		= KEY_F2,
1888c2ecf20Sopenharmony_ci		.active_low	= 1,
1898c2ecf20Sopenharmony_ci	}, {
1908c2ecf20Sopenharmony_ci		.desc		= "key11",
1918c2ecf20Sopenharmony_ci		.code		= KEY_F1,
1928c2ecf20Sopenharmony_ci		.active_low	= 1,
1938c2ecf20Sopenharmony_ci	},
1948c2ecf20Sopenharmony_ci};
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_cistatic struct gpio_keys_platform_data baseboard_buttons_data = {
1978c2ecf20Sopenharmony_ci	.buttons	= baseboard_buttons,
1988c2ecf20Sopenharmony_ci	.nbuttons	= ARRAY_SIZE(baseboard_buttons),
1998c2ecf20Sopenharmony_ci};
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistatic struct platform_device baseboard_buttons_device = {
2028c2ecf20Sopenharmony_ci	.name		= "gpio-keys",
2038c2ecf20Sopenharmony_ci	.id		= -1,
2048c2ecf20Sopenharmony_ci	.dev		= {
2058c2ecf20Sopenharmony_ci		.platform_data	= &baseboard_buttons_data,
2068c2ecf20Sopenharmony_ci	},
2078c2ecf20Sopenharmony_ci};
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic struct platform_device *x3proto_devices[] __initdata = {
2108c2ecf20Sopenharmony_ci	&heartbeat_device,
2118c2ecf20Sopenharmony_ci	&smc91x_device,
2128c2ecf20Sopenharmony_ci	&r8a66597_usb_host_device,
2138c2ecf20Sopenharmony_ci	&m66592_usb_peripheral_device,
2148c2ecf20Sopenharmony_ci	&baseboard_buttons_device,
2158c2ecf20Sopenharmony_ci};
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic void __init x3proto_init_irq(void)
2188c2ecf20Sopenharmony_ci{
2198c2ecf20Sopenharmony_ci	plat_irq_setup_pins(IRQ_MODE_IRL3210);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	/* Set ICR0.LVLMODE */
2228c2ecf20Sopenharmony_ci	__raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic int __init x3proto_devices_setup(void)
2268c2ecf20Sopenharmony_ci{
2278c2ecf20Sopenharmony_ci	int ret, i;
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	/*
2308c2ecf20Sopenharmony_ci	 * IRLs are only needed for ILSEL mappings, so flip over the INTC
2318c2ecf20Sopenharmony_ci	 * pins at a later point to enable the GPIOs to settle.
2328c2ecf20Sopenharmony_ci	 */
2338c2ecf20Sopenharmony_ci	x3proto_init_irq();
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	/*
2368c2ecf20Sopenharmony_ci	 * Now that ILSELs are available, set up the baseboard GPIOs.
2378c2ecf20Sopenharmony_ci	 */
2388c2ecf20Sopenharmony_ci	ret = x3proto_gpio_setup();
2398c2ecf20Sopenharmony_ci	if (unlikely(ret))
2408c2ecf20Sopenharmony_ci		return ret;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	/*
2438c2ecf20Sopenharmony_ci	 * Propagate dynamic GPIOs for the baseboard button device.
2448c2ecf20Sopenharmony_ci	 */
2458c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(baseboard_buttons); i++)
2468c2ecf20Sopenharmony_ci		baseboard_buttons[i].gpio = x3proto_gpio_chip.base + i;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	r8a66597_usb_host_resources[1].start =
2498c2ecf20Sopenharmony_ci		r8a66597_usb_host_resources[1].end = ilsel_enable(ILSEL_USBH_I);
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	m66592_usb_peripheral_resources[1].start =
2528c2ecf20Sopenharmony_ci		m66592_usb_peripheral_resources[1].end = ilsel_enable(ILSEL_USBP_I);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	smc91x_resources[1].start =
2558c2ecf20Sopenharmony_ci		smc91x_resources[1].end = ilsel_enable(ILSEL_LAN);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ci	return platform_add_devices(x3proto_devices,
2588c2ecf20Sopenharmony_ci				    ARRAY_SIZE(x3proto_devices));
2598c2ecf20Sopenharmony_ci}
2608c2ecf20Sopenharmony_cidevice_initcall(x3proto_devices_setup);
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_cistatic void __init x3proto_setup(char **cmdline_p)
2638c2ecf20Sopenharmony_ci{
2648c2ecf20Sopenharmony_ci	register_smp_ops(&shx3_smp_ops);
2658c2ecf20Sopenharmony_ci}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_cistatic struct sh_machine_vector mv_x3proto __initmv = {
2688c2ecf20Sopenharmony_ci	.mv_name		= "x3proto",
2698c2ecf20Sopenharmony_ci	.mv_setup		= x3proto_setup,
2708c2ecf20Sopenharmony_ci};
271