xref: /openbmc/linux/arch/arm/mach-sunxi/sunxi.c (revision 43880f70)
13b52634fSMaxime Ripard /*
23b52634fSMaxime Ripard  * Device Tree support for Allwinner A1X SoCs
33b52634fSMaxime Ripard  *
43b52634fSMaxime Ripard  * Copyright (C) 2012 Maxime Ripard
53b52634fSMaxime Ripard  *
63b52634fSMaxime Ripard  * Maxime Ripard <maxime.ripard@free-electrons.com>
73b52634fSMaxime Ripard  *
83b52634fSMaxime Ripard  * This file is licensed under the terms of the GNU General Public
93b52634fSMaxime Ripard  * License version 2.  This program is licensed "as is" without any
103b52634fSMaxime Ripard  * warranty of any kind, whether express or implied.
113b52634fSMaxime Ripard  */
123b52634fSMaxime Ripard 
135e51651dSJosh Cartwright #include <linux/delay.h>
143b52634fSMaxime Ripard #include <linux/kernel.h>
153b52634fSMaxime Ripard #include <linux/init.h>
1667bea88dSMaxime Ripard #include <linux/of_address.h>
173b52634fSMaxime Ripard #include <linux/of_irq.h>
183b52634fSMaxime Ripard #include <linux/of_platform.h>
193b52634fSMaxime Ripard #include <linux/io.h>
203b52634fSMaxime Ripard #include <linux/sunxi_timer.h>
213b52634fSMaxime Ripard 
223b52634fSMaxime Ripard #include <linux/irqchip/sunxi.h>
233b52634fSMaxime Ripard 
243b52634fSMaxime Ripard #include <asm/hardware/vic.h>
253b52634fSMaxime Ripard 
263b52634fSMaxime Ripard #include <asm/mach/arch.h>
273b52634fSMaxime Ripard #include <asm/mach/map.h>
283b52634fSMaxime Ripard 
293b52634fSMaxime Ripard #include "sunxi.h"
303b52634fSMaxime Ripard 
3167bea88dSMaxime Ripard #define WATCHDOG_CTRL_REG	0x00
3267bea88dSMaxime Ripard #define WATCHDOG_MODE_REG	0x04
3367bea88dSMaxime Ripard 
3467bea88dSMaxime Ripard static void __iomem *wdt_base;
3567bea88dSMaxime Ripard 
3667bea88dSMaxime Ripard static void sunxi_setup_restart(void)
3767bea88dSMaxime Ripard {
3867bea88dSMaxime Ripard 	struct device_node *np = of_find_compatible_node(NULL, NULL,
3967bea88dSMaxime Ripard 						"allwinner,sunxi-wdt");
4067bea88dSMaxime Ripard 	if (WARN(!np, "unable to setup watchdog restart"))
4167bea88dSMaxime Ripard 		return;
4267bea88dSMaxime Ripard 
4367bea88dSMaxime Ripard 	wdt_base = of_iomap(np, 0);
4467bea88dSMaxime Ripard 	WARN(!wdt_base, "failed to map watchdog base address");
4567bea88dSMaxime Ripard }
4667bea88dSMaxime Ripard 
4767bea88dSMaxime Ripard static void sunxi_restart(char mode, const char *cmd)
4867bea88dSMaxime Ripard {
4967bea88dSMaxime Ripard 	if (!wdt_base)
5067bea88dSMaxime Ripard 		return;
5167bea88dSMaxime Ripard 
5267bea88dSMaxime Ripard 	/* Enable timer and set reset bit in the watchdog */
5367bea88dSMaxime Ripard 	writel(3, wdt_base + WATCHDOG_MODE_REG);
5467bea88dSMaxime Ripard 	writel(0xa57 << 1 | 1, wdt_base + WATCHDOG_CTRL_REG);
5567bea88dSMaxime Ripard 	while(1) {
5667bea88dSMaxime Ripard 		mdelay(5);
5767bea88dSMaxime Ripard 		writel(3, wdt_base + WATCHDOG_MODE_REG);
5867bea88dSMaxime Ripard 	}
5967bea88dSMaxime Ripard }
6067bea88dSMaxime Ripard 
613b52634fSMaxime Ripard static struct map_desc sunxi_io_desc[] __initdata = {
623b52634fSMaxime Ripard 	{
633b52634fSMaxime Ripard 		.virtual	= (unsigned long) SUNXI_REGS_VIRT_BASE,
643b52634fSMaxime Ripard 		.pfn		= __phys_to_pfn(SUNXI_REGS_PHYS_BASE),
653b52634fSMaxime Ripard 		.length		= SUNXI_REGS_SIZE,
663b52634fSMaxime Ripard 		.type		= MT_DEVICE,
673b52634fSMaxime Ripard 	},
683b52634fSMaxime Ripard };
693b52634fSMaxime Ripard 
703b52634fSMaxime Ripard void __init sunxi_map_io(void)
713b52634fSMaxime Ripard {
723b52634fSMaxime Ripard 	iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc));
733b52634fSMaxime Ripard }
743b52634fSMaxime Ripard 
753b52634fSMaxime Ripard static void __init sunxi_dt_init(void)
763b52634fSMaxime Ripard {
7767bea88dSMaxime Ripard 	sunxi_setup_restart();
7867bea88dSMaxime Ripard 
793b52634fSMaxime Ripard 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
803b52634fSMaxime Ripard }
813b52634fSMaxime Ripard 
823b52634fSMaxime Ripard static const char * const sunxi_board_dt_compat[] = {
8343880f70SMaxime Ripard 	"allwinner,sun4i-a10",
8443880f70SMaxime Ripard 	"allwinner,sun5i-a13",
853b52634fSMaxime Ripard 	NULL,
863b52634fSMaxime Ripard };
873b52634fSMaxime Ripard 
883b52634fSMaxime Ripard DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
893b52634fSMaxime Ripard 	.init_machine	= sunxi_dt_init,
903b52634fSMaxime Ripard 	.map_io		= sunxi_map_io,
913b52634fSMaxime Ripard 	.init_irq	= sunxi_init_irq,
923b52634fSMaxime Ripard 	.handle_irq	= sunxi_handle_irq,
9367bea88dSMaxime Ripard 	.restart	= sunxi_restart,
943b52634fSMaxime Ripard 	.timer		= &sunxi_timer,
953b52634fSMaxime Ripard 	.dt_compat	= sunxi_board_dt_compat,
963b52634fSMaxime Ripard MACHINE_END
97