blob: db8ddbdba54a1120dbf2b07aed1044170e2c8eea [file] [log] [blame]
Stefan Kristianssoncfbf96b2011-11-26 19:04:52 +00001/*
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 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Stefan Kristianssoncfbf96b2011-11-26 19:04:52 +00008 */
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
Stefan Kristianssond19c2212012-02-22 07:10:10 +000073unsigned 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
Stefan Kristianssoncfbf96b2011-11-26 19:04:52 +000083void __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}