From e9d5f35497885b3c65d494d09a525d443dcccd3b Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 20 Nov 2008 16:44:42 +0900 Subject: sh: Update sh timer function Change to write/readX function and fix timer problem. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Nobuhiro Iwamatsu --- lib_sh/time.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 17 deletions(-) (limited to 'lib_sh/time.c') diff --git a/lib_sh/time.c b/lib_sh/time.c index e637e95a316..2bd77152825 100644 --- a/lib_sh/time.c +++ b/lib_sh/time.c @@ -1,6 +1,9 @@ /* - * Copyright (c) 2007 - * Nobuhiro Iwamatsu + * (C) Copyright 2007-2008 + * Nobobuhiro Iwamatsu + * + * (C) Copyright 2003 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. @@ -23,50 +26,96 @@ #include #include +#include + +#define TMU_MAX_COUNTER (~0UL) +static int clk_adj = 1; static void tmu_timer_start (unsigned int timer) { if (timer > 2) return; + writeb(readb(TSTR) | (1 << timer), TSTR); +} - *((volatile unsigned char *) TSTR0) |= (1 << timer); +static void tmu_timer_stop (unsigned int timer) +{ + if (timer > 2) + return; + writeb(readb(TSTR) & ~(1 << timer), TSTR); } int timer_init (void) { - *(volatile u16 *)TCR0 = 0; + /* Divide clock by TMU_CLK_DIVIDER */ + u16 bit = 0; + switch( TMU_CLK_DIVIDER ){ + case 4: + bit = 0; + break; + case 16: + bit = 1; + break; + case 64: bit = 2; + break; + case 256: + bit = 3; + break; + case 1024: + bit = 4; + break; + default: + bit = 0; + break; + } + writew(readw(TCR0) | bit, TCR0); + + /* Clock adjustment calc */ + clk_adj = (int)(1.0/((1.0/CONFIG_SYS_HZ)*1000000)); + if (clk_adj < 1) + clk_adj = 1; + + tmu_timer_stop(0); + tmu_timer_start(0); - tmu_timer_start (0); return 0; } unsigned long long get_ticks (void) { - return (0 - *((volatile unsigned int *) TCNT0)); + return 0 - readl(TCNT0); } -unsigned long get_timer (unsigned long base) +static unsigned long get_usec (void) { - return ((0 - *((volatile unsigned int *) TCNT0)) - base); + return (0 - readl(TCNT0)); } -void set_timer (unsigned long t) +void udelay (unsigned long usec) { - *((volatile unsigned int *) TCNT0) = (0 - t); + unsigned int start = get_usec(); + unsigned int end = start + (usec * clk_adj); + + while (get_usec() < end) + continue; } -void reset_timer (void) +unsigned long get_timer (unsigned long base) { - set_timer (0); + /* return msec */ + return ((get_usec()/clk_adj)/1000) - base; } -void udelay (unsigned long usec) +void set_timer (unsigned long t) { - unsigned int start = get_timer (0); - unsigned int end = start + (usec * ((CONFIG_SYS_HZ + 500000) / 1000000)); + writel((0 - t), TCNT0); +} - while (get_timer (0) < end) - continue; +void reset_timer (void) +{ + tmu_timer_stop(0); + set_timer (0); + tmu_timer_start(0); } unsigned long get_tbclk (void) -- cgit v1.2.3