diff --git a/sys/arch/sun3/dev/dma.c b/sys/arch/sun3/dev/dma.c index c679492966f3..32cc4da63c4d 100644 --- a/sys/arch/sun3/dev/dma.c +++ b/sys/arch/sun3/dev/dma.c @@ -1,4 +1,4 @@ -/* $NetBSD: dma.c,v 1.16 2005/12/11 12:19:20 christos Exp $ */ +/* $NetBSD: dma.c,v 1.17 2007/02/03 05:17:30 tsutsui Exp $ */ /* * Copyright (c) 1994 Paul Kranenburg. All rights reserved. @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dma.c,v 1.16 2005/12/11 12:19:20 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dma.c,v 1.17 2007/02/03 05:17:30 tsutsui Exp $"); #include #include @@ -99,9 +99,23 @@ dmaattach(struct device *parent, struct device *self, void *aux) /* * Map in the registers. */ - sc->sc_regs = bus_mapin(ca->ca_bustype, ca->ca_paddr, - sizeof(struct dma_regs)); - sc->sc_rev = DMACSR(sc) & D_DEV_ID; + sc->sc_bst = ca->ca_bustag; + sc->sc_dmatag = ca->ca_dmatag; + if (bus_space_map(sc->sc_bst, ca->ca_paddr, DMAREG_SIZE, + 0, &sc->sc_bsh) != 0) { + printf(": can't map register\n"); + return; + } + /* + * Allocate dmamap. + */ + if (bus_dmamap_create(sc->sc_dmatag, MAXPHYS, 1, MAXPHYS, + 0, BUS_DMA_NOWAIT, &sc->sc_dmamap) != 0) { + printf(": can't create DMA map\n"); + return; + } + + sc->sc_rev = DMA_GCSR(sc) & D_DEV_ID; id = (sc->sc_rev >> 28) & 0xf; printf(": rev %d\n", id); @@ -133,57 +147,75 @@ espdmafind(int unit) #define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \ int count = 100000; \ - while ((COND) && --count > 0) DELAY(5); \ + while ((COND) && --count > 0) \ + DELAY(5); \ if (count == 0) { \ printf("%s: line %d: CSR = 0x%x\n", \ - __FILE__, __LINE__, DMACSR(SC)); \ + __FILE__, __LINE__, DMA_GCSR(SC)); \ if (DONTPANIC) \ printf(MSG); \ else \ panic(MSG); \ } \ -} while (0) +} while (/* CONSTCOND */0) #define DMA_DRAIN(sc, dontpanic) do { \ + uint32_t _csr; \ /* \ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \ * and "drain" bits while it is still thinking about a \ * request. \ * other revs: D_R_PEND bit reads as 0 \ */ \ - DMAWAIT(sc, DMACSR(sc) & D_R_PEND, "R_PEND", dontpanic); \ + DMAWAIT(sc, DMA_GCSR(sc) & D_R_PEND, "R_PEND", dontpanic); \ /* \ * Select drain bit (always rev 0,1) \ * also clears errors and D_TC flag \ */ \ - DMACSR(sc) |= D_DRAIN; \ + _csr = DMA_GCSR(sc); \ + _csr |= D_DRAIN; \ + DMA_SCSR(sc, _csr); \ /* \ * Wait for draining to finish \ */ \ - DMAWAIT(sc, DMACSR(sc) & D_PACKCNT, "DRAINING", dontpanic); \ -} while(0) + DMAWAIT(sc, DMA_GCSR(sc) & D_PACKCNT, "DRAINING", dontpanic); \ +} while (/* CONSTCOND */0) #define DMA_FLUSH(sc, dontpanic) do { \ + uint32_t _csr; \ /* \ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \ * and "drain" bits while it is still thinking about a \ * request. \ * other revs: D_R_PEND bit reads as 0 \ */ \ - DMAWAIT(sc, DMACSR(sc) & D_R_PEND, "R_PEND", dontpanic); \ - DMACSR(sc) &= ~(D_WRITE|D_EN_DMA); \ - DMACSR(sc) |= D_FLUSH; \ -} while(0) + DMAWAIT(sc, DMA_GCSR(sc) & D_R_PEND, "R_PEND", dontpanic); \ + _csr = DMA_GCSR(sc); \ + _csr &= ~(D_WRITE|D_EN_DMA); \ + DMA_SCSR(sc, _csr); \ + _csr |= D_FLUSH; \ + DMA_SCSR(sc, _csr); \ +} while (/* CONSTCOND */0) void dma_reset(struct dma_softc *sc) { + uint32_t csr; + + if (sc->sc_dmamap->dm_nsegs > 0) + bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); DMA_FLUSH(sc, 1); - DMACSR(sc) |= D_RESET; /* reset DMA */ + csr = DMA_GCSR(sc); + + csr |= D_RESET; /* reset DMA */ + DMA_SCSR(sc, csr); DELAY(200); /* what should this be ? */ + /*DMAWAIT1(sc); why was this here? */ - DMACSR(sc) &= ~D_RESET; /* de-assert reset line */ + csr = DMA_GCSR(sc); + csr &= ~D_RESET; /* de-assert reset line */ + DMA_SCSR(sc, csr); DELAY(5); /* allow a few ticks to settle */ /* @@ -192,7 +224,10 @@ dma_reset(struct dma_softc *sc) * Do we need it too? Apparently not, because the 3/80 * always has the old, REV zero DMA chip. */ - DMACSR(sc) |= D_INT_EN; /* enable interrupts */ + csr = DMA_GCSR(sc); + csr |= D_INT_EN; /* enable interrupts */ + + DMA_SCSR(sc, csr); sc->sc_active = 0; } @@ -212,7 +247,7 @@ dma_setup(struct dma_softc *sc, caddr_t *addr, size_t *len, int datain, DMA_FLUSH(sc, 0); #if 0 - DMACSR(sc) &= ~D_INT_EN; + DMA_SCSR(sc, DMA_GCSR(sc) & ~D_INT_EN); #endif sc->sc_dmaaddr = addr; sc->sc_dmalen = len; @@ -232,31 +267,27 @@ dma_setup(struct dma_softc *sc, caddr_t *addr, size_t *len, int datain, /* Program the DMA address */ if (sc->sc_dmasize) { - /* - * Use dvma mapin routines to map the buffer into DVMA space. - */ - sc->sc_dvmaaddr = *sc->sc_dmaaddr; - sc->sc_dvmakaddr = dvma_mapin(sc->sc_dvmaaddr, - sc->sc_dmasize, 0); - if (sc->sc_dvmakaddr == NULL) - panic("dma: cannot allocate DVMA address"); - sc->sc_dmasaddr = dvma_kvtopa(sc->sc_dvmakaddr, BUS_OBIO); - DMADDR(sc) = sc->sc_dmasaddr; - } else { - /* XXX: What is this about? -gwr */ - DMADDR(sc) = (uint32_t) *sc->sc_dmaaddr; + if (bus_dmamap_load(sc->sc_dmatag, sc->sc_dmamap, + *sc->sc_dmaaddr, sc->sc_dmasize, + NULL /* kernel address */, BUS_DMA_NOWAIT)) + panic("%s: cannot allocate DVMA address", + sc->sc_dev.dv_xname); + bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, + datain ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, DMA_REG_ADDR, + sc->sc_dmamap->dm_segs[0].ds_addr); } /* We never have DMAREV_ESC. */ /* Setup DMA control register */ - csr = DMACSR(sc); + csr = DMA_GCSR(sc); if (datain) csr |= D_WRITE; else csr &= ~D_WRITE; csr |= D_INT_EN; - DMACSR(sc) = csr; + DMA_SCSR(sc, csr); return 0; } @@ -271,23 +302,25 @@ dma_setup(struct dma_softc *sc, caddr_t *addr, size_t *len, int datain, int espdmaintr(struct dma_softc *sc) { - struct ncr53c9x_softc *nsc = sc->sc_esp; + struct ncr53c9x_softc *nsc = sc->sc_client; char bits[64]; int trans, resid; uint32_t csr; - csr = DMACSR(sc); + csr = DMA_GCSR(sc); NCR_DMA(("%s: intr: addr 0x%x, csr %s\n", sc->sc_dev.dv_xname, DMADDR(sc), bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits)))); if (csr & D_ERR_PEND) { - DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */ - DMACSR(sc) |= D_FLUSH; printf("%s: error: csr=%s\n", sc->sc_dev.dv_xname, bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits))); - return (-1); + csr &= ~D_EN_DMA; /* Stop DMA */ + DMA_SCSR(sc, csr); + csr |= D_FLUSH; + DMA_SCSR(sc, csr); + return -1; } /* This is an "assertion" :) */ @@ -297,7 +330,8 @@ espdmaintr(struct dma_softc *sc) DMA_DRAIN(sc, 0); /* DMA has stopped */ - DMACSR(sc) &= ~D_EN_DMA; + csr &= ~D_EN_DMA; + DMA_SCSR(sc, csr); sc->sc_active = 0; if (sc->sc_dmasize == 0) { @@ -365,8 +399,12 @@ espdmaintr(struct dma_softc *sc) cache_flush(*sc->sc_dmaaddr, trans); #endif - if (sc->sc_dvmakaddr) - dvma_mapout(sc->sc_dvmakaddr, sc->sc_dmasize); + if (sc->sc_dmamap->dm_nsegs > 0) { + bus_dmamap_sync(sc->sc_dmatag, sc->sc_dmamap, 0, sc->sc_dmasize, + (csr & D_WRITE) != 0 ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmatag, sc->sc_dmamap); + } *sc->sc_dmalen -= trans; *sc->sc_dmaaddr += trans; @@ -377,7 +415,7 @@ espdmaintr(struct dma_softc *sc) return 0; /* and again */ - dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMACSR(sc) & D_WRITE); + dma_start(sc, sc->sc_dmaaddr, sc->sc_dmalen, DMA_GCSR(sc) & D_WRITE); return 1; #endif return 0; diff --git a/sys/arch/sun3/dev/dmareg.h b/sys/arch/sun3/dev/dmareg.h index e53f5ce62508..5a70b868f9a3 100644 --- a/sys/arch/sun3/dev/dmareg.h +++ b/sys/arch/sun3/dev/dmareg.h @@ -1,4 +1,4 @@ -/* $NetBSD: dmareg.h,v 1.5 2005/12/11 12:19:20 christos Exp $ */ +/* $NetBSD: dmareg.h,v 1.6 2007/02/03 05:17:30 tsutsui Exp $ */ /* * Copyright (c) 1994 Peter Galbavy. All rights reserved. @@ -30,6 +30,13 @@ #define DMACSRBITS "\020\01INT\02ERR\03DR1\04DR2\05IEN\011WRITE\016ENCNT\017TC\032DMAON" +#define DMAREG_SIZE 0x10 + +#define DMA_REG_CSR 0x00 +#define DMA_REG_ADDR 0x04 +#define DMA_REG_BCNT 0x08 +#define DMA_REG_TEST 0x0c + struct dma_regs { uint32_t csr; /* DMA CSR */ /* bits common to all revs. */ diff --git a/sys/arch/sun3/dev/dmavar.h b/sys/arch/sun3/dev/dmavar.h index 07bd5491563e..d9a5d1f5bf92 100644 --- a/sys/arch/sun3/dev/dmavar.h +++ b/sys/arch/sun3/dev/dmavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: dmavar.h,v 1.6 2005/12/11 12:19:20 christos Exp $ */ +/* $NetBSD: dmavar.h,v 1.7 2007/02/03 05:17:30 tsutsui Exp $ */ /* * Copyright (c) 1994 Peter Galbavy. All rights reserved. @@ -30,14 +30,16 @@ struct dma_softc { struct device sc_dev; /* us as a device */ - struct ncr53c9x_softc *sc_esp; /* my scsi */ - volatile struct dma_regs *sc_regs; /* the registers */ + bus_space_tag_t sc_bst; /* bus space tag */ + bus_dma_tag_t sc_dmatag; /* bus dma tag */ + + bus_space_handle_t sc_bsh; /* bus space handle */ + void *sc_client; /* my client */ + int sc_active; /* DMA active ? */ + bus_dmamap_t sc_dmamap; /* bus dma map */ u_int sc_rev; /* revision */ int sc_burst; /* DVMA burst size in effect */ - caddr_t sc_dvmakaddr; /* DVMA cookies */ - caddr_t sc_dvmaaddr; /* */ - u_long sc_dmasaddr; /* Slave address */ size_t sc_dmasize; caddr_t *sc_dmaaddr; size_t *sc_dmalen; @@ -48,13 +50,47 @@ struct dma_softc { #endif }; -#define DMACSR(sc) ((sc)->sc_regs->csr) -#define DMADDR(sc) ((sc)->sc_regs->addr) -#define DMACNT(sc) ((sc)->sc_regs->bcnt) +#define DMA_GCSR(sc) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, DMA_REG_CSR) +#define DMA_SCSR(sc, csr) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, DMA_REG_CSR, (csr)) -struct dma_softc * espdmafind(int); +/* + * DMA engine interface functions. + */ +#if 0 +#define DMA_RESET(sc) (((sc)->reset)(sc)) +#define DMA_INTR(sc) (((sc)->intr)(sc)) +#define DMA_SETUP(sc, a, l, d, s) (((sc)->setup)(sc, a, l, d, s)) +#endif + +#define DMA_ISACTIVE(sc) ((sc)->sc_active) + +#define DMA_ENINTR(sc) do { \ + uint32_t _csr = DMA_GCSR(sc); \ + _csr |= D_INT_EN; \ + DMA_SCSR(sc, _csr); \ +} while (/* CONSTCOND */0) + +#define DMA_ISINTR(sc) (DMA_GCSR(sc) & (D_INT_PEND|D_ERR_PEND)) + +#define DMA_GO(sc) do { \ + uint32_t _csr = DMA_GCSR(sc); \ + _csr |= D_EN_DMA; \ + DMA_SCSR(sc, _csr); \ + sc->sc_active = 1; \ +} while (/* CONSTCOND */0) + +#define DMA_STOP(sc) do { \ + uint32_t _csr = DMA_GCSR(sc); \ + _csr &= ~D_EN_DMA; \ + DMA_SCSR(sc, _csr); \ + sc->sc_active = 0; \ +} while (/* CONSTCOND */0) + +struct dma_softc *espdmafind(int); +int espdmaintr(struct dma_softc *); void dma_reset(struct dma_softc *); int dma_setup(struct dma_softc *, caddr_t *, size_t *, int, size_t *); -int espdmaintr(struct dma_softc *); diff --git a/sys/arch/sun3/dev/esp.c b/sys/arch/sun3/dev/esp.c index 00cc9ae2c3ae..06a9717ea14f 100644 --- a/sys/arch/sun3/dev/esp.c +++ b/sys/arch/sun3/dev/esp.c @@ -1,4 +1,4 @@ -/* $NetBSD: esp.c,v 1.24 2007/01/23 15:58:22 tsutsui Exp $ */ +/* $NetBSD: esp.c,v 1.25 2007/02/03 05:17:30 tsutsui Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.24 2007/01/23 15:58:22 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: esp.c,v 1.25 2007/02/03 05:17:30 tsutsui Exp $"); #include #include @@ -157,7 +157,7 @@ espattach(struct device *parent, struct device *self, void *aux) * Hook up the DMA driver. */ esc->sc_dma = espdmafind(device_unit(&sc->sc_dev)); - esc->sc_dma->sc_esp = sc; /* Point back to us */ + esc->sc_dma->sc_client = sc; /* Point back to us */ /* * XXX More of this should be in ncr53c9x_attach(), but @@ -276,10 +276,8 @@ int esp_dma_isintr(struct ncr53c9x_softc *sc) { struct esp_softc *esc = (struct esp_softc *)sc; - uint32_t csr; - csr = DMACSR(esc->sc_dma); - return (csr & (D_INT_PEND|D_ERR_PEND)); + return DMA_ISINTR(esc->sc_dma); } void @@ -295,7 +293,7 @@ esp_dma_intr(struct ncr53c9x_softc *sc) { struct esp_softc *esc = (struct esp_softc *)sc; - return (espdmaintr(esc->sc_dma)); + return espdmaintr(esc->sc_dma); } int @@ -304,7 +302,7 @@ esp_dma_setup(struct ncr53c9x_softc *sc, caddr_t *addr, size_t *len, int datain, { struct esp_softc *esc = (struct esp_softc *)sc; - return (dma_setup(esc->sc_dma, addr, len, datain, dmasize)); + return dma_setup(esc->sc_dma, addr, len, datain, dmasize); } void @@ -312,9 +310,7 @@ esp_dma_go(struct ncr53c9x_softc *sc) { struct esp_softc *esc = (struct esp_softc *)sc; - /* Start DMA */ - DMACSR(esc->sc_dma) |= D_EN_DMA; - esc->sc_dma->sc_active = 1; + DMA_GO(esc->sc_dma); } void @@ -322,7 +318,7 @@ esp_dma_stop(struct ncr53c9x_softc *sc) { struct esp_softc *esc = (struct esp_softc *)sc; - DMACSR(esc->sc_dma) &= ~D_EN_DMA; + DMA_STOP(esc->sc_dma); } int @@ -330,5 +326,5 @@ esp_dma_isactive(struct ncr53c9x_softc *sc) { struct esp_softc *esc = (struct esp_softc *)sc; - return (esc->sc_dma->sc_active); + return DMA_ISACTIVE(esc->sc_dma); }