Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Jun 2015 07:14:52 GMT
From:      pratiksinghal@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r286767 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner
Message-ID:  <201506070714.t577Eqd4085190@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pratiksinghal
Date: Sun Jun  7 07:14:52 2015
New Revision: 286767
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286767

Log:
  Added the call statements for DMA transfer

Modified:
  soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c
  soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h

Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c	Sun Jun  7 06:30:25 2015	(r286766)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c	Sun Jun  7 07:14:52 2015	(r286767)
@@ -38,6 +38,7 @@
 #include <sys/resource.h>
 #include <sys/rman.h>
 #include <sys/sysctl.h>
+#include <sys/endian.h> 
 
 #include <machine/bus.h>
 
@@ -48,6 +49,7 @@
 #include <dev/mmc/mmcreg.h>
 #include <dev/mmc/mmcbrvar.h>
 
+
 #include <arm/allwinner/a10_clk.h>
 #include <arm/allwinner/a10_mmc.h>
 
@@ -55,7 +57,7 @@
 #define	A10_MMC_IRQRES		1
 #define	A10_MMC_RESSZ		2
 #define A10_MMC_NDESC		16 
-#define AWIN_MMC_DMA_FTRGLEVEL_A20	0x20070008
+#define A10_MMC_DMA_FTRGLEVEL_A20	0x20070008
 
 struct a10_mmc_softc {
 	bus_space_handle_t	a10_bsh;
@@ -71,6 +73,7 @@
 	struct mtx		a10_mtx;
 	struct resource *	a10_res[A10_MMC_RESSZ];
 	uint32_t		a10_intr;
+	uint32_t		a10_idst ; 
 	uint32_t		a10_intr_wait;
 	void *			a10_intrhand;
 	int 			a10_use_dma ; 
@@ -80,7 +83,7 @@
 	bus_dma_segment_t*	a10_dma_segs ; 
 	int 			a10_dma_nsegs ; 
 	bus_size_t		a10_dma_size ; 
-	int 			a10_dma_cb_arg ;  /* Stores the number of segments */ 
+	struct a10_mmc_cb  	a10_dma_cb_arg ;  
 	bus_dmamap_t		a10_dma_map ; 
 	bus_dma_tag_t 		a10_dma_tag ; 
 	int 			a10_dma_ndesc; 
@@ -258,26 +261,26 @@
 	struct a10_mmc_dma_desc* dma = sc->a10_dma_desc ; 
 	struct mmc_command* cmd = sc->a10_req->cmd ; 
 	int read = (sc->a10_req->cmd->data->flags & MMC_DATA_WRITE) ? 0 : 1 ; 
-	bus_addr_t desc_paddr = sc->a10_dma_map->segments[0].ds_addr ; 
-	bus_size_t off ; 
+	bus_addr_t desc_paddr = (sc->a10_dma_cb_arg).addr ; 
+	bus_size_t off = 0 ; 
 	int desc, rem,seg ; 
 	uint32_t val ; 
 
 	desc = 0 ; 
 
 	/* Pick a segment and program all the descriptors in the segment. */ 
-	for(seg = 0;  seg < sc->a10_dma_cb_arg ; seg++)
+	for(seg = 0;  seg < sc->a10_dma_cb_arg.nsegs ; seg++)
 	{
-		bus_addr_t paddr = sc->a10_dma_map->segments[seg].ds_addr; 
-		bus_size_t len = sc->a10_dma_map->segments[seg].ds_len ; 
+		bus_addr_t paddr = (sc->a10_dma_cb_arg).segs[seg].ds_addr; 
+		bus_size_t len = (sc->a10_dma_cb_arg).segs[seg].ds_len ; 
 		rem = min(len,cmd->data->len) ; 
 		while(rem > 0)
 		{
 			if(desc == sc->a10_dma_ndesc)
 				break ; 
 			len = min(sc->a10_dma_xfer_len, rem) ; 
-			dma[desc].buff_size = hotle32(len) ; 
-			dma[desc].addr = hotle32(paddr + off) ; 
+			dma[desc].buff_size = htole32(len) ; 
+			dma[desc].buff_addr = htole32(paddr + off) ; 
 			dma[desc].config = htole32(A10_MMC_DMA_CONFIG_CH|A10_MMC_DMA_CONFIG_OWN) ; 
 
 			cmd->data->len -= len ; 
@@ -294,7 +297,7 @@
 			}
 			else { 
 				dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_DIC) ; 	
-				dma[desc].next = htole32(desc_paddr + ((desc+1)*sizeof(struct a10_mmc_dma_desc)))
+				dma[desc].next = htole32(desc_paddr + ((desc+1)*sizeof(struct a10_mmc_dma_desc))) ; 
 			}
 			desc++ ; 
 		}
@@ -302,8 +305,11 @@
 
 	if(desc == sc->a10_dma_ndesc) {
 		device_printf(sc->a10_dev, "Couldn't find enough descriptors for DMA transfer") ; 
+		return EIO ;
 	}
 	
+	bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE) ; 
+
 	val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) ; 
 	val |= A10_MMC_DMA_ENABLE ; 
 	val |= A10_MMC_INT_ENABLE ; 
@@ -338,8 +344,9 @@
 		return ; 
 	}
 	
