- jump to real flash location after reset before turning off flash mirror
 - fix timer system to use HZ == 1000, remove broken interrupt-based code

Signed-off-by: Michael Schwingen <mich...@schwingen.org>
---
 arch/arm/cpu/ixp/cpu.c                 |    5 --
 arch/arm/cpu/ixp/start.S               |   59 ++--------------
 arch/arm/cpu/ixp/timer.c               |  125 +++++++++++++++-----------------
 arch/arm/include/asm/arch-ixp/ixp425.h |    5 +-
 4 files changed, 66 insertions(+), 128 deletions(-)

diff --git a/arch/arm/cpu/ixp/cpu.c b/arch/arm/cpu/ixp/cpu.c
index ce275e5..942845d 100644
--- a/arch/arm/cpu/ixp/cpu.c
+++ b/arch/arm/cpu/ixp/cpu.c
@@ -36,8 +36,6 @@
 #include <asm/arch/ixp425.h>
 #include <asm/system.h>
 
-ulong loops_per_jiffy;
-
 static void cache_flush(void);
 
 #if defined(CONFIG_DISPLAY_CPUINFO)
@@ -51,17 +49,14 @@ int print_cpuinfo (void)
        puts("CPU:   Intel IXP425 at ");
        switch ((id & 0x000003f0) >> 4) {
        case 0x1c:
-               loops_per_jiffy = 887467;
                speed = 533;
                break;
 
        case 0x1d:
-               loops_per_jiffy = 666016;
                speed = 400;
                break;
 
        case 0x1f:
-               loops_per_jiffy = 442901;
                speed = 266;
                break;
        }
diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S
index 9f8c15b..2c49aa4 100644
--- a/arch/arm/cpu/ixp/start.S
+++ b/arch/arm/cpu/ixp/start.S
@@ -65,7 +65,8 @@
        .endm
 
 .globl _start
-_start: b      reset
+_start:
+       ldr     pc, _reset
        ldr     pc, _undefined_instruction
        ldr     pc, _software_interrupt
        ldr     pc, _prefetch_abort
@@ -74,6 +75,7 @@ _start: b     reset
        ldr     pc, _irq
        ldr     pc, _fiq
 
+_reset:                 .word reset
 _undefined_instruction: .word undefined_instruction
 _software_interrupt:   .word software_interrupt
 _prefetch_abort:       .word prefetch_abort
@@ -163,12 +165,6 @@ reset:
        str     r1, [r2]
 
        /* make sure flash is visible at 0 */
-#if 0
-       ldr     r2, =IXP425_EXP_CFG0
-       ldr     r1, [r2]
-       orr     r1, r1, #0x80000000
-       str     r1, [r2]
-#endif
        mov     r1, #CONFIG_SYS_SDR_CONFIG
        ldr     r2, =IXP425_SDR_CONFIG
        str     r1, [r2]
@@ -212,19 +208,6 @@ reset:
        str     r1, [r4]
        DELAY_FOR 0x4000, r0
 
-       /* copy */
-       mov     r0, #0
-       mov     r4, r0
-       add     r2, r0, #CONFIG_SYS_MONITOR_LEN
-       mov     r1, #0x10000000
-       mov     r5, r1
-
-    30:
-       ldr     r3, [r0], #4
-       str     r3, [r1], #4
-       cmp     r0, r2
-       bne     30b
-
        /* invalidate I & D caches & BTB */
        mcr     p15, 0, r0, c7, c7, 0
        CPWAIT  r0
@@ -237,19 +220,12 @@ reset:
        mcr     p15, 0, r0, c7, c10, 4
        CPWAIT  r0
 
-       /* move flash to 0x50000000 */
+       /* remove flash mirror at 0x00000000 */
        ldr     r2, =IXP425_EXP_CFG0
        ldr     r1, [r2]
        bic     r1, r1, #0x80000000
        str     r1, [r2]
 
-       nop
-       nop
-       nop
-       nop
-       nop
-       nop
-
        /* invalidate I & Data TLB */
        mcr     p15, 0, r0, c8, c7, 0
        CPWAIT r0
@@ -265,7 +241,7 @@ reset:
        orr     r0,r0,#0x13
        msr     cpsr,r0
 
-/* Set stackpointer in internal RAM to call board_init_f */
+/* Set initial stackpointer in SDRAM to call board_init_f */
 call_board_init_f:
        ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
        bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
@@ -578,28 +554,3 @@ reset_endless:
 
        b       reset_endless
 
-#ifdef CONFIG_USE_IRQ
-
-.LC0:          .word   loops_per_jiffy
-
-/*
- * 0 <= r0 <= 2000
- */
-.globl __udelay
-__udelay:
-       mov     r2,     #0x6800
-       orr     r2, r2, #0x00db
-       mul     r0, r2, r0
-       ldr     r2, .LC0
-       ldr     r2, [r2]                @ max = 0x0fffffff
-       mov     r0, r0, lsr #11         @ max = 0x00003fff
-       mov     r2, r2, lsr #11         @ max = 0x0003ffff
-       mul     r0, r2, r0              @ max = 2^32-1
-       movs    r0, r0, lsr #6
-
-delay_loop:
-       subs    r0, r0, #1
-       bne     delay_loop
-       mov     pc, lr
-
-#endif /* CONFIG_USE_IRQ */
diff --git a/arch/arm/cpu/ixp/timer.c b/arch/arm/cpu/ixp/timer.c
index edf341f..54a7a55 100644
--- a/arch/arm/cpu/ixp/timer.c
+++ b/arch/arm/cpu/ixp/timer.c
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2010
+ * Michael Schwingen, mich...@schwingen.org
+ *
  * (C) Copyright 2006
  * Stefan Roese, DENX Software Engineering, s...@denx.de.
  *
