socsvn commit: r287361 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner

pratiksinghal at FreeBSD.org pratiksinghal at FreeBSD.org
Sat Jun 20 06:12:09 UTC 2015


Author: pratiksinghal
Date: Sat Jun 20 06:12:07 2015
New Revision: 287361
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287361

Log:
  1) Fixed the handling of AUTOCMD interrupt
  2) Removed some style issues
  3) Fixed the handling of maximum descriptors case in prepare function

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

Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c	Sat Jun 20 05:40:35 2015	(r287360)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c	Sat Jun 20 06:12:07 2015	(r287361)
@@ -58,11 +58,12 @@
 #define	A10_MMC_RESSZ		2
 #define A10_MMC_NDESC		16
 #define A10_DMA_NSEGS		16
-#define A10_DMA_BUFF_SIZE	0x2000 
-#define A10_DMA_MAX_SIZE	0x20000 
+#define A10_DMA_BUFF_SIZE	0x2000
+#define A10_DMA_MAX_SIZE	0x20000
 #define A10_MMC_DMA_FTRGLEVEL_A20	0x20070008
 #define A10_MMC_DMA_FTRGLEVEL_A10 	0x00070208
-#define A10_MMC_DMA_MAXLEN  	(A10_DMA_MAX_SIZE)  
+#define A10_MMC_DMA_MAXLEN  	(A10_DMA_MAX_SIZE)
+#define A10_MMC_DMA_MINLEN	512
 
 struct a10_mmc_softc {
 	bus_space_handle_t	a10_bsh;
@@ -223,8 +224,8 @@
 		goto fail;
 	}
 
