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 v2][MIPS] lib_mips/time.c: Fix CP0 count register usage and timer routines
Date: Sat, 31 May 2008 23:40:48 +0900	[thread overview]
Message-ID: <48416370.1090107@ruby.dti.ne.jp> (raw)
In-Reply-To: <483811E4.3070209@ruby.dti.ne.jp>

MIPS port has two problems in timer routines. One is now we assume CFG_HZ
equals to 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 counter.

This patch introduces timestamp and CYCLES_PER_JIFFY. timestamp is a
32-bit non-overflowing CFG_HZ counter, and CYCLES_PER_JIFFY is the number
of calculated CP0 counter cycles in a CFG_HZ.

STRATEGY:

* Fix improper CFG_HZ value to have 1000

* Use CFG_MIPS_TIMER_FREQ for timer counter frequency, instead.

* timer_init: initialize timestamp and set up the first timer expiration.
  Note that we don't need to initialize CP0 count/compare registers here
  as they have been already zeroed out on the system reset. Leave them as
  they are.

* get_timer: calculate how many timestamps have been passed, then return
  base-relative timestamp. Make sure we can easily count missed timestamps
  regardless of CP0 count/compare value.

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

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

v2:
- Remove FIXME comments as they turned out to be trivial.
- Use CP0 compare register as a global variable for expirelo.
- Kill a global variable 'cycles_per_jiffy'. Use #define CYCLES_PER_JIFFY
  instead.

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

 include/configs/dbau1x00.h  |    4 +++-
 include/configs/gth2.h      |    4 +++-
 include/configs/incaip.h    |    4 +++-
 include/configs/pb1x00.h    |    4 +++-
 include/configs/purple.h    |    3 ++-
 include/configs/qemu-mips.h |    4 +++-
 include/configs/tb0229.h    |    4 +++-
 lib_mips/time.c             |   31 +++++++++++++++++++++++++------
 8 files changed, 45 insertions(+), 13 deletions(-)


diff --git a/include/configs/dbau1x00.h b/include/configs/dbau1x00.h
index b2f606f..45ff1e7 100644
--- a/include/configs/dbau1x00.h
+++ b/include/configs/dbau1x00.h
@@ -148,7 +148,9 @@
 #error "Invalid CPU frequency - must be multiple of 12!"
 #endif
 
-#define CFG_HZ                  (CFG_MHZ * 1000000) /* FIXME causes overflow in net.c */
+#define CFG_MIPS_TIMER_FREQ	(CFG_MHZ * 1000000)
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000     /* Cached addr */
 
diff --git a/include/configs/gth2.h b/include/configs/gth2.h
index c2a50c1..23618db 100644
--- a/include/configs/gth2.h
+++ b/include/configs/gth2.h
@@ -118,7 +118,9 @@
 
 #define CFG_MHZ			500
 
-#define CFG_HZ			(CFG_MHZ * 1000000) /* FIXME causes overflow in net.c */
+#define CFG_MIPS_TIMER_FREQ	(CFG_MHZ * 1000000)
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000     /* Cached addr */
 
diff --git a/include/configs/incaip.h b/include/configs/incaip.h
index 5ca00b3..2e4ee66 100644
--- a/include/configs/incaip.h
+++ b/include/configs/incaip.h
@@ -118,7 +118,9 @@
 
 #define CFG_BOOTPARAMS_LEN	128*1024
 
-#define CFG_HZ			(incaip_get_cpuclk() / 2)
+#define CFG_MIPS_TIMER_FREQ	(incaip_get_cpuclk() / 2)
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000
 
diff --git a/include/configs/pb1x00.h b/include/configs/pb1x00.h
index 810e0f0..181cd11 100644
--- a/include/configs/pb1x00.h
+++ b/include/configs/pb1x00.h
@@ -81,7 +81,9 @@
 
 #define CFG_BOOTPARAMS_LEN	128*1024
 
-#define CFG_HZ			396000000      /* FIXME causes overflow in net.c */
+#define CFG_MIPS_TIMER_FREQ	396000000
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000     /* Cached addr */
 