@@ -31,105 +34,95 @@
 
 #include <common.h>
 #include <asm/arch/ixp425.h>
-
-#ifdef CONFIG_TIMER_IRQ
-
-#define FREQ           66666666
-#define CLOCK_TICK_RATE        (((FREQ / CONFIG_SYS_HZ & 
~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ)
-#define LATCH          ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ)   
/* For divider */
+#include <div64.h>
 
 /*
- * When interrupts are enabled, use timer 2 for time/delay generation...
+ * The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a
+ * 33.333MHz crystal).
  */
-
-static volatile ulong timestamp;
-
-static void timer_isr(void *data)
+static inline unsigned long long tick_to_time(unsigned long long tick)
 {
-       unsigned int *pTime = (unsigned int *)data;
-
-       (*pTime)++;
-
-       /*
-        * Reset IRQ source
-        */
-       *IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
+       tick *= CONFIG_SYS_HZ;
+       do_div(tick, CONFIG_IXP425_TIMER_CLK);
+       return tick;
 }
 
-ulong get_timer (ulong base)
+static inline unsigned long long time_to_tick(unsigned long long time)
 {
-       return timestamp - base;
+       time *= CONFIG_IXP425_TIMER_CLK;
+       do_div(time, CONFIG_SYS_HZ);
+       return time;
 }
 
-void reset_timer (void)
+static inline unsigned long long us_to_tick(unsigned long long us)
 {
-       timestamp = 0;
+       us = us * CONFIG_IXP425_TIMER_CLK + 999999;
+       do_div(us, 1000000);
+       return us;
 }
 
-int timer_init (void)
+static ulong timestamp;
+static ulong lastinc;
+
+unsigned long long get_ticks (void)
 {
-       /* install interrupt handler for timer */
-       irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)&timestamp);
+       ulong now = *IXP425_OSTS_B;
 
-       /* setup the Timer counter value */
-       *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
+       if (*IXP425_OSST & IXP425_OSST_TIMER_TS_PEND) {
+               /* rollover of timestamp timer register */
+               timestamp += (0xFFFFFFFF - lastinc) + now + 1;
+               *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND;
+       }
+       else {
+               /* move stamp forward with absolut diff ticks */
+               timestamp += (now - lastinc);
+       }
+       lastinc = now;
+       return timestamp;
+}
 
-       /* enable timer irq */
-       *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
 
-       return 0;
-}
-#else
-ulong get_timer (ulong base)
+void reset_timer_masked (void)
 {
-       return get_timer_masked () - base;
+       /* reset time */
+       lastinc = *IXP425_OSTS_B; /* capture current timestamp counter */
+       timestamp = 0;          /* start "advancing" time stamp from 0 */
 }
 
-void ixp425_udelay(unsigned long usec)
+void reset_timer(void)
 {
-       /*
-        * This function has a max usec, but since it is called from udelay
-        * we should not have to worry... be happy
-        */
-       unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK;
-
-       *IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
-       usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE;
-       *IXP425_OSRT1 = usecs;
-       while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND));
+       reset_timer_masked();
 }
 
-void __udelay (unsigned long usec)
+ulong get_timer_masked (void)
 {
-       while (usec--) ixp425_udelay(1);
+       return tick_to_time(get_ticks());
 }
 
-static ulong reload_constant = 0xfffffff0;
-
-void reset_timer_masked (void)
+ulong get_timer (ulong base)
 {
-       ulong reload = reload_constant | IXP425_OST_ONE_SHOT | 
IXP425_OST_ENABLE;
+       return get_timer_masked() - base;
+}
 
-       *IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
-       *IXP425_OSRT1 = reload;
+void set_timer (ulong t)
+{
+       timestamp = time_to_tick(t);
 }
 
-ulong get_timer_masked (void)
+/* delay x useconds AND preserve advance timestamp value */
+void __udelay (unsigned long usec)
 {
-       /*
-        * Note that it is possible for this to wrap!
-        * In this case we return max.
-        */
-       ulong current = *IXP425_OST1;
-       if (*IXP425_OSST & IXP425_OSST_TIMER_1_PEND)
-       {
-               return reload_constant;
-       }
-       return (reload_constant - current);
+       unsigned long long tmp;
+
+       tmp = get_ticks() + us_to_tick(usec);
+
+       while (get_ticks() < tmp)
+               ;
 }
 
+
 int timer_init(void)
 {
+       *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND;
        return 0;
 }
-#endif
diff --git a/arch/arm/include/asm/arch-ixp/ixp425.h 
b/arch/arm/include/asm/arch-ixp/ixp425.h
index 2114437..ddbf713 100644
--- a/arch/arm/include/asm/arch-ixp/ixp425.h
+++ b/arch/arm/include/asm/arch-ixp/ixp425.h
@@ -391,9 +391,8 @@
 #define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
 #endif
 
-#if 0 /* test-only: also defined in npe/include/... */
-#define IXP425_OSTS    IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
-#endif
+/* _B to avoid collision: also defined in npe/include/... */
+#define IXP425_OSTS_B  IXP425_TIMER_REG(IXP425_OSTS_OFFSET) 
 #define IXP425_OST1    IXP425_TIMER_REG(IXP425_OST1_OFFSET)
 #define IXP425_OSRT1   IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
 #define IXP425_OST2    IXP425_TIMER_REG(IXP425_OST2_OFFSET)
-- 
1.7.2.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to