uboot/arch/openrisc/lib/timer.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
   3 * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
   4 * (C) Copyright 2003
   5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   6 *
   7 * SPDX-License-Identifier:     GPL-2.0+
   8 */
   9
  10#include <common.h>
  11#include <asm/system.h>
  12#include <asm/openrisc_exc.h>
  13
  14static ulong timestamp;
  15
  16/* how many counter cycles in a jiffy */
  17#define TIMER_COUNTER_CYCLES  (CONFIG_SYS_CLK_FREQ/CONFIG_SYS_OPENRISC_TMR_HZ)
  18/* how many ms elapses between each timer interrupt */
  19#define TIMER_TIMESTAMP_INC   (1000/CONFIG_SYS_OPENRISC_TMR_HZ)
  20/* how many cycles per ms */
  21#define TIMER_CYCLES_MS       (CONFIG_SYS_CLK_FREQ/1000)
  22/* how many cycles per us */
  23#define TIMER_CYCLES_US       (CONFIG_SYS_CLK_FREQ/1000000uL)
  24
  25void timer_isr(void)
  26{
  27        timestamp += TIMER_TIMESTAMP_INC;
  28        mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
  29                (TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
  30}
  31
  32int timer_init(void)
  33{
  34        /* Install timer exception handler */
  35        exception_install_handler(EXC_TIMER, timer_isr);
  36
  37        /* Set up the timer for the first expiration. */
  38        timestamp = 0;
  39
  40        mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
  41                (TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
  42
  43        /* Enable tick timer exception in supervisor register */
  44        mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
  45
  46        return 0;
  47}
  48
  49void reset_timer(void)
  50{
  51        timestamp = 0;
  52
  53        mtspr(SPR_TTMR, SPR_TTMR_IE | SPR_TTMR_RT |
  54                (TIMER_COUNTER_CYCLES & SPR_TTMR_TP));
  55}
  56
  57/*
  58 * The timer value in ms is calculated by taking the
  59 * value accumulated by full timer revolutions plus the value
  60 * accumulated in this period
  61 */
  62ulong get_timer(ulong base)
  63{
  64        return timestamp + mfspr(SPR_TTCR)/TIMER_CYCLES_MS - base;
  65}
  66
  67void set_timer(ulong t)
  68{
  69        reset_timer();
  70        timestamp = t;
  71}
  72
  73unsigned long long get_ticks(void)
  74{
  75        return get_timer(0);
  76}
  77
  78ulong get_tbclk(void)
  79{
  80        return CONFIG_SYS_HZ;
  81}
  82
  83void __udelay(ulong usec)
  84{
  85        ulong elapsed = 0;
  86        ulong tick;
  87        ulong last_tick;
  88
  89        last_tick = mfspr(SPR_TTCR);
  90        while ((elapsed / TIMER_CYCLES_US) < usec) {
  91                tick = mfspr(SPR_TTCR);
  92                if (tick >= last_tick)
  93                        elapsed += (tick - last_tick);
  94                else
  95                        elapsed += TIMER_COUNTER_CYCLES - (last_tick - tick);
  96                last_tick = tick;
  97        }
  98}
  99