watchdog: designware: Convert to DM and DT probing
authorMarek Vasut <marex@denx.de>
Wed, 26 Jun 2019 23:19:23 +0000 (01:19 +0200)
committerMarek Vasut <marex@denx.de>
Wed, 5 Feb 2020 02:01:57 +0000 (03:01 +0100)
Convert the designware watchdog timer driver to DM and add DT probing
support. Perform minor coding style clean up, like drop superfluous
braces. These ought to be no functional change.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Chin Liang See <chin.liang.see@intel.com>
Cc: Dalon Westergreen <dwesterg@gmail.com>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Ley Foon Tan <ley.foon.tan@intel.com>
Cc: Philipp Tomisch <philipp.tomisch@theobroma-systems.com>
Cc: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Cc: Tien Fong Chee <tien.fong.chee@intel.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
Tested-by: Jagan Teki <jagan@amarulasolutions.com> # roc-rk3399-pc
arch/arm/dts/socfpga_cyclone5_vining_fpga-u-boot.dtsi
arch/arm/dts/socfpga_stratix10_socdk-u-boot.dtsi
configs/socfpga_stratix10_defconfig
configs/socfpga_vining_fpga_defconfig
drivers/watchdog/Kconfig
drivers/watchdog/designware_wdt.c
include/configs/socfpga_soc64_common.h

index 44bedd8b6737634e65580cb2141ec40570417400..2e4468e8d80e3781ff4acd146fa80e8408936d9d 100644 (file)
@@ -56,3 +56,7 @@
 &portc {
        bank-name = "portc";
 };
+
+&watchdog0 {
+       u-boot,dm-pre-reloc;
+};
index 38855aecd7ea0c4a73703fee392eac67873661eb..a903040d604fd9bcc60c496f2045bf880954fee1 100755 (executable)
@@ -31,3 +31,7 @@
 &sysmgr {
        u-boot,dm-pre-reloc;
 };
+
+&watchdog0 {
+       u-boot,dm-pre-reloc;
+};
index a83d991f321119a6a4017140143c001f0cf129cd..26db40ffe3345127b7a0012bd7f13d6656ace37a 100644 (file)
@@ -58,5 +58,6 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_DWC2=y
 CONFIG_USB_STORAGE=y
-# CONFIG_SPL_USE_TINY_PRINTF is not set
 CONFIG_DESIGNWARE_WATCHDOG=y
+CONFIG_WDT=y
+# CONFIG_SPL_USE_TINY_PRINTF is not set
index 85c458ae02dedc45216cc39f629bb7c6bbd23861..0dcae8199a4389219a08bb83f487cbfd8cc0ba01 100644 (file)
@@ -96,5 +96,5 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525
 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DOWNLOAD=y
-# CONFIG_SPL_WDT is not set
 CONFIG_DESIGNWARE_WATCHDOG=y
+CONFIG_WDT=y
index c9987d42ff200ebc49d59c4341e3712f9a433f5b..77354ad20986c38c65b932b8eaef7fee65ef970b 100644 (file)
@@ -47,7 +47,7 @@ config ULP_WATCHDOG
 
 config DESIGNWARE_WATCHDOG
        bool "Designware watchdog timer support"
-       select HW_WATCHDOG
+       select HW_WATCHDOG if !WDT
        help
           Enable this to support Designware Watchdog Timer IP, present e.g.
           on Altera SoCFPGA SoCs.
index c668567c66330c49e0b41af9fd4ac1d9e792f565..a7b735979aec030bfabd77a0714b6ba0be5bee5b 100644 (file)
@@ -4,7 +4,8 @@
  */
 
 #include <common.h>
-#include <watchdog.h>
+#include <dm.h>
+#include <wdt.h>
 #include <asm/io.h>
 #include <asm/utils.h>
 
 #define DW_WDT_CR_RMOD_VAL     0x00
 #define DW_WDT_CRR_RESTART_VAL 0x76
 
+struct designware_wdt_priv {
+       void __iomem    *base;
+};
+
 /*
  * Set the watchdog time interval.
  * Counter is 32 bit.
  */
-static int designware_wdt_settimeout(unsigned int timeout)
+static int designware_wdt_settimeout(void __iomem *base, unsigned int clk_khz,
+                                    unsigned int timeout)
 {
        signed int i;
 
        /* calculate the timeout range value */
-       i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16;
-       if (i > 15)
-               i = 15;
-       if (i < 0)
-               i = 0;
+       i = log_2_n_round_up(timeout * clk_khz) - 16;
+       i = clamp(i, 0, 15);
+
+       writel(i | (i << 4), base + DW_WDT_TORR);
 
-       writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR));
        return 0;
 }
 
