1d8c67dc6SChin Liang See /* 2d8c67dc6SChin Liang See * Copyright (C) 2013 Altera Corporation <www.altera.com> 3d8c67dc6SChin Liang See * 4d8c67dc6SChin Liang See * SPDX-License-Identifier: GPL-2.0+ 5d8c67dc6SChin Liang See */ 6d8c67dc6SChin Liang See 7d8c67dc6SChin Liang See #include <common.h> 8d8c67dc6SChin Liang See #include <watchdog.h> 9d8c67dc6SChin Liang See #include <asm/io.h> 10d8c67dc6SChin Liang See #include <asm/utils.h> 11d8c67dc6SChin Liang See 12d8c67dc6SChin Liang See #define DW_WDT_CR 0x00 13d8c67dc6SChin Liang See #define DW_WDT_TORR 0x04 14d8c67dc6SChin Liang See #define DW_WDT_CRR 0x0C 15d8c67dc6SChin Liang See 16d8c67dc6SChin Liang See #define DW_WDT_CR_EN_OFFSET 0x00 17d8c67dc6SChin Liang See #define DW_WDT_CR_RMOD_OFFSET 0x01 18d8c67dc6SChin Liang See #define DW_WDT_CR_RMOD_VAL 0x00 19d8c67dc6SChin Liang See #define DW_WDT_CRR_RESTART_VAL 0x76 20d8c67dc6SChin Liang See 21d8c67dc6SChin Liang See /* 22d8c67dc6SChin Liang See * Set the watchdog time interval. 23d8c67dc6SChin Liang See * Counter is 32 bit. 24d8c67dc6SChin Liang See */ designware_wdt_settimeout(unsigned int timeout)25d8c67dc6SChin Liang Seestatic int designware_wdt_settimeout(unsigned int timeout) 26d8c67dc6SChin Liang See { 27d8c67dc6SChin Liang See signed int i; 28d8c67dc6SChin Liang See 29d8c67dc6SChin Liang See /* calculate the timeout range value */ 30d8c67dc6SChin Liang See i = (log_2_n_round_up(timeout * CONFIG_DW_WDT_CLOCK_KHZ)) - 16; 31d8c67dc6SChin Liang See if (i > 15) 32d8c67dc6SChin Liang See i = 15; 33d8c67dc6SChin Liang See if (i < 0) 34d8c67dc6SChin Liang See i = 0; 35d8c67dc6SChin Liang See 36d8c67dc6SChin Liang See writel((i | (i << 4)), (CONFIG_DW_WDT_BASE + DW_WDT_TORR)); 37d8c67dc6SChin Liang See return 0; 38d8c67dc6SChin Liang See } 39d8c67dc6SChin Liang See designware_wdt_enable(void)40d8c67dc6SChin Liang Seestatic void designware_wdt_enable(void) 41d8c67dc6SChin Liang See { 42d8c67dc6SChin Liang See writel(((DW_WDT_CR_RMOD_VAL << DW_WDT_CR_RMOD_OFFSET) | 43d8c67dc6SChin Liang See (0x1 << DW_WDT_CR_EN_OFFSET)), 44d8c67dc6SChin Liang See (CONFIG_DW_WDT_BASE + DW_WDT_CR)); 45d8c67dc6SChin Liang See } 46d8c67dc6SChin Liang See designware_wdt_is_enabled(void)47d8c67dc6SChin Liang Seestatic unsigned int designware_wdt_is_enabled(void) 48d8c67dc6SChin Liang See { 49d8c67dc6SChin Liang See unsigned long val; 50d8c67dc6SChin Liang See val = readl((CONFIG_DW_WDT_BASE + DW_WDT_CR)); 51d8c67dc6SChin Liang See return val & 0x1; 52d8c67dc6SChin Liang See } 53d8c67dc6SChin Liang See 54d8c67dc6SChin Liang See #if defined(CONFIG_HW_WATCHDOG) hw_watchdog_reset(void)55d8c67dc6SChin Liang Seevoid hw_watchdog_reset(void) 56d8c67dc6SChin Liang See { 57d8c67dc6SChin Liang See if (designware_wdt_is_enabled()) 58d8c67dc6SChin Liang See /* restart the watchdog counter */ 59d8c67dc6SChin Liang See writel(DW_WDT_CRR_RESTART_VAL, 60d8c67dc6SChin Liang See (CONFIG_DW_WDT_BASE + DW_WDT_CRR)); 61d8c67dc6SChin Liang See } 62d8c67dc6SChin Liang See hw_watchdog_init(void)63d8c67dc6SChin Liang Seevoid hw_watchdog_init(void) 64d8c67dc6SChin Liang See { 65d8c67dc6SChin Liang See /* reset to disable the watchdog */ 66d8c67dc6SChin Liang See hw_watchdog_reset(); 67d8c67dc6SChin Liang See /* set timer in miliseconds */ 68*ea926511SAndy Shevchenko designware_wdt_settimeout(CONFIG_WATCHDOG_TIMEOUT_MSECS); 69d8c67dc6SChin Liang See /* enable the watchdog */ 70d8c67dc6SChin Liang See designware_wdt_enable(); 71d8c67dc6SChin Liang See /* reset the watchdog */ 72d8c67dc6SChin Liang See hw_watchdog_reset(); 73d8c67dc6SChin Liang See } 74d8c67dc6SChin Liang See #endif 75