uboot/cpu/arm926ejs/nomadik/timer.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009 Alessandro Rubini
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License as
   9 * published by the Free Software Foundation; either version 2 of
  10 * the License, or (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 * MA 02111-1307 USA
  21 */
  22
  23#include <common.h>
  24#include <asm/io.h>
  25#include <asm/arch/mtu.h>
  26
  27/*
  28 * The timer is a decrementer, we'll left it free running at 2.4MHz.
  29 * We have 2.4 ticks per microsecond and an overflow in almost 30min
  30 */
  31#define TIMER_CLOCK             (24 * 100 * 1000)
  32#define COUNT_TO_USEC(x)        ((x) * 5 / 12)  /* overflows at 6min */
  33#define USEC_TO_COUNT(x)        ((x) * 12 / 5)  /* overflows at 6min */
  34#define TICKS_PER_HZ            (TIMER_CLOCK / CONFIG_SYS_HZ)
  35#define TICKS_TO_HZ(x)          ((x) / TICKS_PER_HZ)
  36
  37/* macro to read the 32 bit timer: since it decrements, we invert read value */
  38#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0)))
  39
  40/* Configure a free-running, auto-wrap counter with no prescaler */
  41int timer_init(void)
  42{
  43        writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS,
  44               CONFIG_SYS_TIMERBASE + MTU_CR(0));
  45        reset_timer();
  46        return 0;
  47}
  48
  49/* Restart counting from 0 */
  50void reset_timer(void)
  51{
  52        writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */
  53}
  54
  55/* Return how many HZ passed since "base" */
  56ulong get_timer(ulong base)
  57{
  58        return  TICKS_TO_HZ(READ_TIMER()) - base;
  59}
  60
  61/* Delay x useconds */
  62void udelay(unsigned long usec)
  63{
  64        ulong ini, end;
  65
  66        ini = READ_TIMER();
  67        end = ini + USEC_TO_COUNT(usec);
  68        while ((signed)(end - READ_TIMER()) > 0)
  69                ;
  70}
  71