[PATCH v2 3/4] watchdog: stm32mp: check the watchdog status

Patrice CHOTARD patrice.chotard at foss.st.com
Tue May 27 16:00:03 CEST 2025



On 5/23/25 11:46, Antonio Borneo wrote:
> From: Clément Le Goffic <clement.legoffic at foss.st.com>
> 
> Add a mean to check the IWDG status based on the peripheral version.
> This is done by either checking the status bit ONF either by updating
> the reload register with the same value and check if the reload succeed.
> 
> Signed-off-by: Clément Le Goffic <clement.legoffic at foss.st.com>
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> ---
>  drivers/watchdog/stm32mp_wdt.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/drivers/watchdog/stm32mp_wdt.c b/drivers/watchdog/stm32mp_wdt.c
> index 97ab8cfe7ab..0712524b4a8 100644
> --- a/drivers/watchdog/stm32mp_wdt.c
> +++ b/drivers/watchdog/stm32mp_wdt.c
> @@ -21,11 +21,13 @@
>  #define IWDG_PR		0x04	/* Prescaler Register */
>  #define IWDG_RLR	0x08	/* ReLoad Register */
>  #define IWDG_SR		0x0C	/* Status Register */
> +#define IWDG_VERR	0x3F4	/* Version Register */
>  
>  /* IWDG_KR register bit mask */
>  #define KR_KEY_RELOAD	0xAAAA	/* Reload counter enable */
>  #define KR_KEY_ENABLE	0xCCCC	/* Peripheral enable */
>  #define KR_KEY_EWA	0x5555	/* Write access enable */
> +#define KR_KEY_DWA	0x0000	/* Write access disable*/
>  
>  /* IWDG_PR register bit values */
>  #define PR_256		0x06	/* Prescaler set to 256 */
> @@ -36,10 +38,17 @@
>  /* IWDG_SR register bit values */
>  #define SR_PVU		BIT(0)	/* Watchdog prescaler value update */
>  #define SR_RVU		BIT(1)	/* Watchdog counter reload value update */
> +#define SR_ONF		BIT(8)	/* Watchdog enable status bit */
> +
> +/* IWDG Compatibility */
> +#define ONF_MIN_VER	0x31
> +
> +#define TIMEOUT_US	10000
>  
>  struct stm32mp_wdt_priv {
>  	fdt_addr_t base;		/* registers addr in physical memory */
>  	unsigned long wdt_clk_rate;	/* Watchdog dedicated clock rate */
> +	unsigned int hw_version;	/* Peripheral version */
>  };
>  
>  static int stm32mp_wdt_reset(struct udevice *dev)
> @@ -90,6 +99,7 @@ static int stm32mp_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
>  static int stm32mp_wdt_probe(struct udevice *dev)
>  {
>  	struct stm32mp_wdt_priv *priv = dev_get_priv(dev);
> +	u32 rlr, sr;
>  	struct clk clk;
>  	int ret;
>  
> @@ -115,6 +125,29 @@ static int stm32mp_wdt_probe(struct udevice *dev)
>  
>  	priv->wdt_clk_rate = clk_get_rate(&clk);
>  
> +	priv->hw_version = readl(priv->base + IWDG_VERR);
> +
> +	if (priv->hw_version >= ONF_MIN_VER) {
> +		if (readl(priv->base + IWDG_SR) & SR_ONF)
> +			wdt_set_force_autostart(dev);
> +	} else {
> +		/*
> +		 * Workaround for old versions without IWDG_SR_ONF bit:
> +		 * - write in IWDG_RLR_OFFSET
> +		 * - wait for sync
> +		 * - if sync succeeds, then iwdg is running
> +		 */
> +		writel(KR_KEY_EWA, priv->base + IWDG_KR);
> +		rlr = readl(priv->base + IWDG_RLR);
> +		writel(rlr, priv->base + IWDG_RLR);
> +		ret = readl_poll_timeout(priv->base + IWDG_SR, sr, sr & SR_RVU,
> +					 TIMEOUT_US);
> +		if (!ret)
> +			wdt_set_force_autostart(dev);
> +
> +		writel(KR_KEY_DWA, priv->base + IWDG_KR);
> +	}
> +
>  	dev_dbg(dev, "IWDG init done\n");
>  
>  	return 0;
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


More information about the U-Boot mailing list