socsvn commit: r286767 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner
pratiksinghal at FreeBSD.org
pratiksinghal at FreeBSD.org
Sun Jun 7 07:14:53 UTC 2015
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_ */
More information about the svn-soc-all
mailing list