uboot/arch/sh/lib/time.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
   4 *
   5 * (C) Copyright 2007-2010
   6 * Nobobuhiro Iwamatsu <iwamatsu@nigauri.org>
   7 *
   8 * (C) Copyright 2003
   9 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  10 *
  11 * See file CREDITS for list of people who contributed to this
  12 * project.
  13 *
  14 * This program is free software; you can redistribute it and/or
  15 * modify it under the terms of the GNU General Public License as
  16 * published by the Free Software Foundation; either version 2 of
  17 * the License, or (at your option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, write to the Free Software
  26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  27 * MA 02111-1307 USA
  28 */
  29
  30#include <common.h>
  31#include <div64.h>
  32#include <asm/processor.h>
  33#include <asm/clk.h>
  34#include <asm/io.h>
  35
  36#define TMU_MAX_COUNTER (~0UL)
  37
  38static ulong timer_freq;
  39static unsigned long last_tcnt;
  40static unsigned long long overflow_ticks;
  41
  42static inline unsigned long long tick_to_time(unsigned long long tick)
  43{
  44        tick *= CONFIG_SYS_HZ;
  45        do_div(tick, timer_freq);
  46
  47        return tick;
  48}
  49
  50static inline unsigned long long usec_to_tick(unsigned long long usec)
  51{
  52        usec *= timer_freq;
  53        do_div(usec, 1000000);
  54
  55        return usec;
  56}
  57
  58static void tmu_timer_start (unsigned int timer)
  59{
  60        if (timer > 2)
  61                return;
  62        writeb(readb(TSTR) | (1 << timer), TSTR);
  63}
  64
  65static void tmu_timer_stop (unsigned int timer)
  66{
  67        if (timer > 2)
  68                return;
  69        writeb(readb(TSTR) & ~(1 << timer), TSTR);
  70}
  71
  72int timer_init (void)
  73{
  74        /* Divide clock by CONFIG_SYS_TMU_CLK_DIV */
  75        u16 bit = 0;
  76
  77        switch (CONFIG_SYS_TMU_CLK_DIV) {
  78        case 1024:
  79                bit = 4;
  80                break;
  81        case 256:
  82                bit = 3;
  83                break;
  84        case 64:
  85                bit = 2;
  86                break;
  87        case 16:
  88                bit = 1;
  89                break;
  90        case 4:
  91        default:
  92                break;
  93        }
  94        writew(readw(TCR0) | bit, TCR0);
  95
  96        /* Calc clock rate */
  97        timer_freq = get_tmu0_clk_rate() >> ((bit + 1) * 2);
  98
  99        tmu_timer_stop(0);
 100        tmu_timer_start(0);
 101
 102        last_tcnt = 0;
 103        overflow_ticks = 0;
 104
 105        return 0;
 106}
 107
 108unsigned long long get_ticks (void)
 109{
 110        unsigned long tcnt = 0 - readl(TCNT0);
 111        unsigned long ticks;
 112
 113        if (last_tcnt > tcnt) { /* overflow */
 114                overflow_ticks++;
 115                ticks = (0xffffffff - last_tcnt) + tcnt;
 116        } else {
 117                ticks = tcnt;
 118        }
 119        last_tcnt = tcnt;
 120
 121        return (overflow_ticks << 32) | tcnt;
 122}
 123
 124void __udelay (unsigned long usec)
 125{
 126        unsigned long long tmp;
 127        ulong tmo;
 128
 129        tmo = usec_to_tick(usec);
 130        tmp = get_ticks() + tmo;        /* get current timestamp */
 131
 132        while (get_ticks() < tmp)       /* loop till event */
 133                 /*NOP*/;
 134}
 135
 136unsigned long get_timer (unsigned long base)
 137{
 138        /* return msec */
 139        return tick_to_time(get_ticks()) - base;
 140}
 141
 142unsigned long get_tbclk (void)
 143{
 144        return timer_freq;
 145}
 146