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