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>