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