[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.