105 lines
2.0 KiB
C
105 lines
2.0 KiB
C
/*
|
|
* Copyright (C) 2019 Allwinner Tech
|
|
* frank <frank@allwinnertech.com>
|
|
*/
|
|
|
|
#include <arch/watchdog.h>
|
|
|
|
static const int wdt_timeout_map[] = {
|
|
[1] = 0x1, /* 1s */
|
|
[2] = 0x2, /* 2s */
|
|
[3] = 0x3, /* 3s */
|
|
[4] = 0x4, /* 4s */
|
|
[5] = 0x5, /* 5s */
|
|
[6] = 0x6, /* 6s */
|
|
[8] = 0x7, /* 8s */
|
|
[10] = 0x8, /* 10s */
|
|
[12] = 0x9, /* 12s */
|
|
[14] = 0xA, /* 14s */
|
|
[16] = 0xB, /* 16s */
|
|
};
|
|
|
|
#if defined(CONFIG_ARCH_SUN8IW21)
|
|
void wdt_stop(void)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wtmode = readl(&wdt->mode);
|
|
wtmode &= ~WDT_MODE_EN;
|
|
|
|
writel(wtmode | KEY_FIELD, &wdt->mode);
|
|
}
|
|
|
|
void wdt_start(unsigned int timeout)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wdt_stop();
|
|
|
|
if (wdt_timeout_map[timeout] == 0)
|
|
timeout++;
|
|
|
|
wtmode = wdt_timeout_map[timeout] << 4 | WDT_MODE_EN | KEY_FIELD;
|
|
|
|
writel(WDT_CFG_RESET, &wdt->cfg);
|
|
writel(wtmode, &wdt->mode);
|
|
writel(WDT_CTRL_RELOAD, &wdt->ctl);
|
|
}
|
|
#elif !defined(CONFIG_MACH_SUN8IW11)
|
|
void wdt_stop(void)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wtmode = readl(&wdt->mode);
|
|
wtmode &= ~WDT_MODE_EN;
|
|
|
|
writel(wtmode, &wdt->mode);
|
|
}
|
|
|
|
void wdt_start(unsigned int timeout)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wdt_stop();
|
|
|
|
if (wdt_timeout_map[timeout] == 0)
|
|
timeout++;
|
|
|
|
wtmode = wdt_timeout_map[timeout] << 4 | WDT_MODE_EN;
|
|
|
|
writel(WDT_CFG_RESET, &wdt->cfg);
|
|
writel(wtmode, &wdt->mode);
|
|
}
|
|
#else
|
|
void wdt_stop(void)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wtmode = readl(&wdt->mode);
|
|
wtmode &= ~WDT_MODE_EN;
|
|
|
|
writel(wtmode, &wdt->mode);
|
|
}
|
|
|
|
void wdt_start(unsigned int timeout)
|
|
{
|
|
struct sunxi_wdog *wdt = (struct sunxi_wdog *)SUNXI_WDOG_BASE;
|
|
unsigned int wtmode;
|
|
|
|
wdt_stop();
|
|
|
|
if (wdt_timeout_map[timeout] == 0)
|
|
timeout++;
|
|
|
|
wtmode =
|
|
wdt_timeout_map[timeout] << 3 | WDT_MODE_EN | WDT_MODE_RESET_EN;
|
|
|
|
writel(wtmode, &wdt->mode);
|
|
}
|
|
#endif
|