Skip to contentSkip to conversation

watchdog: add Tegra20 watchdog driver

PATCH New Artur Kowalski 1 participant 1 message Nov 10

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 watchdog: add Tegra20 watchdog driver

The timer driver binds tegra_wdt to Tegra20's timer node as well, but tegra_wdt programs timer 5 and watchdog 0, which only exist on Tegra30 and later. On Tegra20 they lie past the end of the timer block, so starting the watchdog writes to unrelated registers.

Tegra20 has no watchdog block. Instead, the clock and reset controller can reset the system when the interrupt of timer 1 or 2 fires while the previous one is still pending, enabled through the WDT bits of RST_SOURCE. Use timer 1 for it, which U-Boot doesn't use otherwise, as it only reads the microsecond counter. Run it periodically with half of the timeout as its period. Clearing the interrupt alone doesn't restart the period, which would leave between half and all of the timeout after a ping, so a ping also rewrites the timer setting, read back from the timer, to restart it.

As this has nothing in common with the watchdog block of Tegra30 and later, add it as a separate driver and make tegra_wdt depend on !TEGRA20. The new driver keeps the tegra_wdt driver name, and the timer driver also binds it when WDT_TEGRA20 is enabled.

Assisted-by Claude:claude-opus-5-5

---
Add watchdog support for Tegra20. This makes it possible to recover from hangs in U-Boot or early during Linux boot.

Linux doesn't handle a running Tegra20 watchdog yet. Its timer driver uses timer 1 for CPU0's clock event device, which can reset the system early during boot. A Linux series that keeps the timer driver off timers 1-2 and adds Tegra20 support to tegra_wdt is under review [1].

There is also a Tegra20 quirk that affects any watchdog reset while Linux runs: the watchdog resets the system through the clock and reset controller, which doesn't reset the PMC, so the power partitions keep their state. Linux powers the VDE partition off when its PMC driver registers it, and whenever the VDE is idle. If the watchdog fires while the partition is off, the boot ROM hangs and the device stays dead until it is powered off. Linux already works around the same hang for reboots (commit 8f0c714ad9be ("media: staging: tegra-vde: Turn ON power domain on shutdown") and commit 510f276df2b9 ("mfd: tps6586x: Register restart handler")). The Linux series either stops the watchdog before the VDE partition is powered off or, with tegra_pmc.vde_always_on=1, keeps the partition powered on.

For these reasons I haven't enabled the watchdog in any defconfig.

The patch was developed with the help of Claude Code. I have reviewed it and tested it on an ASUS TF101 (Tegra20). Tegra30 and later are untested, but tegra_wdt is unchanged apart from its Kconfig dependency.

[1] https://lore.kernel.org/lkml/[email protected]/
---
Changes in v2:
- Move Tegra20 support into a separate driver, tegra20_wdt.c, exclusive with tegra_wdt.c and keeping its driver name
- Link to v1: https://patch.msgid.link/[email protected]

---
 drivers/timer/tegra-timer.c    |   2 +-
 drivers/watchdog/Kconfig       |  12 +++-
 drivers/watchdog/Makefile      |   1 +
 drivers/watchdog/tegra20_wdt.c | 134 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+), 3 deletions(-)
drivers/timer/tegra-timer.c +1 -1
index 778b65b6062..e76ec4a3a44 100644
@@ -109,7 +109,7 @@ static int tegra_timer_probe(struct udevice *dev)
 
 static int tegra_timer_bind(struct udevice *dev)
 {
-	if (CONFIG_IS_ENABLED(WDT_TEGRA))
+	if (CONFIG_IS_ENABLED(WDT_TEGRA) || CONFIG_IS_ENABLED(WDT_TEGRA20))
 		return device_bind_driver_to_node(dev, "tegra_wdt", "tegra-wdt",
 						  dev_ofnode(dev), NULL);
 	return 0;
drivers/watchdog/Kconfig +10 -2
index 3c56c541505..2da75ded02d 100644
@@ -467,9 +467,17 @@ config WDT_TANGIER
 
 config WDT_TEGRA
 	bool "Tegra watchdog"
-	depends on WDT && ARCH_TEGRA
+	depends on WDT && ARCH_TEGRA && !TEGRA20
 	help
-	  Enable support for the watchdog timer found in Tegra SoCs.
+	  Enable support for the watchdog timer found in Tegra30 and newer SoCs.
+
+config WDT_TEGRA20
+	bool "Tegra20 watchdog"
+	depends on WDT && TEGRA20
+	help
+	  Enable support for the watchdog of Tegra20 SoCs. Tegra20 has no watchdog
+	  block, so this uses timer 1 and the clock and reset controller to reset
+	  the system.
 
 config WDT_ARM_SMC
 	bool "ARM SMC watchdog timer support"
drivers/watchdog/Makefile +1 -0
index 84faefdb4c2..50c983d6637 100644
@@ -55,6 +55,7 @@ obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
 obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o
 obj-$(CONFIG_WDT_TEGRA) += tegra_wdt.o
+obj-$(CONFIG_WDT_TEGRA20) += tegra20_wdt.o
 obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o
 obj-$(CONFIG_WDT_ADI) += adi_wdt.o
 obj-$(CONFIG_WDT_QCOM) += qcom-wdt.o
drivers/watchdog/tegra20_wdt.c new file +134 -0

134 lines not on this page · raw message

---
base-commit: 2f797312a4e2c5d104786dbcde9f7db8e355ee6e
change-id: 20261108-wdt-tegra20-8d66e6b6b0dd

Best regards,

Signature · 1 line
Artur Kowalski <[email protected]>