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>
This commit is contained in:
Troy Kisky 2012-10-22 15:19:01 +00:00 committed by Stefano Babic
parent 17c5ef2007
commit abbab70363
16 changed files with 106 additions and 101 deletions

View File

@ -161,42 +161,3 @@ ulong get_tbclk(void)
{
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

View File

@ -488,12 +488,6 @@ int get_clocks(void)
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

View File

@ -175,11 +175,6 @@ int cpu_mmc_init(bd_t *bis)
}
#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;

View File

@ -58,7 +58,5 @@ extern void mx31_set_gpr(enum iomux_gp_func gp, char en);
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 */

View File

@ -68,17 +68,6 @@ struct cspi_regs {
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 @@ struct esdc_regs {
#define ARM_PPMRR 0x40000015
#define WDOG_BASE 0x53FDC000
#define WDOG1_BASE_ADDR 0x53FDC000
/*
* GPIO

View File

@ -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 @@ struct cspi_regs {
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;

View File

@ -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

View File

@ -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 @@ int board_late_init(void)
pmic_reg_write(p, REG_INT_STATUS1, RTCRSTI);
#ifdef CONFIG_HW_WATCHDOG
mxc_hw_watchdog_enable();
hw_watchdog_init();
#endif
return 0;

View File

@ -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 @@ int board_late_init(void)
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;
}

View File

@ -179,7 +179,7 @@ int board_init(void)
int board_late_init(void)
{
#ifdef CONFIG_HW_WATCHDOG
mxc_hw_watchdog_enable();
hw_watchdog_init();
#endif
return 0;

29
doc/README.watchdog Normal file
View File

@ -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.

View File

@ -27,6 +27,9 @@ LIB := $(obj)libwatchdog.o
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

View File

@ -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
*/
}
}

View File

@ -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

View File

@ -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

View File

@ -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