diff mbox series

[U-Boot,V2,2/2] watchdog: imx: Add DM support

Message ID 20190609014622.14067-2-marex@denx.de
State Accepted
Commit 4b969deac059a6957cdce47195f1bdd763ee5f85
Delegated to: Stefano Babic
Headers show
Series [U-Boot,V2,1/2] watchdog: Split WDT from SPL_WDT | expand

Commit Message

Marek Vasut June 9, 2019, 1:46 a.m. UTC
Add DM and DT probing support to iMX watchdog driver. This should
allow boards to move over to this driver, enable SYSRESET_WATCHDOG
to handle cpu_reset() if required.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Peng Fan <Peng.Fan@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
---
V2: No change
---
 drivers/watchdog/Kconfig        |   2 +-
 drivers/watchdog/imx_watchdog.c | 119 +++++++++++++++++++++++++++-----
 2 files changed, 104 insertions(+), 17 deletions(-)

Comments

Heiko Schocher June 11, 2019, 5:33 a.m. UTC | #1
Hello Marek,

Am 09.06.2019 um 03:46 schrieb Marek Vasut:
> Add DM and DT probing support to iMX watchdog driver. This should
> allow boards to move over to this driver, enable SYSRESET_WATCHDOG
> to handle cpu_reset() if required.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Peng Fan <Peng.Fan@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> ---
> V2: No change
> ---
>   drivers/watchdog/Kconfig        |   2 +-
>   drivers/watchdog/imx_watchdog.c | 119 +++++++++++++++++++++++++++-----
>   2 files changed, 104 insertions(+), 17 deletions(-)

just worked on similiar patch (not ready for mainline) ... patch looks
good to me, but I stumbled over a nitpick ...

CONFIG_WATCHDOG_TIMEOUT_MSECS is defined in imx_watchdog to 128000 ms

37 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
38 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
39 #endif

If now using DM approach it is set to 60000 ms, see include/wdt.h

109 #if defined(CONFIG_WDT)
110 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
111 #define CONFIG_WATCHDOG_TIMEOUT_MSECS   (60 * 1000)
112 #endif
113 #define WATCHDOG_TIMEOUT_SECS   (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000)

Can you try my patch:
https://github.com/hsdenx/u-boot-test/commit/11503dba89cade8b81ee9d93d503d0bcce868b33

which moves WATCHDOG_TIMEOUT_MSECS to Kconfig ?
(Travis build just started, may not mainline ready, also patman
  notes in commit messages can now be removed.)

Thanks!

