[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