[U-Boot] [PATCH V2 2/3] watchdog: designware: Convert to DM and DT probing

Ley Foon Tan lftan.linux at gmail.com
Fri Oct 4 09:26:15 UTC 2019


On Thu, Oct 3, 2019 at 9:00 PM Marek Vasut <marex at 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. There ought to be no functional change.

All watchdog DT nodes with compatible "snps,dw-wdt" need to add
"u-boot,dm-pre-reloc;".

>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Chin Liang See <chin.liang.see at intel.com>
> Cc: Dalon Westergreen <dwesterg at gmail.com>
> Cc: Dinh Nguyen <dinguyen at kernel.org>
> Cc: Jagan Teki <jagan at amarulasolutions.com>
> Cc: Ley Foon Tan <ley.foon.tan at intel.com>
> Cc: Philipp Tomisch <philipp.tomisch at theobroma-systems.com>
> Cc: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
> Cc: Tien Fong Chee <tien.fong.chee at intel.com>
> ---
> V2: - Support both DM and non-DM probing
>     - Fix watchdog stop handling by setting CR bit
> ---
>  configs/socfpga_stratix10_defconfig       |   2 +
>  configs/socfpga_vining_fpga_defconfig     |   1 +

Same here. All socfpga defconfig files need to add CONFIG_WDT.

>  drivers/watchdog/Kconfig                  |   2 +-
>  drivers/watchdog/designware_wdt.c         | 122 ++++++++++++++++++----
>  include/configs/socfpga_stratix10_socdk.h |   1 +
>  5 files changed, 104 insertions(+), 24 deletions(-)
>
> diff --git a/configs/socfpga_stratix10_defconfig b/configs/socfpga_stratix10_defconfig
> index 462082b67b..752fa545bd 100644
> --- a/configs/socfpga_stratix10_defconfig
> +++ b/configs/socfpga_stratix10_defconfig
> @@ -57,3 +57,5 @@ CONFIG_DM_USB=y
>  CONFIG_USB_DWC2=y
>  CONFIG_USB_STORAGE=y
>  CONFIG_DESIGNWARE_WATCHDOG=y
> +CONFIG_WDT=y
> +# CONFIG_SPL_WDT is not set
> 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..bfb91af947 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -38,7 +38,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.
> diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
> index c668567c66..a7b735979a 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,46 +18,51 @@
>  #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();

In my "arm: socfpga: Convert drivers from struct to defines" patch
series, I have moved spl_early_init() to the beginning of
spl_board_f().
So, DM framework is initialized in early stage, you should able to use
DM for watchdog in SPL too.
But, maybe need to add a wrapper function to probe watchdog device and
start watchdog. Something like this:

uclass_get_device(UCLASS_WDT, 0, &dev);
wdt_start(dev, CONFIG_WATCHDOG_TIMEOUT_MSECS, 0);

>  }
> +#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);

Still no fixing 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(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);
> +

Need de-assert watchdog reset using reset framework function, reset_get_bulk().



> +       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
> diff --git a/include/configs/socfpga_stratix10_socdk.h b/include/configs/socfpga_stratix10_socdk.h
> index 353e08f982..0c0c27000a 100644
> --- a/include/configs/socfpga_stratix10_socdk.h
> +++ b/include/configs/socfpga_stratix10_socdk.h
> @@ -161,6 +161,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
>   * L4 Watchdog
>   */
>  #ifdef CONFIG_SPL_BUILD
> +#undef CONFIG_WATCHDOG
>  #define CONFIG_HW_WATCHDOG
>  #else
>  #undef CONFIG_HW_WATCHDOG
> --
> 2.23.0
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list