bcm2835_wdt: support for the BCM2835/2836 watchdog
authorPaolo Pisati <p.pisati@gmail.com>
Fri, 10 Feb 2017 16:28:05 +0000 (17:28 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 10 May 2017 00:30:08 +0000 (20:30 -0400)
Signed-off-by: Paolo Pisati <p.pisati@gmail.com>
arch/arm/mach-bcm283x/reset.c
board/raspberrypi/rpi/rpi.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/bcm2835_wdt.c [new file with mode: 0644]

index 685815c..b62cb8a 100644 (file)
  */
 #define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT     0x555
 
+/* max ticks timeout */
+#define BCM2835_WDOG_MAX_TIMEOUT       0x000fffff
+
+#ifdef CONFIG_BCM2835_WDT
+extern void hw_watchdog_disable(void);
+#else
+void hw_watchdog_disable(void) {}
+#endif
+
 __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs =
        (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
 
-void __efi_runtime reset_cpu(ulong addr)
+void __efi_runtime reset_cpu(ulong ticks)
 {
-       uint32_t rstc;
+       uint32_t rstc, timeout;
+
+       if (ticks == 0) {
+               hw_watchdog_disable();
+               timeout = RESET_TIMEOUT;
+       } else
+               timeout = ticks & BCM2835_WDOG_MAX_TIMEOUT;
 
        rstc = readl(&wdog_regs->rstc);
        rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK;
        rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET;
 
-       writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, &wdog_regs->wdog);
+       writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog);
        writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc);
 }
 
index c99beed..82da9e5 100644 (file)
@@ -23,6 +23,7 @@
 #ifdef CONFIG_ARM64
 #include <asm/armv8/mmu.h>
 #endif
+#include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -455,6 +456,9 @@ static void rpi_disable_inactive_uart(void)
 
 int board_init(void)
 {
+#ifdef CONFIG_HW_WATCHDOG
+       hw_watchdog_init();
+#endif
 #ifndef CONFIG_PL01X_SERIAL
        rpi_disable_inactive_uart();
 #endif
index 2034e3c..bdaf5d4 100644 (file)
@@ -1,5 +1,17 @@
 menu "Watchdog Timer Support"
 
+config HW_WATCHDOG
+       bool
+
+config BCM2835_WDT
+       bool "Enable BCM2835/2836 watchdog driver"
+       select HW_WATCHDOG
+       help
+         Say Y here to enable the BCM2835/2836 watchdog
+
+         This provides basic infrastructure to support BCM2835/2836 watchdog
+         hardware, with a max timeout of ~15secs.
+
 config ULP_WATCHDOG
        bool "i.MX7ULP watchdog"
        help
index dfc7fbd..8378601 100644 (file)
@@ -18,3 +18,4 @@ obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
 obj-$(CONFIG_WDT) += wdt-uclass.o
 obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
 obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
+obj-$(CONFIG_BCM2835_WDT)       += bcm2835_wdt.o
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
new file mode 100644 (file)
index 0000000..6f753ae
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Watchdog driver for Broadcom BCM2835
+ *
+ * Copyright (C) 2017 Paolo Pisati <p.pisati@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <efi_loader.h>
+#include <asm/io.h>
+#include <asm/arch/wdog.h>
+
+#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
+#define MAX_TIMEOUT   0xf /* ~15s */
+
+static __efi_runtime_data bool enabled = true;
+
+extern void reset_cpu(ulong ticks);
+
+void hw_watchdog_reset(void)
+{
+       if (enabled)
+               reset_cpu(SECS_TO_WDOG_TICKS(MAX_TIMEOUT));
+}
+
+void hw_watchdog_init(void)
+{
+       hw_watchdog_reset();
+}
+
+void __efi_runtime hw_watchdog_disable(void)
+{
+       enabled = false;
+}