]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
drivers: watchdog: qcom: Add timeout configuration support in watchdog
authorBalaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Tue, 27 May 2025 12:49:26 +0000 (18:19 +0530)
committerCasey Connolly <casey.connolly@linaro.org>
Mon, 23 Jun 2025 16:50:39 +0000 (18:50 +0200)
This patch enhances the Qualcomm watchdog driver by introducing
support for dynamic timeout configuration. Specifically:

- Calculates and sets the bark and bite timeout values based on
  the clock rate and the requested timeout in milliseconds.
- Adds retrieval of the watchdog clock rate during probe using
  the common clock framework.
- Adds a default timeout value for ARCH_SNAPDRAGON
  in WATCHDOG_TIMEOUT_MSECS.

These changes improve the configurability and accuracy of the
watchdog timer on Qualcomm platforms.

This work builds upon the previous submission:
https://lore.kernel.org/all/20250422-b4-qcom-wdt-v3-1-730d4d5a858d@paulsajna.com/

Signed-off-by: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20250527124926.128413-1-balaji.selvanathan@oss.qualcomm.com
Signed-off-by: Casey Connolly <casey.connolly@linaro.org>
drivers/watchdog/Kconfig
drivers/watchdog/qcom-wdt.c

index 38519add771b0abc5b56137873e9d148db49d5c3..45eb9b4d3f99ad063f9e8cd7fd8ddfbd285a0e00 100644 (file)
@@ -29,6 +29,7 @@ config WATCHDOG_TIMEOUT_MSECS
        int "Watchdog timeout in msec"
        default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6
        default 128000 if ARCH_MX7 || ARCH_VF610
+       default 30000 if ARCH_SNAPDRAGON
        default 30000 if ARCH_SOCFPGA
        default 16000 if ARCH_SUNXI
        default 5376 if ULP_WATCHDOG
@@ -338,6 +339,7 @@ endif
 config WDT_QCOM
        bool "Qualcomm watchdog timer support"
        depends on WDT && ARCH_SNAPDRAGON
+       imply WATCHDOG
        help
          Select this to enable Qualcomm watchdog timer, which can be found on
          some Qualcomm chips.
index 3601ba93774730f78574b2fd74b8c513e7ce22e1..adbb5aacdc3b5cfc307cc4ff2dd6ee7c3131c7f2 100644 (file)
@@ -13,6 +13,7 @@
 #include <dm.h>
 #include <dm/device_compat.h>
 #include <wdt.h>
+#include <clk.h>
 
 #include <asm/io.h>
 
@@ -30,6 +31,7 @@ struct qcom_wdt_match_data {
 
 struct qcom_wdt {
        void __iomem *base;
+       ulong clk_rate;
        const u32 *layout;
 };
 
@@ -53,10 +55,14 @@ static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg)
 int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 {
        struct qcom_wdt *wdt = dev_get_priv(dev);
+       ulong bark_timeout_s = ((timeout_ms - 1)  * wdt->clk_rate) / 1000;
+       ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000;
 
        writel(0, wdt_addr(wdt, WDT_EN));
-       writel(1, wdt_addr(wdt, WDT_RST));
-       writel(1, wdt_addr(wdt, WDT_EN));
+       writel(BIT(0), wdt_addr(wdt, WDT_RST));
+       writel(bark_timeout_s, wdt_addr(wdt, WDT_BARK_TIME));
+       writel(bite_timeout_s, wdt_addr(wdt, WDT_BITE_TIME));
+       writel(BIT(0), wdt_addr(wdt, WDT_EN));
        if (readl(wdt_addr(wdt, WDT_EN)) != 1) {
                dev_err(dev, "Failed to enable Qualcomm watchdog!\n");
                return -EIO;
@@ -87,12 +93,26 @@ int qcom_wdt_reset(struct udevice *dev)
 
 static int qcom_wdt_probe(struct udevice *dev)
 {
+       struct clk clk;
+       long rate;
+       int ret;
+
        struct qcom_wdt *wdt = dev_get_priv(dev);
        struct qcom_wdt_match_data *data = (void *)dev_get_driver_data(dev);
 
        wdt->base = dev_read_addr_ptr(dev);
        wdt->layout = data->offset;
 
+       ret = clk_get_by_index(dev, 0, &clk);
+       if (ret)
+               return ret;
+
+       rate = clk_get_rate(&clk);
+       if (rate <= 0)
+               return rate < 0 ? (int)rate : -EINVAL;
+
+       wdt->clk_rate = (ulong)rate;
+
        return 0;
 }