]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/openrisc/lib/timer.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / openrisc / lib / timer.c
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
14 static 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
25 void 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
32 int 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
49 void 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  */
62 ulong get_timer(ulong base)
63 {
64         return timestamp + mfspr(SPR_TTCR)/TIMER_CYCLES_MS - base;
65 }
66
67 void set_timer(ulong t)
68 {
69         reset_timer();
70         timestamp = t;
71 }
72
73 unsigned long long get_ticks(void)
74 {
75         return get_timer(0);
76 }
77
78 ulong get_tbclk(void)
79 {
80         return CONFIG_SYS_HZ;
81 }
82
83 void __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 }