1*9096963cSMacpaul Lin /* 2*9096963cSMacpaul Lin * Watchdog driver for the FTWDT010 Watch Dog Driver 3*9096963cSMacpaul Lin * 4*9096963cSMacpaul Lin * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) 5*9096963cSMacpaul Lin * Based on sa1100_wdt.c by Oleg Drokin <green@crimea.edu> 6*9096963cSMacpaul Lin * Based on SoftDog driver by Alan Cox <alan@redhat.com> 7*9096963cSMacpaul Lin * 8*9096963cSMacpaul Lin * Copyright (C) 2011 Andes Technology Corporation 9*9096963cSMacpaul Lin * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 10*9096963cSMacpaul Lin * 11*9096963cSMacpaul Lin * This program is free software; you can redistribute it and/or modify 12*9096963cSMacpaul Lin * it under the terms of the GNU General Public License as published by 13*9096963cSMacpaul Lin * the Free Software Foundation; either version 2 of the License, or 14*9096963cSMacpaul Lin * (at your option) any later version. 15*9096963cSMacpaul Lin * 16*9096963cSMacpaul Lin * This program is distributed in the hope that it will be useful, 17*9096963cSMacpaul Lin * but WITHOUT ANY WARRANTY; without even the implied warranty of 18*9096963cSMacpaul Lin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*9096963cSMacpaul Lin * GNU General Public License for more details. 20*9096963cSMacpaul Lin * 21*9096963cSMacpaul Lin * You should have received a copy of the GNU General Public License 22*9096963cSMacpaul Lin * along with this program; if not, write to the Free Software 23*9096963cSMacpaul Lin * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24*9096963cSMacpaul Lin * 25*9096963cSMacpaul Lin * 27/11/2004 Initial release, Faraday. 26*9096963cSMacpaul Lin * 12/01/2011 Port to u-boot, Macpaul Lin. 27*9096963cSMacpaul Lin */ 28*9096963cSMacpaul Lin 29*9096963cSMacpaul Lin #include <common.h> 30*9096963cSMacpaul Lin #include <watchdog.h> 31*9096963cSMacpaul Lin #include <asm/io.h> 32*9096963cSMacpaul Lin #include "ftwdt010_wdt.h" 33*9096963cSMacpaul Lin 34*9096963cSMacpaul Lin /* 35*9096963cSMacpaul Lin * Set the watchdog time interval. 36*9096963cSMacpaul Lin * Counter is 32 bit. 37*9096963cSMacpaul Lin */ 38*9096963cSMacpaul Lin static int ftwdt010_wdt_settimeout(unsigned int timeout) 39*9096963cSMacpaul Lin { 40*9096963cSMacpaul Lin unsigned int reg; 41*9096963cSMacpaul Lin 42*9096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 43*9096963cSMacpaul Lin 44*9096963cSMacpaul Lin debug("Activating WDT..\n"); 45*9096963cSMacpaul Lin 46*9096963cSMacpaul Lin /* Check if disabled */ 47*9096963cSMacpaul Lin if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) { 48*9096963cSMacpaul Lin printf("sorry, watchdog is disabled\n"); 49*9096963cSMacpaul Lin return -1; 50*9096963cSMacpaul Lin } 51*9096963cSMacpaul Lin 52*9096963cSMacpaul Lin /* 53*9096963cSMacpaul Lin * In a 66MHz system, 54*9096963cSMacpaul Lin * if you set WDLOAD as 0x03EF1480 (66000000) 55*9096963cSMacpaul Lin * the reset timer is 1 second. 56*9096963cSMacpaul Lin */ 57*9096963cSMacpaul Lin reg = FTWDT010_WDLOAD(timeout * FTWDT010_TIMEOUT_FACTOR); 58*9096963cSMacpaul Lin 59*9096963cSMacpaul Lin writel(reg, &wd->wdload); 60*9096963cSMacpaul Lin 61*9096963cSMacpaul Lin return 0; 62*9096963cSMacpaul Lin } 63*9096963cSMacpaul Lin 64*9096963cSMacpaul Lin void ftwdt010_wdt_reset() 65*9096963cSMacpaul Lin { 66*9096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 67*9096963cSMacpaul Lin 68*9096963cSMacpaul Lin /* clear control register */ 69*9096963cSMacpaul Lin writel(0, &wd->wdcr); 70*9096963cSMacpaul Lin 71*9096963cSMacpaul Lin /* Write Magic number */ 72*9096963cSMacpaul Lin writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart); 73*9096963cSMacpaul Lin 74*9096963cSMacpaul Lin /* Enable WDT */ 75*9096963cSMacpaul Lin writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr); 76*9096963cSMacpaul Lin } 77*9096963cSMacpaul Lin 78*9096963cSMacpaul Lin void ftwdt010_wdt_disable() 79*9096963cSMacpaul Lin { 80*9096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 81*9096963cSMacpaul Lin 82*9096963cSMacpaul Lin debug("Deactivating WDT..\n"); 83*9096963cSMacpaul Lin 84*9096963cSMacpaul Lin /* 85*9096963cSMacpaul Lin * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux 86*9096963cSMacpaul Lin * 87*9096963cSMacpaul Lin * Shut off the timer. 88*9096963cSMacpaul Lin * Lock it in if it's a module and we defined ...NOWAYOUT 89*9096963cSMacpaul Lin */ 90*9096963cSMacpaul Lin writel(0, &wd->wdcr); 91*9096963cSMacpaul Lin } 92*9096963cSMacpaul Lin 93*9096963cSMacpaul Lin void hw_watchdog_reset() 94*9096963cSMacpaul Lin { 95*9096963cSMacpaul Lin ftwdt010_wdt_reset(); 96*9096963cSMacpaul Lin } 97*9096963cSMacpaul Lin 98*9096963cSMacpaul Lin void hw_watchdog_init(void) 99*9096963cSMacpaul Lin { 100*9096963cSMacpaul Lin /* set timer in ms */ 101*9096963cSMacpaul Lin ftwdt010_wdt_settimeout(CONFIG_FTWDT010_HW_TIMEOUT * 1000); 102*9096963cSMacpaul Lin } 103