sunxi.c 2.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Device Tree support for Allwinner A1X SoCs
 *
 * Copyright (C) 2012 Maxime Ripard
 *
 * Maxime Ripard <maxime.ripard@free-electrons.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
15
#include <linux/of_address.h>
16 17 18 19 20 21 22 23 24 25 26 27 28 29
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/io.h>
#include <linux/sunxi_timer.h>

#include <linux/irqchip/sunxi.h>

#include <asm/hardware/vic.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>

#include "sunxi.h"

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#define WATCHDOG_CTRL_REG	0x00
#define WATCHDOG_MODE_REG	0x04

static void __iomem *wdt_base;

static void sunxi_setup_restart(void)
{
	struct device_node *np = of_find_compatible_node(NULL, NULL,
						"allwinner,sunxi-wdt");
	if (WARN(!np, "unable to setup watchdog restart"))
		return;

	wdt_base = of_iomap(np, 0);
	WARN(!wdt_base, "failed to map watchdog base address");
}

static void sunxi_restart(char mode, const char *cmd)
{
	if (!wdt_base)
		return;

	/* Enable timer and set reset bit in the watchdog */
	writel(3, wdt_base + WATCHDOG_MODE_REG);
	writel(0xa57 << 1 | 1, wdt_base + WATCHDOG_CTRL_REG);
	while(1) {
		mdelay(5);
		writel(3, wdt_base + WATCHDOG_MODE_REG);
	}
}

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
static struct map_desc sunxi_io_desc[] __initdata = {
	{
		.virtual	= (unsigned long) SUNXI_REGS_VIRT_BASE,
		.pfn		= __phys_to_pfn(SUNXI_REGS_PHYS_BASE),
		.length		= SUNXI_REGS_SIZE,
		.type		= MT_DEVICE,
	},
};

void __init sunxi_map_io(void)
{
	iotable_init(sunxi_io_desc, ARRAY_SIZE(sunxi_io_desc));
}

static void __init sunxi_dt_init(void)
{
76 77
	sunxi_setup_restart();

78 79 80 81
	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}

static const char * const sunxi_board_dt_compat[] = {
82
	"allwinner,sun4i",
83 84 85 86 87 88 89 90 91
	"allwinner,sun5i",
	NULL,
};

DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
	.init_machine	= sunxi_dt_init,
	.map_io		= sunxi_map_io,
	.init_irq	= sunxi_init_irq,
	.handle_irq	= sunxi_handle_irq,
92
	.restart	= sunxi_restart,
93 94 95
	.timer		= &sunxi_timer,
	.dt_compat	= sunxi_board_dt_compat,
MACHINE_END