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....@nxp.com>
Signed-off-by: Ye Li <ye...@nxp.com>
Cc: Stefano Babic <sba...@denx.de>
---
 drivers/watchdog/Kconfig    |  8 ++++
 drivers/watchdog/Makefile   |  1 +
 drivers/watchdog/ulp_wdog.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 101 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..30dbff6
--- /dev/null
+++ b/drivers/watchdog/ulp_wdog.c
@@ -0,0 +1,92 @@
+#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);
+}
-- 
2.6.2

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to