
Wolfgang Denk wrote:
Sure. We'll probably need to move timer_init to board_init_r at the end.
I'm not sure if this works. We use udelay() and friends all over the place - a long time before that.
Hmm.
My udelay is already global-variable-free. And as for cycles_per_jiffy and expirelo, we could make it work like this:
diff --git a/lib_mips/time.c b/lib_mips/time.c index f6678e1..d4754e3 100644 --- a/lib_mips/time.c +++ b/lib_mips/time.c @@ -27,10 +27,7 @@ static unsigned long timestamp;
/* how many counter cycles in a jiffy */ -static unsigned long cycles_per_jiffy; - -/* expirelo is the count value for next CPU timer interrupt */ -static unsigned int expirelo; +static unsigned long cycles_per_jiffy = (CONFIG_MIPS_TIMER_FREQ + CFG_HZ / 2) / CFG_HZ;
/* * timer without interrupts @@ -38,9 +35,6 @@ static unsigned int expirelo;
int timer_init(void) { - /* Calculate cache parameters. */ - cycles_per_jiffy = (CONFIG_MIPS_TIMER_FREQ + CFG_HZ / 2) / CFG_HZ; - /* Report the high precision timer rate for a reference. */ printf("Using %u.%03u MHz high precision timer.\n", ((CONFIG_MIPS_TIMER_FREQ + 500) / 1000) / 1000, @@ -48,7 +42,7 @@ int timer_init(void)
/* Set up the timer for the first expiration. */ timestamp = 0; - expirelo = read_c0_count() + cycles_per_jiffy; + write_c0_compare(read_c0_count() + cycles_per_jiffy);
return 0; } @@ -56,12 +50,13 @@ int timer_init(void) void reset_timer(void) { timestamp = 0; - expirelo = read_c0_count() + cycles_per_jiffy; + write_c0_compare(read_c0_count() + cycles_per_jiffy); }
ulong get_timer(ulong base) { unsigned int count; + unsigned int expirelo = read_c0_compare();
/* Check to see if we have missed any timestamps. */ count = read_c0_count(); @@ -73,6 +68,7 @@ ulong get_timer(ulong base) expirelo += cycles_per_jiffy; timestamp++; } + write_c0_compare(expirelo);
return (timestamp - base); } @@ -80,7 +76,7 @@ ulong get_timer(ulong base) void set_timer(ulong t) { timestamp = t; - expirelo = read_c0_count() + cycles_per_jiffy; + write_c0_compare(read_c0_count() + cycles_per_jiffy); }
void udelay(unsigned long usec) _
But I have no clue about timestamp.
The timer implementation should have no such restrictions as being available only after relocation. Timers / delays are such a basic feature that they should be available everywhere.
I'll remember that.
Shinya