mx31/mx35/mx51/mx53/mx6: add watchdog
Use a common watchdog driver for all these cpus.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Stefano Babic <sbabic@denx.de>
diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c
index 36266da..86916d1 100644
--- a/arch/arm/cpu/arm1136/mx31/timer.c
+++ b/arch/arm/cpu/arm1136/mx31/timer.c
@@ -161,42 +161,3 @@
{
return MXC_CLK32;
}
-
-void reset_cpu(ulong addr)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
- wdog->wcr = WDOG_ENABLE;
- while (1)
- ;
-}
-
-#ifdef CONFIG_HW_WATCHDOG
-void mxc_hw_watchdog_enable(void)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
- u16 secs;
-
- /*
- * The timer watchdog can be set between
- * 0.5 and 128 Seconds. If not defined
- * in configuration file, sets 64 Seconds
- */
-#ifdef CONFIG_SYS_WD_TIMER_SECS
- secs = (CONFIG_SYS_WD_TIMER_SECS << 1) & 0xFF;
- if (!secs) secs = 1;
-#else
- secs = 64;
-#endif
- setbits_le16(&wdog->wcr, (secs << WDOG_WT_SHIFT) | WDOG_ENABLE
- | WDOG_WDZST);
-}
-
-
-void mxc_hw_watchdog_reset(void)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE;
-
- writew(0x5555, &wdog->wsr);
- writew(0xAAAA, &wdog->wsr);
-}
-#endif
diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c
index 98aa4d1..295a98e 100644
--- a/arch/arm/cpu/arm1136/mx35/generic.c
+++ b/arch/arm/cpu/arm1136/mx35/generic.c
@@ -488,12 +488,6 @@
return 0;
}
-void reset_cpu(ulong addr)
-{
- struct wdog_regs *wdog = (struct wdog_regs *)WDOG_BASE_ADDR;
- writew(4, &wdog->wcr);
-}
-
#define RCSR_MEM_CTL_WEIM 0
#define RCSR_MEM_CTL_NAND 1
#define RCSR_MEM_CTL_ATA 2
diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
index 5081908..a9b86c1 100644
--- a/arch/arm/imx-common/cpu.c
+++ b/arch/arm/imx-common/cpu.c
@@ -175,11 +175,6 @@
}
#endif
-void reset_cpu(ulong addr)
-{
- __raw_writew(4, WDOG1_BASE_ADDR);
-}
-
u32 get_ahb_clk(void)
{
struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
diff --git a/arch/arm/include/asm/arch-mx31/clock.h b/arch/arm/include/asm/arch-mx31/clock.h
index 1dbb8da..25c3f70 100644
--- a/arch/arm/include/asm/arch-mx31/clock.h
+++ b/arch/arm/include/asm/arch-mx31/clock.h
@@ -58,7 +58,5 @@
void mx31_uart1_hw_init(void);
void mx31_uart2_hw_init(void);
void mx31_spi2_hw_init(void);
-void mxc_hw_watchdog_enable(void);
-void mxc_hw_watchdog_reset(void);
#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h
index ae3658b..3f58318 100644
--- a/arch/arm/include/asm/arch-mx31/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx31/imx-regs.h
@@ -68,17 +68,6 @@
u32 test;
};
-/* Watchdog Timer (WDOG) registers */
-#define WDOG_ENABLE (1 << 2)
-#define WDOG_WT_SHIFT 8
-#define WDOG_WDZST (1 << 0)
-
-struct wdog_regs {
- u16 wcr; /* Control */
- u16 wsr; /* Service */
- u16 wrsr; /* Reset Status */
-};
-
/* IIM Control Registers */
struct iim_regs {
u32 iim_stat;
@@ -687,7 +676,7 @@
#define ARM_PPMRR 0x40000015
-#define WDOG_BASE 0x53FDC000
+#define WDOG1_BASE_ADDR 0x53FDC000
/*
* GPIO
diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h
index 18c6816..7f337be 100644
--- a/arch/arm/include/asm/arch-mx35/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx35/imx-regs.h
@@ -80,7 +80,7 @@
#define GPIO2_BASE_ADDR 0x53FD0000
#define SDMA_BASE_ADDR 0x53FD4000
#define RTC_BASE_ADDR 0x53FD8000
-#define WDOG_BASE_ADDR 0x53FDC000
+#define WDOG1_BASE_ADDR 0x53FDC000
#define PWM_BASE_ADDR 0x53FE0000
#define RTIC_BASE_ADDR 0x53FEC000
#define IIM_BASE_ADDR 0x53FF0000
@@ -292,15 +292,6 @@
u32 test;
};
-/* Watchdog Timer (WDOG) registers */
-struct wdog_regs {
- u16 wcr; /* Control */
- u16 wsr; /* Service */
- u16 wrsr; /* Reset Status */
- u16 wicr; /* Interrupt Control */
- u16 wmcr; /* Misc Control */
-};
-
struct esdc_regs {
u32 esdctl0;
u32 esdcfg0;
diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index 1d060fd..249d15a 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -218,16 +218,6 @@
*/
#define WBED 1
-/*
- * WEIM WCR
- */
-#define BCM 1
-#define GBCD(x) (((x) & 0x3) << 1)
-#define INTEN (1 << 4)
-#define INTPOL (1 << 5)
-#define WDOG_EN (1 << 8)
-#define WDOG_LIMIT(x) (((x) & 0x3) << 9)
-
#define CS0_128 0
#define CS0_64M_CS1_64M 1
#define CS0_64M_CS1_32M_CS2_32M 2
diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index a3079db..06ca17c 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -37,13 +37,6 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_HW_WATCHDOG
-void hw_watchdog_reset(void)
-{
- mxc_hw_watchdog_reset();
-}
-#endif
-
int dram_init(void)
{
/* dram_init must store complete ramsize in gd->ram_size */
@@ -188,7 +181,7 @@
pmic_reg_write(p, REG_INT_STATUS1, RTCRSTI);
#ifdef CONFIG_HW_WATCHDOG
- mxc_hw_watchdog_enable();
+ hw_watchdog_init();
#endif
return 0;
diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c
index bc60632..895396c 100644
--- a/board/freescale/mx31pdk/mx31pdk.c
+++ b/board/freescale/mx31pdk/mx31pdk.c
@@ -36,13 +36,6 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_HW_WATCHDOG
-void hw_watchdog_reset(void)
-{
- mxc_hw_watchdog_reset();
-}
-#endif
-
int dram_init(void)
{
/* dram_init must store complete ramsize in gd->ram_size */
@@ -98,7 +91,7 @@
pmic_reg_write(p, REG_POWER_CTL0, val | COINCHEN);
pmic_reg_write(p, REG_INT_STATUS1, RTCRSTI);
#ifdef CONFIG_HW_WATCHDOG
- mxc_hw_watchdog_enable();
+ hw_watchdog_init();
#endif
return 0;
}
diff --git a/board/hale/tt01/tt01.c b/board/hale/tt01/tt01.c
index 0c2cb79..b4b8209 100644
--- a/board/hale/tt01/tt01.c
+++ b/board/hale/tt01/tt01.c
@@ -179,7 +179,7 @@
int board_late_init(void)
{
#ifdef CONFIG_HW_WATCHDOG
- mxc_hw_watchdog_enable();
+ hw_watchdog_init();
#endif
return 0;
diff --git a/doc/README.watchdog b/doc/README.watchdog
new file mode 100644
index 0000000..ee65008
--- /dev/null
+++ b/doc/README.watchdog
@@ -0,0 +1,29 @@
+Watchdog driver general info
+
+CONFIG_HW_WATCHDOG
+ This enables hw_watchdog_reset to be called during various loops,
+ including waiting for a character on a serial port. But it
+ does not also call hw_watchdog_init. Boards which want this
+ enabled must call this function in their board file. This split
+ is useful because some rom's enable the watchdog when downloading
+ new code, so it must be serviced, but the board would rather it
+ was off. And, it cannot always be turned off once on.
+
+CONFIG_WATCHDOG_TIMEOUT_MSECS
+ Can be used to change the timeout for i.mx31/35/5x/6x.
+ If not given, will default to maximum timeout. This would
+ be 128000 msec for i.mx31/35/5x/6x.
+
+CONFIG_AT91SAM9_WATCHDOG
+ Available for AT91SAM9 to service the watchdog.
+
+CONFIG_FTWDT010_WATCHDOG
+ Available for FTWDT010 to service the watchdog.
+
+CONFIG_FTWDT010_HW_TIMEOUT
+ Can be used to change the timeout for FTWDT010.
+
+CONFIG_IMX_WATCHDOG
+ Available for i.mx31/35/5x/6x to service the watchdog. This is not
+ automatically set because some boards (vision2) still need to define
+ their own hw_watchdog_reset routine.
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index bc09123..b1f4e0f 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -27,6 +27,9 @@
COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
COBJS-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
+ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6))
+COBJS-y += imx_watchdog.o
+endif
COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
COBJS-$(CONFIG_S5P) += s5p_wdt.o
diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c
new file mode 100644
index 0000000..50e602a
--- /dev/null
+++ b/drivers/watchdog/imx_watchdog.c
@@ -0,0 +1,66 @@
+/*
+ * watchdog.c - driver for i.mx on-chip watchdog
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <watchdog.h>
+#include <asm/arch/imx-regs.h>
+
+struct watchdog_regs {
+ u16 wcr; /* Control */
+ u16 wsr; /* Service */
+ u16 wrsr; /* Reset Status */
+};
+
+#define WCR_WDZST 0x01
+#define WCR_WDBG 0x02
+#define WCR_WDE 0x04 /* WDOG enable */
+#define WCR_WDT 0x08
+#define WCR_WDW 0x80
+#define SET_WCR_WT(x) (x << 8)
+
+#ifdef CONFIG_IMX_WATCHDOG
+void hw_watchdog_reset(void)
+{
+ struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+ writew(0x5555, &wdog->wsr);
+ writew(0xaaaa, &wdog->wsr);
+}
+
+void hw_watchdog_init(void)
+{
+ struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+ u16 timeout;
+
+ /*
+ * The timer watchdog can be set between
+ * 0.5 and 128 Seconds. If not defined
+ * in configuration file, sets 128 Seconds
+ */
+#ifndef CONFIG_WATCHDOG_TIMEOUT_MSECS
+#define CONFIG_WATCHDOG_TIMEOUT_MSECS 128000
+#endif
+ timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1;
+ writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT |
+ WCR_WDW | SET_WCR_WT(timeout), &wdog->wcr);
+ hw_watchdog_reset();
+}
+#endif
+
+void reset_cpu(ulong addr)
+{
+ struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
+
+ writew(WCR_WDE, &wdog->wcr);
+ writew(0x5555, &wdog->wsr);
+ writew(0xaaaa, &wdog->wsr); /* load minimum 1/2 second timeout */
+ while (1) {
+ /*
+ * spin for .5 seconds before reset
+ */
+ }
+}
diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h
index 138a941..34e4295 100644
--- a/include/configs/mx31pdk.h
+++ b/include/configs/mx31pdk.h
@@ -61,6 +61,7 @@
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART1_BASE
#define CONFIG_HW_WATCHDOG
+#define CONFIG_IMX_WATCHDOG
#define CONFIG_MXC_GPIO
#define CONFIG_HARD_SPI
diff --git a/include/configs/qong.h b/include/configs/qong.h
index d9bf201..685c618 100644
--- a/include/configs/qong.h
+++ b/include/configs/qong.h
@@ -52,6 +52,7 @@
#define CONFIG_MXC_GPIO
#define CONFIG_HW_WATCHDOG
+#define CONFIG_IMX_WATCHDOG
#define CONFIG_MXC_SPI
#define CONFIG_DEFAULT_SPI_BUS 1
diff --git a/include/watchdog.h b/include/watchdog.h
index b959914..328a30b 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -35,6 +35,7 @@
* Hardware watchdog
*/
#ifdef CONFIG_HW_WATCHDOG
+ void hw_watchdog_init(void);
#if defined(__ASSEMBLY__)
#define WATCHDOG_RESET bl hw_watchdog_reset
#else