diff --git a/include/configs/purple.h b/include/configs/purple.h
index 1be4e05..ef92637 100644
--- a/include/configs/purple.h
+++ b/include/configs/purple.h
@@ -114,7 +114,8 @@
 #define	CFG_PROMPT		"PURPLE # "	/* Monitor Command Prompt    */
 #define	CFG_CBSIZE		256		/* Console I/O Buffer Size   */
 #define	CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)  /* Print Buffer Size */
-#define CFG_HZ			(CPU_CLOCK_RATE/2)
+#define CFG_MIPS_TIMER_FREQ	(CPU_CLOCK_RATE/2)
+#define CFG_HZ			1000
 #define	CFG_MAXARGS		16		/* max number of command args*/
 
 #define	CFG_LOAD_ADDR		0x80500000	/* default load address	*/
diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h
index d6bcc8e..3dfd218 100644
--- a/include/configs/qemu-mips.h
+++ b/include/configs/qemu-mips.h
@@ -120,7 +120,9 @@
 
 #define CFG_MHZ			132
 
-#define CFG_HZ			(CFG_MHZ * 1000000)
+#define CFG_MIPS_TIMER_FREQ	(CFG_MHZ * 1000000)
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000	/* Cached addr */
 
diff --git a/include/configs/tb0229.h b/include/configs/tb0229.h
index dadf5d3..fc2357d 100644
--- a/include/configs/tb0229.h
+++ b/include/configs/tb0229.h
@@ -122,7 +122,9 @@
 
 #define CFG_BOOTPARAMS_LEN	128*1024
 
-#define CFG_HZ			(CPU_TCLOCK_RATE/4)
+#define CFG_MIPS_TIMER_FREQ	(CPU_TCLOCK_RATE/4)
+
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000
 
diff --git a/lib_mips/time.c b/lib_mips/time.c
index fe36530..1e92789 100644
--- a/lib_mips/time.c
+++ b/lib_mips/time.c
@@ -24,31 +24,50 @@
 #include <common.h>
 #include <asm/mipsregs.h>
 
+static unsigned long timestamp;
+
+/* how many counter cycles in a jiffy */
+#define CYCLES_PER_JIFFY	(CFG_MIPS_TIMER_FREQ + CFG_HZ / 2) / CFG_HZ
+
 /*
  * timer without interrupts
  */
 
 int timer_init(void)
 {
-	write_c0_compare(0);
-	write_c0_count(0);
+	/* Set up the timer for the first expiration. */
+	timestamp = 0;
+	write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
 
 	return 0;
 }
 
 void reset_timer(void)
 {
-	write_c0_count(0);
+	timestamp = 0;
+	write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
 }
 
 ulong get_timer(ulong base)
 {
-	return read_c0_count() - base;
+	unsigned int count;
+	unsigned int expirelo = read_c0_compare();
+
+	/* Check to see if we have missed any timestamps. */
+	count = read_c0_count();
+	while ((count - expirelo) < 0x7fffffff) {
+		expirelo += CYCLES_PER_JIFFY;
+		timestamp++;
+	}
+	write_c0_compare(expirelo);
+
+	return (timestamp - base);
 }
 
 void set_timer(ulong t)
 {
-	write_c0_count(t);
+	timestamp = t;
+	write_c0_compare(read_c0_count() + CYCLES_PER_JIFFY);
 }
 
 void udelay(unsigned long usec)
@@ -66,7 +85,7 @@ void udelay(unsigned long usec)
  */
 unsigned long long get_ticks(void)
 {
-	return read_c0_count();
+	return get_timer(0);
 }
 
 /*

      parent reply	other threads:[~2008-05-31 14:40 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         ` [U-Boot-Users] [PATCH 3/3][MIPS] lib_mips/time.c: Fix improper use of CFG_HZ and timer routines Shinya Kuribayashi
2008-05-24 19:59           ` 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           ` Shinya Kuribayashi [this message]

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=48416370.1090107@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.