-	if(sc->a10_use_dma == 1) {
-		if(a10_mmc_setup_dma(sc,dev) != 0) {
+	if (sc->a10_use_dma == 1) {
+		if (a10_mmc_setup_dma(sc,dev) != 0) {
 			device_printf(sc->a10_dev, "Couldn't setup DMA!\n") ;
 			sc->a10_use_dma = 0 ;
 		}
@@ -244,7 +245,6 @@
 	return (ENXIO);
 }
 
-/*TODO :- Add the dismantling DMA part also with goto statements */
 static int
 a10_mmc_setup_dma(struct a10_mmc_softc* sc, device_t dev)
 {
@@ -253,45 +253,37 @@
 	sc->a10_dma_size = sizeof(struct a10_mmc_dma_desc)*(sc->a10_dma_ndesc) ;
 
 	uint32_t error ;
-	/* First create the tag */
 	error = bus_dma_tag_create(bus_get_dma_tag(dev),1,
 				sc->a10_dma_size,BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
 				NULL,NULL,sc->a10_dma_size,
 				1,sc->a10_dma_size,0,
 				NULL,NULL,&sc->a10_dma_tag) ;
-	if(error)
+	if (error)
 		return (error) ;
-
-	/* Allocate the memory and map at kva sc->a10_dma_desc*/
-
 	error = bus_dmamem_alloc(sc->a10_dma_tag,&sc->a10_dma_desc,BUS_DMA_WAITOK|BUS_DMA_ZERO,&sc->a10_dma_map) ;
-		if(error)
+		if (error)
 			return (error) ;
 
-	/* Load the map */
 	error = bus_dmamap_load(sc->a10_dma_tag, sc->a10_dma_map,sc->a10_dma_desc,sc->a10_dma_size,a10_dma_cb, &sc->a10_dma_cb_arg,0) ;
 
-	if((error != 0)&&(error != EINPROGRESS))
+	if ((error != 0)&&(error != EINPROGRESS))
 		return (error) ;
-
-	/* Now allocate tag and map for the buffer to be used with transfer. */
 	error = bus_dma_tag_create(bus_get_dma_tag(dev),1,
 				0,BUS_SPACE_MAXADDR_32BIT,BUS_SPACE_MAXADDR,
 				NULL,NULL,A10_DMA_MAX_SIZE,
 				A10_DMA_NSEGS,A10_DMA_BUFF_SIZE,0,
 				NULL,NULL,&sc->a10_dma_buff_tag) ;
-	if(error)
+	if (error)
 		return (error) ;
 
 	error = bus_dmamap_create(sc->a10_dma_buff_tag,0,&sc->a10_dma_buff_map) ;
-	if(error)
+	if (error)
 		return (error) ;
 
 	return(0) ;
 
 }
 
-/* Transfer at most 0x1000 (4K) of data (Experimental) */
 static int
 a10_mmc_prepare_dma(struct a10_mmc_softc* sc)
 {
@@ -304,14 +296,13 @@
 	int desc, rem ;
 	uint32_t val;
 	desc = 0 ;
-	//bus_size_t len = (sc->a10_dma_cb_arg).segs[0].ds_len ;
 	bus_size_t len = A10_MMC_DMA_MAXLEN ;
 	rem = min(len,cmd->data->len) ;
 	uint32_t error = bus_dmamap_load(sc->a10_dma_buff_tag, sc->a10_dma_buff_map,
 					cmd->data->data,rem,a10_dma_buff_cb,
 					&sc->a10_dma_buff_addr,0) ;
-	if(error == EINPROGRESS) {
-		for( ; sc->a10_dma_buff_addr == 0 ; )  { } 
+	if (error == EINPROGRESS) {
+		for( ; sc->a10_dma_buff_addr == 0 ; )  { }
 	}
 	else if (error != 0)  {
 		device_printf(sc->a10_dev, "DMA transaction failed due to insufficient resources\n") ;
@@ -345,16 +336,16 @@
 		desc++ ;
 	}
 
-	if(desc == sc->a10_dma_ndesc) {
+	if ((desc == sc->a10_dma_ndesc) && (rem > 0)) {
 		device_printf(sc->a10_dev, "Couldn't find enough descriptors for DMA transfer! desc = %d,sc->a10_dma_ndesc = %d\n",desc, sc->a10_dma_ndesc) ;
 		return EIO ;
 	}
 
 	if (sc->a10_dma_ops == 0)
-		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREREAD) ; 
-	else if(sc->a10_dma_ops == 1)
-		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREWRITE) ; 
-		
+		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREREAD) ;
+	else if (sc->a10_dma_ops == 1)
+		bus_dmamap_sync(sc->a10_dma_buff_tag, sc->a10_dma_buff_map, BUS_DMASYNC_PREWRITE) ;
+
 	bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE) ;
 
 	val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) ;
@@ -368,7 +359,7 @@
 	val = A10_MMC_READ_4(sc,A10_MMC_IDIE) ;
 	val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT) ;
 	A10_MMC_WRITE_4(sc,A10_MMC_IDIE, val) ;
-	if(read == 1)
+	if (read == 1)
 		val |= A10_MMC_IDMAC_RECEIVE_INT ;
 	else
 		val |= A10_MMC_IDMAC_TRANSMIT_INT ;
@@ -380,19 +371,19 @@
 }
 
 
