]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm926ejs/mb86r0x/timer.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mb86r0x / timer.c
1 /*
2  * (C) Copyright 2007-2008
3  * Stelian Pop <stelian@popies.net>
4  * Lead Tech Design <www.leadtechdesign.com>
5  *
6  * (C) Copyright 2010
7  * Matthias Weisser, Graf-Syteco <weisserm@arcor.de>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <div64.h>
13 #include <common.h>
14 #include <asm/io.h>
15 #include <asm/arch/hardware.h>
16
17 #define TIMER_LOAD_VAL  0xffffffff
18 #define TIMER_FREQ      (CONFIG_MB86R0x_IOCLK  / 256)
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 #define timestamp gd->arch.tbl
23 #define lastdec gd->arch.lastinc
24
25 static inline unsigned long long tick_to_time(unsigned long long tick)
26 {
27         tick *= CONFIG_SYS_HZ;
28         do_div(tick, TIMER_FREQ);
29
30         return tick;
31 }
32
33 static inline unsigned long long usec_to_tick(unsigned long long usec)
34 {
35         usec *= TIMER_FREQ;
36         do_div(usec, 1000000);
37
38         return usec;
39 }
40
41 /* nothing really to do with interrupts, just starts up a counter. */
42 int timer_init(void)
43 {
44         struct mb86r0x_timer * timer = (struct mb86r0x_timer *)
45                                         MB86R0x_TIMER_BASE;
46         ulong ctrl = readl(&timer->control);
47
48         writel(TIMER_LOAD_VAL, &timer->load);
49
50         ctrl |= MB86R0x_TIMER_ENABLE | MB86R0x_TIMER_PRS_8S |
51                 MB86R0x_TIMER_SIZE_32;
52
53         writel(ctrl, &timer->control);
54
55         /* capture current value time */
56         lastdec = readl(&timer->value);
57         timestamp = 0; /* start "advancing" time stamp from 0 */
58
59         return 0;
60 }
61
62 /*
63  * timer without interrupts
64  */
65 unsigned long long get_ticks(void)
66 {
67         struct mb86r0x_timer * timer = (struct mb86r0x_timer *)
68                                         MB86R0x_TIMER_BASE;
69         ulong now = readl(&timer->value);
70
71         if (now <= lastdec) {
72                 /* normal mode (non roll) */
73                 /* move stamp forward with absolut diff ticks */
74                 timestamp += lastdec - now;
75         } else {
76                 /* we have rollover of incrementer */
77                 timestamp += lastdec + TIMER_LOAD_VAL - now;
78         }
79         lastdec = now;
80         return timestamp;
81 }
82
83 ulong get_timer_masked(void)
84 {
85         return tick_to_time(get_ticks());
86 }
87
88 void __udelay(unsigned long usec)
89 {
90         unsigned long long tmp;
91         ulong tmo;
92
93         tmo = usec_to_tick(usec);
94         tmp = get_ticks();                      /* get current timestamp */
95
96         while ((get_ticks() - tmp) < tmo)       /* loop till event */
97                  /*NOP*/;
98 }
99
100 ulong get_timer(ulong base)
101 {
102         return get_timer_masked() - base;
103 }
104
105 /*
106  * This function is derived from PowerPC code (timebase clock frequency).
107  * On ARM it returns the number of timer ticks per second.
108  */
109 ulong get_tbclk(void)
110 {
111         ulong tbclk;
112
113         tbclk = TIMER_FREQ;
114         return tbclk;
115 }