
On 27/12/2016 11:04, Peng Fan wrote:
From: Ye Li ye.li@nxp.com
This driver implements the HW WATCHDOG functions. Which needs to set CONFIG_HW_WATCHDOG to use them. This is disabled by default for mx7ulp.
Use watchdog for reset cpu. Implement this in the driver. Need to define CONFIG_ULP_WATCHDOG to build it.
Signed-off-by: Peng Fan peng.fan@nxp.com Signed-off-by: Ye Li ye.li@nxp.com Cc: Stefano Babic sbabic@denx.de
V2: Add License
drivers/watchdog/Kconfig | 8 ++++ drivers/watchdog/Makefile | 1 + drivers/watchdog/ulp_wdog.c | 98 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 drivers/watchdog/ulp_wdog.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index e69de29..dbdaafc 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -0,0 +1,8 @@ +menu "WATCHDOG support"
+config ULP_WATCHDOG
- bool "i.MX7ULP watchdog"
- help
Say Y here to enable i.MX7ULP watchdog driver.
+endmenu diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index a007ae8..dea1836 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o obj-$(CONFIG_BFIN_WATCHDOG) += bfin_wdt.o obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o +obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o diff --git a/drivers/watchdog/ulp_wdog.c b/drivers/watchdog/ulp_wdog.c new file mode 100644 index 0000000..72ec694 --- /dev/null +++ b/drivers/watchdog/ulp_wdog.c @@ -0,0 +1,98 @@ +/*
- Copyright (C) 2016 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/arch/imx-regs.h>
+/*
- MX7ULP WDOG Register Map
- */
+struct wdog_regs {
- u8 cs1;
- u8 cs2;
- u16 reserve0;
- u32 cnt;
- u32 toval;
- u32 win;
+};
+#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS +#define CONFIG_WATCHDOG_TIMEOUT_MSECS 0x1500 +#endif
+#define REFRESH_WORD0 0xA602 /* 1st refresh word */ +#define REFRESH_WORD1 0xB480 /* 2nd refresh word */
+#define UNLOCK_WORD0 0xC520 /* 1st unlock word */ +#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */
+#define WDGCS1_WDGE (1<<7) +#define WDGCS1_WDGUPDATE (1<<5)
+#define WDGCS2_FLG (1<<6)
+#define WDG_BUS_CLK (0x0) +#define WDG_LPO_CLK (0x1) +#define WDG_32KHZ_CLK (0x2) +#define WDG_EXT_CLK (0x3)
+DECLARE_GLOBAL_DATA_PTR;
+void hw_watchdog_set_timeout(u16 val) +{
- /* setting timeout value */
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(val, &wdog->toval);
+}
+void hw_watchdog_reset(void) +{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(REFRESH_WORD0, &wdog->cnt);
- writel(REFRESH_WORD1, &wdog->cnt);
+}
+void hw_watchdog_init(void) +{
- u8 val;
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(UNLOCK_WORD0, &wdog->cnt);
- writel(UNLOCK_WORD1, &wdog->cnt);
- val = readb(&wdog->cs2);
- val |= WDGCS2_FLG;
- writeb(val, &wdog->cs2);
- hw_watchdog_set_timeout(CONFIG_WATCHDOG_TIMEOUT_MSECS);
- writel(0, &wdog->win);
- writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
- writeb((WDGCS1_WDGE | WDGCS1_WDGUPDATE), &wdog->cs1);/* enable counter running */
- hw_watchdog_reset();
+}
+void reset_cpu(ulong addr) +{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writel(UNLOCK_WORD0, &wdog->cnt);
- writel(UNLOCK_WORD1, &wdog->cnt);
- hw_watchdog_set_timeout(5); /* 5ms timeout */
- writel(0, &wdog->win);
- writeb(WDG_LPO_CLK, &wdog->cs2);/* setting 1-kHz clock source */
- writeb(WDGCS1_WDGE, &wdog->cs1);/* enable counter running */
- hw_watchdog_reset();
- while (1);
+}
This goes into drivers/watchdog, and it slightly differs from the implementation in imx-watchdog.c. Code is quite simple, too, I think it could be merged into the same file.
Best regards, Stefano Babic