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.
This commit is contained in:
parent
7cd3e3bad5
commit
6c4ac1de6e
|
@ -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_attach(parent, self, aux)
|
|||
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 @@ footbridge_attach(parent, self, aux)
|
|||
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)
|
||||
|
|
|
@ -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_io_bs_tag __P((struct bus_space *, void *));
|
|||
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
|
||||
|
|
|
@ -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 @@ microtime(tvp)
|
|||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue