1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 29096963cSMacpaul Lin /* 39096963cSMacpaul Lin * Watchdog driver for the FTWDT010 Watch Dog Driver 49096963cSMacpaul Lin * 59096963cSMacpaul Lin * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) 69096963cSMacpaul Lin * Based on sa1100_wdt.c by Oleg Drokin <green@crimea.edu> 79096963cSMacpaul Lin * Based on SoftDog driver by Alan Cox <alan@redhat.com> 89096963cSMacpaul Lin * 99096963cSMacpaul Lin * Copyright (C) 2011 Andes Technology Corporation 109096963cSMacpaul Lin * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com> 119096963cSMacpaul Lin * 129096963cSMacpaul Lin * 27/11/2004 Initial release, Faraday. 139096963cSMacpaul Lin * 12/01/2011 Port to u-boot, Macpaul Lin. 149096963cSMacpaul Lin */ 159096963cSMacpaul Lin 169096963cSMacpaul Lin #include <common.h> 179096963cSMacpaul Lin #include <watchdog.h> 189096963cSMacpaul Lin #include <asm/io.h> 1904c2dd82SMacpaul Lin #include <faraday/ftwdt010_wdt.h> 209096963cSMacpaul Lin 219096963cSMacpaul Lin /* 229096963cSMacpaul Lin * Set the watchdog time interval. 239096963cSMacpaul Lin * Counter is 32 bit. 249096963cSMacpaul Lin */ 2504c2dd82SMacpaul Lin int ftwdt010_wdt_settimeout(unsigned int timeout) 269096963cSMacpaul Lin { 279096963cSMacpaul Lin unsigned int reg; 289096963cSMacpaul Lin 299096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 309096963cSMacpaul Lin 319096963cSMacpaul Lin debug("Activating WDT..\n"); 329096963cSMacpaul Lin 339096963cSMacpaul Lin /* Check if disabled */ 349096963cSMacpaul Lin if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) { 359096963cSMacpaul Lin printf("sorry, watchdog is disabled\n"); 369096963cSMacpaul Lin return -1; 379096963cSMacpaul Lin } 389096963cSMacpaul Lin 399096963cSMacpaul Lin /* 409096963cSMacpaul Lin * In a 66MHz system, 419096963cSMacpaul Lin * if you set WDLOAD as 0x03EF1480 (66000000) 429096963cSMacpaul Lin * the reset timer is 1 second. 439096963cSMacpaul Lin */ 449096963cSMacpaul Lin reg = FTWDT010_WDLOAD(timeout * FTWDT010_TIMEOUT_FACTOR); 459096963cSMacpaul Lin 469096963cSMacpaul Lin writel(reg, &wd->wdload); 479096963cSMacpaul Lin 489096963cSMacpaul Lin return 0; 499096963cSMacpaul Lin } 509096963cSMacpaul Lin 5104c2dd82SMacpaul Lin void ftwdt010_wdt_reset(void) 529096963cSMacpaul Lin { 539096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 549096963cSMacpaul Lin 559096963cSMacpaul Lin /* clear control register */ 569096963cSMacpaul Lin writel(0, &wd->wdcr); 579096963cSMacpaul Lin 589096963cSMacpaul Lin /* Write Magic number */ 599096963cSMacpaul Lin writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart); 609096963cSMacpaul Lin 619096963cSMacpaul Lin /* Enable WDT */ 629096963cSMacpaul Lin writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr); 639096963cSMacpaul Lin } 649096963cSMacpaul Lin 6504c2dd82SMacpaul Lin void ftwdt010_wdt_disable(void) 669096963cSMacpaul Lin { 679096963cSMacpaul Lin struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; 689096963cSMacpaul Lin 699096963cSMacpaul Lin debug("Deactivating WDT..\n"); 709096963cSMacpaul Lin 719096963cSMacpaul Lin /* 729096963cSMacpaul Lin * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux 739096963cSMacpaul Lin * 749096963cSMacpaul Lin * Shut off the timer. 759096963cSMacpaul Lin * Lock it in if it's a module and we defined ...NOWAYOUT 769096963cSMacpaul Lin */ 779096963cSMacpaul Lin writel(0, &wd->wdcr); 789096963cSMacpaul Lin } 799096963cSMacpaul Lin 8004c2dd82SMacpaul Lin #if defined(CONFIG_HW_WATCHDOG) 8104c2dd82SMacpaul Lin void hw_watchdog_reset(void) 829096963cSMacpaul Lin { 839096963cSMacpaul Lin ftwdt010_wdt_reset(); 849096963cSMacpaul Lin } 859096963cSMacpaul Lin 869096963cSMacpaul Lin void hw_watchdog_init(void) 879096963cSMacpaul Lin { 889096963cSMacpaul Lin /* set timer in ms */ 899096963cSMacpaul Lin ftwdt010_wdt_settimeout(CONFIG_FTWDT010_HW_TIMEOUT * 1000); 909096963cSMacpaul Lin } 9104c2dd82SMacpaul Lin #endif 92