00001
00041 #include <debug.h>
00042 #include <io.h>
00043 #include <util.h>
00044 #include <watchdog.h>
00045 #include <chip/clk.h>
00046
00047 #define WDT_CTRL 0x00
00048 # define WDT_CTRL_KEY1 (0x55 << 24)
00049 # define WDT_CTRL_KEY2 (0xaa << 24)
00050 # define WDT_CTRL_PSEL(x) ((x) << 8)
00051 # define WDT_CTRL_EN (1 << 0)
00052 #define WDT_CLR 0x04
00053
00054
00058 #define wdt_read_reg(reg) \
00059 mmio_read32((void *)(WDT_BASE + WDT_##reg))
00060
00065 #define wdt_write_reg(reg, val) \
00066 mmio_write32((void *)(WDT_BASE + WDT_##reg), val)
00067
00077 void watchdog_set_timeout(unsigned long timeout_ms)
00078 {
00079 unsigned long cycles;
00080 unsigned int psel;
00081
00082 cycles = (PM_RCOSC_MAX_RATE * timeout_ms) / 1000;
00083 psel = ilog2(cycles);
00084
00085 dbg_info("WDT: setting %lu ms timeout (requested %lu ms; psel=%u)\n",
00086 ((1UL << (psel + 1)) * 1000) / PM_RCOSC_MAX_RATE,
00087 timeout_ms, psel);
00088
00089 wdt_write_reg(CTRL, WDT_CTRL_KEY1 | WDT_CTRL_PSEL(psel));
00090 wdt_write_reg(CTRL, WDT_CTRL_KEY2 | WDT_CTRL_PSEL(psel));
00091 }
00092
00100 void watchdog_enable(void)
00101 {
00102 uint32_t ctrl;
00103
00104 ctrl = wdt_read_reg(CTRL) | WDT_CTRL_EN;
00105 wdt_write_reg(CTRL, WDT_CTRL_KEY1 | ctrl);
00106 wdt_write_reg(CTRL, WDT_CTRL_KEY2 | ctrl);
00107 }
00108
00115 void watchdog_disable(void)
00116 {
00117 uint32_t ctrl;
00118
00119 ctrl = wdt_read_reg(CTRL) & ~WDT_CTRL_EN;
00120 wdt_write_reg(CTRL, WDT_CTRL_KEY1 | ctrl);
00121 wdt_write_reg(CTRL, WDT_CTRL_KEY2 | ctrl);
00122 }
00123
00131 void watchdog_reset(void)
00132 {
00133 wdt_write_reg(CLR, 0);
00134 }