From mboxrd@z Thu Jan 1 00:00:00 1970 From: Shinya Kuribayashi Date: Sun, 25 May 2008 22:45:48 +0900 Subject: [U-Boot-Users] [PATCH 3/3][MIPS] lib_mips/time.c: Fix improper use of CFG_HZ and timer routines In-Reply-To: <20080525081501.241BF247CC@gemini.denx.de> References: <20080525081501.241BF247CC@gemini.denx.de> Message-ID: <48396D8C.8050402@ruby.dti.ne.jp> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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