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:
parent
17c5ef2007
commit
abbab70363
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
29
doc/README.watchdog
Normal 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.
|
@ -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
|
||||
|
||||
|
66
drivers/watchdog/imx_watchdog.c
Normal file
66
drivers/watchdog/imx_watchdog.c
Normal 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
|
||||
*/
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user