Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/footbridge Implement a proper delay routine for...



details:   https://anonhg.NetBSD.org/src/rev/a0d2baa08c48
branches:  trunk
changeset: 526482:a0d2baa08c48
user:      chris <chris%NetBSD.org@localhost>
date:      Sat May 04 10:04:42 2002 +0000

description:
Implement a proper delay routine for footbridge based systems.  Note that
until the footbridge is attached we still have to rely on a loop.  This
uses TIMER_3 running at 100Hz.
Sadly this doesn't appear to fix the tlp problems, which either means that this
delay routine is not as accurate as it should/could be or tlp is still broken.

diffstat:

 sys/arch/arm/footbridge/footbridge.c       |   6 +-
 sys/arch/arm/footbridge/footbridge.h       |   3 +-
 sys/arch/arm/footbridge/footbridge_clock.c |  65 ++++++++++++++++++++++++-----
 3 files changed, 60 insertions(+), 14 deletions(-)

diffs (140 lines):

diff -r 7e1a7f5db4d0 -r a0d2baa08c48 sys/arch/arm/footbridge/footbridge.c
--- a/sys/arch/arm/footbridge/footbridge.c      Sat May 04 09:37:24 2002 +0000
+++ b/sys/arch/arm/footbridge/footbridge.c      Sat May 04 10:04:42 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: footbridge.c,v 1.5 2002/04/12 18:50:31 thorpej Exp $   */
+/*     $NetBSD: footbridge.c,v 1.6 2002/05/04 10:04:42 chris Exp $     */
 
 /*
  * Copyright (c) 1997,1998 Mark Brinicombe.
@@ -203,6 +203,8 @@
        footbridge_create_mem_bs_tag(&footbridge_pci_mem_bs_tag,
            (void *)DC21285_PCI_MEM_BASE);
 
+       /* calibrate the delay loop */
+       calibrate_delay();
        /* Attach the PCI bus */
        fba.fba_pba.pba_busname = "pci";
        fba.fba_pba.pba_pc = &footbridge_pci_chipset;
@@ -228,7 +230,7 @@
        fba.fba_fca.fca_rx_irq = IRQ_SERIAL_RX;
        fba.fba_fca.fca_tx_irq = IRQ_SERIAL_TX;
        config_found(self, &fba.fba_fca, footbridge_print); 
-
+       
        /* Setup fast SA110 cache clean area */
 #ifdef CPU_SA110
        if (cputype == CPU_ID_SA110)
diff -r 7e1a7f5db4d0 -r a0d2baa08c48 sys/arch/arm/footbridge/footbridge.h
--- a/sys/arch/arm/footbridge/footbridge.h      Sat May 04 09:37:24 2002 +0000
+++ b/sys/arch/arm/footbridge/footbridge.h      Sat May 04 10:04:42 2002 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: footbridge.h,v 1.1 2002/01/05 22:41:47 chris Exp $  */
+/*      $NetBSD: footbridge.h,v 1.2 2002/05/04 10:04:42 chris Exp $  */
 
 #ifndef _FOOTBRIDGE_H_
 #define _FOOTBRIDGE_H_
@@ -11,5 +11,6 @@
 void footbridge_create_mem_bs_tag __P((struct bus_space *, void *));
 int fcomcnattach __P((u_int, int, tcflag_t));
 int fcomcndetach __P((void));
+void calibrate_delay __P((void));
 
 #endif
diff -r 7e1a7f5db4d0 -r a0d2baa08c48 sys/arch/arm/footbridge/footbridge_clock.c
--- a/sys/arch/arm/footbridge/footbridge_clock.c        Sat May 04 09:37:24 2002 +0000
+++ b/sys/arch/arm/footbridge/footbridge_clock.c        Sat May 04 10:04:42 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: footbridge_clock.c,v 1.5 2002/05/02 22:01:46 mycroft Exp $     */
+/*     $NetBSD: footbridge_clock.c,v 1.6 2002/05/04 10:04:42 chris Exp $       */
 
 /*
  * Copyright (c) 1997 Mark Brinicombe.
@@ -49,6 +49,7 @@
 
 #include <arm/footbridge/dc21285reg.h>
 #include <arm/footbridge/footbridgevar.h>
+#include <arm/footbridge/footbridge.h>
 
 extern struct footbridge_softc *clock_sc;
 extern u_int dc21285_fclk;
@@ -291,27 +292,69 @@
 }
 
 /*
- * Estimated loop for n microseconds
+ * Use a timer to track microseconds, if the footbridge hasn't been setup we
+ * rely on an estimated loop, however footbridge is attached very early on.
  */
 
-/* Need to re-write this to use the timers */
+static int delay_clock_count = 0;
+static int delay_count_per_usec = 0;
 
-/* One day soon I will actually do this */
+void
+calibrate_delay(void)
+{
+     delay_clock_count = load_timer(TIMER_3_BASE, 100);
+     delay_count_per_usec = delay_clock_count/10000;
+}
 
-int delaycount = 50;
+int delaycount = 500;
 
 void
 delay(n)
        u_int n;
 {
-       u_int i;
+       volatile u_int i;
+       uint32_t cur, last, delta, usecs;
 
        if (n == 0) return;
-       while (n-- > 0) {
-               if (cputype == CPU_ID_SA110)    /* XXX - Seriously gross hack */
-                       for (i = delaycount; --i;);
-               else
-                       for (i = 8; --i;);
+
+
+       // not calibrated the timer yet, so try to live with this horrible
+       // loop!
+       if (delay_clock_count == 0)
+       {
+           while (n-- > 0) {
+               for (i = delaycount; --i;);
+           }
+           return;     
+       }
+       last = bus_space_read_4(clock_sc->sc_iot, clock_sc->sc_ioh,
+               TIMER_3_VALUE);
+
+       delta = usecs = 0;
+
+       while (n > usecs)
+       {
+           cur = bus_space_read_4(clock_sc->sc_iot, clock_sc->sc_ioh,
+                   TIMER_3_VALUE);
+           if (last < cur)
+               /* timer has wrapped */
+               delta += ((delay_clock_count - cur) + last);
+           else
+               delta += (last - cur);
+           
+           if (last == 0 && cur == 0)
+           {
+               /* reset the timer, not sure this is really needed */
+               bus_space_write_4(clock_sc->sc_iot, clock_sc->sc_ioh,
+                       TIMER_3_CLEAR, 0);
+           }
+           last = cur;
+           
+           if (delta >= delay_count_per_usec)
+           {
+               usecs += delta / delay_count_per_usec;
+               delta %= delay_count_per_usec;
+           }
        }
 }
 



Home | Main Index | Thread Index | Old Index