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