X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=lib_sh%2Ftime.c;h=9a8f89aef60cf9cf183ec6367d91c7efd555afd1;hb=6fffcdf8c869a3d8436be8eff6428d8121aa76e6;hp=9c1dc509bb7cc757deda31db43925e02296acb6a;hpb=9e23fe0560b84e324dc5f0ff8813dab2aa34f074;p=u-boot diff --git a/lib_sh/time.c b/lib_sh/time.c index 9c1dc509bb..9a8f89aef6 100644 --- a/lib_sh/time.c +++ b/lib_sh/time.c @@ -1,6 +1,12 @@ /* - * Copyright (c) 2007 - * Nobuhiro Iwamatsu + * (C) Copyright 2009 + * Jean-Christophe PLAGNIOL-VILLARD + * + * (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. @@ -22,54 +28,114 @@ */ #include +#include #include +#include +#include + +#define TMU_MAX_COUNTER (~0UL) + +static ulong timer_freq; + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, timer_freq); + + return tick; +} + +static inline unsigned long long usec_to_tick(unsigned long long usec) +{ + usec *= timer_freq; + do_div(usec, 1000000); + + return usec; +} 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 CONFIG_SYS_TMU_CLK_DIV */ + u16 bit = 0; + + switch (CONFIG_SYS_TMU_CLK_DIV) { + case 1024: + bit = 4; + break; + case 256: + bit = 3; + break; + case 64: + bit = 2; + break; + case 16: + bit = 1; + break; + case 4: + default: + break; + } + writew(readw(TCR0) | bit, TCR0); + + /* Calc clock rate */ + timer_freq = get_tmu0_clk_rate() >> ((bit + 1) * 2); + + 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); +} + +void __udelay (unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = usec_to_tick(usec); + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp) /* loop till event */ + /*NOP*/; } unsigned long get_timer (unsigned long base) { - return ((0 - *((volatile unsigned int *) TCNT0)) - base); + /* return msec */ + return tick_to_time(get_ticks()) - base; } void set_timer (unsigned long t) { - *((volatile unsigned int *) TCNT0) = (0 - t); + writel((0 - t), TCNT0); } void reset_timer (void) { + tmu_timer_stop(0); set_timer (0); -} - -void udelay (unsigned long usec) -{ - unsigned int start = get_timer (0); - unsigned int end = start + (usec * ((CFG_HZ + 500000) / 1000000)); - - while (get_timer (0) < end) - continue; + tmu_timer_start(0); } unsigned long get_tbclk (void) { - return CFG_HZ; + return timer_freq; }