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