Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / arch / arm / cpu / arm926ejs / orion5x / timer.c
1 /*
2   * Copyright (C) 2010 Albert ARIBAUD <albert.u.boot@aribaud.net>
3  *
4  * Based on original Kirkwood support which is
5  * Copyright (C) Marvell International Ltd. and its affiliates
6  * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <asm/io.h>
13
14 #define UBOOT_CNTR      0       /* counter to use for uboot timer */
15
16 /* Timer reload and current value registers */
17 struct orion5x_tmr_val {
18         u32 reload;     /* Timer reload reg */
19         u32 val;        /* Timer value reg */
20 };
21
22 /* Timer registers */
23 struct orion5x_tmr_registers {
24         u32 ctrl;       /* Timer control reg */
25         u32 pad[3];
26         struct orion5x_tmr_val tmr[2];
27         u32 wdt_reload;
28         u32 wdt_val;
29 };
30
31 struct orion5x_tmr_registers *orion5x_tmr_regs =
32         (struct orion5x_tmr_registers *)ORION5X_TIMER_BASE;
33
34 /*
35  * ARM Timers Registers Map
36  */
37 #define CNTMR_CTRL_REG                  (&orion5x_tmr_regs->ctrl)
38 #define CNTMR_RELOAD_REG(tmrnum)        (&orion5x_tmr_regs->tmr[tmrnum].reload)
39 #define CNTMR_VAL_REG(tmrnum)           (&orion5x_tmr_regs->tmr[tmrnum].val)
40
41 /*
42  * ARM Timers Control Register
43  * CPU_TIMERS_CTRL_REG (CTCR)
44  */
45 #define CTCR_ARM_TIMER_EN_OFFS(cntr)    (cntr * 2)
46 #define CTCR_ARM_TIMER_EN_MASK(cntr)    (1 << CTCR_ARM_TIMER_EN_OFFS)
47 #define CTCR_ARM_TIMER_EN(cntr)         (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
48 #define CTCR_ARM_TIMER_DIS(cntr)        (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
49
50 #define CTCR_ARM_TIMER_AUTO_OFFS(cntr)  ((cntr * 2) + 1)
51 #define CTCR_ARM_TIMER_AUTO_MASK(cntr)  (1 << 1)
52 #define CTCR_ARM_TIMER_AUTO_EN(cntr)    (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
53 #define CTCR_ARM_TIMER_AUTO_DIS(cntr)   (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
54
55 /*
56  * ARM Timer\Watchdog Reload Register
57  * CNTMR_RELOAD_REG (TRR)
58  */
59 #define TRG_ARM_TIMER_REL_OFFS          0
60 #define TRG_ARM_TIMER_REL_MASK          0xffffffff
61
62 /*
63  * ARM Timer\Watchdog Register
64  * CNTMR_VAL_REG (TVRG)
65  */
66 #define TVR_ARM_TIMER_OFFS              0
67 #define TVR_ARM_TIMER_MASK              0xffffffff
68 #define TVR_ARM_TIMER_MAX               0xffffffff
69 #define TIMER_LOAD_VAL                  0xffffffff
70
71 static inline ulong read_timer(void)
72 {
73         return readl(CNTMR_VAL_REG(UBOOT_CNTR))
74               / (CONFIG_SYS_TCLK / 1000);
75 }
76
77 DECLARE_GLOBAL_DATA_PTR;
78
79 #define timestamp gd->arch.tbl
80 #define lastdec gd->arch.lastinc
81
82 ulong get_timer_masked(void)
83 {
84         ulong now = read_timer();
85
86         if (lastdec >= now) {
87                 /* normal mode */
88                 timestamp += lastdec - now;
89         } else {
90                 /* we have an overflow ... */
91                 timestamp += lastdec +
92                         (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now;
93         }
94         lastdec = now;
95
96         return timestamp;
97 }
98
99 ulong get_timer(ulong base)
100 {
101         return get_timer_masked() - base;
102 }
103
104 static inline ulong uboot_cntr_val(void)
105 {
106         return readl(CNTMR_VAL_REG(UBOOT_CNTR));
107 }
108
109 void __udelay(unsigned long usec)
110 {
111         uint current;
112         ulong delayticks;
113
114         current = uboot_cntr_val();
115         delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));
116
117         if (current < delayticks) {
118                 delayticks -= current;
119                 while (uboot_cntr_val() < current)
120                         ;
121                 while ((TIMER_LOAD_VAL - delayticks) < uboot_cntr_val())
122                         ;
123         } else {
124                 while (uboot_cntr_val() > (current - delayticks))
125                         ;
126         }
127 }
128
129 /*
130  * init the counter
131  */
132 int timer_init(void)
133 {
134         unsigned int cntmrctrl;
135
136         /* load value into timer */
137         writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
138         writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
139
140         /* enable timer in auto reload mode */
141         cntmrctrl = readl(CNTMR_CTRL_REG);
142         cntmrctrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);
143         cntmrctrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);
144         writel(cntmrctrl, CNTMR_CTRL_REG);
145         return 0;
146 }
147
148 void timer_init_r(void)
149 {
150         /* init the timestamp and lastdec value */
151         lastdec = read_timer();
152         timestamp = 0;
153 }
154
155 /*
156  * This function is derived from PowerPC code (read timebase as long long).
157  * On ARM it just returns the timer value.
158  */
159 unsigned long long get_ticks(void)
160 {
161         return get_timer(0);
162 }
163
164 /*
165  * This function is derived from PowerPC code (timebase clock frequency).
166  * On ARM it returns the number of timer ticks per second.
167  */
168 ulong get_tbclk (void)
169 {
170         return (ulong)CONFIG_SYS_HZ;
171 }