Add ARM946E cpu and core module targets; remap memory to 0x00000000
Patch by Peter Pearse, 2 Feb 2005
diff --git a/board/integratorap/integratorap.c b/board/integratorap/integratorap.c
index fb83c82..6140a7a 100644
--- a/board/integratorap/integratorap.c
+++ b/board/integratorap/integratorap.c
@@ -477,3 +477,140 @@
 {
 	return 0;
 }
+
+/* The Integrator/AP timer1 is clocked at 24MHz
+ * can be divided by 16 or 256
+ * and is a 16-bit counter
+ */
+/* U-Boot expects a 32 bit timer running at CFG_HZ*/
+static ulong timestamp;		/* U-Boot ticks since startup         */
+static ulong total_count = 0;	/* Total timer count                  */
+static ulong lastdec;		/* Timer reading at last call         */
+static ulong div_clock   = 256;	/* Divisor applied to the timer clock */
+static ulong div_timer   = 1;	/* Divisor to convert timer reading   
+                                 * change to U-Boot ticks
+                                 */
+/* CFG_HZ = CFG_HZ_CLOCK/(div_clock * div_timer) */
+
+#define TIMER_LOAD_VAL 0x0000FFFFL
+#define READ_TIMER ((*(volatile ulong *)(CFG_TIMERBASE+4)) & 0x0000FFFFL)
+
+/* all function return values in U-Boot ticks i.e. (1/CFG_HZ) sec 
+ *  - unless otherwise stated
+ */
+
+/* starts a counter 
+ * - the Integrator/AP timer issues an interrupt 
+ *   each time it reaches zero 
+ */
+int interrupt_init (void)
+{
+	/* Load timer with initial value */
+	*(volatile ulong *)(CFG_TIMERBASE + 0) = TIMER_LOAD_VAL;
+	/* Set timer to be
+	 * 	enabled           1
+	 * 	free-running      0
+         * 	XX               00
+	 * 	divider 256      10
+         * 	XX               00
+	 */
+	*(volatile ulong *)(CFG_TIMERBASE + 8) = 0x00000088;
+	total_count = 0;
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	div_timer  = CFG_HZ_CLOCK / CFG_HZ;
+	div_timer /= div_clock;
+
+	return (0);
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer (void)
+{
+	reset_timer_masked ();
+}
+
+ulong get_timer (ulong base_ticks)
+{
+	return get_timer_masked () - base_ticks;
+}
+
+void set_timer (ulong ticks)
+{
+	timestamp = ticks;
+	total_count = ticks * div_timer;
+	reset_timer_masked();
+}
+
+/* delay x useconds */
+void udelay (unsigned long usec)
+{
+	ulong tmo, tmp;
+
+	/* Convert to U-Boot ticks */
+	tmo  = usec * CFG_HZ;
+	tmo /= (1000000L);
+
+	tmp  = get_timer_masked();	/* get current timestamp */
+	tmo += tmp;			/* wake up timestamp     */
+
+	while (get_timer_masked () < tmo)/* loop till event */
+	{
+		/*NOP*/;
+	}
+}
+
+void reset_timer_masked (void)
+{
+	/* reset time */
+	lastdec   = READ_TIMER;	/* capture current decrementer value   */
+	timestamp = 0;		/* start "advancing" time stamp from 0 */
+}
+
+/* converts the timer reading to U-Boot ticks          */
+/* the timestamp is the number of ticks since reset    */
+/* This routine does not detect wraps unless called regularly
+   ASSUMES a call at least every 16 seconds to detect every reload */
+ulong get_timer_masked (void)
+{
+	ulong now = READ_TIMER;		/* current count */
+
+	if(now > lastdec)
+	{
+		/* Must have wrapped */
+		total_count += lastdec + TIMER_LOAD_VAL + 1 - now; 	
+	} else {
+		total_count += lastdec - now;
+	}
+	lastdec   = now;
+	timestamp = total_count/div_timer;
+
+	return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked (unsigned long usec)
+{
+    udelay(usec);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * Return the timebase clock frequency
+ * i.e. how often the timer decrements
+ */
+ulong get_tbclk (void)
+{
+	return CFG_HZ_CLOCK/div_clock;
+}