PERFORCE change 182351 for review
Jakub Wojciech Klama
jceel at FreeBSD.org
Fri Aug 13 11:43:40 UTC 2010
http://p4web.freebsd.org/@@182351?ac=10
Change 182351 by jceel at 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),
More information about the p4-projects
mailing list