From owner-p4-projects@FreeBSD.ORG Fri Aug 13 11:43:40 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8CB2810656A7; Fri, 13 Aug 2010 11:43:40 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5057D10656A3 for ; Fri, 13 Aug 2010 11:43:40 +0000 (UTC) (envelope-from jceel@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 2135C8FC20 for ; Fri, 13 Aug 2010 11:43:40 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id o7DBhecs007773 for ; Fri, 13 Aug 2010 11:43:40 GMT (envelope-from jceel@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id o7DBhdY7007770 for perforce@freebsd.org; Fri, 13 Aug 2010 11:43:39 GMT (envelope-from jceel@freebsd.org) Date: Fri, 13 Aug 2010 11:43:39 GMT Message-Id: <201008131143.o7DBhdY7007770@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jceel@freebsd.org using -f From: Jakub Wojciech Klama To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 182351 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Aug 2010 11:43:40 -0000 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),