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