From owner-svn-soc-all@FreeBSD.ORG Sun Jun 7 07:14:53 2015 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A8CFD411 for ; Sun, 7 Jun 2015 07:14:53 +0000 (UTC) (envelope-from pratiksinghal@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 963AB152F for ; Sun, 7 Jun 2015 07:14:53 +0000 (UTC) (envelope-from pratiksinghal@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id t577Ersj085206 for ; Sun, 7 Jun 2015 07:14:53 GMT (envelope-from pratiksinghal@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t577Eqd4085190 for svn-soc-all@FreeBSD.org; Sun, 7 Jun 2015 07:14:52 GMT (envelope-from pratiksinghal@FreeBSD.org) Date: Sun, 7 Jun 2015 07:14:52 GMT Message-Id: <201506070714.t577Eqd4085190@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to pratiksinghal@FreeBSD.org using -f From: pratiksinghal@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286767 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 07 Jun 2015 07:14:53 -0000 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 #include #include +#include #include @@ -48,6 +49,7 @@ #include #include + #include #include @@ -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_ */