-static void designware_wdt_enable(void)
+static void designware_wdt_enable(void __iomem *base)
 {
-       writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
-             (0x1 << DW_WDT_CR_EN_OFFSET)),
-             (CONFIG_DW_WDT_BASE + DW_WDT_CR));
+       writel((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) |
+               BIT(DW_WDT_CR_EN_OFFSET),
+               base + DW_WDT_CR);
 }
 
-static unsigned int designware_wdt_is_enabled(void)
+static unsigned int designware_wdt_is_enabled(void __iomem *base)
 {
-       unsigned long val;
-       val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR));
-       return val & 0x1;
+       return readl(base + DW_WDT_CR) & BIT(0);
 }
 
-#if defined(CONFIG_HW_WATCHDOG)
-void hw_watchdog_reset(void)
+static void designware_wdt_reset_common(void __iomem *base)
 {
-       if (designware_wdt_is_enabled())
+       if (designware_wdt_is_enabled(base))
                /* restart the watchdog counter */
-               writel(DW_WDT_CRR_RESTART_VAL,
-                      (CONFIG_DW_WDT_BASE + DW_WDT_CRR));
+               writel(DW_WDT_CRR_RESTART_VAL, base + DW_WDT_CRR);
+}
+
+#if !CONFIG_IS_ENABLED(WDT)
+void hw_watchdog_reset(void)
+{
+       designware_wdt_reset_common((void __iomem *)CONFIG_DW_WDT_BASE);
 }
 
 void hw_watchdog_init(void)
@@ -64,10 +70,80 @@ void hw_watchdog_init(void)
        /* reset to disable the watchdog */
        hw_watchdog_reset();
        /* set timer in miliseconds */
-       designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
+       designware_wdt_settimeout((void __iomem *)CONFIG_DW_WDT_BASE,
+                                 CONFIG_DW_WDT_CLOCK_KHZ,
+                                 CONFIG_WATCHDOG_TIMEOUT_MSECS);
        /* enable the watchdog */
-       designware_wdt_enable();
+       designware_wdt_enable((void __iomem *)CONFIG_DW_WDT_BASE);
        /* reset the watchdog */
        hw_watchdog_reset();
 }
+#else
+static int designware_wdt_reset(struct udevice *dev)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       designware_wdt_reset_common(priv->base);
+
+       return 0;
+}
+
+static int designware_wdt_stop(struct udevice *dev)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       designware_wdt_reset(dev);
+       writel(DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET,
+               priv->base + DW_WDT_CR);
+
+       return 0;
+}
+
+static int designware_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       designware_wdt_stop(dev);
+
+       /* set timer in miliseconds */
+       designware_wdt_settimeout(priv->base, CONFIG_DW_WDT_CLOCK_KHZ, timeout);
+
+       designware_wdt_enable(priv->base);
+
+       /* reset the watchdog */
+       return designware_wdt_reset(dev);
+}
+
+static int designware_wdt_probe(struct udevice *dev)
+{
+       struct designware_wdt_priv *priv = dev_get_priv(dev);
+
+       priv->base = dev_remap_addr(dev);
+       if (!priv->base)
+               return -EINVAL;
+
+       /* reset to disable the watchdog */
+       return designware_wdt_stop(dev);
+}
+
+static const struct wdt_ops designware_wdt_ops = {
+       .start = designware_wdt_start,
+       .reset = designware_wdt_reset,
+       .stop = designware_wdt_stop,
+};
+
+static const struct udevice_id designware_wdt_ids[] = {
+       { .compatible = "snps,dw-wdt"},
+       {}
+};
+
+U_BOOT_DRIVER(designware_wdt) = {
+       .name = "designware_wdt",
+       .id = UCLASS_WDT,
+       .of_match = designware_wdt_ids,
+       .priv_auto_alloc_size = sizeof(struct designware_wdt_priv),
+       .probe = designware_wdt_probe,
+       .ops = &designware_wdt_ops,
+       .flags = DM_FLAG_PRE_RELOC,
+};
 #endif
index ac7c00505580a08d3e3fd7ac90fce98fd9548d81..87c73457a0ae7eba8e576be10ea91a2b6759ac7d 100644 (file)
@@ -150,9 +150,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
 /*
  * L4 Watchdog
  */
-#ifdef CONFIG_SPL_BUILD
-#define CONFIG_HW_WATCHDOG
-#else
+#ifndef CONFIG_SPL_BUILD
 #undef CONFIG_HW_WATCHDOG
 #undef CONFIG_DESIGNWARE_WATCHDOG
 #endif