On Thu, Oct 3, 2019 at 6:56 AM Marek Vasut <ma...@denx.de> wrote: > > 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 <ma...@denx.de> > Cc: Chin Liang See <chin.liang....@intel.com> > Cc: Dalon Westergreen <dwest...@gmail.com> > Cc: Dinh Nguyen <dingu...@kernel.org> > Cc: Ley Foon Tan <ley.foon....@intel.com> > Cc: Simon Goldschmidt <simon.k.r.goldschm...@gmail.com> > Cc: Tien Fong Chee <tien.fong.c...@intel.com> > --- > configs/socfpga_stratix10_defconfig | 1 + > configs/socfpga_vining_fpga_defconfig | 1 + > drivers/watchdog/Kconfig | 14 ++-- > drivers/watchdog/designware_wdt.c | 97 +++++++++++++++++++-------- > 4 files changed, 77 insertions(+), 36 deletions(-) > > diff --git a/configs/socfpga_stratix10_defconfig > b/configs/socfpga_stratix10_defconfig > index 462082b67b..cc5f49a536 100644 > --- a/configs/socfpga_stratix10_defconfig > +++ b/configs/socfpga_stratix10_defconfig > @@ -56,4 +56,5 @@ CONFIG_USB=y > CONFIG_DM_USB=y > CONFIG_USB_DWC2=y > CONFIG_USB_STORAGE=y > +CONFIG_WDT=y > CONFIG_DESIGNWARE_WATCHDOG=y > diff --git a/configs/socfpga_vining_fpga_defconfig > b/configs/socfpga_vining_fpga_defconfig > index 03c43fa8b9..def7a3eca7 100644 > --- a/configs/socfpga_vining_fpga_defconfig > +++ b/configs/socfpga_vining_fpga_defconfig > @@ -91,4 +91,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_WDT=y > CONFIG_DESIGNWARE_WATCHDOG=y > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig > index 6fd9b0a177..ec34993664 100644 > --- a/drivers/watchdog/Kconfig > +++ b/drivers/watchdog/Kconfig > @@ -36,13 +36,6 @@ config ULP_WATCHDOG > help > Say Y here to enable i.MX7ULP watchdog driver. > > -config DESIGNWARE_WATCHDOG > - bool "Designware watchdog timer support" > - select HW_WATCHDOG CONFIG_HW_WATCHDOG is disabled now. Few areas of code in arm/mach-socfpga/ still using this CONFIG and call to hw_watchdog_init(). They need to remove too. Do we need call to uclass_get_device(UCLASS_WDT, 0, &dev) in SPL to probe watchdog and call to wdt_start() to start watchdog? Can't find place that start watchdog.
> - help > - Enable this to support Designware Watchdog Timer IP, present e.g. > - on Altera SoCFPGA SoCs. > - > config WDT > bool "Enable driver model for watchdog timer drivers" > depends on DM > @@ -54,6 +47,13 @@ config WDT > What exactly happens when the timer expires is up to a particular > device/driver. > > +config DESIGNWARE_WATCHDOG > + bool "Designware watchdog timer support" > + depends on WDT > + help > + Enable this to support Designware Watchdog Timer IP, present e.g. > + on Altera SoCFPGA SoCs. > + > config WDT_ARMADA_37XX > bool "Marvell Armada 37xx watchdog timer support" > depends on WDT && ARMADA_3700 > diff --git a/drivers/watchdog/designware_wdt.c > b/drivers/watchdog/designware_wdt.c > index c668567c66..f2b9175345 100644 > --- a/drivers/watchdog/designware_wdt.c > +++ b/drivers/watchdog/designware_wdt.c > @@ -4,7 +4,8 @@ > */ > > #include <common.h> > -#include <watchdog.h> > +#include <dm.h> > +#include <wdt.h> > #include <asm/io.h> > #include <asm/utils.h> > > @@ -17,57 +18,95 @@ > #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(struct udevice *dev, unsigned int > timeout) > { > + struct designware_wdt_priv *priv = dev_get_priv(dev); > 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 = clamp(i, 0, 15); > + > + writel(i | (i << 4), priv->base + DW_WDT_TORR); > > - writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR)); > return 0; > } > > -static void designware_wdt_enable(void) > +static unsigned int designware_wdt_is_enabled(struct udevice *dev) > { > - writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) | > - (0x1 << DW_WDT_CR_EN_OFFSET)), > - (CONFIG_DW_WDT_BASE + DW_WDT_CR)); > -} > + struct designware_wdt_priv *priv = dev_get_priv(dev); > > -static unsigned int designware_wdt_is_enabled(void) > -{ > - unsigned long val; > - val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR)); > - return val & 0x1; > + return readl(priv->base + DW_WDT_CR) & BIT(0); > } > > -#if defined(CONFIG_HW_WATCHDOG) > -void hw_watchdog_reset(void) > +static int designware_wdt_reset(struct udevice *dev) > { > - if (designware_wdt_is_enabled()) > + struct designware_wdt_priv *priv = dev_get_priv(dev); > + > + if (designware_wdt_is_enabled(dev)) > /* restart the watchdog counter */ > - writel(DW_WDT_CRR_RESTART_VAL, > - (CONFIG_DW_WDT_BASE + DW_WDT_CRR)); > + writel(DW_WDT_CRR_RESTART_VAL, priv->base + DW_WDT_CRR); > + > + return 0; > } > > -void hw_watchdog_init(void) > +static int designware_wdt_stop(struct udevice *dev) > { > /* reset to disable the watchdog */ > - hw_watchdog_reset(); > + designware_wdt_reset(dev); Need to clear BIT(DW_WDT_CR_EN_OFFSET) in CR register to disable watchdog. > + 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(CONFIG_WATCHDOG_TIMEOUT_MSECS); > - /* enable the watchdog */ > - designware_wdt_enable(); > + designware_wdt_settimeout(dev, timeout); > + > + writel((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) | > + BIT(DW_WDT_CR_EN_OFFSET), > + priv->base + DW_WDT_CR); > + > /* reset the watchdog */ > - hw_watchdog_reset(); > + designware_wdt_reset(dev); Need move to before enable CR_EN bit if we add clear CR_EN bit in designware_wdt_reset(). > + return 0; > +} > + > +static int designware_wdt_probe(struct udevice *dev) > +{ Need to de-assert reset for watchdog in probe using reset framework. > + /* reset to disable the watchdog */ > + designware_wdt_reset(dev); designware_wdt_reset() only reset watchdog counter, but doesn't disable the watchdog. Can change call to designware_wdt_stop() if _stop() add clear CR_EN bit. > + return 0; > } > -#endif > + > +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, > +}; > -- > 2.23.0 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot