From patchwork Thu Dec 2 13:57:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Thompson X-Patchwork-Id: 73973 X-Patchwork-Delegate: s-paulraj@ti.com 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 64939B6EF0 for ; Fri, 3 Dec 2010 00:57:45 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7D4DF28102; Thu, 2 Dec 2010 14:57:42 +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 6nVNuhPerMpV; Thu, 2 Dec 2010 14:57:42 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E8C90280D9; Thu, 2 Dec 2010 14:57:40 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 519C4280D9 for ; Thu, 2 Dec 2010 14:57:38 +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 wkOppOVpCkQ1 for ; Thu, 2 Dec 2010 14:57:33 +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 exprod5og110.obsmtp.com (exprod5og110.obsmtp.com [64.18.0.20]) by theia.denx.de (Postfix) with ESMTPS id 0A8A7280C4 for ; Thu, 2 Dec 2010 14:57:30 +0100 (CET) Received: from source ([12.43.191.1]) (using TLSv1) by exprod5ob110.postini.com ([64.18.4.12]) with SMTP ID DSNKTPelyFqCVisPvacvgxq1wAKj33pb5xoS@postini.com; Thu, 02 Dec 2010 05:57:33 PST Received: from unknown (HELO cinmlef06.e2k.ad.ge.com) ([3.159.213.37]) by Alpmlip04.e2k.ad.ge.com with ESMTP; 02 Dec 2010 08:57:27 -0500 Received: from [3.138.53.78] ([3.138.53.78]) by cinmlef06.e2k.ad.ge.com with Microsoft SMTPSVC(6.0.3790.4675); Thu, 2 Dec 2010 08:57:27 -0500 Message-ID: <4CF7A5C4.6010303@ge.com> Date: Thu, 02 Dec 2010 13:57:24 +0000 From: Nick Thompson User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.2.12) Gecko/20101027 Lightning/1.0b2 Thunderbird/3.1.6 MIME-Version: 1.0 To: "u-boot@lists.denx.de" X-OriginalArrivalTime: 02 Dec 2010 13:57:27.0283 (UTC) FILETIME=[DA872C30:01CB9228] Subject: [U-Boot] [PATCH] davinci: Rewrite timer.c to use tbl/tbu emulation variables in gd 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 This change allows the davinci timer functions to be used before relocation since it avoids using static variables prior to BSS being made available. The code is based on that used in the at91 timers, modified to use a davinci specific hardware timer. It also maintains reset_timer() to allow deprecated timer usage to continue to work (for example, in nand_base.c) Signed-off-by: Nick Thompson Tested-by: Ben Gardiner Tested-by: Sudhakar Rajashekhara --- This patch relies on http://patchwork.ozlabs.org/patch/73758/ which has not been accepted yet. I have made a comment on it, suggesting that it should be changed: http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/90040/focus=90162 arch/arm/cpu/arm926ejs/davinci/timer.c | 77 ++++++++++++-------------------- 1 files changed, 28 insertions(+), 49 deletions(-) diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c index 9da7443..bfc6b40 100644 --- a/arch/arm/cpu/arm926ejs/davinci/timer.c +++ b/arch/arm/cpu/arm926ejs/davinci/timer.c @@ -40,6 +40,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + struct davinci_timer { u_int32_t pid12; u_int32_t emumgt; @@ -57,11 +59,9 @@ struct davinci_timer { static struct davinci_timer * const timer = (struct davinci_timer *)CONFIG_SYS_TIMERBASE; -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ) -#define TIM_CLK_DIV 16 +#define TIMER_LOAD_VAL 0xffffffff -static ulong timestamp; -static ulong lastinc; +#define TIM_CLK_DIV 16 int timer_init(void) { @@ -71,72 +71,51 @@ int timer_init(void) writel(0x06 | ((TIM_CLK_DIV - 1) << 8), &timer->tgcr); writel(0x0, &timer->tim34); writel(TIMER_LOAD_VAL, &timer->prd34); - lastinc = 0; - timestamp = 0; writel(2 << 22, &timer->tcr); + gd->timer_rate_hz = CONFIG_SYS_HZ_CLOCK / TIM_CLK_DIV; + gd->timer_reset_value = 0; return(0); } void reset_timer(void) { - writel(0x0, &timer->tcr); - writel(0x0, &timer->tim34); - lastinc = 0; - timestamp = 0; - writel(2 << 22, &timer->tcr); + gd->timer_reset_value = get_ticks(); } -static ulong get_timer_raw(void) +/* + * Get the current 64 bit timer tick count + */ +unsigned long long get_ticks(void) { - ulong now = readl(&timer->tim34); - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } - lastinc = now; - return timestamp; + unsigned long now = readl(&timer->tim34); + + /* increment tbu if tbl has rolled over */ + if (now < gd->tbl) + gd->tbu++; + gd->tbl = now; + + return (((unsigned long long)gd->tbu) << 32) | gd->tbl; } ulong get_timer(ulong base) { - return((get_timer_raw() / (TIMER_LOAD_VAL / TIM_CLK_DIV)) - base); -} + unsigned long long timer_diff; -void set_timer(ulong t) -{ - timestamp = t; + timer_diff = get_ticks() - gd->timer_reset_value; + + return (timer_diff / (gd->timer_rate_hz / CONFIG_SYS_HZ)) - base; } void __udelay(unsigned long usec) { - ulong tmo; - ulong endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= (1000 * TIM_CLK_DIV); - - endtime = get_timer_raw() + tmo; + unsigned long long endtime; - do { - ulong now = get_timer_raw(); - diff = endtime - now; - } while (diff >= 0); -} + endtime = ((unsigned long long )usec * gd->timer_rate_hz) / 1000000UL; + endtime += get_ticks(); -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return(get_timer(0)); + while (get_ticks() < endtime) + ; } /*