bye,
Heiko
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 0330a3b3a1..5993865647 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -136,7 +136,7 @@ config XILINX_TB_WATCHDOG
>   
>   config IMX_WATCHDOG
>   	bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP"
> -	select HW_WATCHDOG
> +	select HW_WATCHDOG if !WDT
>   	help
>   	   Select this to enable the IMX and LSCH2 of Layerscape watchdog
>   	   driver.
> diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
> index 14cc618074..53a3e9f5c7 100644
> --- a/drivers/watchdog/imx_watchdog.c
> +++ b/drivers/watchdog/imx_watchdog.c
> @@ -5,7 +5,9 @@
>    */
>   
>   #include <common.h>
> +#include <dm.h>
>   #include <asm/io.h>
> +#include <wdt.h>
>   #include <watchdog.h>
>   #include <asm/arch/imx-regs.h>
>   #ifdef CONFIG_FSL_LSCH2
> @@ -13,20 +15,40 @@
>   #endif
>   #include <fsl_wdog.h>
>   
> -#ifdef CONFIG_IMX_WATCHDOG
> -void hw_watchdog_reset(void)
> +static void imx_watchdog_expire_now(struct watchdog_regs *wdog)
> +{
> +	clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
> +
> +	writew(0x5555, &wdog->wsr);
> +	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
> +	while (1) {
> +		/*
> +		 * spin for .5 seconds before reset
> +		 */
> +	}
> +}
> +
> +#if !defined(CONFIG_IMX_WATCHDOG) || \
> +    (defined(CONFIG_IMX_WATCHDOG) && !CONFIG_IS_ENABLED(WDT))
> +void __attribute__((weak)) reset_cpu(ulong addr)
>   {
> -#ifndef CONFIG_WATCHDOG_RESET_DISABLE
>   	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
>   
> +	imx_watchdog_expire_now(wdog);
> +}
> +#endif
> +
> +#if defined(CONFIG_IMX_WATCHDOG)
> +static void imx_watchdog_reset(struct watchdog_regs *wdog)
> +{
> +#ifndef CONFIG_WATCHDOG_RESET_DISABLE
>   	writew(0x5555, &wdog->wsr);
>   	writew(0xaaaa, &wdog->wsr);
>   #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/
>   }
>   
> -void hw_watchdog_init(void)
> +static void imx_watchdog_init(struct watchdog_regs *wdog)
>   {
> -	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
>   	u16 timeout;
>   
>   	/*
> @@ -44,21 +66,86 @@ void hw_watchdog_init(void)
>   	writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
>   		WCR_WDA | SET_WCR_WT(timeout), &wdog->wcr);
>   #endif /* CONFIG_FSL_LSCH2*/
> -	hw_watchdog_reset();
> +	imx_watchdog_reset(wdog);
>   }
> -#endif
>   
> -void __attribute__((weak)) reset_cpu(ulong addr)
> +#if !CONFIG_IS_ENABLED(WDT)
> +void hw_watchdog_reset(void)
>   {
>   	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
>   
> -	clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
> +	imx_watchdog_reset(wdog);
> +}
>   
> -	writew(0x5555, &wdog->wsr);
> -	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
> -	while (1) {
> -		/*
> -		 * spin for .5 seconds before reset
> -		 */
> -	}
> +void hw_watchdog_init(void)
> +{
> +	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
> +
> +	imx_watchdog_init(wdog);
> +}
> +#else
> +struct imx_wdt_priv {
> +	void __iomem *base;
> +};
> +
> +static int imx_wdt_reset(struct udevice *dev)
> +{
> +	struct imx_wdt_priv *priv = dev_get_priv(dev);
> +
> +	imx_watchdog_reset(priv->base);
> +
> +	return 0;
> +}
> +
> +static int imx_wdt_expire_now(struct udevice *dev, ulong flags)
> +{
> +	struct imx_wdt_priv *priv = dev_get_priv(dev);
> +
> +	imx_watchdog_expire_now(priv->base);
> +	hang();
> +
> +	return 0;
> +}
> +
> +static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
> +{
> +	struct imx_wdt_priv *priv = dev_get_priv(dev);
> +
> +	imx_watchdog_init(priv->base);
> +
> +	return 0;
> +}
> +
> +static int imx_wdt_probe(struct udevice *dev)
> +{
> +	struct imx_wdt_priv *priv = dev_get_priv(dev);
> +
> +	priv->base = dev_read_addr_ptr(dev);
> +	if (!priv->base)
> +		return -ENOENT;
> +
> +	return 0;
>   }
> +
> +static const struct wdt_ops imx_wdt_ops = {
> +	.start		= imx_wdt_start,
> +	.reset		= imx_wdt_reset,
> +	.expire_now	= imx_wdt_expire_now,
> +};
> +
> +static const struct udevice_id imx_wdt_ids[] = {
> +	{ .compatible = "fsl,imx21-wdt" },
> +	{}
> +};
> +
> +U_BOOT_DRIVER(imx_wdt) = {
> +	.name		= "imx_wdt",
> +	.id		= UCLASS_WDT,
> +	.of_match	= imx_wdt_ids,
> +	.probe		= imx_wdt_probe,
> +	.ops		= &imx_wdt_ops,
> +	.priv_auto_alloc_size = sizeof(struct imx_wdt_priv),
> +	.flags		= DM_FLAG_PRE_RELOC,
> +};
> +#endif
> +#endif
>
Marek Vasut June 11, 2019, 9:55 a.m. UTC | #2
On 6/11/19 7:33 AM, Heiko Schocher wrote:
> Hello Marek,
> 
> Am 09.06.2019 um 03:46 schrieb Marek Vasut:
>> Add DM and DT probing support to iMX watchdog driver. This should
>> allow boards to move over to this driver, enable SYSRESET_WATCHDOG
>> to handle cpu_reset() if required.
>>
>> Signed-off-by: Marek Vasut <marex@denx.de>
>> Cc: Peng Fan <Peng.Fan@freescale.com>
>> Cc: Stefano Babic <sbabic@denx.de>
>> ---
>> V2: No change
>> ---
>>   drivers/watchdog/Kconfig        |   2 +-
>>   drivers/watchdog/imx_watchdog.c | 119 +++++++++++++++++++++++++++-----
>>   2 files changed, 104 insertions(+), 17 deletions(-)
> 
> just worked on similiar patch (not ready for mainline) ... patch looks
> good to me, but I stumbled over a nitpick ...
> 
> CONFIG_WATCHDOG_TIMEOUT_MSECS is defined in imx_watchdog to 128000 ms
> 
> 37 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
> 38 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
> 39 #endif
> 
> If now using DM approach it is set to 60000 ms, see include/wdt.h
> 
> 109 #if defined(CONFIG_WDT)
> 110 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
> 111 #define CONFIG_WATCHDOG_TIMEOUT_MSECS   (60 * 1000)
> 112 #endif
> 113 #define WATCHDOG_TIMEOUT_SECS   (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000)
> 
> Can you try my patch:
> https://github.com/hsdenx/u-boot-test/commit/11503dba89cade8b81ee9d93d503d0bcce868b33
> 
> 
> which moves WATCHDOG_TIMEOUT_MSECS to Kconfig ?
> (Travis build just started, may not mainline ready, also patman
>  notes in commit messages can now be removed.)

