diff --git a/board/silverbox/silverbox.c b/board/silverbox/silverbox.c
index 28eab0c..961965b 100644
--- a/board/silverbox/silverbox.c
+++ b/board/silverbox/silverbox.c
@@ -70,21 +70,10 @@ #endif
 
 int checkboard (void)
 {
-	int configPR;
 #ifdef CONFIG_PCI
 	int mem_size = initdram(0) / (1024 * 1024);
 	int pci_mem_code;
-#endif /* CONFIG_PCI */
-
-	/* enable and start counter */
-	configPR = read_c0_configPR();
-	configPR &= ~0x8;
-	write_c0_configPR(configPR);
 
-	write_32bit_cp0_register(CP0_COUNT, 0);
-	write_32bit_cp0_register(CP0_COMPARE, 0xffffff);
-
-#ifdef CONFIG_PCI
 	/* Calc the PCI mem size code */
 	if (mem_size >= 128)
 		pci_mem_code = SIZE_128M;
diff --git a/cpu/mips/start.S b/cpu/mips/start.S
index 29c57c9..99a28c6 100644
--- a/cpu/mips/start.S
+++ b/cpu/mips/start.S
@@ -228,10 +228,6 @@ #endif
 	/* CAUSE register */
 	mtc0	zero, CP0_CAUSE
 
-	/* Init Timer */
-	mtc0	zero, CP0_COUNT
-	mtc0	zero, CP0_COMPARE
-
 	/* CONFIG0 register */
 	li	t0, CONF_CM_UNCACHED
 	mtc0	t0, CP0_CONFIG
diff --git a/include/configs/dbau1x00.h b/include/configs/dbau1x00.h
index 4cc5085..3206125 100644
--- a/include/configs/dbau1x00.h
+++ b/include/configs/dbau1x00.h
@@ -112,7 +112,8 @@ #if (CFG_MHZ % 12) != 0
 #error "Invalid CPU frequency - must be multiple of 12!"
 #endif
 
-#define CFG_HZ                  (CFG_MHZ * 1000000) /* FIXME causes overflow in net.c */
+#define CFG_CP0_COUNT_RATE	(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 a49ed3b..0a56b6f 100644
--- a/include/configs/gth2.h
+++ b/include/configs/gth2.h
@@ -93,7 +93,8 @@ #define CFG_BOOTPARAMS_LEN	128*1024
 
 #define CFG_MHZ			500
 
-#define CFG_HZ			(CFG_MHZ * 1000000) /* FIXME causes overflow in net.c */
+#define CFG_CP0_COUNT_RATE	(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 1c6216b..c62c57a 100644
--- a/include/configs/incaip.h
+++ b/include/configs/incaip.h
@@ -33,7 +33,7 @@ #define CONFIG_INCA_IP		1	/* on a INCA-I
 
 #ifndef	CPU_CLOCK_RATE
 /* allowed values: 100000000, 133000000, and 150000000 */
-#define CPU_CLOCK_RATE	150000000	/* default: 150 MHz clock for the MIPS core */
+#define CPU_CLOCK_RATE		150000000	/* default: 150 MHz clock for the MIPS core */
 #endif
 
 #define INFINEON_EBU_BOOTCFG	0x40C4	/* CMULT = 8 */
@@ -104,7 +104,8 @@ #define CFG_MALLOC_LEN		128*1024
 
 #define CFG_BOOTPARAMS_LEN	128*1024
 
-#define CFG_HZ			(incaip_get_cpuclk() / 2)
+#define CFG_CP0_COUNT_RATE	(incaip_get_cpuclk() / 2)
+#define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000
 
diff --git a/include/configs/purple.h b/include/configs/purple.h
index 2ecb7fb..28d11e5 100644
--- a/include/configs/purple.h
+++ b/include/configs/purple.h
@@ -31,8 +31,8 @@ #define __CONFIG_H
 #define CONFIG_MIPS32		1	/* MIPS 5Kc CPU core	*/
 #define CONFIG_PURPLE		1	/* on a PURPLE Board	*/
 
-#define CPU_CLOCK_RATE	125000000   /* 125 MHz clock for the MIPS core */
-#define ASC_CLOCK_RATE	 62500000   /* 62.5 MHz ASC clock              */
+#define CPU_CLOCK_RATE		125000000   /* 125 MHz clock for the MIPS core */
+#define ASC_CLOCK_RATE		62500000   /* 62.5 MHz ASC clock              */
 
 #define INFINEON_EBU_BOOTCFG	0xE0CC
 
@@ -99,7 +99,8 @@ #define	CFG_LONGHELP				/* undef to save
 #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_CP0_COUNT_RATE	(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/silverbox.h b/include/configs/silverbox.h
index 66843f8..122ed60 100644
--- a/include/configs/silverbox.h
+++ b/include/configs/silverbox.h
@@ -79,6 +79,7 @@ #define CFG_MALLOC_LEN		128*1024
 
 #define CFG_BOOTPARAMS_LEN	128*1024
 
+#define CFG_CP0_COUNT_RATE	250000000	/* Equal to CPU core frequency */
 #define CFG_HZ			1000
 
 #define CFG_SDRAM_BASE		0x80000000     /* Cached addr */
diff --git a/lib_mips/time.c b/lib_mips/time.c
index cd8dc72..9c9529c 100644
--- a/lib_mips/time.c
+++ b/lib_mips/time.c
@@ -22,62 +22,56 @@
  */
 
 #include <common.h>
+#include <asm/mipsregs.h>
 
-
-static inline void mips_compare_set(u32 v)
-{
-	asm volatile ("mtc0 %0, $11" : : "r" (v));
-}
-
-static inline void mips_count_set(u32 v)
-{
-	asm volatile ("mtc0 %0, $9" : : "r" (v));
-}
-
-
-static inline u32 mips_count_get(void)
-{
-	u32 count;
-
-	asm volatile ("mfc0 %0, $9" : "=r" (count) :);
-	return count;
-}
+#define TICKS_PER_USEC		1000000
 
 /*
  * timer without interrupts
  */
-
 int timer_init(void)
 {
-	mips_compare_set(0);
-	mips_count_set(0);
+#ifdef CONFIG_MIPS_CPU_PR4450
+	int configPR;
 
-	return 0;
-}
+	/* enable and start counter */
+	configPR = read_c0_configPR();
+	configPR &= ~0x8;
+	write_c0_configPR(configPR);
 
-void reset_timer(void)
-{
-	mips_count_set(0);
-}
+#endif /* CONFIG_MIPS_CPU_PR4450 */
 
-ulong get_timer(ulong base)
-{
-	return mips_count_get() - base;
+	write_32bit_cp0_register(CP0_COUNT, 0);
+	write_32bit_cp0_register(CP0_COMPARE, ~0);
+
+	return 0;
 }
 
-void set_timer(ulong t)
+ulong get_timer(ulong base)
 {
-	mips_count_set(t);
+	return (read_32bit_cp0_register(CP0_COUNT)/(CFG_CP0_COUNT_RATE/CFG_HZ)) - base;
 }
 
 void udelay (unsigned long usec)
 {
-	ulong tmo;
-	ulong start = get_timer(0);
+	ulong startTicks = read_32bit_cp0_register(CP0_COUNT);
+	ulong delayTicks = usec*(CFG_CP0_COUNT_RATE/TICKS_PER_USEC);
+	ulong endTicks;
+
+	/* Safeguard for too-long delays */
+	if (delayTicks >= 0x80000000)
+		delayTicks = 0x7FFFFFFF;
+
+	/* Calculate end of delay (once) */
+	endTicks = startTicks + delayTicks;
+
+	/* If end of delay is behind COUNT rol-over, wait for COUNT to rol-over first */
+	while ((read_32bit_cp0_register(CP0_COUNT) & 0x80000000) > (endTicks & 0x80000000))
+		; /* nop */
 
-	tmo = usec * (CFG_HZ / 1000000);
-	while ((ulong)((mips_count_get() - start)) < tmo)
-		/*NOP*/;
+	/* Wait for end of delay */
+	while (read_32bit_cp0_register(CP0_COUNT) < endTicks)
+		; /* nop */
 }
 
 /*
@@ -86,7 +80,7 @@ void udelay (unsigned long usec)
  */
 unsigned long long get_ticks(void)
 {
-	return mips_count_get();
+	return read_32bit_cp0_register(CP0_COUNT);
 }
 
 /*
@@ -95,5 +89,5 @@ unsigned long long get_ticks(void)
  */
 ulong get_tbclk(void)
 {
-	return CFG_HZ;
+	return CFG_CP0_COUNT_RATE;
 }
