bcm2835: wdt: support for the bcm2835/2836 wdt
Subsystems (5)
PATCH 1/1 bcm2835: wdt: support for the bcm2835/2836 wdt
The following patch add support for the watchdog built into the bcm2835/2836 chips, using the max timeout (~15s).
By default the watchdog is compiled in, but disabled. To enable it, apply the following patch:
include/configs/rpi.h +1 -0
@@ -109,6 +109,7 @@/* Watchdog support */ #define CONFIG_BCM2835_WDT +#define CONFIG_HW_WATCHDOG /* Console configuration */ #define CONFIG_SYS_CBSIZE 1024
Signature · 18 lines
2.7.4 Tested on my RaspberryPi2. Paolo Pisati (1): bcm2835_wdt: support for the BCM2835/2836 watchdog arch/arm/mach-bcm283x/reset.c | 21 ++++++++++++++++++--- board/raspberrypi/rpi/rpi.c | 4 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2835_wdt.c | 34 ++++++++++++++++++++++++++++++++++ include/configs/rpi.h | 3 +++ scripts/config_whitelist.txt | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/bcm2835_wdt.c -- 2.7.4
PATCH 1/1 bcm2835_wdt: support for the BCM2835/2836 watchdog
--- arch/arm/mach-bcm283x/reset.c | 21 ++++++++++++++++++--- board/raspberrypi/rpi/rpi.c | 4 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2835_wdt.c | 34 ++++++++++++++++++++++++++++++++++ include/configs/rpi.h | 3 +++ scripts/config_whitelist.txt | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/bcm2835_wdt.c
arch/arm/mach-bcm283x/reset.c +18 -3
@@ -21,18 +21,33 @@*/ #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); }
board/raspberrypi/rpi/rpi.c +4 -0
@@ -22,6 +22,7 @@#ifdef CONFIG_ARM64 #include <asm/armv8/mmu.h> #endif +#include <watchdog.h> DECLARE_GLOBAL_DATA_PTR ;
@@ -478,6 +479,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
drivers/watchdog/Makefile +1 -0
@@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o +obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
drivers/watchdog/bcm2835_wdt.c new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Watchdog driver for Broadcom BCM2835 +* +* Copyright (C) 2017 Paolo Pisati <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0 +*/ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/wdog.h> + +#define SECS_TO_WDOG_TICKS (x) ((x) << 16) +#define MAX_TIMEOUT 0xf/* ~15s */ + +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 hw_watchdog_disable (void ) +{ + enabled = false; +}
include/configs/rpi.h +3 -0
@@ -107,6 +107,9 @@#define CONFIG_CONS_INDEX 0#define CONFIG_BAUDRATE 115200 +/* Watchdog support */ +#define CONFIG_BCM2835_WDT +/* Console configuration */ #define CONFIG_SYS_CBSIZE 1024#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
scripts/config_whitelist.txt +1 -0
@@ -294,6 +294,7 @@ CONFIG_BCH_CONST_M CONFIG_BCH_CONST_PARAMS CONFIG_BCH_CONST_T CONFIG_BCM2835_GPIO +CONFIG_BCM2835_WDT CONFIG_BCM283X_MU_SERIAL CONFIG_BCM_SF2_ETH CONFIG_BCM_SF2_ETH_DEFAULT_PORT
Signature · 1 line
2.7.4
PATCH 1/1 bcm2835_wdt: support for the BCM2835/2836 watchdog
Quoted 30 lines · On Freitag, 27. Januar 2017 10:59:05 CET Paolo Pisati wrote:
Signed-off-by Paolo Pisati <[email protected]>--- arch/arm/mach-bcm283x/reset.c | 21 ++++++++++++++++++--- board/raspberrypi/rpi/rpi.c | 4 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2835_wdt.c | 34 ++++++++++++++++++++++++++++++++++ include/configs/rpi.h | 3 +++ scripts/config_whitelist.txt | 1 + 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 drivers/watchdog/bcm2835_wdt.carch/arm/mach-bcm283x/reset.c +9
-0@@ -21,18 +21,33 @@*/ #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 ;
arch/arm/mach-bcm283x/reset.c line 42
Quoted 10 lines
arch/arm/mach-bcm283x/reset.c +6
-2-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 ;
This is wrong. The efi runtime reset function calls this as reset_cpu(0), and then tries to call hw_watchdog_disable, which is not marked as __efi_runtime.
Actually, I can see no reason the watchdog setup piggybacks on the reset_cpu funtion.
Quoted 16 lines
arch/arm/mach-bcm283x/reset.c +3
-1+ }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); }board/raspberrypi/rpi/rpi.c +0
-0
[...]
scripts/config_whitelist.txt CONFIG_BCH_CONST_M · line 300
Quoted 10 lines
scripts/config_whitelist.txt +1
-0@@ -294,6 +294,7 @@ CONFIG_BCH_CONST_M CONFIG_BCH_CONST_PARAMS CONFIG_BCH_CONST_T CONFIG_BCM2835_GPIO +CONFIG_BCM2835_WDT CONFIG_BCM283X_MU_SERIAL CONFIG_BCM_SF2_ETH CONFIG_BCM_SF2_ETH_DEFAULT_PORT
I think the rule is no new CONFIG_xxx options, but appropriate options in KConfig.
Kind regards,
Stefan
PATCH 1/1 bcm2835_wdt: support for the BCM2835/2836 watchdog
Quoted 5 lines · Stefan
Quoted 5 lines
...
arch/arm/mach-bcm283x/reset.c +1
-0+ __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR ;
Quoted 12 lines
arch/arm/mach-bcm283x/reset.c line 42
Quoted 9 lines
arch/arm/mach-bcm283x/reset.c +6
-2-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 ;This is wrong. The efi runtime reset function calls this as
reset_cpu(0), and then tries to callhw_watchdog_disable, which is not marked as__efi_runtime.
Ok.
Quoted 2 lines
Actually, I can see no reason the watchdog setup piggybacks on the
reset_cpufuntion.
Because there's a window after reset_cpu() is called but before real reset happens, and if hw_watchdog_reset() is called in between, it breaks the reset procedure.
There must be a mechanism for reset_cpu() to disable the watchdog driver so it won't interfere.
Quoted 3 lines
I think the rule is no new
CONFIG_xxxoptions, but appropriate options in KConfig.
I'll send a V2.
Signature · 2 lines
bye, p.