Looks good to me :)
Heiko Schocher June 12, 2019, 3:26 a.m. UTC | #3
Hello Marek,

Am 11.06.2019 um 11:55 schrieb Marek Vasut:
> On 6/11/19 7:33 AM, Heiko Schocher wrote:
>> Hello Marek,
>>
>> Am 09.06.2019 um 03:46 schrieb Marek Vasut:
>>> Add DM and DT probing support to iMX watchdog driver. This should
>>> allow boards to move over to this driver, enable SYSRESET_WATCHDOG
>>> to handle cpu_reset() if required.
>>>
>>> Signed-off-by: Marek Vasut <marex@denx.de>
>>> Cc: Peng Fan <Peng.Fan@freescale.com>
>>> Cc: Stefano Babic <sbabic@denx.de>
>>> ---
>>> V2: No change
>>> ---
>>>    drivers/watchdog/Kconfig        |   2 +-
>>>    drivers/watchdog/imx_watchdog.c | 119 +++++++++++++++++++++++++++-----
>>>    2 files changed, 104 insertions(+), 17 deletions(-)
>>
>> just worked on similiar patch (not ready for mainline) ... patch looks
>> good to me, but I stumbled over a nitpick ...
>>
>> CONFIG_WATCHDOG_TIMEOUT_MSECS is defined in imx_watchdog to 128000 ms
>>
>> 37 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
>> 38 #define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
>> 39 #endif
>>
>> If now using DM approach it is set to 60000 ms, see include/wdt.h
>>
>> 109 #if defined(CONFIG_WDT)
>> 110 #ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
>> 111 #define CONFIG_WATCHDOG_TIMEOUT_MSECS   (60 * 1000)
>> 112 #endif
>> 113 #define WATCHDOG_TIMEOUT_SECS   (CONFIG_WATCHDOG_TIMEOUT_MSECS / 1000)
>>
>> Can you try my patch:
>> https://github.com/hsdenx/u-boot-test/commit/11503dba89cade8b81ee9d93d503d0bcce868b33
>>
>>
>> which moves WATCHDOG_TIMEOUT_MSECS to Kconfig ?
>> (Travis build just started, may not mainline ready, also patman
>>   notes in commit messages can now be removed.)
> 
> Looks good to me :)

Fine, so I rework the commit message and post it.

Thanks!

bye,
Heiko
Heiko Schocher June 12, 2019, 4:01 a.m. UTC | #4
Hello Marek,

Am 09.06.2019 um 03:46 schrieb Marek Vasut:
> Add DM and DT probing support to iMX watchdog driver. This should
> allow boards to move over to this driver, enable SYSRESET_WATCHDOG
> to handle cpu_reset() if required.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Peng Fan <Peng.Fan@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> ---
> V2: No change
> ---
>   drivers/watchdog/Kconfig        |   2 +-
>   drivers/watchdog/imx_watchdog.c | 119 +++++++++++++++++++++++++++-----
>   2 files changed, 104 insertions(+), 17 deletions(-)

Tested on the aristainetos board.

Tested-by: Heiko Schocher <hs@denx.de>

bye,
Heiko
Stefano Babic July 20, 2019, 9:06 a.m. UTC | #5
> Add DM and DT probing support to iMX watchdog driver. This should
> allow boards to move over to this driver, enable SYSRESET_WATCHDOG
> to handle cpu_reset() if required.
> Signed-off-by: Marek Vasut <marex@denx.de>
> Cc: Peng Fan <Peng.Fan@freescale.com>
> Cc: Stefano Babic <sbabic@denx.de>
> Tested-by: Heiko Schocher <hs@denx.de>

Applied to u-boot-imx, master, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 0330a3b3a1..5993865647 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -136,7 +136,7 @@  config XILINX_TB_WATCHDOG
 
 config IMX_WATCHDOG
 	bool "Enable Watchdog Timer support for IMX and LSCH2 of NXP"
