All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [PATCH 3/3][MIPS] lib_mips/time.c: Fix improper use of CFG_HZ and timer routines
Date: Sat, 24 May 2008 22:02:28 +0900	[thread overview]
Message-ID: <483811E4.3070209@ruby.dti.ne.jp> (raw)
In-Reply-To: <48381147.5060803@ruby.dti.ne.jp>

MIPS port has two problems in timer routines. One is now we assume CFG_HZ
== CP0 counter frequency, but this is wrong. CFG_HZ has to be 1000 in the
U-Boot system.

The other is we don't have a proper time management counter like timestamp
other ARCHs have. We need the 32-bit millisecond clock that U-Boot wants.

This patch adds 3 global variables; timestamp, cycles_per_jiffy, expirelo.
timestamp is a 32-bit non-overflowing CFG_HZ counter. cycles_per_jiffy is
calculated counter cycles in a CFG_HZ. And expirelo holds the count value
for next CPU timer expiration.

With these variables, fix each functions. Notably,

* timer_init: Initialize cycles_per_jiffy, timestamp, and expirelo. Note
  that we don't have to initialize CP0 count/compare registers here. They
  have been already cleared on the system reset. Leave them as they are.

* get_timer: Calculate how many timestamps have been passed, then return
  (relative) timestamp. I'm afraid we might suffer from a big catch up
  loop if this function is called after a long delay.

* get_ticks: Return the current timestamp, that is get_timer(0).

Most parts are from good old Linux v2.6.16 kernel.

Signed-off-by: Shinya Kuribayashi <skuribay@ruby.dti.ne.jp>
---

 lib_mips/time.c |   44 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 38 insertions(+), 6 deletions(-)


diff --git a/lib_mips/time.c b/lib_mips/time.c
index 154d792..4b47e41 100644
--- a/lib_mips/time.c
+++ b/lib_mips/time.c
@@ -24,31 +24,63 @@
 #include <common.h>
 #include <asm/mipsregs.h>
 
+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;
+
 /*
  * timer without interrupts
  */
 
 int timer_init(void)
 {
-	write_32bit_cp0_register(CP0_COMPARE, 0);
-	write_32bit_cp0_register(CP0_COUNT, 0);
+	/* 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,
+	       ((CONFIG_MIPS_TIMER_FREQ + 500) / 1000) % 1000);
+
+	/* Set up the timer for the first expiration. */
+	timestamp = 0;
+	expirelo = read_32bit_cp0_register(CP0_COUNT) + cycles_per_jiffy;
 
 	return 0;
 }
 
 void reset_timer(void)
 {
-	write_32bit_cp0_register(CP0_COUNT, 0);
+	timestamp = 0;
+	expirelo = read_32bit_cp0_register(CP0_COUNT) + cycles_per_jiffy;
 }
 
 ulong get_timer(ulong base)
 {
-	return read_32bit_cp0_register(CP0_COUNT) - base;
+	unsigned int count;
+
+	/* Check to see if we have missed any timestamps. */
+	count = read_32bit_cp0_register(CP0_COUNT);
+	while ((count - expirelo) < 0x7fffffff) {
+		/*
+		 * FIXME: We might suffer from a big catch up loop
+		 * if called after a long delay.
+		 */
+		expirelo += cycles_per_jiffy;
+		timestamp++;
+	}
+
+	return (timestamp - base);
 }
 
 void set_timer(ulong t)
 {
-	write_32bit_cp0_register(CP0_COUNT, t);
+	timestamp = t;
+	expirelo = read_32bit_cp0_register(CP0_COUNT) + cycles_per_jiffy;
 }
 
 void udelay(unsigned long usec)
@@ -67,7 +99,7 @@ void udelay(unsigned long usec)
  */
 unsigned long long get_ticks(void)
 {
-	return read_32bit_cp0_register(CP0_COUNT);
+	return get_timer(0);
 }
 
 /*

  reply	other threads:[~2008-05-24 13:02 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-20 16:24 [U-Boot-Users] [PATCH] [resend] mips: Support to set CFG_HZ to 1000, consistent with other architectures Jason McMullan
2008-05-21  3:53 ` Shinya Kuribayashi
2008-05-21 15:32   ` Scott Wood
2008-05-24 12:58     ` [U-Boot-Users] [PATCH 1/3][MIPS] lib_mips/time.c: Replace CP0 access functions with existing macros Shinya Kuribayashi
2008-05-24 12:59       ` [U-Boot-Users] [PATCH 2/3][MIPS] lib_mips/time.c: Fix udelay Shinya Kuribayashi
2008-05-24 13:02         ` Shinya Kuribayashi [this message]
2008-05-24 19:59           ` [U-Boot-Users] [PATCH 3/3][MIPS] lib_mips/time.c: Fix improper use of CFG_HZ and timer routines Wolfgang Denk
2008-05-25  2:04             ` Shinya Kuribayashi
2008-05-25  8:15               ` Wolfgang Denk
2008-05-25 13:45                 ` Shinya Kuribayashi
2008-05-25 15:18                   ` Wolfgang Denk
2008-05-31  6:12                     ` Shinya Kuribayashi
2008-05-31  6:17                       ` Shinya Kuribayashi
2008-05-31 14:40           ` [U-Boot-Users] [PATCH 3/3 v2][MIPS] lib_mips/time.c: Fix CP0 count register usage " Shinya Kuribayashi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=483811E4.3070209@ruby.dti.ne.jp \
    --to=skuribay@ruby.dti.ne.jp \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.