From owner-svn-soc-all@FreeBSD.ORG Thu Jun 4 02:29:04 2015 Return-Path: Delivered-To: svn-soc-all@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 757CA7A8 for ; Thu, 4 Jun 2015 02:29:04 +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 615BC1473 for ; Thu, 4 Jun 2015 02:29:04 +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 t542T4uq073529 for ; Thu, 4 Jun 2015 02:29:04 GMT (envelope-from pratiksinghal@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t542T1jw073492 for svn-soc-all@FreeBSD.org; Thu, 4 Jun 2015 02:29:01 GMT (envelope-from pratiksinghal@FreeBSD.org) Date: Thu, 4 Jun 2015 02:29:01 GMT Message-Id: <201506040229.t542T1jw073492@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: r286624 - in soc2015/pratiksinghal/cubie-head/sys/arm: allwinner broadcom/bcm2835 conf 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: Thu, 04 Jun 2015 02:29:04 -0000 Author: pratiksinghal Date: Thu Jun 4 02:29:01 2015 New Revision: 286624 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286624 Log: Made changes in the DMA API Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_dma.c soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c Thu Jun 4 02:29:01 2015 (r286624) @@ -34,15 +34,19 @@ int a10_dma_mem_rid ; int a10_dma_irq_rid ; void* a10_dma_intrhand ; - #define BUFF_SIZE 64 +#define BUFF_SIZE 64 } ; struct a10_dma_channel { - bus_dma_tag_t a10_dma_tag ; - bus_dmamap_t a10_dma_map ; - uint32_t buff ; - uint32_t a10_dma_busaddr ; + uint32_t ch_no ; + bus_dmamap_t* dma_map ; + void* buff ; + uint32_t config ; + uint32_t src ; + uint32_t dest ; enum a10_dma_channel_type a10_dma_channel_type ; + void (*intr) (void* args) ; + void* args ; uint8_t in_use ; } ; @@ -59,6 +63,8 @@ static MALLOC_DEFINE(M_DMA_CONT, "memory for dma controller", "memory for dma controller") ; +uint8_t a10_config_src(uint8_t , uint32_t , uint32_t) ; +uint8_t a10_config_dest(uint8_t, uint32_t, uint32_t) ; static int a10_dma_probe(device_t) ; static int a10_dma_attach(device_t) ; static int a10_dma_detach(device_t) ; @@ -100,7 +106,7 @@ sc->a10_dma_bsh = rman_get_bushandle(sc->a10_dma_mem_resource) ; sc->a10_dma_irq_resource = bus_alloc_resource_any(sc->a10_dma_dev, SYS_RES_IRQ, &sc->a10_dma_irq_rid, RF_ACTIVE | RF_SHAREABLE) ; - + if(sc->a10_dma_irq_resource == NULL) { device_printf(dev, "Cannot allocate irq resource!\n") ; a10_dma_release_resources(dev) ; @@ -115,7 +121,7 @@ sc->a10_dma_intrhand = a10_dma_intr ; - + a10_dma_cnt = malloc(sizeof(struct a10_dma_controller), M_DMA_CONT, M_ZERO | M_WAITOK ) ; a10_dma_cnt->sc = sc ; @@ -132,11 +138,11 @@ return (0) ; } -static void + static void a10_dma_release_resources(device_t dev) { struct a10_dma_softc* sc = device_get_softc(dev) ; - + if(sc->a10_dma_mem_resource != NULL) bus_release_resource(dev, SYS_RES_MEMORY,sc->a10_dma_mem_rid, sc->a10_dma_mem_resource) ; @@ -148,15 +154,18 @@ free(a10_dma_cnt, M_DMA_CONT) ; } -/* Not implemented yet. */ static void a10_dma_intr(void* ptr) { struct a10_dma_softc* sc = (struct a10_dma_softc*) ptr ; - if(DMA_READ(sc, DMA_IRQ_PEND_STA_REG)&DDMA_IRQ_FULL_ENABLE(0)) - device_printf(sc->a10_dma_dev, "DDMA channel 0 end transfer interrupt received on the dma controller.") ; - else - device_printf(sc->a10_dma_dev, "Unexpected interrupt received in a10_dma_intr") ; + int i=0; + uint32_t val = DMA_READ(sc, DMA_IRQ_PEND_STA_REG) ; + for(i=0; ia10_dma_dev, "DDMA channel %d end transfer interrupt received on the dma controller",i) ; + sc->ddma_channels[i].intr(sc->ddma_channels[i].args) ; + } return ; } @@ -198,22 +207,10 @@ device_printf(a10_dma_cnt->sc->a10_dma_dev, "Freed DDMA Channel no %u\n", pos) ; } -/* -void -a10_temp_setup_dma(int count, void* src, void* dest) -{ - struct a10_dma_softc* sc = a10_dma_cnt->sc ; - DMA_WRITE(sc, DMA_IRQ_EN_REG,DDMA_IRQ_FULL_ENABLE(0)) ; - DMA_WRITE(sc, DDMA_SRC_START_ADDR_REG(0),src) ; - DMA_WRITE(sc, DDMA_DEST_START_ADDR_REG(0), dest) ; - DMA_WRITE(sc, DDMA_BC_REG(0),4) ; - DMA_WRITE(sc, DMA_CFG_REG(0),BIT_SET(31)|BIT_SET(30)|BIT_SET(29)|BIT_SET(28)|BIT_SET(26)|BIT_SET(15)|BIT_SET(12)|BIT_SET(10)|BIT_SET(0)) ; -} */ - -/* The address supplied to this method are physical addresses not virtual addresses */ +/* The address supplied is the bus address */ uint8_t -a10_ddma_config_channel(uint8_t pos, void* src, void* dest, int32_t count, int32_t cfg) +a10_ddma_config_channel(uint8_t pos, uint32_t src, uint32_t dest, int32_t count, int32_t cfg, void* buff, bus_dmamap_t* map, void (*ptr) (void* arg), void* args) { if((pos >=8) || (pos < 0)) { device_printf(a10_dma_cnt->sc->a10_dma_dev, "Invalid position supplied in a10_ddma_set_src pos: %d\n", pos) ; @@ -223,13 +220,84 @@ device_printf(a10_dma_cnt->sc->a10_dma_dev, "DMA channel currently not allocated pos: %d\n", pos) ; return 1 ; } - DMA_WRITE(a10_dma_cnt->sc, DDMA_SRC_START_ADDR_REG(pos), (uint32_t)src) ; - DMA_WRITE(a10_dma_cnt->sc, DDMA_DEST_START_ADDR_REG(pos), (uint32_t)dest) ; + + a10_dma_cnt->ddma_channels[pos].src = src ; + a10_dma_cnt->ddma_channels[pos].dest = dest ; + a10_dma_cnt->ddma_channels[pos].config = cfg ; + a10_dma_cnt->ddma_channels[pos].buff = buff ; + a10_dma_cnt->ddma_channels[pos].dma_map = map ; + a10_dma_cnt->ddma_channels[pos].ptr = ptr ; + a10_dma_cnt->ddma_channels[pos].args = args ; + DMA_WRITE(a10_dma_cnt->sc, DDMA_SRC_ADDR_REG(pos), src) ; + DMA_WRITE(a10_dma_cnt->sc, DDMA_DEST_ADDR_REG(pos), dest) ; DMA_WRITE(a10_dma_cnt->sc, DDMA_BC_REG(pos), count) ; DMA_WRITE(a10_dma_cnt->sc, DDMA_CFG_REG(pos), cfg) ; return (0) ; } +/* Supply the correct macro from a10_dma.h in this functions type parameter. */ +uint8_t +a10_config_src(uint8_t pos, uint32_t src, uint32_t type) +{ + if((pos < 0) || (pos >= NDDMA)) { + device_printf(a10_dma_cnt->sc->a10_dma_dev,"Invalid channel number supplied in a10_config_src ch_no = %d\n", pos) ; + return 1 ; + } + + if(a10_dma_cnt->ddma_channels[pos].in_use == 0) { + device_printf(a10_dma_cnt->sc->a10_dma_dev,"Invalid channel number supplied (not in use) ch_no = %d\n", pos) ; + return (2) ; + } + + a10_dma_cnt->ddma_channels[pos].src = src ; + a10_dma_cnt->ddma_channels[pos].config |= (DMA_SRC_NON_SEC | DMA_SRC_DATA_4 | DMA_SRC_BURST_4 | DMA_SRC_ADDR_LIN | type) ; + + return (0) ; + +} + +/* type parameter supplied should always be from a constant defined in a10_dma.h file. */ +uint8_t +a10_config_dest(uint8_t pos, uint32_t dest, uint32_t type) +{ + if((pos < 0)&&(pos >= NDDMA)) + { + device_printf(a10_dma_cnt->sc->a10_dma_dev, "Invalid channel number supplied in a10_config_dest ch_no = %d\n", pos) ; + return (1) ; + } + + if(a10_dma_cnt->ddma_channels[pos].in_use == 0) { + device_printf(a10_dma_cnt->sc->a10_dma_dev,"Invalid channel number supplied (not in use) ch_no = %d\n", pos) ; + return (2) ; + } + + a10_dma_cnt->ddma_channels[pos].dest = dest ; + a10_dma_cnt->ddma_channels[pos].config |= (DMA_LOADING | DMA_IDLE | DMA_CONT_MOD_EN | DMA_DEST_DATA_2 | DMA_DEST_BURST_4 | DMA_DEST_ADDR_LIN | BC_MODE_NORMAL | type) ; + + return (0) ; +} + +/* How to start the transfer ? */ +void +a10_dma_sync_registers(uint8_t pos, uint32_t bc) +{ + if((pos < 0) || (pos >= NDDMA)) { + device_printf(a10_dma_cnt->sc->a10_dma_dev, "Invalid channel number supplied in sync_dma_registers ch_no = %d\n",pos) ; + } + + if(a10_dma_cnt->ddma_channels[pos].in_use == 0) { + device_printf(a10_dma_cnt->sc->a10_dma_dev,"Invalid channel number supplied (not in use) ch_no = %d\n", pos) ; + } + + uint32_t intm = 0 ; + intm |= DMA_IRQ_FULL_ENABLE(pos) ; + DMA_WRITE(a10_dma_cnt->sc,DDMA_SRC_ADDR_REG(pos), a10_dma_cnt->ddma_channels[pos].src) ; + DMA_WRITE(a10_dma_cnt->sc,DDMA_DEST_ADDR_REG(pos), a10_dma_cnt->ddma_channels[pos].dest) ; + DMA_WRITE(a10_dma_cnt->sc,DDMA_BC_REG(pos), bc) ; + DMA_WRITE(a10_dma_cnt->sc,DDMA_CFG_REG(pos), a10_dma_cnt->ddma_channels[pos].config) ; + DMA_WRITE(a10_dma_cnt->sc, DDMA_IRQ_EN_REG, intm) ; +} + static device_method_t a10_dma_methods[] = { DEVMETHOD(device_probe, a10_dma_probe), DEVMETHOD(device_attach, a10_dma_attach), Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h Thu Jun 4 02:29:01 2015 (r286624) @@ -6,6 +6,10 @@ #include +/* How to determine the buffer size ? */ +#define DMA_BUFF_SIZE 512 +#define DMA_NSEGS 2 + /*Total no of channels for Dedicated and Normal DMA */ #define NNDMA 8 #define NDDMA 8 @@ -25,8 +29,8 @@ /* These are macros of Dedicated DMA */ #define DDMA_CFG_REG(n) (0x300 + ((n)*0x20) ) -#define DDMA_SRC_START_ADDR_REG(n) (0x300 + ((n)*0x20) + 4) -#define DDMA_DEST_START_ADDR_REG(n) (0x300 + ((n)*0x20) + 8) +#define DDMA_SRC_ADDR_REG(n) (0x300 + ((n)*0x20) + 4) +#define DDMA_DEST_ADDR_REG(n) (0x300 + ((n)*0x20) + 8) #define DDMA_BC_REG(n) (0x300 + ((n)*0x20 ) + 0x0C ) #define DDMA_PARA_REG(n) (0x300 + ((n)*0x20) + 0x18) @@ -60,7 +64,8 @@ /* Useful constants. */ #define DMA_LOADING (1U << 31) -#define DMA_BUSY (1U << 30) +#define DMA_BUSY (1U << 30) +#define DMA_IDLE (0U << 30) #define DMA_CONT_MOD_EN (1U << 29) #define DMA_DEST_NON_SEC (1U << 28) #define DMA_DEST_DATA_2 (1U << 25) @@ -88,7 +93,7 @@ #define DMA_DEST_SPI_3 (30U << 16) #define BC_MODE_NORMAL (0U << 15) #define BC_MODE_REMAIN (1U << 15) -#define DMA_SRC_SEC (0U << 12) +#define DMA_SRC_SEC (0U << 12) #define DMA_SRC_NON_SEC (1U << 12) #define DMA_SRC_DATA_1 (0U << 9) #define DMA_SRC_DATA_2 (1U << 9) @@ -112,10 +117,12 @@ #define DMA_SRC_SPI_0 (27U) #define DMA_SRC_SPI_2 (29U) #define DMA_SRC_SPI_3 (31U) + /* Function prototypes */ /* Currently these two methods are implemented for only DDMA */ uint8_t a10_get_ddma_channel(void) ; -uint8_t a10_ddma_config_channel(uint8_t, void*, void*, int32_t, int32_t) ; +uint8_t a10_ddma_config_channel(uint8_t pos, uint32_t src, uint32_t dest, int32_t count, int32_t cfg, void* buff, bus_dmamap_t* map) ; void a10_free_dma_channel(uint8_t) ; +void a10_dma_sync_registers(uint8_t, uint32_t ) ; #endif /* _A10_DMA_H_ */ Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Thu Jun 4 02:29:01 2015 (r286624) @@ -51,6 +51,8 @@ #include #include +#include "a10_dma.h" + #define A10_MMC_MEMRES 0 #define A10_MMC_IRQRES 1 #define A10_MMC_RESSZ 2 @@ -72,14 +74,13 @@ uint32_t a10_intr; uint32_t a10_intr_wait; void * a10_intrhand; + void* a10_dma_buff ; bus_dma_tag_t a10_mmc_dmat ; bus_dma_segment_t a10_mmc_dma_segments ; bus_dmamap_t a10_mmc_dmamap ; - bus_size_t buf_size ; - bus_dma_segment_t a10_mmc_dmasegs[1] ; - void * a10_mmc_buff ; /* Pointer to the buffer */ - uint32_t a10_mmc_nseg ; /* No of segments */ - bus_addr_t a10_mmc_seg ; /* Address of the first descriptor */ + bus_addr_t a10_dma_buff_addr; /* Device visible physical address. */ + int32_t a10_use_dma ; /* Whether to use dma or not */ + uint32_t a10_dma_ch[2] ; }; static struct resource_spec a10_mmc_res_spec[] = { @@ -94,7 +95,7 @@ static int a10_mmc_reset(struct a10_mmc_softc *); static void a10_mmc_intr(void *); static int a10_mmc_update_clock(struct a10_mmc_softc *); -static int a10_mmc_init_dma(struct a10_mmc_softc *, struct mmc_command *) ; /* Not defined yet */ +static int a10_mmc_init_dma(struct a10_mmc_softc *, struct mmc_data *, int read) ; /* Not defined yet */ static void a10_mmc_dma_callback(void *, bus_dma_segment_t *,int , int) ; static int a10_mmc_update_ios(device_t, device_t); @@ -110,7 +111,7 @@ #define A10_MMC_WRITE_4(_sc, _reg, _value) \ bus_space_write_4((_sc)->a10_bst, (_sc)->a10_bsh, _reg, _value) -static int + static int a10_mmc_probe(device_t dev) { @@ -123,7 +124,7 @@ return (BUS_PROBE_DEFAULT); } -static int + static int a10_mmc_attach(device_t dev) { device_t child; @@ -146,8 +147,8 @@ sc->a10_bst = rman_get_bustag(sc->a10_res[A10_MMC_MEMRES]); sc->a10_bsh = rman_get_bushandle(sc->a10_res[A10_MMC_MEMRES]); if (bus_setup_intr(dev, sc->a10_res[A10_MMC_IRQRES], - INTR_TYPE_MISC | INTR_MPSAFE, NULL, a10_mmc_intr, sc, - &sc->a10_intrhand)) { + INTR_TYPE_MISC | INTR_MPSAFE, NULL, a10_mmc_intr, sc, + &sc->a10_intrhand)) { bus_release_resources(dev, a10_mmc_res_spec, sc->a10_res); device_printf(dev, "cannot setup interrupt handler\n"); return (ENXIO); @@ -156,7 +157,7 @@ /* Activate the module clock. */ if (a10_clk_mmc_activate(sc->a10_id) != 0) { bus_teardown_intr(dev, sc->a10_res[A10_MMC_IRQRES], - sc->a10_intrhand); + sc->a10_intrhand); bus_release_resources(dev, a10_mmc_res_spec, sc->a10_res); device_printf(dev, "cannot activate mmc clock\n"); return (ENXIO); @@ -166,9 +167,9 @@ ctx = device_get_sysctl_ctx(dev); tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); SYSCTL_ADD_INT(ctx, tree, OID_AUTO, "req_timeout", CTLFLAG_RW, - &sc->a10_timeout, 0, "Request timeout in seconds"); + &sc->a10_timeout, 0, "Request timeout in seconds"); mtx_init(&sc->a10_mtx, device_get_nameunit(sc->a10_dev), "a10_mmc", - MTX_DEF); + MTX_DEF); callout_init_mtx(&sc->a10_timeoutc, &sc->a10_mtx, 0); /* Reset controller. */ @@ -194,30 +195,29 @@ goto fail; } - /* Create the tag. */ - uint32_t err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, - 0,BUS_SPACE_MAXADDR,BUS_SPACE_MAXADDR, - NULL,NULL,sizeof(struct a10_mmc_dma_desc)*2, - 1,PAGE_SIZE,0, - NULL,NULL,&sc->a10_mmc_dmat) ; - - if(err) { - device_printf(dev, "Could not create dma tag.\n"); - goto fail ; - } - /* Allocate buffer */ - bus_dmamem_alloc(sc->a10_mmc_dmat, &sc->a10_mmc_buff,BUS_DMA_WAITOK|BUS_DMA_ZERO|BUS_DMA_COHERENT, &sc->a10_mmc_dmamap) ; - - err = bus_dmamap_load(sc->a10_mmc_dmat, sc->a10_mmc_dmamap, sc->a10_mmc_buff, sizeof(struct a10_mmc_dma_desc)*2, a10_mmc_dma_callback, - &sc->a10_mmc_seg, BUS_DMA_NOWAIT) ; + /* Since, max segments is 2 we can use only 2 channels. */ + sc->a10_dma_ch[0] = a10_get_ddma_channel() ; + sc->a10_dma_ch[1] = a10_get_ddma_channel() ; + if((sc->a10_dma_ch[0] >= NDDMA + 1) || (sc->a10_dma_ch[1] >= NDDMA + 1)) + sc->a10_use_dma = 0 ; + else + sc->a10_use_dma = 1 ; - if(err) + if(sc->a10_use_dma == 1) { - device_printf(sc->a10_dev, "Error while loading dma map! code = %d\n", err) ; - goto fail ; + /* Create the tag. */ + uint32_t err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, + 0,BUS_SPACE_MAXADDR,BUS_SPACE_MAXADDR, + NULL,NULL,DMA_BUFF_SIZE, + DMA_NSEGS,DMA_BUFF_SIZE,0, + NULL,NULL,&sc->a10_mmc_dmat) ; + + if(err) { + device_printf(dev, "Could not create dma tag.\n"); + sc->a10_use_dma = 0 ; + goto fail ; + } } - - device_printf(sc->a10_dev, "dma_map loaded succesfully!\n") ; return (0); fail: @@ -229,20 +229,20 @@ return (ENXIO); } -static int + static int a10_mmc_detach(device_t dev) { return (EBUSY); } -static int + static int a10_mmc_reset(struct a10_mmc_softc *sc) { int timeout; A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, - A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_RESET); + A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_RESET); timeout = 1000; while (--timeout > 0) { if ((A10_MMC_READ_4(sc, A10_MMC_GCTRL) & A10_MMC_RESET) == 0) @@ -259,23 +259,24 @@ A10_MMC_WRITE_4(sc, A10_MMC_RINTR, 0xffffffff); /* Unmask interrupts. */ A10_MMC_WRITE_4(sc, A10_MMC_IMASK, - A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT | - A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE | - A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ); + A10_MMC_CMD_DONE | A10_MMC_INT_ERR_BIT | + A10_MMC_DATA_OVER | A10_MMC_AUTOCMD_DONE | + A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ); /* Enable interrupts and AHB access. */ A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, - A10_MMC_READ_4(sc, A10_MMC_GCTRL) | - A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB); + A10_MMC_READ_4(sc, A10_MMC_GCTRL) | + A10_MMC_INT_ENABLE | A10_MMC_ACCESS_BY_AHB); return (0); } -static void + static void a10_mmc_req_done(struct a10_mmc_softc *sc) { struct mmc_command *cmd; struct mmc_request *req; + device_printf(sc->a10_dev,"a10_mmc_req_done called\n") ; cmd = sc->a10_req->cmd; if (cmd->error != MMC_ERR_NONE) { /* Reset the controller. */ @@ -284,7 +285,7 @@ } /* Reset the FIFO. */ A10_MMC_WRITE_4(sc, A10_MMC_GCTRL, - A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_FIFO_RESET); + A10_MMC_READ_4(sc, A10_MMC_GCTRL) | A10_MMC_FIFO_RESET); req = sc->a10_req; callout_stop(&sc->a10_timeoutc); @@ -295,13 +296,14 @@ req->done(req); } -static void + static void a10_mmc_req_ok(struct a10_mmc_softc *sc) { int timeout; struct mmc_command *cmd; uint32_t status; + device_printf(sc->a10_dev, "a10_mmc_req_ok called\n") ; timeout = 1000; while (--timeout > 0) { status = A10_MMC_READ_4(sc, A10_MMC_STAS); @@ -330,27 +332,29 @@ a10_mmc_req_done(sc); } -static void + static void a10_mmc_timeout(void *arg) { struct a10_mmc_softc *sc; sc = (struct a10_mmc_softc *)arg; + device_printf(sc->a10_dev, "a10_mmc_timeout called\n") ; if (sc->a10_req != NULL) { device_printf(sc->a10_dev, "controller timeout\n"); sc->a10_req->cmd->error = MMC_ERR_TIMEOUT; a10_mmc_req_done(sc); } else device_printf(sc->a10_dev, - "Spurious timeout - no active request\n"); + "Spurious timeout - no active request\n"); } -static int + static int a10_mmc_pio_transfer(struct a10_mmc_softc *sc, struct mmc_data *data) { int i, write; uint32_t bit, *buf; + device_printf(sc->a10_dev, "a10_mmc_pio_transfer called\n") ; buf = (uint32_t *)data->data; write = (data->flags & MMC_DATA_WRITE) ? 1 : 0; bit = write ? A10_MMC_FIFO_FULL : A10_MMC_FIFO_EMPTY; @@ -367,7 +371,7 @@ return (0); } -static void + static void a10_mmc_intr(void *arg) { struct a10_mmc_softc *sc; @@ -375,6 +379,7 @@ uint32_t imask, rint; sc = (struct a10_mmc_softc *)arg; + device_printf(sc->a10_dev, "a10_mmc_intr called\n") ; A10_MMC_LOCK(sc); rint = A10_MMC_READ_4(sc, A10_MMC_RINTR); imask = A10_MMC_READ_4(sc, A10_MMC_IMASK); @@ -387,8 +392,8 @@ #endif if (sc->a10_req == NULL) { device_printf(sc->a10_dev, - "Spurious interrupt - no active request, rint: 0x%08X\n", - rint); + "Spurious interrupt - no active request, rint: 0x%08X\n", + rint); A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint); A10_MMC_UNLOCK(sc); return; @@ -408,16 +413,19 @@ 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) - a10_mmc_pio_transfer(sc, data); - if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait) - a10_mmc_req_ok(sc); + A10_MMC_RX_DATA_REQ | A10_MMC_TX_DATA_REQ)) != 0) { + if(sc->a10_use_dma == 0) + a10_mmc_pio_transfer(sc, data); + else + a10_mmc_init_dma(sc, data, 1) ; + if ((sc->a10_intr & sc->a10_intr_wait) == sc->a10_intr_wait) + a10_mmc_req_ok(sc); - A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint); - A10_MMC_UNLOCK(sc); + A10_MMC_WRITE_4(sc, A10_MMC_RINTR, rint); + A10_MMC_UNLOCK(sc); + } } - -static int + static int a10_mmc_request(device_t bus, device_t child, struct mmc_request *req) { int blksz; @@ -426,6 +434,7 @@ uint32_t cmdreg; sc = device_get_softc(bus); + device_printf(sc->a10_dev, "a10_mmc_request called\n") ; A10_MMC_LOCK(sc); if (sc->a10_req) { A10_MMC_UNLOCK(sc); @@ -464,113 +473,113 @@ A10_MMC_WRITE_4(sc, A10_MMC_CARG, cmd->arg); 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_timeout, sc); A10_MMC_UNLOCK(sc); return (0); } -static int + static int a10_mmc_read_ivar(device_t bus, device_t child, int which, - uintptr_t *result) + uintptr_t *result) { struct a10_mmc_softc *sc; sc = device_get_softc(bus); switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - *(int *)result = sc->a10_host.ios.bus_mode; - break; - case MMCBR_IVAR_BUS_WIDTH: - *(int *)result = sc->a10_host.ios.bus_width; - break; - case MMCBR_IVAR_CHIP_SELECT: - *(int *)result = sc->a10_host.ios.chip_select; - break; - case MMCBR_IVAR_CLOCK: - *(int *)result = sc->a10_host.ios.clock; - break; - case MMCBR_IVAR_F_MIN: - *(int *)result = sc->a10_host.f_min; - break; - case MMCBR_IVAR_F_MAX: - *(int *)result = sc->a10_host.f_max; - break; - case MMCBR_IVAR_HOST_OCR: - *(int *)result = sc->a10_host.host_ocr; - break; - case MMCBR_IVAR_MODE: - *(int *)result = sc->a10_host.mode; - break; - case MMCBR_IVAR_OCR: - *(int *)result = sc->a10_host.ocr; - break; - case MMCBR_IVAR_POWER_MODE: - *(int *)result = sc->a10_host.ios.power_mode; - break; - case MMCBR_IVAR_VDD: - *(int *)result = sc->a10_host.ios.vdd; - break; - case MMCBR_IVAR_CAPS: - *(int *)result = sc->a10_host.caps; - break; - case MMCBR_IVAR_MAX_DATA: - *(int *)result = 65535; - break; + default: + return (EINVAL); + case MMCBR_IVAR_BUS_MODE: + *(int *)result = sc->a10_host.ios.bus_mode; + break; + case MMCBR_IVAR_BUS_WIDTH: + *(int *)result = sc->a10_host.ios.bus_width; + break; + case MMCBR_IVAR_CHIP_SELECT: + *(int *)result = sc->a10_host.ios.chip_select; + break; + case MMCBR_IVAR_CLOCK: + *(int *)result = sc->a10_host.ios.clock; + break; + case MMCBR_IVAR_F_MIN: + *(int *)result = sc->a10_host.f_min; + break; + case MMCBR_IVAR_F_MAX: + *(int *)result = sc->a10_host.f_max; + break; + case MMCBR_IVAR_HOST_OCR: + *(int *)result = sc->a10_host.host_ocr; + break; + case MMCBR_IVAR_MODE: + *(int *)result = sc->a10_host.mode; + break; + case MMCBR_IVAR_OCR: + *(int *)result = sc->a10_host.ocr; + break; + case MMCBR_IVAR_POWER_MODE: + *(int *)result = sc->a10_host.ios.power_mode; + break; + case MMCBR_IVAR_VDD: + *(int *)result = sc->a10_host.ios.vdd; + break; + case MMCBR_IVAR_CAPS: + *(int *)result = sc->a10_host.caps; + break; + case MMCBR_IVAR_MAX_DATA: + *(int *)result = 65535; + break; } return (0); } -static int + static int a10_mmc_write_ivar(device_t bus, device_t child, int which, - uintptr_t value) + uintptr_t value) { struct a10_mmc_softc *sc; sc = device_get_softc(bus); switch (which) { - default: - return (EINVAL); - case MMCBR_IVAR_BUS_MODE: - sc->a10_host.ios.bus_mode = value; - break; - case MMCBR_IVAR_BUS_WIDTH: - sc->a10_host.ios.bus_width = value; - break; - case MMCBR_IVAR_CHIP_SELECT: - sc->a10_host.ios.chip_select = value; - break; - case MMCBR_IVAR_CLOCK: - sc->a10_host.ios.clock = value; - break; - case MMCBR_IVAR_MODE: - sc->a10_host.mode = value; - break; - case MMCBR_IVAR_OCR: - sc->a10_host.ocr = value; - break; - case MMCBR_IVAR_POWER_MODE: - sc->a10_host.ios.power_mode = value; - break; - case MMCBR_IVAR_VDD: - sc->a10_host.ios.vdd = value; - break; - /* These are read-only */ - case MMCBR_IVAR_CAPS: - case MMCBR_IVAR_HOST_OCR: - case MMCBR_IVAR_F_MIN: - case MMCBR_IVAR_F_MAX: - case MMCBR_IVAR_MAX_DATA: - return (EINVAL); + default: + return (EINVAL); + case MMCBR_IVAR_BUS_MODE: + sc->a10_host.ios.bus_mode = value; + break; + case MMCBR_IVAR_BUS_WIDTH: + sc->a10_host.ios.bus_width = value; + break; + case MMCBR_IVAR_CHIP_SELECT: + sc->a10_host.ios.chip_select = value; + break; + case MMCBR_IVAR_CLOCK: + sc->a10_host.ios.clock = value; + break; + case MMCBR_IVAR_MODE: + sc->a10_host.mode = value; + break; + case MMCBR_IVAR_OCR: + sc->a10_host.ocr = value; + break; + case MMCBR_IVAR_POWER_MODE: + sc->a10_host.ios.power_mode = value; + break; + case MMCBR_IVAR_VDD: + sc->a10_host.ios.vdd = value; + break; + /* These are read-only */ + case MMCBR_IVAR_CAPS: + case MMCBR_IVAR_HOST_OCR: + case MMCBR_IVAR_F_MIN: + case MMCBR_IVAR_F_MAX: + case MMCBR_IVAR_MAX_DATA: + return (EINVAL); } return (0); } -static int + static int a10_mmc_update_clock(struct a10_mmc_softc *sc) { uint32_t cmdreg; @@ -596,9 +605,22 @@ /* This function will map the buffer into a device visible address space and will be called before the actual transfer of data takes place. */ +/* Currently valid for only reading data */ static int -a10_mmc_init_dma(struct a10_mmc_softc* sc, struct mmc_command* cmd) +a10_mmc_init_dma(struct a10_mmc_softc* sc, struct mmc_data* data, int read) { + bus_dmamem_alloc(sc->a10_mmc_dmat, &sc->a10_dma_buff,BUS_DMA_WAITOK|BUS_DMA_ZERO|BUS_DMA_COHERENT, &sc->a10_mmc_dmamap) ; + + uint32_t err = bus_dmamap_load(sc->a10_mmc_dmat, sc->a10_mmc_dmamap, sc->a10_dma_buff, DMA_BUFF_SIZE, + a10_mmc_dma_callback,&sc->a10_dma_buff_addr,BUS_DMA_NOWAIT) ; + + if(err) + { + device_printf(sc->a10_dev, "Error while loading dma map! code = %d\n", err) ; + sc->a10_use_dma = 0 ; + } + + device_printf(sc->a10_dev, "dma_map loaded succesfully!\n") ; return (0) ; } @@ -609,9 +631,10 @@ printf("a10_mmc : Error in the callback function code = %d\n", error) ; return ; } - *(bus_addr_t*)arg = segs[0].ds_addr ; + printf("a10_mmc: The number of segments allocated is %d\n",nsegs) ; + *(bus_addr_t*)arg = segs[0].ds_addr ; /* Device visible address space */ } -static int + static int a10_mmc_update_ios(device_t bus, device_t child) { int error; @@ -620,6 +643,7 @@ uint32_t clkcr; sc = device_get_softc(bus); + device_printf(sc->a10_dev, "a10_mmc_update_ios called\n") ; clkcr = A10_MMC_READ_4(sc, A10_MMC_CLKCR); if (clkcr & A10_MMC_CARD_CLK_ON) { /* Disable clock. */ @@ -654,34 +678,35 @@ /* Set the bus width. */ switch (ios->bus_width) { - case bus_width_1: - A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH1); - break; - case bus_width_4: - A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH4); - break; - case bus_width_8: - A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH8); - break; + case bus_width_1: + A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH1); + break; + case bus_width_4: + A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH4); + break; + case bus_width_8: + A10_MMC_WRITE_4(sc, A10_MMC_WIDTH, A10_MMC_WIDTH8); + break; } return (0); } -static int + static int a10_mmc_get_ro(device_t bus, device_t child) { return (0); } -static int + static int a10_mmc_acquire_host(device_t bus, device_t child) { struct a10_mmc_softc *sc; int error; sc = device_get_softc(bus); + device_printf(sc->a10_dev, "a10_mmc_acquire_host called\n") ; A10_MMC_LOCK(sc); while (sc->a10_bus_busy) { error = msleep(sc, &sc->a10_mtx, PCATCH, "mmchw", 0); @@ -696,12 +721,13 @@ return (0); } -static int + static int a10_mmc_release_host(device_t bus, device_t child) { struct a10_mmc_softc *sc; sc = device_get_softc(bus); + device_printf(sc->a10_dev, "a10_mmc_release_host called\n") ; A10_MMC_LOCK(sc); sc->a10_bus_busy--; wakeup(sc); Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h Thu Jun 4 02:29:01 2015 (r286624) @@ -60,6 +60,8 @@ #define A10_MMC_CBDA 0x94 #define A10_MMC_FIFO 0x100 /* FIFO Access Address */ +#define A10_MMC_BUFF_ADDR 0xFFF /* Some random access */ + /* A10_MMC_GCTRL */ #define A10_MMC_SOFT_RESET (1U << 0) #define A10_MMC_FIFO_RESET (1U << 1) @@ -72,6 +74,7 @@ #define A10_MMC_ACCESS_BY_AHB (1U << 31) #define A10_MMC_RESET \ (A10_MMC_SOFT_RESET | A10_MMC_FIFO_RESET | A10_MMC_DMA_RESET) +#define A10_MMC_DMA_FTRGLEVEL_A20 0x20070008 /* A10_MMC_CLKCR */ #define A10_MMC_CARD_CLK_ON (1U << 16) Modified: soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_dma.c ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_dma.c Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_dma.c Thu Jun 4 02:29:01 2015 (r286624) @@ -556,6 +556,7 @@ bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch), sc->sc_dma_ch[ch].vc_cb); + /* Is this the chip select signal with which we enable the DMA transfer operations ? */ bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), CS_ACTIVE); #ifdef DEBUG Modified: soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Thu Jun 4 02:29:01 2015 (r286624) @@ -103,6 +103,7 @@ static int bcm_sdhci_get_ro(device_t, device_t); static void bcm_sdhci_dma_intr(int ch, void *arg); +/* This is the callback function */ static void bcm_sdhci_dmacb(void *arg, bus_dma_segment_t *segs, int nseg, int err) { Modified: soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD ============================================================================== --- soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD Thu Jun 4 01:52:17 2015 (r286623) +++ soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD Thu Jun 4 02:29:01 2015 (r286624) @@ -101,7 +101,7 @@ device emac #DMA controller -#device dma +device dma # USB ethernet support, requires miibus device miibus