[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] ARM: sunxi: support more Allwinner SoCs
So far we only supported the Allwinner A20 SoC. Add support for most of the other virtualization capable Allwinner SoCs by: - supporting the watchdog in newer (sun8i) SoCs - getting the watchdog address from DT - adding compatible strings for other 32-bit SoCs - adding compatible strings for 64-bit SoCs As all 64-bit SoCs support system reset via PSCI, we don't use the platform specific reset routine there. Should the 32-bit SoCs start to properly support the PSCI 0.2 SYSTEM_RESET call, we will use it for them automatically, as we try PSCI first, then fall back to platform reset. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- Hi, this is based on staging, which has the required UART fix. Tested on: - BananaPi M1 (A20) - OrangePi Zero (H2+, which is almost the same as H3) - OrangePi PC 2 (H5, arm64) - Pine64+ (A64, arm64) On the 64-bit boards I could boot into Dom0 prompt. I had issues with U-Boot's fdt command on the two 32-bit boards, so couldn't inject the Dom0 magic into the DT. But at least Xen booted and reset worked with both the "old" and "new" watchdog. The newer boards require "clk_ignore_unused" on the Linux command line at the moment, I will try to find a more sustainable solution next week. Will try to update the Wiki later on. Please let me know if this is worth splitting up into multiple patches (watchdog address from DT, new watchdog support, arm64 support). Many thanks to Awais for the idea and his original patch, and for testing this one! Cheers, Andre. xen/arch/arm/platforms/Makefile | 2 +- xen/arch/arm/platforms/sunxi.c | 96 +++++++++++++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile index 49fa683780..53a47e48d2 100644 --- a/xen/arch/arm/platforms/Makefile +++ b/xen/arch/arm/platforms/Makefile @@ -5,6 +5,6 @@ obj-$(CONFIG_ARM_32) += midway.o obj-$(CONFIG_ARM_32) += omap5.o obj-$(CONFIG_ARM_32) += rcar2.o obj-$(CONFIG_ARM_64) += seattle.o -obj-$(CONFIG_ARM_32) += sunxi.o +obj-y += sunxi.o obj-$(CONFIG_ARM_64) += xgene-storm.o obj-$(CONFIG_ARM_64) += xilinx-zynqmp.o diff --git a/xen/arch/arm/platforms/sunxi.c b/xen/arch/arm/platforms/sunxi.c index 0ba7b3d9b4..c8a3e8eec8 100644 --- a/xen/arch/arm/platforms/sunxi.c +++ b/xen/arch/arm/platforms/sunxi.c @@ -1,7 +1,7 @@ /* * xen/arch/arm/platforms/sunxi.c * - * SUNXI (AllWinner A20/A31) specific settings + * SUNXI (Allwinner ARM SoCs) specific settings * * Copyright (c) 2013 Citrix Systems. * @@ -22,36 +22,103 @@ #include <asm/io.h> /* Watchdog constants: */ -#define SUNXI_WDT_BASE 0x01c20c90 -#define SUNXI_WDT_MODE 0x04 -#define SUNXI_WDT_MODEADDR (SUNXI_WDT_BASE + SUNXI_WDT_MODE) +#define SUNXI_WDT_MODE_REG 0x04 #define SUNXI_WDT_MODE_EN (1 << 0) #define SUNXI_WDT_MODE_RST_EN (1 << 1) +#define SUNXI_WDT_CONFIG_SYSTEM_RESET (1 << 0) +#define SUNXI_WDOG0_CFG_REG 0x14 +#define SUNXI_WDOG0_MODE_REG 0x18 -static void sunxi_reset(void) +static void __iomem *sunxi_map_watchdog(bool *new_wdt) { void __iomem *wdt; + struct dt_device_node *node; + paddr_t wdt_start, wdt_len; + bool _new_wdt = false; + int ret; + + node = dt_find_compatible_node(NULL, NULL, "allwinner,sun6i-a31-wdt"); + if ( node ) + _new_wdt = true; + else + node = dt_find_compatible_node(NULL, NULL, "allwinner,sun4i-a10-wdt"); + + if ( !node ) + { + dprintk(XENLOG_ERR, "Cannot find matching watchdog node in DT\n"); + return NULL; + } - wdt = ioremap_nocache(SUNXI_WDT_MODEADDR & PAGE_MASK, PAGE_SIZE); + ret = dt_device_get_address(node, 0, &wdt_start, &wdt_len); + if ( ret ) + { + dprintk(XENLOG_ERR, "Cannot read watchdog register address\n"); + return NULL; + } + + wdt = ioremap_nocache(wdt_start & PAGE_MASK, PAGE_SIZE); if ( !wdt ) { dprintk(XENLOG_ERR, "Unable to map watchdog register!\n"); - return; + return NULL; } - /* Enable watchdog to trigger a reset after 500 ms: */ + if ( new_wdt ) + *new_wdt = _new_wdt; + + return wdt + (wdt_start & ~PAGE_MASK); +} + +/* Enable watchdog to trigger a reset after 500 ms */ +static void sunxi_old_wdt_reset(void __iomem *wdt) +{ writel(SUNXI_WDT_MODE_EN | SUNXI_WDT_MODE_RST_EN, - wdt + (SUNXI_WDT_MODEADDR & ~PAGE_MASK)); + wdt + SUNXI_WDT_MODE_REG); +} + +static void sunxi_new_wdt_reset(void __iomem *wdt) +{ + writel(SUNXI_WDT_CONFIG_SYSTEM_RESET, wdt + SUNXI_WDOG0_CFG_REG); + writel(SUNXI_WDT_MODE_EN, wdt + SUNXI_WDOG0_MODE_REG); +} + +static void sunxi_reset(void) +{ + void __iomem *wdt; + bool is_new_wdt; + + wdt = sunxi_map_watchdog(&is_new_wdt); + if ( !wdt ) + return; + + if ( is_new_wdt ) + sunxi_new_wdt_reset(wdt); + else + sunxi_old_wdt_reset(wdt); + iounmap(wdt); for (;;) wfi(); } -static const char * const sunxi_dt_compat[] __initconst = +static const char * const sunxi_v7_dt_compat[] __initconst = { + "allwinner,sun6i-a31", + "allwinner,sun6i-a31s", "allwinner,sun7i-a20", + "allwinner,sun8i-a23", + "allwinner,sun8i-a33", + "allwinner,sun8i-h2-plus", + "allwinner,sun8i-h3", + NULL +}; + +static const char * const sunxi_v8_dt_compat[] __initconst = +{ + "allwinner,sun50i-a64", + "allwinner,sun50i-h5", NULL }; @@ -65,12 +132,17 @@ static const struct dt_device_match sunxi_blacklist_dev[] __initconst = { /* sentinel */ }, }; -PLATFORM_START(sunxi, "Allwinner A20") - .compatible = sunxi_dt_compat, +PLATFORM_START(sunxi_v7, "Allwinner ARMv7") + .compatible = sunxi_v7_dt_compat, .blacklist_dev = sunxi_blacklist_dev, .reset = sunxi_reset, PLATFORM_END +PLATFORM_START(sunxi_v8, "Allwinner ARMv8") + .compatible = sunxi_v8_dt_compat, + .blacklist_dev = sunxi_blacklist_dev, +PLATFORM_END + /* * Local variables: * mode: C -- 2.14.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |