Skip site navigation (1)Skip section navigation (2)
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>