
--- arch/arm/cpu/arm926ejs/davinci/dm365.c | 61 ++++++++++++++++++++++++ arch/arm/include/asm/arch-davinci/timer_defs.h | 2 + board/davinci/dm365evm/dm365evm.c | 19 ++++++++ include/configs/davinci_dm365evm.h | 11 +++++ 4 files changed, 93 insertions(+)
diff --git a/arch/arm/cpu/arm926ejs/davinci/dm365.c b/arch/arm/cpu/arm926ejs/davinci/dm365.c index 56c1bc0..48f9631 100644 --- a/arch/arm/cpu/arm926ejs/davinci/dm365.c +++ b/arch/arm/cpu/arm926ejs/davinci/dm365.c @@ -20,6 +20,7 @@ */
#include <common.h> +#include <asm/io.h> #include <asm/arch/hardware.h>
void davinci_enable_uart0(void) @@ -33,3 +34,63 @@ void davinci_enable_i2c(void) lpsc_on(DAVINCI_LPSC_I2C); } #endif + +#ifdef CONFIG_HW_WATCHDOG +static struct davinci_timer * const wdttimer = + (struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE; + +/* WDTCR bit definitions */ +#define WDEN (1 << 14) +#define WDFLAG (1 << 15) +#define WDKEY_SEQ0 (0xa5c6 << 16) +#define WDKEY_SEQ1 (0xda7e << 16) + +/* TCR bit definitions */ +#define ENAMODE12_DISABLED (0 << 6) +#define ENAMODE12_ONESHOT (1 << 6) +#define ENAMODE12_PERIODIC (2 << 6) + +/* TGCR bit definitions */ +#define TIM12RS_UNRESET (1 << 0) +#define TIM34RS_UNRESET (1 << 1) +#define TIMMODE_64BIT_WDOG (2 << 2) + +void davinci_dm365_hw_watchdog_enable(void) +{ + u32 timer_margin; + ulong wdt_freq; + + /* disable, internal clock source */ + writel(0x0, &wdttimer->tcr); + /* reset timer, set mode to 64-bit watchdog, and unreset */ + writel(0x0, &wdttimer->tgcr); + writel(TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET, &wdttimer->tgcr); + /* clear counter regs */ + writel(0x0, &wdttimer->tim12); + writel(0x0, &wdttimer->tim34); + + /* set timeout period */ + wdt_freq = CONFIG_SYS_HZ_CLOCK; + printf("Setting watchdog period to %llu ticks == %is * %luHz\n",((u64)CONFIG_SYS_WDT_PERIOD_SECONDS * wdt_freq), CONFIG_SYS_WDT_PERIOD_SECONDS, wdt_freq); + timer_margin = (((u64)CONFIG_SYS_WDT_PERIOD_SECONDS * wdt_freq) & 0xffffffff); + writel(timer_margin, &wdttimer->prd12); + timer_margin = (((u64)CONFIG_SYS_WDT_PERIOD_SECONDS * wdt_freq) >> 32); + writel(timer_margin, &wdttimer->prd34); + + /* enable run continuously */ + writel(ENAMODE12_PERIODIC, &wdttimer->tcr); + + /* put watchdog in pre-active state */ + writel(WDKEY_SEQ0 | WDEN, &wdttimer->wdtcr); + /* put watchdog in active state */ + writel(WDKEY_SEQ1 | WDEN, &wdttimer->wdtcr); +} + +void davinci_dm365_hw_watchdog_reset(void) +{ + writel(WDKEY_SEQ0, &wdttimer->wdtcr); + writel(WDKEY_SEQ1, &wdttimer->wdtcr); +} + +#endif + diff --git a/arch/arm/include/asm/arch-davinci/timer_defs.h b/arch/arm/include/asm/arch-davinci/timer_defs.h index 914ae07..93f788c 100644 --- a/arch/arm/include/asm/arch-davinci/timer_defs.h +++ b/arch/arm/include/asm/arch-davinci/timer_defs.h @@ -56,5 +56,7 @@ struct davinci_timer { #ifdef CONFIG_HW_WATCHDOG void davinci_hw_watchdog_enable(void); void davinci_hw_watchdog_reset(void); +void davinci_dm365_hw_watchdog_enable(void); +void davinci_dm365_hw_watchdog_reset(void); #endif #endif /* _TIMER_DEFS_H_ */ diff --git a/board/davinci/dm365evm/dm365evm.c b/board/davinci/dm365evm/dm365evm.c index ac54106..19e3527 100644 --- a/board/davinci/dm365evm/dm365evm.c +++ b/board/davinci/dm365evm/dm365evm.c @@ -29,6 +29,9 @@ #include <mmc.h> #include <asm/arch/sdmmc_defs.h> #endif +#ifdef CONFIG_HW_WATCHDOG +#include <asm/arch/timer_defs.h> +#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -150,3 +153,19 @@ int board_mmc_init(bd_t *bis) return err; } #endif + +#ifdef CONFIG_HW_WATCHDOG +void hw_watchdog_reset(void) +{ + davinci_dm365_hw_watchdog_reset(); +} +#endif + +int misc_init_r(void) +{ +#ifdef CONFIG_HW_WATCHDOG + davinci_dm365_hw_watchdog_enable(); +#endif + return 0; +} + diff --git a/include/configs/davinci_dm365evm.h b/include/configs/davinci_dm365evm.h index a75bce6..04173b9 100644 --- a/include/configs/davinci_dm365evm.h +++ b/include/configs/davinci_dm365evm.h @@ -245,4 +245,15 @@ #define CONFIG_SYS_INIT_SP_ADDR \ (CONFIG_SYS_SDRAM_BASE + 0x1000 - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_MISC_INIT_R + +// Hardware watchdog config +#ifdef CONFIG_HW_WATCHDOG +#define CONFIG_SYS_WDTTIMERBASE 0x01C21C00 +#define CONFIG_SYS_WDT_PERIOD_SECONDS 60 +// These two are insignificant but required to build arch/arm/cpu/arm926ejs/davinci/timer.c +#define CONFIG_SYS_WDT_PERIOD_LOW 0 +#define CONFIG_SYS_WDT_PERIOD_HIGH 0 +#endif + #endif /* __CONFIG_H */