All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xen/rpi4: implement watchdog-based reset
@ 2020-06-03 22:31 Stefano Stabellini
  2020-06-03 23:21 ` Roman Shaposhnik
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Stefano Stabellini @ 2020-06-03 22:31 UTC (permalink / raw)
  To: julien
  Cc: cminyard, tamas, roman, Stefano Stabellini, xen-devel,
	Stefano Stabellini

Touching the watchdog is required to be able to reboot the board.

The implementation is based on
drivers/watchdog/bcm2835_wdt.c:__bcm2835_restart in Linux.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com>
---
 xen/arch/arm/platforms/brcm-raspberry-pi.c | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/xen/arch/arm/platforms/brcm-raspberry-pi.c b/xen/arch/arm/platforms/brcm-raspberry-pi.c
index f5ae58a7d5..0214ae2b3c 100644
--- a/xen/arch/arm/platforms/brcm-raspberry-pi.c
+++ b/xen/arch/arm/platforms/brcm-raspberry-pi.c
@@ -18,6 +18,10 @@
  */
 
 #include <asm/platform.h>
+#include <xen/delay.h>
+#include <xen/mm.h>
+#include <xen/vmap.h>
+#include <asm/io.h>
 
 static const char *const rpi4_dt_compat[] __initconst =
 {
@@ -37,12 +41,68 @@ static const struct dt_device_match rpi4_blacklist_dev[] __initconst =
      * The aux peripheral also shares a page with the aux UART.
      */
     DT_MATCH_COMPATIBLE("brcm,bcm2835-aux"),
+    /* Special device used for rebooting */
+    DT_MATCH_COMPATIBLE("brcm,bcm2835-pm"),
     { /* sentinel */ },
 };
 
+
+#define PM_PASSWORD         0x5a000000
+#define PM_RSTC             0x1c
+#define PM_WDOG             0x24
+#define PM_RSTC_WRCFG_FULL_RESET    0x00000020
+#define PM_RSTC_WRCFG_CLR           0xffffffcf
+
+static void __iomem *rpi4_map_watchdog(void)
+{
+    void __iomem *base;
+    struct dt_device_node *node;
+    paddr_t start, len;
+    int ret;
+
+    node = dt_find_compatible_node(NULL, NULL, "brcm,bcm2835-pm");
+    if ( !node )
+        return NULL;
+
+    ret = dt_device_get_address(node, 0, &start, &len);
+    if ( ret )
+    {
+        dprintk(XENLOG_ERR, "Cannot read watchdog register address\n");
+        return NULL;
+    }
+
+    base = ioremap_nocache(start & PAGE_MASK, PAGE_SIZE);
+    if ( !base )
+    {
+        dprintk(XENLOG_ERR, "Unable to map watchdog register!\n");
+        return NULL;
+    }
+
+    return base;
+}
+
+static void rpi4_reset(void)
+{
+    u32 val;
+    void __iomem *base = rpi4_map_watchdog();
+    if ( !base )
+        return;
+
+    /* use a timeout of 10 ticks (~150us) */
+    writel(10 | PM_PASSWORD, base + PM_WDOG);
+    val = readl(base + PM_RSTC);
+    val &= PM_RSTC_WRCFG_CLR;
+    val |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
+    writel(val, base + PM_RSTC);
+
+    /* No sleeping, possibly atomic. */
+    mdelay(1);
+}
+
 PLATFORM_START(rpi4, "Raspberry Pi 4")
     .compatible     = rpi4_dt_compat,
     .blacklist_dev  = rpi4_blacklist_dev,
+    .reset = rpi4_reset,
     .dma_bitsize    = 30,
 PLATFORM_END
 
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-06-06  1:58 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-03 22:31 [PATCH] xen/rpi4: implement watchdog-based reset Stefano Stabellini
2020-06-03 23:21 ` Roman Shaposhnik
2020-06-04  0:09 ` Tamas K Lengyel
2020-06-04  0:15 ` Corey Minyard
2020-06-04  8:15   ` Julien Grall
2020-06-04 11:59     ` Corey Minyard
2020-06-04 12:07       ` Julien Grall
2020-06-04  8:48 ` Julien Grall
2020-06-04  8:59   ` André Przywara
2020-06-04 16:24     ` Stefano Stabellini
2020-06-04 16:36       ` Julien Grall
2020-06-04 16:48         ` Roman Shaposhnik
2020-06-04 16:54           ` Stefano Stabellini
2020-06-04 16:53         ` Stefano Stabellini
2020-06-04 16:37       ` André Przywara
2020-06-04 16:46         ` Stefano Stabellini
2020-06-04 17:12           ` André Przywara
2020-06-04 17:19           ` Julien Grall
2020-06-06  1:57             ` Stefano Stabellini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.