-	/* This is because, we can't get the number of segments alloted from bus_dmamap_t */ 
-	*(int*)arg = nsegs ; 
+	(*(struct a10_mmc_cb*)arg).nsegs = nsegs  ; 
+	(*(struct a10_mmc_cb*)arg).addr = segs[0].ds_addr ; 
+	(*(struct a10_mmc_cb*)arg).segs = segs; 
 }
 
 static int
@@ -404,6 +411,7 @@
 	sc->a10_req = NULL;
 	sc->a10_intr = 0;
 	sc->a10_resid = 0;
+	sc->a10_idst = 0 ; 
 	sc->a10_intr_wait = 0;
 	req->done(req);
 }
@@ -485,12 +493,13 @@
 {
 	struct a10_mmc_softc *sc;
 	struct mmc_data *data;
-	uint32_t imask, rint;
+	uint32_t imask, rint,idst;
 
 	sc = (struct a10_mmc_softc *)arg;
 	A10_MMC_LOCK(sc);
 	rint = A10_MMC_READ_4(sc, A10_MMC_RINTR);
 	imask = A10_MMC_READ_4(sc, A10_MMC_IMASK);
+	idst = A10_MMC_READ_4(sc, A10_MMC_IDST) ; 
 	if (imask == 0 && rint == 0) {
 		A10_MMC_UNLOCK(sc);
 		return;
@@ -506,6 +515,33 @@
 		A10_MMC_UNLOCK(sc);
 		return;
 	}
+
+	if(sc->a10_use_dma == 1) { 
+		if(idst) { 
+			uint32_t comp = 0 ; 
+			sc->a10_idst = idst ; 
+
+			if(idst & A10_MMC_IDMAC_ERROR)
+				sc->a10_req->cmd->error = EIO ; 
+			if(!(idst & A10_MMC_IDMAC_COMPLETE))
+				sc->a10_req->cmd->error = ETIMEDOUT ;
+			else
+				comp = 1 ; 
+
+			data = sc->a10_req->cmd->data ; 
+
+			if(data->flags&MMC_DATA_WRITE)
+				bus_dmamap_sync(sc->a10_dma_tag,sc->a10_dma_map,BUS_DMASYNC_POSTWRITE) ; 
+			else
+				bus_dmamap_sync(sc->a10_dma_tag,sc->a10_dma_map, BUS_DMASYNC_POSTREAD) ; 
+			if(comp == 0)
+				a10_mmc_req_done(sc) ; 
+			else
+				a10_mmc_req_ok(sc) ; 
+		}
+		return ; 
+	}
+
 	if (rint & A10_MMC_INT_ERR_BIT) {
 		device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
 		if (rint & A10_MMC_RESP_TIMEOUT)
@@ -521,12 +557,8 @@
 	sc->a10_intr |= rint;
 	data = sc->a10_req->cmd->data;
 	if (data != NULL && (rint & (A10_MMC_DATA_OVER |
-	    A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ)) != 0) {
-	    	if(sc->a10_use_dma == 0)
+	    A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ)) != 0)
 			a10_mmc_pio_transfer(sc, data);
-		else {
-			a10_mmc_prepare_dma(sc) ; 
-		}
 	if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)
 		a10_mmc_req_ok(sc);
 
@@ -562,6 +594,7 @@
 
 	sc->a10_intr = 0;
 	sc->a10_resid = 0;
+	sc->a10_idst = 0 ; 
 	sc->a10_intr_wait = A10_MMC_CMD_DONE;
 	cmd->error = MMC_ERR_NONE;
 	if (cmd->data != NULL) {
@@ -579,7 +612,11 @@
 	}
 
 	A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);
-	A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg | cmd->opcode);
+	if(sc->a10_use_dma == 1) { 
+		a10_mmc_prepare_dma(sc) ; 
+		A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg | cmd->opcode);
+	}
+
 	callout_reset(&sc->a10_timeoutc, sc->a10_timeout * hz,
 	    a10_mmc_timeout, sc);
 	A10_MMC_UNLOCK(sc);

Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h	Sun Jun  7 06:30:25 2015	(r286766)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h	Sun Jun  7 07:14:52 2015	(r286767)
@@ -175,6 +175,11 @@
 #define	A10_MMC_IDMAC_RD		(6U << 13)
 #define	A10_MMC_IDMAC_WR		(7U << 13)
 #define	A10_MMC_IDMAC_DESC_CLOSE	(8U << 13)
+#define A10_MMC_IDMAC_ERROR \
+	(A10_MMC_IDMAC_FATAL_BUS_ERR | A10_MMC_IDMAC_CARD_ERR_SUM | A10_MMC_IDMAC_DES_INVALID | \
+	A10_MMC_IDMAC_ABNORMAL_INT_SUM) 
+#define A10_MMC_IDMAC_COMPLETE \
+	(A10_MMC_IDMAC_TRANSMIT_INT | A10_MMC_IDMAC_RECEIVE_INT) 
 
 /* Used to make the descriptor table for suppoting DMA Access */ 
 struct a10_mmc_dma_desc { 
@@ -190,4 +195,12 @@
 	uint32_t buff_addr ; 
 	uint32_t next; 
 } ; 
+
+struct a10_mmc_cb
+{
+	uint32_t nsegs ; 
+	bus_addr_t addr ; 
+	bus_dma_segment_t* segs ; 
+} ; 
+
 #endif /* _A10_MMC_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506070714.t577Eqd4085190>