-	select HW_WATCHDOG
+	select HW_WATCHDOG if !WDT
 	help
 	   Select this to enable the IMX and LSCH2 of Layerscape watchdog
 	   driver.
diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
index 14cc618074..53a3e9f5c7 100644
--- a/drivers/watchdog/imx_watchdog.c
+++ b/drivers/watchdog/imx_watchdog.c
@@ -5,7 +5,9 @@ 
  */
 
 #include <common.h>
+#include <dm.h>
 #include <asm/io.h>
+#include <wdt.h>
 #include <watchdog.h>
 #include <asm/arch/imx-regs.h>
 #ifdef CONFIG_FSL_LSCH2
@@ -13,20 +15,40 @@ 
 #endif
 #include <fsl_wdog.h>
 
-#ifdef CONFIG_IMX_WATCHDOG
-void hw_watchdog_reset(void)
+static void imx_watchdog_expire_now(struct watchdog_regs *wdog)
+{
+	clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
+
+	writew(0x5555, &wdog->wsr);
+	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
+	while (1) {
+		/*
+		 * spin for .5 seconds before reset
+		 */
+	}
+}
+
+#if !defined(CONFIG_IMX_WATCHDOG) || \
+    (defined(CONFIG_IMX_WATCHDOG) && !CONFIG_IS_ENABLED(WDT))
+void __attribute__((weak)) reset_cpu(ulong addr)
 {
-#ifndef CONFIG_WATCHDOG_RESET_DISABLE
 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 
+	imx_watchdog_expire_now(wdog);
+}
+#endif
+
+#if defined(CONFIG_IMX_WATCHDOG)
+static void imx_watchdog_reset(struct watchdog_regs *wdog)
+{
+#ifndef CONFIG_WATCHDOG_RESET_DISABLE
 	writew(0x5555, &wdog->wsr);
 	writew(0xaaaa, &wdog->wsr);
 #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/
 }
 
-void hw_watchdog_init(void)
+static void imx_watchdog_init(struct watchdog_regs *wdog)
 {
-	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 	u16 timeout;
 
 	/*
@@ -44,21 +66,86 @@  void hw_watchdog_init(void)
 	writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS |
 		WCR_WDA | SET_WCR_WT(timeout), &wdog->wcr);
 #endif /* CONFIG_FSL_LSCH2*/
-	hw_watchdog_reset();
+	imx_watchdog_reset(wdog);
 }
-#endif
 
-void __attribute__((weak)) reset_cpu(ulong addr)
+#if !CONFIG_IS_ENABLED(WDT)
+void hw_watchdog_reset(void)
 {
 	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 
-	clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE);
+	imx_watchdog_reset(wdog);
+}
 
-	writew(0x5555, &wdog->wsr);
-	writew(0xaaaa, &wdog->wsr);	/* load minimum 1/2 second timeout */
-	while (1) {
-		/*
-		 * spin for .5 seconds before reset
-		 */
-	}
+void hw_watchdog_init(void)
+{
+	struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+	imx_watchdog_init(wdog);
+}
+#else
+struct imx_wdt_priv {
+	void __iomem *base;
+};
+
+static int imx_wdt_reset(struct udevice *dev)
+{
+	struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+	imx_watchdog_reset(priv->base);
+
+	return 0;
+}
+
+static int imx_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+	imx_watchdog_expire_now(priv->base);
+	hang();
+
+	return 0;
+}
+
+static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+	struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+	imx_watchdog_init(priv->base);
+
+	return 0;
+}
+
+static int imx_wdt_probe(struct udevice *dev)
+{
+	struct imx_wdt_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (!priv->base)
+		return -ENOENT;
+
+	return 0;
 }
+
+static const struct wdt_ops imx_wdt_ops = {
+	.start		= imx_wdt_start,
+	.reset		= imx_wdt_reset,
+	.expire_now	= imx_wdt_expire_now,
+};
+
+static const struct udevice_id imx_wdt_ids[] = {
+	{ .compatible = "fsl,imx21-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(imx_wdt) = {
+	.name		= "imx_wdt",
+	.id		= UCLASS_WDT,
+	.of_match	= imx_wdt_ids,
+	.probe		= imx_wdt_probe,
+	.ops		= &imx_wdt_ops,
+	.priv_auto_alloc_size = sizeof(struct imx_wdt_priv),
+	.flags		= DM_FLAG_PRE_RELOC,
+};
+#endif
+#endif