timer: Provide an early timer
In some cases the timer must be accessible before driver model is active. Examples include when using CONFIG_TRACE to trace U-Boot's execution before driver model is set up. Enable this option to use an early timer. These functions must be supported by your timer driver: timer_early_get_count() and timer_early_get_rate(). Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
4f051824b5
commit
c95fec3192
|
@ -9,6 +9,16 @@ config TIMER
|
||||||
will be used. The timer is usually a 32 bits free-running up
|
will be used. The timer is usually a 32 bits free-running up
|
||||||
counter. There may be no real tick, and no timer interrupt.
|
counter. There may be no real tick, and no timer interrupt.
|
||||||
|
|
||||||
|
config TIMER_EARLY
|
||||||
|
bool "Allow timer to be used early in U-Boot"
|
||||||
|
depends on TIMER
|
||||||
|
help
|
||||||
|
In some cases the timer must be accessible before driver model is
|
||||||
|
active. Examples include when using CONFIG_TRACE to trace U-Boot's
|
||||||
|
execution before driver model is set up. Enable this option to
|
||||||
|
use an early timer. These functions must be supported by your timer
|
||||||
|
driver: timer_early_get_count() and timer_early_get_rate().
|
||||||
|
|
||||||
config ALTERA_TIMER
|
config ALTERA_TIMER
|
||||||
bool "Altera timer support"
|
bool "Altera timer support"
|
||||||
depends on TIMER
|
depends on TIMER
|
||||||
|
|
|
@ -67,4 +67,25 @@ struct timer_dev_priv {
|
||||||
unsigned long clock_rate;
|
unsigned long clock_rate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timer_early_get_count() - Implement timer_get_count() before driver model
|
||||||
|
*
|
||||||
|
* If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
|
||||||
|
* the current timer value before the proper driver model timer is ready.
|
||||||
|
* It should be implemented by one of the timer values. This is mostly useful
|
||||||
|
* for tracing.
|
||||||
|
*/
|
||||||
|
u64 timer_early_get_count(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* timer_early_get_rate() - Get the timer rate before driver model
|
||||||
|
*
|
||||||
|
* If CONFIG_TIMER_EARLY is enabled, this function wil be called to return
|
||||||
|
* the current timer rate in Hz before the proper driver model timer is ready.
|
||||||
|
* It should be implemented by one of the timer values. This is mostly useful
|
||||||
|
* for tracing. This corresponds to the clock_rate value in struct
|
||||||
|
* timer_dev_priv.
|
||||||
|
*/
|
||||||
|
unsigned long timer_early_get_rate(void);
|
||||||
|
|
||||||
#endif /* _TIMER_H_ */
|
#endif /* _TIMER_H_ */
|
||||||
|
|
28
lib/time.c
28
lib/time.c
|
@ -43,11 +43,17 @@ extern unsigned long __weak timer_read_counter(void);
|
||||||
#ifdef CONFIG_TIMER
|
#ifdef CONFIG_TIMER
|
||||||
ulong notrace get_tbclk(void)
|
ulong notrace get_tbclk(void)
|
||||||
{
|
{
|
||||||
int ret;
|
if (!gd->timer) {
|
||||||
|
#ifdef CONFIG_TIMER_EARLY
|
||||||
|
return timer_early_get_rate();
|
||||||
|
#else
|
||||||
|
int ret;
|
||||||
|
|
||||||
ret = dm_timer_init();
|
ret = dm_timer_init();
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return timer_get_rate(gd->timer);
|
return timer_get_rate(gd->timer);
|
||||||
}
|
}
|
||||||
|
@ -57,9 +63,17 @@ uint64_t notrace get_ticks(void)
|
||||||
u64 count;
|
u64 count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = dm_timer_init();
|
if (!gd->timer) {
|
||||||
if (ret)
|
#ifdef CONFIG_TIMER_EARLY
|
||||||
return ret;
|
return timer_early_get_count();
|
||||||
|
#else
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = dm_timer_init();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
ret = timer_get_count(gd->timer, &count);
|
ret = timer_get_count(gd->timer, &count);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue