93 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0
 | |
| /*
 | |
|  * Watchdog driver for Novatek IVOT SoCs
 | |
|  *
 | |
|  * Copyright (C) 2020 Novatek Inc.
 | |
|  * Author: Howard Chang
 | |
|  */
 | |
| 
 | |
| #include <common.h>
 | |
| #include <dm.h>
 | |
| #include <wdt.h>
 | |
| #include <asm/io.h>
 | |
| #include <asm/nvt-common/rcw_macro.h>
 | |
| #include <asm/arch/IOAddress.h>
 | |
| 
 | |
| #define WDT_REG_ADDR(ofs)       (IOADDR_WDT_REG_BASE+(ofs))
 | |
| #define WDT_GETREG(ofs)         INW(WDT_REG_ADDR(ofs))
 | |
| #define WDT_SETREG(ofs,value)   OUTW(WDT_REG_ADDR(ofs), (value))
 | |
| 
 | |
| #define CG_REG_ADDR(ofs)       (IOADDR_CG_REG_BASE+(ofs))
 | |
| #define CG_GETREG(ofs)         INW(CG_REG_ADDR(ofs))
 | |
| #define CG_SETREG(ofs,value)   OUTW(CG_REG_ADDR(ofs), (value))
 | |
| 
 | |
| #if defined(CONFIG_TARGET_NA51090) || defined(CONFIG_TARGET_NA51090_A64)
 | |
| #define CG_ENABLE_OFS 0x7C
 | |
| #define CG_RESET_OFS 0x9C
 | |
| #define WDT_POS (1 << 4)
 | |
| #define WDT_RST (1 << 12)
 | |
| 
 | |
| #define WDT_CLK_DIV	(2048)
 | |
| #define WDT_TIMEOUT_MAX	(178)
 | |
| 
 | |
| #else
 | |
| 
 | |
| #define CG_ENABLE_OFS 0x74
 | |
| #define CG_RESET_OFS 0x84
 | |
| #define WDT_POS (1 << 17)
 | |
| #define WDT_RST (1 << 17)
 | |
| 
 | |
| #define WDT_CLK_DIV	(1024)
 | |
| #define WDT_TIMEOUT_MAX	(89)
 | |
| #endif
 | |
| 
 | |
| #define WDT_CTRL_OFS 0x0
 | |
| #define WDT_TRIG_OFS 0x8
 | |
| 
 | |
| static void nvtviot_wdt_init(void)
 | |
| {
 | |
| 	u32 reg_value;
 | |
| 	u32 timeout, timeout_unit = CONFIG_NVT_WDT_TIMEOUT;
 | |
| 
 | |
| 	reg_value = CG_GETREG(CG_ENABLE_OFS);
 | |
| 	CG_SETREG(CG_ENABLE_OFS, reg_value | WDT_POS);
 | |
| 
 | |
| 	reg_value = CG_GETREG(CG_RESET_OFS);
 | |
| 	CG_SETREG(CG_RESET_OFS, reg_value | WDT_RST);
 | |
| 
 | |
| 	if ((timeout_unit > WDT_TIMEOUT_MAX) || !timeout_unit) {
 | |
| 		printf("invalid timer config %d, set to %ds\n", timeout_unit, WDT_TIMEOUT_MAX);
 | |
| 		timeout = 0xFF;
 | |
| 	} else {
 | |
| 		timeout = (timeout_unit * 12000000 / WDT_CLK_DIV) >> 12;
 | |
| 	}
 | |
| 
 | |
| 	reg_value = (0x5A960012 | (timeout << 8));
 | |
| 
 | |
| 	WDT_SETREG(WDT_CTRL_OFS, reg_value);
 | |
| 
 | |
| 	udelay(80);
 | |
| 
 | |
| 	WDT_SETREG(WDT_CTRL_OFS, reg_value | 0x1);
 | |
| }
 | |
| 
 | |
| static void nvtviot_wdt_reset(void)
 | |
| {
 | |
| #ifndef CONFIG_WATCHDOG_RESET_DISABLE
 | |
| 	/*Kick the dog*/
 | |
| 	WDT_SETREG(WDT_TRIG_OFS, 0x1);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| #if defined(CONFIG_HW_WATCHDOG)
 | |
| void hw_watchdog_reset(void)
 | |
| {
 | |
| 	nvtviot_wdt_reset();
 | |
| }
 | |
| 
 | |
| void hw_watchdog_init(void)
 | |
| {
 | |
| 	nvtviot_wdt_init();
 | |
| }
 | |
| #endif
 | 
