Subject: Re: fas and hme support
To: None <eeh@netbsd.org, thorpej@nas.nasa.gov>
From: Chris Torek <torek@BSDI.COM>
List: port-sparc
Date: 12/25/1999 16:23:32
>> Really?  Is the `fas' DMA engine really *just like* the LSI Logic DMA chip on
>> the Sun4{c,m}?

>The register map looks the same.  Some of the bits inside the
>registers may have changed slightly, but then I don't have the spec
>for either MACIO or FEPS.

The DMA bits are substantially different.  There are some I never
figured out (the "wide enable" bit seems to have no effect, for
instance).  The most important difference, and the one that caused
me no end of trouble, is that the chip apparently has a bug in its
logic that requires a reset before (or after) *every* DMA op, rather
than "when it is in an unknown state".  This one was not, as far
as I could tell, documented anywhere (the other bits are).

The actual code I use in BSD/OS, post-DMA:

	case DMAREV_HME:
		/*
		 * HME DMA auto-drains, but requires reset after every op!
		 * FEPS book says not to set RESET while RP|DRAINING;
		 * they should both be clear here, but we'll try the belt
		 * and suspenders approach, with a temporary printf just
		 * to see if it happens...
		 */
		if (dma->dma_csr & (DMA_RP | DMA_HME_DRAINING)) {
printf("%s: note: dmacsr = %b (should not happen?)\n",
sc->sc_dev.dv_xname, dma->dma_csr, sc->sc_dc->dc_fmt);
			(void) dma_wait0(sc->sc_dc, dma,
			    DMA_RP | DMA_HME_DRAINING);
		}

		/*
		 * Change only the DMA_RESET bit.  The HME DMA chip is
		 * picky about this -- I tried setting DMA_RESET, then
		 * letting the code after the "break" clear it, and lost
		 * interrupts.  (We last set the csr to whatever is in
		 * dmactl now, so we need not read it back here.)
		 */
		dma->dma_csr = dmactl | DMA_RESET;
		dma->dma_csr = dmactl;
		dma->dma_addr = 0;	/* for FEPS 2.2 hw bug */
		break;

Chris