From patchwork Tue Jan 4 13:32:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Macpaul Lin X-Patchwork-Id: 77464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id C35A4B7102 for ; Wed, 5 Jan 2011 00:32:04 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 77039282B2; Tue, 4 Jan 2011 14:31:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9rDIoapWwzid; Tue, 4 Jan 2011 14:31:59 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4E78928297; Tue, 4 Jan 2011 14:31:57 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 78D0828297 for ; Tue, 4 Jan 2011 14:31:55 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1NegKyC7kyZD for ; Tue, 4 Jan 2011 14:31:53 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from ATCPCS06.andestech.com (59-124-160-117.HINET-IP.hinet.net [59.124.160.117]) by theia.denx.de (Postfix) with ESMTP id 06FE228292 for ; Tue, 4 Jan 2011 14:31:48 +0100 (CET) Received: from andestech.com ([10.0.4.31]) by ATCPCS06.andestech.com with Microsoft SMTPSVC(6.0.3790.4675); Tue, 4 Jan 2011 21:32:19 +0800 From: Macpaul Lin To: u-boot@lists.denx.de, wd@denx.de, vapier@gentoo.org Date: Tue, 4 Jan 2011 21:32:14 +0800 Message-Id: <1294147934-6742-1-git-send-email-macpaul@andestech.com> X-Mailer: git-send-email 1.7.3.2 MIME-Version: 1.0 X-OriginalArrivalTime: 04 Jan 2011 13:32:19.0817 (UTC) FILETIME=[CFA3DD90:01CBAC13] Cc: Macpaul Lin Subject: [U-Boot] =?utf-8?q?=5BPATCH_1/4=5D_ftwdt010=5Fwdt=3A_support_fara?= =?utf-8?q?day_ftwdt010_watchdog?= X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Faraday ftwdt010 watchdog is an architecture independant watchdog. It is usaually used in SoC chip design. Signed-off-by: Macpaul Lin --- drivers/watchdog/Makefile | 1 + drivers/watchdog/ftwdt010_wdt.c | 95 ++++++++++++++++++++++++++++++++++++++ drivers/watchdog/ftwdt010_wdt.h | 96 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 0 deletions(-) create mode 100644 drivers/watchdog/ftwdt010_wdt.c create mode 100644 drivers/watchdog/ftwdt010_wdt.h diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 6ab4d52..5579bf2 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libwatchdog.o COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o +COBJS-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c new file mode 100644 index 0000000..8571f15 --- /dev/null +++ b/drivers/watchdog/ftwdt010_wdt.c @@ -0,0 +1,95 @@ +/* + * [origin: Linux kernel drivers/watchdog/ftwdt010_wdt.c] + * + * Watchdog driver for the FTWDT010 Watch Dog Driver + * + * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) + * Based on sa1100_wdt.c by Oleg Drokin + * Based on SoftDog driver by Alan Cox + * + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * 27/11/2004 Initial release, Faraday. + * 12/01/2011 Port to u-boot, Macpaul Lin. + */ + +#include +#include +#include +#include "ftwdt010_wdt.h" + +/* + * Set the watchdog time interval. + * Counter is 32 bit. + */ +static int ftwdt010_wdt_settimeout(unsigned int timeout) +{ + unsigned int reg; + + struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; + + debug("Activating WDT..\n"); + + /* Check if disabled */ + if (readl(&wd->wdcr) & ~FTWDT010_WDCR_ENABLE) { + printf("sorry, watchdog is disabled\n"); + return -1; + } + + /* + * In a 66MHz system, + * if you set WDLOAD as 0x03EF1480 (66000000) + * the reset timer is 1 second. + */ + reg = FTWDT010_WDLOAD(timeout * FTWDT010_TIMEOUT_FACTOR); + + writel(reg, &wd->wdload); + + return 0; +} + +void ftwdt010_wdt_reset() +{ + struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; + + /* clear control register */ + writel(0, &wd->wdcr); + + /* Write Magic number */ + writel(FTWDT010_WDRESTART_MAGIC, &wd->wdrestart); + + /* Enable WDT */ + writel((FTWDT010_WDCR_RST | FTWDT010_WDCR_ENABLE), &wd->wdcr); +} + +void ftwdt010_wdt_disable() +{ + struct ftwdt010_wdt *wd = (struct ftwdt010_wdt *)CONFIG_FTWDT010_BASE; + + debug("Deactivating WDT..\n"); + + /* + * It was defined with CONFIG_WATCHDOG_NOWAYOUT in Linux + * + * Shut off the timer. + * Lock it in if it's a module and we defined ...NOWAYOUT + */ + writel(0, &wd->wdcr); +} + +void hw_watchdog_reset() +{ + ftwdt010_wdt_reset(); +} + +void hw_watchdog_init(void) +{ + /* set timer in ms */ + ftwdt010_wdt_settimeout(CONFIG_FTWDT010_HW_TIMEOUT * 1000); +} diff --git a/drivers/watchdog/ftwdt010_wdt.h b/drivers/watchdog/ftwdt010_wdt.h new file mode 100644 index 0000000..00daec5 --- /dev/null +++ b/drivers/watchdog/ftwdt010_wdt.h @@ -0,0 +1,96 @@ +/* + * [origin: Linux kernel drivers/watchdog/ftwdt010_wdt.c] + * + * Watchdog driver for the FTWDT010 Watch Dog Driver + * + * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) + * Based on sa1100_wdt.c by Oleg Drokin + * Based on SoftDog driver by Alan Cox + * + * Copyright (C) 2011 Andes Technology Corporation + * Macpaul Lin, Andes Technology Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * 27/11/2004 Initial release, Faraday. + * 12/01/2011 Port to u-boot, Macpaul Lin. + */ + +#ifndef __FTWDT010_H +#define __FTWDT010_H + +struct ftwdt010_wdt { + unsigned int wdcounter; /* Counter Reg - 0x00 */ + unsigned int wdload; /* Counter Auto Reload Reg - 0x04 */ + unsigned int wdrestart; /* Counter Restart Reg - 0x08 */ + unsigned int wdcr; /* Control Reg - 0x0c */ + unsigned int wdstatus; /* Status Reg - 0x10 */ + unsigned int wdclear; /* Timer Clear - 0x14 */ + unsigned int wdintrlen; /* Interrupt Length - 0x18 */ +}; + +/* + * WDLOAD - Counter Auto Reload Register + * The Auto Reload Register is set to 0x03EF1480 (66Mhz) by default. + * Which means in a 66MHz system, the period of Watch Dog timer reset is + * one second. + */ +#define FTWDT010_WDLOAD(x) ((x) & 0xffffffff) + +/* + * WDRESTART - Watch Dog Timer Counter Restart Register + * If writing 0x5AB9 to WDRESTART register, Watch Dog timer will + * automatically reload WDLOAD to WDCOUNTER and restart counting. + */ +#define FTWDT010_WDRESTART_MAGIC 0x5AB9 + +/* WDCR - Watch Dog Timer Control Register */ +#define FTWDT010_WDCR_ENABLE (1 << 0) +#define FTWDT010_WDCR_RST (1 << 1) +#define FTWDT010_WDCR_INTR (1 << 2) +/* FTWDT010_WDCR_EXT bit: Watch Dog Timer External Signal Enable */ +#define FTWDT010_WDCR_EXT (1 << 3) +/* FTWDT010_WDCR_CLOCK bit: Clock Source: 0: PCLK, 1: EXTCLK. + * The clock source PCLK cannot be gated when system sleeps, even if + * WDCLOCK bit is turned on. + * + * Faraday’s Watch Dog timer can be driven by an external clock. The + * programmer just needs to write one to WdCR[WdClock] bit. + * + * Note: There is a limitation between EXTCLK and PCLK: + * EXTCLK cycle time / PCLK cycle time > 2. + * If the system does not need an external clock, + * just keep WdCR[WdClock] bit in its default value. + */ +#define FTWDT010_WDCR_CLOCK (1 << 4) + +/* + * WDSTATUS - Watch Dog Timer Status Register + * This bit is set when the counter reaches Zero + */ +#define FTWDT010_WDSTATUS(x) ((x) & 0x1) + +/* + * WDCLEAR - Watch Dog Timer Clear Register + * Writing one to this register will clear WDSTATUS. + */ +#define FTWDT010_WDCLEAR (1 << 0) + +/* + * WDINTRLEN - Watch Dog Timer Interrupt Length + * This register controls the duration length of wd_rst, wd_intr and wd_ext. + * The default value is 0xFF. + */ +#define FTWDT010_WDINTRLEN(x) ((x) & 0xff) + +/* + * Variable timeout should be set in ms. + * (CONFIG_SYS_CLK_FREQ/1000) equals 1 ms. + * WDLOAD = timeout * TIMEOUT_FACTOR. + */ +#define FTWDT010_TIMEOUT_FACTOR (CONFIG_SYS_CLK_FREQ / 1000) /* 1 ms */ + +#endif /* __FTWDT010_H */