-/* Not implemented yet. */
 static int
 a10_mmc_can_do_dma(struct mmc_request* req)
 {
-	if(req->cmd->data->len >= A10_MMC_DMA_MAXLEN)
-		return (0) ;
-	else
-		return (1) ;
+	return (1) ; 
+	//if ((req->cmd->data->len > A10_MMC_DMA_MAXLEN) || (req->cmd->data->len <= A10_MMC_DMA_MINLEN))
+	//	return (0) ;
+	//else
+	//	return (1) ;
 }
 static void
 a10_dma_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error)
 {
-	if(error) {
+	if (error) {
 		printf("a10_mmc: Error in a10_dma_callback function, code = %d\n",error) ;
 		return ;
 	}
@@ -404,7 +395,7 @@
 static void
 a10_dma_buff_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error)
 {
-	if(error) {
+	if (error) {
 		printf("a10_mmc: Error in a10_dma_buff_callback function, code = %d\n", error) ;
 		return  ;
 	}
@@ -434,12 +425,8 @@
 	if (timeout == 0)
 		return (ETIMEDOUT);
 
-	/* Set the timeout. */
 	A10_MMC_WRITE_4(sc, A10_MMC_TIMEOUT, 0xffffffff);
-
-	/* Clear pending interrupts. */
 	A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff);
-	/* Dubious Will it remove the interrupt throttle? */
 	A10_MMC_WRITE_4(sc, A10_MMC_IDST, 0xffffffff) ;
 	/* Unmask interrupts. */
 	A10_MMC_WRITE_4(sc, A10_MMC_IMASK,
@@ -476,7 +463,7 @@
 	sc->a10_resid = 0;
 	sc->a10_idst = 0 ;
 	sc->a10_intr_wait = 0;
-	sc->a10_dma_buff_addr = 0 ; 
+	sc->a10_dma_buff_addr = 0 ;
 	req->done(req);
 }
 
@@ -582,6 +569,7 @@
 		return;
 	}
 
+	sc->a10_intr |= rint;
 	if (rint & A10_MMC_INT_ERR_BIT) {
 		device_printf(sc->a10_dev, "error rint: 0x%08X\n", rint);
 		if (rint & A10_MMC_RESP_TIMEOUT) {
@@ -594,7 +582,7 @@
 		return;
 	}
 
-	if(idst & A10_MMC_IDMAC_ERROR) {
+	if (idst & A10_MMC_IDMAC_ERROR) {
 		device_printf(sc->a10_dev, "error idst: 0x%08x\n", idst) ;
 		sc->a10_req->cmd->error = MMC_ERR_FAILED ;
 		a10_mmc_req_done(sc) ;
@@ -602,11 +590,10 @@
 		return ;
 	}
 
-	if(idst & A10_MMC_IDMAC_COMPLETE) {
-		//device_printf(sc->a10_dev, "DMA transfer complete!\n") ;
-		if(sc->a10_dma_ops == 0)
+	if ((idst & A10_MMC_IDMAC_COMPLETE) && ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait)) {
+		if (sc->a10_dma_ops == 0)
 			bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_POSTREAD) ;
-		else if(sc->a10_dma_ops == 1)
+		else if (sc->a10_dma_ops == 1)
 			bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_POSTWRITE) ;
 		else
 			device_printf(sc->a10_dev, "Invalid operations request!\n") ;
@@ -616,7 +603,7 @@
 		return ;
 	}
 
-	if((idst)&&(!(idst & A10_MMC_IDMAC_COMPLETE))) {
+	if ((idst)&&(!(idst & A10_MMC_IDMAC_COMPLETE))) {
 		device_printf(sc->a10_dev, "DMA timeout error!\n") ;
 		sc->a10_req->cmd->error = MMC_ERR_TIMEOUT ;
 		a10_mmc_req_done(sc) ;
@@ -624,7 +611,6 @@
 		return  ;
 	}
 
-	sc->a10_intr |= rint;
 	data = sc->a10_req->cmd->data;
 
 	if (data != NULL && (rint & (A10_MMC_DATA_OVER |
@@ -695,7 +681,6 @@
 				uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
 				temp_val  = temp_val & (~A10_MMC_DMA_ENABLE) ;
 				A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
-				device_printf(sc->a10_dev, "Couldn't prepare DMA, using pio instead\n") ;
 			}
 		}
 		else
@@ -703,15 +688,14 @@
 			uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
 			temp_val  = temp_val & (~A10_MMC_DMA_ENABLE) ;
 			A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
-			device_printf(sc->a10_dev, "Couldn't transfer this data with DMA, using pio instead\n") ;
 		}
 
 	}
 	else
 	{
-		uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ; 
-		temp_val = temp_val & (~A10_MMC_DMA_ENABLE) ; 
-		A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ; 
+		uint32_t temp_val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB ;
+		temp_val = temp_val & (~A10_MMC_DMA_ENABLE) ;
+		A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, temp_val) ;
 	}
 
 	A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg);


More information about the svn-soc-all mailing list