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