From 5b5124e3d5cabac31d18fcd97c934aa13819fef6 Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Fri, 8 Nov 2024 22:15:03 +0100 Subject: [PATCH 1/2] watchdog: rti: support SPL (or re-start) If the RTI watchdog has been enabled in SPL, enabling it in U-Boot proper fails because it can only be enabled once in HW and never stopped. This however leads to a situation that wdt_cyclic() watchdog trigger is not being started any longer and the WDT fires at some point. Allow for WDT re-start by not bailing out if the [previously] configured period matches the one to be configured. Enabling in [A53] SPL has been tested on AM62x-based HW (where [A53] SPL is responsible for loading R5 DM firmware and not this driver). Signed-off-by: Alexander Sverdlin Reviewed-by: Jan Kiszka Reviewed-by: Stefan Roese --- drivers/watchdog/rti_wdt.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 99168d0cad0..320c5ca19e0 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -131,18 +131,19 @@ static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) u32 timer_margin; int ret; - if (readl(priv->regs + RTIDWDCTRL) == WDENABLE_KEY) + timer_margin = timeout_ms * priv->clk_hz / 1000; + timer_margin >>= WDT_PRELOAD_SHIFT; + if (timer_margin > WDT_PRELOAD_MAX) + timer_margin = WDT_PRELOAD_MAX; + + if (readl(priv->regs + RTIDWDCTRL) == WDENABLE_KEY && + readl(priv->regs + RTIDWDPRLD) != timer_margin) return -EBUSY; ret = rti_wdt_load_fw(dev); if (ret < 0) return ret; - timer_margin = timeout_ms * priv->clk_hz / 1000; - timer_margin >>= WDT_PRELOAD_SHIFT; - if (timer_margin > WDT_PRELOAD_MAX) - timer_margin = WDT_PRELOAD_MAX; - writel(timer_margin, priv->regs + RTIDWDPRLD); writel(RTIWWDRX_NMI, priv->regs + RTIWWDRXCTRL); writel(RTIWWDSIZE_50P, priv->regs + RTIWWDSIZECTRL); From 5964f24f15473709fb9d897230c3f20e998c88ca Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Thu, 21 Nov 2024 09:03:25 +0100 Subject: [PATCH 2/2] watchdog: rti: drop hack manipulating WDT clock rate The hack itself seems to be copied from Linux rti_wdt.c, but the WDT reset principle is different in U-Boot. While Linux relies on correct frequencies and timers and doesn't check the actual WDT counter value U-Boot driver seems to be more robust: it does compare RTIDWDCNTR vs RTIDWDPRLD. Now the root cause of the original motivation to manipulate the clock rate is said to be understood and fixed in Linux commit cae58516534e ("watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin") which simultaneously removed the hack itself. While is fix part of the mentioned patch is neither applicable nor requried for the U-Boot driver just drop the hack setting WDT clock rate to 90% of the real rate. This has a nice effect that the WDT timeout is now as requested and not 10% shorter. Signed-off-by: Alexander Sverdlin Reviewed-by: Jan Kiszka Reviewed-by: Stefan Roese --- drivers/watchdog/rti_wdt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 320c5ca19e0..7b387266b99 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c @@ -187,14 +187,6 @@ static int rti_wdt_probe(struct udevice *dev) priv->clk_hz = clk_get_rate(&clk); - /* - * If watchdog is running at 32k clock, it is not accurate. - * Adjust frequency down in this case so that it does not expire - * earlier than expected. - */ - if (priv->clk_hz < 32768) - priv->clk_hz = priv->clk_hz * 9 / 10; - return 0; }