From patchwork Wed Apr 14 18:45:00 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyril Chemparathy X-Patchwork-Id: 92463 Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3EIns9R002078 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 14 Apr 2010 18:50:32 GMT Received: from dlep34.itg.ti.com ([157.170.170.115]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id o3EIlnL7020083 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 14 Apr 2010 13:47:49 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep34.itg.ti.com (8.13.7/8.13.7) with ESMTP id o3EIllIb009022; Wed, 14 Apr 2010 13:47:48 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id CD49C806A8; Wed, 14 Apr 2010 13:46:58 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dlep33.itg.ti.com (dlep33.itg.ti.com [157.170.170.112]) by linux.omap.com (Postfix) with ESMTP id CC8A68062B for ; Wed, 14 Apr 2010 13:45:10 -0500 (CDT) Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id o3EIj7Pp025469; Wed, 14 Apr 2010 13:45:08 -0500 (CDT) Received: from gtrgwdeb (gtrgwdeb.telogy.design.ti.com [158.218.102.24]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id o3EIj7Z05947; Wed, 14 Apr 2010 13:45:07 -0500 (CDT) Received: by gtrgwdeb (Postfix, from userid 39959) id 96E9B1E067B; Wed, 14 Apr 2010 14:45:06 -0400 (EDT) From: Cyril Chemparathy To: davinci-linux-open-source@linux.davincidsp.com Subject: [PATCH v3 14/16] Davinci: tnetv107x watchdog reset support Date: Wed, 14 Apr 2010 14:45:00 -0400 Message-Id: <1271270702-28307-15-git-send-email-cyril@ti.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1271270702-28307-14-git-send-email-cyril@ti.com> References: <1271270702-28307-1-git-send-email-cyril@ti.com> <1271270702-28307-2-git-send-email-cyril@ti.com> <1271270702-28307-3-git-send-email-cyril@ti.com> <1271270702-28307-4-git-send-email-cyril@ti.com> <1271270702-28307-5-git-send-email-cyril@ti.com> <1271270702-28307-6-git-send-email-cyril@ti.com> <1271270702-28307-7-git-send-email-cyril@ti.com> <1271270702-28307-8-git-send-email-cyril@ti.com> <1271270702-28307-9-git-send-email-cyril@ti.com> <1271270702-28307-10-git-send-email-cyril@ti.com> <1271270702-28307-11-git-send-email-cyril@ti.com> <1271270702-28307-12-git-send-email-cyril@ti.com> <1271270702-28307-13-git-send-email-cyril@ti.com> <1271270702-28307-14-git-send-email-cyril@ti.com> Cc: sshtylyov@mvista.com X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Greylist: Sender succeeded STARTTLS authentication, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 14 Apr 2010 18:50:33 +0000 (UTC) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index ab54c91..43cd2ea 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -26,6 +26,7 @@ #define TNETV107X_TPCC_BASE 0x01c00000 #define TNETV107X_TPTC0_BASE 0x01c10000 #define TNETV107X_TPTC1_BASE 0x01c10400 +#define TNETV107X_WDOG_BASE 0x08086700 /* TNETV107X specific EDMA3 information */ #define EDMA_TNETV107X_NUM_DMACH 64 @@ -103,11 +104,31 @@ static struct platform_device edma_device = { .dev.platform_data = edma_info, }; +static struct resource wdt_resources[] = { + { + .start = TNETV107X_WDOG_BASE, + .end = TNETV107X_WDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device tnetv107x_wdt_device = { + .name = "watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + void __init tnetv107x_edma_init(void) { platform_device_register(&edma_device); } +void __init tnetv107x_watchdog_init(void) +{ + platform_device_register(&tnetv107x_wdt_device); +} + void __init tnetv107x_serial_init(struct plat_serial8250_port* ports) { int i; diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h index 90be3f6..141d910 100644 --- a/arch/arm/mach-davinci/include/mach/system.h +++ b/arch/arm/mach-davinci/include/mach/system.h @@ -16,8 +16,10 @@ extern struct platform_device davinci_wdt_device; extern struct platform_device da8xx_wdt_device; +extern struct platform_device tnetv107x_wdt_device; extern void davinci_watchdog_reset(struct platform_device *); +extern void tnetv107x_watchdog_reset(struct platform_device *); static inline void arch_idle(void) { @@ -31,6 +33,9 @@ static inline void arch_reset(char mode, const char *cmd) if (cpu_class_is_da8xx()) davinci_watchdog_reset(&da8xx_wdt_device); + + if (cpu_class_is_tnetv107x()) + tnetv107x_watchdog_reset(&tnetv107x_wdt_device); } #endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 5eafdb8..0ad5466 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -59,6 +59,7 @@ extern void __init tnetv107x_init(void); extern void __init tnetv107x_gpio_init(void); extern void __init tnetv107x_edma_init(void); +extern void __init tnetv107x_watchdog_init(void); extern void __init tnetv107x_irq_init(void); extern void __init tnetv107x_serial_init(struct plat_serial8250_port* ports); #endif diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index a444ef7..fc5085d 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -81,6 +81,18 @@ struct sspll_regs { u32 diag; }; +/* Watchdog Timer Registers */ +struct wdt_regs { + u32 kick_lock; + u32 kick; + u32 change_lock; + u32 change ; + u32 disable_lock; + u32 disable; + u32 prescale_lock; + u32 prescale; +}; + static struct clk_ctrl_regs __iomem *clk_ctrl_regs; static struct sspll_regs __iomem *sspll_regs[N_PLLS]; @@ -1173,3 +1185,98 @@ static unsigned long clk_sspll_recalc(struct clk *clk) return ret; } + +static int tnetv107x_wdt_set_period(struct wdt_regs __iomem *regs, + unsigned long msec, unsigned long refclk) +{ + unsigned long change; + unsigned long count; + unsigned long prescale = 1; + + refclk /= 1000; + + /* compute prescale and change reg values */ + count = refclk * msec; + + if (count > 0xffff) { + change = count / 0xffff + 1; + prescale = count / change; + } else { + change = count; + } + + __raw_writel(0x5a5a, ®s->prescale_lock); + if ((__raw_readl(®s->prescale_lock) & 0x3) != 1) + return -EIO; + + __raw_writel(0xa5a5, ®s->prescale_lock); + if ((__raw_readl(®s->prescale_lock) & 0x3) != 3) + return -EIO; + + __raw_writel(prescale - 1, ®s->prescale); + + __raw_writel(0x6666, ®s->change_lock); + if ((__raw_readl(®s->change_lock) & 0x3) != 1) + return -EIO; + + __raw_writel(0xbbbb, ®s->change_lock); + if ((__raw_readl(®s->change_lock) & 0x3) != 3) + return -EIO; + + __raw_writel(change, ®s->change); + return 0; +} + +static int tnetv107x_wdt_ctrl(struct wdt_regs __iomem *regs, int enable) +{ + + enable = enable ? 1 : 0; + + __raw_writel(0x7777, ®s->disable_lock); + if ((__raw_readl(®s->disable_lock) & 0x3) != 1) + return -EIO; + + __raw_writel(0xcccc, ®s->disable_lock); + if ((__raw_readl(®s->disable_lock) & 0x3) != 2) + return -EIO; + + __raw_writel(0xdddd, ®s->disable_lock); + if ((__raw_readl(®s->disable_lock) & 0x3) != 3) + return -EIO; + + __raw_writel(enable, ®s->disable); + return 0; +} + +static int tnetv107x_wdt_kick(struct wdt_regs __iomem *regs) +{ + __raw_writel(0x5555, ®s->kick_lock); + if ((__raw_readl(®s->kick_lock) & 0x3) != 1) + return -EIO; + + __raw_writel(0xaaaa, ®s->kick_lock); + if ((__raw_readl(®s->kick_lock) & 0x3) != 3) + return -EIO; + + __raw_writel(1, ®s->kick); + return 0; +} + +void tnetv107x_watchdog_reset(struct platform_device *pdev) +{ + struct wdt_regs __iomem *regs; + struct clk *wdt_clk; + unsigned long wdt_clk_rate; + + regs = ioremap(pdev->resource[0].start, SZ_4K); + wdt_clk = clk_get(&pdev->dev, NULL); + if (WARN_ON(IS_ERR(wdt_clk))) + return; + clk_enable(wdt_clk); + wdt_clk_rate = clk_get_rate(wdt_clk); + + tnetv107x_wdt_ctrl(regs, 0); + tnetv107x_wdt_set_period(regs, 1, wdt_clk_rate); + tnetv107x_wdt_ctrl(regs, 1); + tnetv107x_wdt_kick(regs); +}