From owner-svn-soc-all@FreeBSD.ORG Sat Jun 13 01:46:52 2015 Return-Path: Delivered-To: svn-soc-all@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2FA7ADE8 for ; Sat, 13 Jun 2015 01:46:52 +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 1D1BCDB0 for ; Sat, 13 Jun 2015 01:46:52 +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 t5D1kpbu022775 for ; Sat, 13 Jun 2015 01:46:51 GMT (envelope-from pratiksinghal@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t5D1kpba022758 for svn-soc-all@FreeBSD.org; Sat, 13 Jun 2015 01:46:51 GMT (envelope-from pratiksinghal@FreeBSD.org) Date: Sat, 13 Jun 2015 01:46:51 GMT Message-Id: <201506130146.t5D1kpba022758@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: r287028 - 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: Sat, 13 Jun 2015 01:46:52 -0000 Author: pratiksinghal Date: Sat Jun 13 01:46:51 2015 New Revision: 287028 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=287028 Log: 1) Added the code for setting up data buffer 2) Cleaned up the code in a10_mmc_request. Changes in a10_mmc_prepare_dma still to be done though. 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 Fri Jun 12 22:05:04 2015 (r287027) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Sat Jun 13 01:46:51 2015 (r287028) @@ -57,6 +57,8 @@ #define A10_MMC_IRQRES 1 #define A10_MMC_RESSZ 2 #define A10_MMC_NDESC 16 +#define A10_DMA_NSEGS 16 +#define A10_DMA_BUFF_SIZE 512 #define A10_MMC_DMA_FTRGLEVEL_A20 0x20070008 #define A10_MMC_DMA_FTRGLEVEL_A10 0x00070208 @@ -103,6 +105,7 @@ static int a10_mmc_attach(device_t); static int a10_mmc_setup_dma(struct a10_mmc_softc*, device_t) ; static int a10_mmc_prepare_dma(struct a10_mmc_softc*) ; +static int a10_mmc_can_do_dma(struct mmc_request*) ; static int a10_mmc_detach(device_t); static int a10_mmc_reset(struct a10_mmc_softc *); static void a10_mmc_intr(void *); @@ -220,8 +223,9 @@ sc->a10_use_dma = 0 ; } } - //sc->a10_use_dma = 0 ; /* Remove this after testing */ - device_printf(sc->a10_dev, "Setting up dma finished %d\n", sc->a10_use_dma) ; +#ifdef DEBUG + device_printf(sc->a10_dev, "DMA status %d\n", sc->a10_use_dma) ; +#endif return (0); fail: @@ -262,6 +266,19 @@ 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_BUFF_SIZE, + A10_DMA_NSEGS,A10_DMA_BUFF_SIZE,0, + NULL,NULL,&sc->a10_dma_buf_tag) ; + if(error) + return (error) ; + + error = bus_dma_map_create(sc->a10_dma_buf_tag,0,&sc->a10_dma_buf_map) ; + if(error) + return (error) ; return(0) ; @@ -270,9 +287,11 @@ static int a10_mmc_prepare_dma(struct a10_mmc_softc* sc) { + device_printf(sc->a10_dev, "Call to prepare dma\n") ; struct a10_mmc_dma_desc* dma = sc->a10_dma_desc ; struct mmc_command* cmd = sc->a10_req->cmd ; + device_printf(sc->a10_dev,"sc->a10_req = %p, sc->a10_req->cmd = %p, sc->a10_req->cmd->data = %p, dma = %p\n", sc->a10_req,sc->a10_req->cmd,sc->a10_req->cmd->data,dma) ; int read = (sc->a10_req->cmd->data->flags & MMC_DATA_WRITE) ? 0 : 1 ; bus_addr_t desc_paddr = (sc->a10_dma_cb_arg).addr ; bus_size_t off = 0 ; @@ -280,11 +299,12 @@ uint32_t val; desc = 0 ; - + device_printf(sc->a10_dev,"Before loop\n") ; /* Pick a segment and program all the descriptors in the segment. */ bus_addr_t paddr = (sc->a10_dma_cb_arg).segs[0].ds_addr; bus_size_t len = (sc->a10_dma_cb_arg).segs[0].ds_len ; rem = min(len,cmd->data->len) ; + device_printf(sc->a10_dev, "Before rem\n") ; while(rem > 0) { if(desc == sc->a10_dma_ndesc) @@ -313,12 +333,15 @@ desc++ ; } + device_printf(sc->a10_dev, "After the completion of loop\n") ; if(desc == sc->a10_dma_ndesc) { 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 ; } + device_printf(sc->a10_dev, "Before syncing\n") ; bus_dmamap_sync(sc->a10_dma_tag, sc->a10_dma_map, BUS_DMASYNC_PREWRITE) ; + device_printf(sc->a10_dev, "After syncing\n") ; /* Enable DMA and interrupts*/ val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) ; @@ -356,11 +379,17 @@ /* Disable debounce*/ A10_MMC_WRITE_4(sc, A10_MMC_READ_4(sc, A10_MMC_GCTRL) & (~A10_MMC_DEBOUNCE_ENABLE), A10_MMC_GCTRL); - + device_printf(sc->a10_dev, "Completed the prepare function\n") ; return (0) ; } +/* Not implemented yet. */ +static int +a10_mmc_can_do_dma(struct mmc_request* req) +{ + return (1) ; +} static void a10_dma_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error) { @@ -369,7 +398,6 @@ return ; } - (*(struct a10_mmc_cb*)arg).nsegs = nsegs ; (*(struct a10_mmc_cb*)arg).addr = segs[0].ds_addr ; (*(struct a10_mmc_cb*)arg).segs = segs; } @@ -566,7 +594,7 @@ } if(idst & A10_MMC_IDMAC_COMPLETE) { - device_printf(sc->a10_dev, "DMA transfer complete!\n", idst) ; + device_printf(sc->a10_dev, "DMA transfer complete!\n") ; 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) @@ -579,8 +607,8 @@ } if((idst)&&(!(idst & A10_MMC_IDMAC_COMPLETE))) { - device_printf(sc->a10_dev, "DMA timeout error!\n", idst) ; - sc->a10_req_cmd->error = MMC_ERR_TIMEOUT ; + device_printf(sc->a10_dev, "DMA timeout error!\n") ; + sc->a10_req->cmd->error = MMC_ERR_TIMEOUT ; a10_mmc_req_done(sc) ; A10_MMC_UNLOCK(sc) ; } @@ -591,8 +619,6 @@ if (data != NULL && (rint & (A10_MMC_DATA_OVER | A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ)) != 0) a10_mmc_pio_transfer(sc, data); - } - if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait) a10_mmc_req_ok(sc); @@ -601,6 +627,7 @@ A10_MMC_UNLOCK(sc); } +/* Interrupt masking in linux kernel apart from RX/TX is still dubious. */ static int a10_mmc_request(device_t bus, device_t child, struct mmc_request *req) { @@ -609,16 +636,15 @@ struct mmc_command *cmd; uint32_t cmdreg,imask; - imask = A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT | A10_MMC_WAIT_PREOVER | A10_MMC_DATA_OVER ; - sc = device_get_softc(bus); A10_MMC_LOCK(sc); if (sc->a10_req) { A10_MMC_UNLOCK(sc); return (EBUSY); } + sc->a10_req = req; - device_printf(sc->a10_dev, "a10_req = %p\n", sc->a10_req) ; + imask = 0 ; cmd = req->cmd; cmdreg = A10_MMC_START; if (cmd->opcode == MMC_GO_IDLE_STATE) @@ -635,7 +661,7 @@ sc->a10_idst = 0 ; sc->a10_intr_wait = A10_MMC_CMD_DONE; cmd->error = MMC_ERR_NONE; - /* Will data be NULL when reading data ? */ + if (cmd->data != NULL) { sc->a10_intr_wait |= A10_MMC_DATA_OVER; cmdreg |= A10_MMC_DATA_EXP | A10_MMC_WAIT_PREOVER; @@ -643,20 +669,20 @@ cmdreg |= A10_MMC_SEND_AUTOSTOP; sc->a10_intr_wait |= A10_MMC_AUTOCMD_DONE; } - if (cmd->data->flags & MMC_DATA_WRITE) { + if (cmd->data->flags & MMC_DATA_WRITE) cmdreg |= A10_MMC_WRITE; - if(sc->a10_use_dma == 1) - imask |= A10_MMC_TX_DATA_REQ ; - } - else { - if(sc->a10_use_dma == 1) - imask |= A10_MMC_RX_DATA_REQ ; - } + blksz = min(cmd->data->len, MMC_SECTOR_SIZE); A10_MMC_WRITE_4(sc, A10_MMC_BLKSZ, blksz); A10_MMC_WRITE_4(sc, A10_MMC_BCNTR, cmd->data->len); - if(sc->a10_use_dma == 1) - a10_mmc_prepare_dma(sc) ; + + if((sc->a10_use_dma == 1)&&(a10_mmc_can_do_dma(req))) { + uint32_t error = a10_mmc_prepare_dma(sc) ; + if(error == 0) + imask |= (A10_MMC_TX_DATA_REQ|A10_MMC_RX_DATA_REQ) ; + else + device_printf(sc->a10_dev, "Couldn't prepare DMA, using pio instead\n") ; + } } uint32_t newmask = A10_MMC_READ_4(sc, A10_MMC_IMASK) ;