Date: Fri, 13 Aug 2010 11:43:39 GMT From: Jakub Wojciech Klama <jceel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 182351 for review Message-ID: <201008131143.o7DBhdY7007770@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@182351?ac=10 Change 182351 by jceel@jceel on 2010/08/13 11:42:59 EDMA3 driver cleanups & add support for GPDMA_TRANSFER_BLOCKING flag. Affected files ... .. //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#6 edit Differences ... ==== //depot/projects/soc2010/jceel_dma/sys/arm/davinci/davinci_edma.c#6 (text+ko) ==== @@ -139,6 +139,8 @@ struct davinci_edma_desc *); static void davinci_edma_printdesc(struct davinci_edma_softc *, int); static uint64_t ffs64(uint64_t); +static uint64_t davinci_edma_read64(struct davinci_edma_softc *, uint32_t, + uint32_t); #define davinci_edma_lock(sc) \ mtx_lock(&sc->ds_mtx) @@ -149,15 +151,15 @@ #define davinci_edma_channel_unlock(ch) \ mtx_unlock(&ch->dc_mtx) -#define davinci_read_edmacc_4(_sc, _reg) \ +#define davinci_read_edmacc_4(_sc, _reg) \ bus_space_read_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMACC_BASE + (_reg)) -#define davinci_write_edmacc_4(_sc, _reg, _data) \ +#define davinci_write_edmacc_4(_sc, _reg, _data) \ bus_space_write_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMACC_BASE + (_reg), (_data)) -#define davinci_read_edmatc_4(_sc, _tc, _reg) \ +#define davinci_read_edmatc_4(_sc, _tc, _reg) \ bus_space_read_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMATC ## _tc ## _BASE + (_reg)) #define davinci_write_edmatc_4(_sc, _tc, _reg, _data) \ bus_space_write_4((_sc)->ds_bst, (_sc)->ds_bsh, DAVINCI_EDMATC ## _tc ## _BASE + (_reg), (_data)) -#define davinci_edma_copydesc(_sc, _desc, _idx) \ +#define davinci_edma_copydesc(_sc, _desc, _idx) \ memcpy((uint8_t *)(DAVINCI_EDMA_BASE + DAVINCI_EDMA_PARAM(_idx)), (_desc), sizeof(param_desc)) static int @@ -297,19 +299,27 @@ if (chno > 31) { chno -= 32; - davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESRH, (1 << chno)); + if (!(xfer->dt_flags & GPDMA_TRANSFER_BLOCKING)) + davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESRH, + (1 << chno)); + davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EESRH, (1 << chno)); } else { - davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESR, (1 << chno)); + if (!(xfer->dt_flags & GPDMA_TRANSFER_BLOCKING)) + davinci_write_edmacc_4(sc, DAVINCI_EDMACC_IESR, + (1 << chno)); + davinci_write_edmacc_4(sc, DAVINCI_EDMACC_EESR, (1 << chno)); } + if (xfer->dt_src.db_needsync) + bus_dmamap_sync(xfer->dt_src.db_dmatag, xfer->dt_src.db_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + if (xfer->dt_dst.db_needsync) + bus_dmamap_sync(xfer->dt_dst.db_dmatag, xfer->dt_dst.db_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(xfer->dt_src.db_dmatag, xfer->dt_src.db_dmamap, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(xfer->dt_dst.db_dmatag, xfer->dt_dst.db_dmamap, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - debugf("channel setup done."); return (0); @@ -338,24 +348,45 @@ { struct davinci_edma_softc *sc = device_get_softc(dev); struct davinci_edma_channel *ch; - uint32_t reg; + uint32_t reg, tmp_chno; + uint64_t emr; + int status; debugf("start channel chno=%d", chno); ch = &sc->ds_channels[chno]; + tmp_chno = chno; - if (ch->dc_status == CHANNEL_ACTIVE) { + if (ch->dc_status == CHANNEL_ACTIVE) return (EINPROGRESS); - } if (chno > 31) { - chno -= 32; + tmp_chno -= 32; reg = DAVINCI_EDMACC_ESRH; } else reg = DAVINCI_EDMACC_ESR; - davinci_write_edmacc_4(sc, reg, (1 << chno)); + davinci_write_edmacc_4(sc, reg, (1 << tmp_chno)); ch->dc_status = CHANNEL_ACTIVE; + + if (ch->dc_xfer->dt_flags & GPDMA_TRANSFER_BLOCKING) { + for (;;) { + davinci_edma_poll_channel(dev, chno, &status); + if (status != GPDMA_TRANSFER_INPROGRESS) + break; + } + + /* Check for errors */ + emr = davinci_edma_read64(sc, DAVINCI_EDMACC_EMR, + DAVINCI_EDMACC_EMRH); + if (emr & (1 << chno)) + ch->dc_laststatus = GPDMA_TRANSFER_ERROR; + else + ch->dc_laststatus = GPDMA_TRANSFER_COMPLETED; + + ch->dc_status = CHANNEL_IDLE; + } + return (0); } @@ -404,15 +435,13 @@ struct davinci_edma_channel *ch; struct gpdma_transfer *xfer = NULL; uint64_t ipr; - uint32_t iprl, iprh; int chno; debugf("transfer completion interrupt"); while (1) { - iprl = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_IPR); - iprh = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_IPRH); - ipr = (uint64_t)iprh << 32 | iprl; + ipr = davinci_edma_read64(sc, DAVINCI_EDMACC_IPR, + DAVINCI_EDMACC_IPRH); if (ipr == 0) return; @@ -469,12 +498,9 @@ struct davinci_edma_channel *ch; struct gpdma_transfer *xfer = NULL; uint64_t emr; - uint32_t emrl, emrh; int chno; - emrl = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_EMR); - emrh = davinci_read_edmacc_4(sc, DAVINCI_EDMACC_EMRH); - emr = (uint64_t)emrh << 32 | emrl; + emr = davinci_edma_read64(sc, DAVINCI_EDMACC_EMR, DAVINCI_EDMACC_EMRH); if (emr == 0) return; @@ -691,6 +717,17 @@ return (bit); } +static __inline uint64_t +davinci_edma_read64(struct davinci_edma_softc *sc, uint32_t reg1, + uint32_t reg2) +{ + uint32_t vall, valh; + + vall = davinci_read_edmacc_4(sc, reg1); + valh = davinci_read_edmacc_4(sc, reg2); + return ((uint64_t)valh << 32 | vall); +} + static device_method_t davinci_edma_methods[] = { /* Device methods */ DEVMETHOD(device_probe, davinci_edma_probe),
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008131143.o7DBhdY7007770>