]> Git Repo - J-u-boot.git/blame - lib/time.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-tegra
[J-u-boot.git] / lib / time.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
3eb90bad
IL
2/*
3 * (C) Copyright 2000-2009
4 * Wolfgang Denk, DENX Software Engineering, [email protected].
3eb90bad
IL
5 */
6
7#include <common.h>
52f24238 8#include <bootstage.h>
c8a7ba9e
TC
9#include <dm.h>
10#include <errno.h>
691d719d 11#include <init.h>
6d1a8ebe 12#include <spl.h>
1045315d 13#include <time.h>
c8a7ba9e 14#include <timer.h>
3eb90bad 15#include <watchdog.h>
8dfafdde 16#include <div64.h>
401d1c4f 17#include <asm/global_data.h>
8dfafdde 18#include <asm/io.h>
c05ed00a 19#include <linux/delay.h>
3eb90bad
IL
20
21#ifndef CONFIG_WD_PERIOD
fccacd3b 22# define CONFIG_WD_PERIOD (10 * 1000 * 1000) /* 10 seconds default */
3eb90bad
IL
23#endif
24
8dfafdde
RH
25DECLARE_GLOBAL_DATA_PTR;
26
27#ifdef CONFIG_SYS_TIMER_RATE
fccacd3b 28/* Returns tick rate in ticks per second */
8dfafdde
RH
29ulong notrace get_tbclk(void)
30{
31 return CONFIG_SYS_TIMER_RATE;
32}
33#endif
34
35#ifdef CONFIG_SYS_TIMER_COUNTER
36unsigned long notrace timer_read_counter(void)
37{
38#ifdef CONFIG_SYS_TIMER_COUNTS_DOWN
39 return ~readl(CONFIG_SYS_TIMER_COUNTER);
40#else
41 return readl(CONFIG_SYS_TIMER_COUNTER);
42#endif
43}
9fb34b01
SG
44
45ulong timer_get_boot_us(void)
46{
47 ulong count = timer_read_counter();
48
49#if CONFIG_SYS_TIMER_RATE == 1000000
50 return count;
51#elif CONFIG_SYS_TIMER_RATE > 1000000
52 return lldiv(count, CONFIG_SYS_TIMER_RATE / 1000000);
53#elif defined(CONFIG_SYS_TIMER_RATE)
54 return (unsigned long long)count * 1000000 / CONFIG_SYS_TIMER_RATE;
55#else
56 /* Assume the counter is in microseconds */
57 return count;
58#endif
59}
60
8dfafdde 61#else
65ba7add 62extern unsigned long __weak timer_read_counter(void);
8dfafdde
RH
63#endif
64
f00c2628 65#if CONFIG_IS_ENABLED(TIMER)
c8a7ba9e
TC
66ulong notrace get_tbclk(void)
67{
c95fec31
SG
68 if (!gd->timer) {
69#ifdef CONFIG_TIMER_EARLY
70 return timer_early_get_rate();
71#else
72 int ret;
c8a7ba9e 73
c95fec31
SG
74 ret = dm_timer_init();
75 if (ret)
76 return ret;
77#endif
78 }
c8a7ba9e
TC
79
80 return timer_get_rate(gd->timer);
81}
82
9ca07ebb 83uint64_t notrace get_ticks(void)
c8a7ba9e 84{
9ca07ebb 85 u64 count;
c8a7ba9e
TC
86 int ret;
87
c95fec31
SG
88 if (!gd->timer) {
89#ifdef CONFIG_TIMER_EARLY
90 return timer_early_get_count();
91#else
92 int ret;
93
94 ret = dm_timer_init();
95 if (ret)
4b2be78a 96 panic("Could not initialize timer (err %d)\n", ret);
c95fec31
SG
97#endif
98 }
c8a7ba9e
TC
99
100 ret = timer_get_count(gd->timer, &count);
6d1a8ebe
SG
101 if (ret) {
102 if (spl_phase() > PHASE_TPL)
103 panic("Could not read count from timer (err %d)\n",
104 ret);
105 else
106 panic("no timer (err %d)\n", ret);
107 }
c8a7ba9e
TC
108
109 return count;
110}
9ca07ebb
BM
111
112#else /* !CONFIG_TIMER */
c8a7ba9e 113
19ea4678 114uint64_t __weak notrace get_ticks(void)
8dfafdde
RH
115{
116 unsigned long now = timer_read_counter();
117
118 /* increment tbu if tbl has rolled over */
119 if (now < gd->timebase_l)
120 gd->timebase_h++;
121 gd->timebase_l = now;
19ea4678 122 return ((uint64_t)gd->timebase_h << 32) | gd->timebase_l;
8dfafdde
RH
123}
124
9ca07ebb
BM
125#endif /* CONFIG_TIMER */
126
fccacd3b 127/* Returns time in milliseconds */
19ea4678 128static uint64_t notrace tick_to_time(uint64_t tick)
8dfafdde 129{
fccacd3b 130 ulong div = get_tbclk();
8dfafdde
RH
131
132 tick *= CONFIG_SYS_HZ;
133 do_div(tick, div);
134 return tick;
135}
136
de351d6b
DR
137int __weak timer_init(void)
138{
139 return 0;
140}
141
fccacd3b 142/* Returns time in milliseconds */
8dfafdde
RH
143ulong __weak get_timer(ulong base)
144{
145 return tick_to_time(get_ticks()) - base;
146}
147
80e7e7c2
MV
148static uint64_t notrace tick_to_time_us(uint64_t tick)
149{
150 ulong div = get_tbclk() / 1000;
151
152 tick *= CONFIG_SYS_HZ;
153 do_div(tick, div);
154 return tick;
155}
156
157uint64_t __weak get_timer_us(uint64_t base)
158{
159 return tick_to_time_us(get_ticks()) - base;
160}
161
e1ddf67c
SG
162unsigned long __weak get_timer_us_long(unsigned long base)
163{
164 return timer_get_us() - base;
165}
166
8dfafdde
RH
167unsigned long __weak notrace timer_get_us(void)
168{
169 return tick_to_time(get_ticks() * 1000);
170}
fccacd3b 171
6a853dbc 172uint64_t usec_to_tick(unsigned long usec)
8dfafdde 173{
19ea4678 174 uint64_t tick = usec;
2cd1b572 175 tick *= get_tbclk();
8dfafdde
RH
176 do_div(tick, 1000000);
177 return tick;
178}
179
180void __weak __udelay(unsigned long usec)
181{
19ea4678 182 uint64_t tmp;
8dfafdde 183
fccacd3b 184 tmp = get_ticks() + usec_to_tick(usec); /* get current timestamp */
8dfafdde 185
fccacd3b 186 while (get_ticks() < tmp+1) /* loop till event */
8dfafdde
RH
187 /*NOP*/;
188}
189
3eb90bad
IL
190/* ------------------------------------------------------------------------- */
191
192void udelay(unsigned long usec)
193{
194 ulong kv;
195
196 do {
197 WATCHDOG_RESET();
198 kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec;
07e11146 199 __udelay(kv);
3eb90bad
IL
200 usec -= kv;
201 } while(usec);
202}
This page took 0.48953 seconds and 4 git commands to generate.