19096963cSMacpaul Lin /* 29096963cSMacpaul Lin * Watchdog driver for the FTWDT010 Watch Dog Driver 39096963cSMacpaul Lin * 49096963cSMacpaul Lin * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) 59096963cSMacpaul Lin * Based on sa1100_wdt.c by Oleg Drokin <green@crimea.edu> 69096963cSMacpaul Lin * Based on SoftDog driver by Alan Cox <alan@redhat.com> 79096963cSMacpaul Lin * 89096963cSMacpaul Lin * Copyright (C) 2011 Andes Technology Corporation 99096963cSMacpaul Lin * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 109096963cSMacpaul Lin * 119096963cSMacpaul Lin * This program is free software; you can redistribute it and/or modify 129096963cSMacpaul Lin * it under the terms of the GNU General Public License as published by 139096963cSMacpaul Lin * the Free Software Foundation; either version 2 of the License, or 149096963cSMacpaul Lin * (at your option) any later version. 159096963cSMacpaul Lin * 169096963cSMacpaul Lin * This program is distributed in the hope that it will be useful, 179096963cSMacpaul Lin * but WITHOUT ANY WARRANTY; without even the implied warranty of 189096963cSMacpaul Lin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 199096963cSMacpaul Lin * GNU General Public License for more details. 209096963cSMacpaul Lin * 219096963cSMacpaul Lin * You should have received a copy of the GNU General Public License 229096963cSMacpaul Lin * along with this program; if not, write to the Free Software 239096963cSMacpaul Lin * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 249096963cSMacpaul Lin * 259096963cSMacpaul Lin * 27/11/2004 Initial release, Faraday. 269096963cSMacpaul Lin * 12/01/2011 Port to u-boot, Macpaul Lin. 279096963cSMacpaul Lin */ 289096963cSMacpaul Lin 299096963cSMacpaul Lin #include <common.h> 309096963cSMacpaul Lin #include <watchdog.h> 319096963cSMacpaul Lin #include <asm/io.h> 32*04c2dd82SMacpaul Lin #include <faraday/ftwdt010_wdt.h> 339096963cSMacpaul Lin 349096963cSMacpaul Lin /* 359096963cSMacpaul Lin * Set the watchdog time interval. 369096963cSMacpaul Lin * Counter is 32 bit. 379096963cSMacpaul Lin */ 38*04c2dd82SMacpaul Lin int ftwdt010_wdt_settimeout(unsigned int timeout) 399096963cSMacpaul Lin { 409096963cSMacpaul Lin unsigned int reg; 419096963cSMacpaul Lin 429096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 439096963cSMacpaul Lin 449096963cSMacpaul Lin debug("Activating WDT..\n"); 459096963cSMacpaul Lin 469096963cSMacpaul Lin /* Check if disabled */ 479096963cSMacpaul Lin if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) { 489096963cSMacpaul Lin printf("sorry, watchdog is disabled\n"); 499096963cSMacpaul Lin return -1; 509096963cSMacpaul Lin } 519096963cSMacpaul Lin 529096963cSMacpaul Lin /* 539096963cSMacpaul Lin * In a 66MHz system, 549096963cSMacpaul Lin * if you set WDLOAD as 0x03EF1480 (66000000) 559096963cSMacpaul Lin * the reset timer is 1 second. 569096963cSMacpaul Lin */ 579096963cSMacpaul Lin reg = FTWDT010_WDLOAD(timeout * FTWDT010_TIMEOUT_FACTOR); 589096963cSMacpaul Lin 599096963cSMacpaul Lin writel(reg, &wd->wdload); 609096963cSMacpaul Lin 619096963cSMacpaul Lin return 0; 629096963cSMacpaul Lin } 639096963cSMacpaul Lin 64*04c2dd82SMacpaul Lin void ftwdt010_wdt_reset(void) 659096963cSMacpaul Lin { 669096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 679096963cSMacpaul Lin 689096963cSMacpaul Lin /* clear control register */ 699096963cSMacpaul Lin writel(0, &wd->wdcr); 709096963cSMacpaul Lin 719096963cSMacpaul Lin /* Write Magic number */ 729096963cSMacpaul Lin writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart); 739096963cSMacpaul Lin 749096963cSMacpaul Lin /* Enable WDT */ 759096963cSMacpaul Lin writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr); 769096963cSMacpaul Lin } 779096963cSMacpaul Lin 78*04c2dd82SMacpaul Lin void ftwdt010_wdt_disable(void) 799096963cSMacpaul Lin { 809096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 819096963cSMacpaul Lin 829096963cSMacpaul Lin debug("Deactivating WDT..\n"); 839096963cSMacpaul Lin 849096963cSMacpaul Lin /* 859096963cSMacpaul Lin * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux 869096963cSMacpaul Lin * 879096963cSMacpaul Lin * Shut off the timer. 889096963cSMacpaul Lin * Lock it in if it's a module and we defined ...NOWAYOUT 899096963cSMacpaul Lin */ 909096963cSMacpaul Lin writel(0, &wd->wdcr); 919096963cSMacpaul Lin } 929096963cSMacpaul Lin 93*04c2dd82SMacpaul Lin #if defined(CONFIG_HW_WATCHDOG) 94*04c2dd82SMacpaul Lin void hw_watchdog_reset(void) 959096963cSMacpaul Lin { 969096963cSMacpaul Lin ftwdt010_wdt_reset(); 979096963cSMacpaul Lin } 989096963cSMacpaul Lin 999096963cSMacpaul Lin void hw_watchdog_init(void) 1009096963cSMacpaul Lin { 1019096963cSMacpaul Lin /* set timer in ms */ 1029096963cSMacpaul Lin ftwdt010_wdt_settimeout(CONFIG_FTWDT010_HW_TIMEOUT * 1000); 1039096963cSMacpaul Lin } 104*04c2dd82SMacpaul Lin #endif 105