]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/u8500/timer.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / u8500 / timer.c
1 /*
2  * Copyright (C) 2010 Linaro Limited
3  * John Rigby <john.rigby@linaro.org>
4  *
5  * Based on original from Linux kernel source and
6  * internal ST-Ericsson U-Boot source.
7  * (C) Copyright 2009 Alessandro Rubini
8  * (C) Copyright 2010 ST-Ericsson
9  *
10  * SPDX-License-Identifier:     GPL-2.0+
11  */
12
13 #include <common.h>
14 #include <asm/io.h>
15 #include <asm/arch/hardware.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 /*
20  * The MTU device has some interrupt control registers
21  * followed by 4 timers.
22  */
23
24 /* The timers */
25 struct u8500_mtu_timer {
26         u32 lr;                 /* Load value */
27         u32 cv;                 /* Current value */
28         u32 cr;                 /* Control reg */
29         u32 bglr;               /* ??? */
30 };
31
32 /* The MTU that contains the timers */
33 struct u8500_mtu {
34         u32 imsc;               /* Interrupt mask set/clear */
35         u32 ris;                /* Raw interrupt status */
36         u32 mis;                /* Masked interrupt status */
37         u32 icr;                /* Interrupt clear register */
38         struct u8500_mtu_timer pt[4];
39 };
40
41 /* bits for the control register */
42 #define MTU_CR_ONESHOT          0x01    /* if 0 = wraps reloading from BGLR */
43 #define MTU_CR_32BITS           0x02
44
45 #define MTU_CR_PRESCALE_1       0x00
46 #define MTU_CR_PRESCALE_16      0x04
47 #define MTU_CR_PRESCALE_256     0x08
48 #define MTU_CR_PRESCALE_MASK    0x0c
49
50 #define MTU_CR_PERIODIC         0x40    /* if 0 = free-running */
51 #define MTU_CR_ENA              0x80
52
53 /*
54  * The MTU is clocked at 133 MHz by default. (V1 and later)
55  */
56 #define TIMER_CLOCK             (133 * 1000 * 1000 / 16)
57 #define COUNT_TO_USEC(x)        ((x) * 16 / 133)
58 #define USEC_TO_COUNT(x)        ((x) * 133 / 16)
59 #define TICKS_PER_HZ            (TIMER_CLOCK / CONFIG_SYS_HZ)
60 #define TICKS_TO_HZ(x)          ((x) / TICKS_PER_HZ)
61 #define TIMER_LOAD_VAL          0xffffffff
62
63 /*
64  * MTU timer to use (from 0 to 3).
65  */
66 #define MTU_TIMER 2
67
68 static struct u8500_mtu_timer *timer_base =
69         &((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
70
71 /* macro to read the 32 bit timer: since it decrements, we invert read value */
72 #define READ_TIMER() (~readl(&timer_base->cv))
73
74 /* Configure a free-running, auto-wrap counter with /16 prescaler */
75 int timer_init(void)
76 {
77         writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
78                &timer_base->cr);
79         return 0;
80 }
81
82 ulong get_timer_masked(void)
83 {
84         /* current tick value */
85         ulong now = TICKS_TO_HZ(READ_TIMER());
86
87         if (now >= gd->arch.lastinc) {  /* normal (non rollover) */
88                 gd->arch.tbl += (now - gd->arch.lastinc);
89         } else {                        /* rollover */
90                 gd->arch.tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) -
91                                         gd->arch.lastinc) + now;
92         }
93         gd->arch.lastinc = now;
94         return gd->arch.tbl;
95 }
96
97 /* Delay x useconds */
98 void __udelay(ulong usec)
99 {
100         long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
101         ulong now, last = READ_TIMER();
102
103         while (tmo > 0) {
104                 now = READ_TIMER();
105                 if (now > last) /* normal (non rollover) */
106                         tmo -= now - last;
107                 else            /* rollover */
108                         tmo -= TIMER_LOAD_VAL - last + now;
109                 last = now;
110         }
111 }
112
113 ulong get_timer(ulong base)
114 {
115         return get_timer_masked() - base;
116 }
117
118 /*
119  * Emulation of Power architecture long long timebase.
120  *
121  * TODO: Support gd->arch.tbu for real long long timebase.
122  */
123 unsigned long long get_ticks(void)
124 {
125         return get_timer(0);
126 }
127
128 /*
129  * Emulation of Power architecture timebase.
130  * NB: Low resolution compared to Power tbclk.
131  */
132 ulong get_tbclk(void)
133 {
134         return CONFIG_SYS_HZ;
135 }