Date: Sat, 6 Jun 2015 03:47:59 GMT From: pratiksinghal@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286707 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner Message-ID: <201506060347.t563lxdQ077718@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pratiksinghal Date: Sat Jun 6 03:47:59 2015 New Revision: 286707 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286707 Log: Implemented the prepare and init functions and removed unused code 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 Sat Jun 6 01:18:28 2015 (r286706) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Sat Jun 6 03:47:59 2015 (r286707) @@ -51,12 +51,11 @@ #include <arm/allwinner/a10_clk.h> #include <arm/allwinner/a10_mmc.h> -#include "a10_dma.h" - #define A10_MMC_MEMRES 0 #define A10_MMC_IRQRES 1 #define A10_MMC_RESSZ 2 - +#define A10_MMC_NDESC 16 +#define AWIN_MMC_DMA_FTRGLEVEL_A20 0x20070008 struct a10_mmc_softc { bus_space_handle_t a10_bsh; @@ -74,13 +73,19 @@ 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_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] ; + int a10_use_dma ; + + /* Fields required for DMA access */ + uint32_t a10_dma_xfer_len ; + 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 */ + bus_dmamap_t a10_dma_map ; + bus_dma_tag_t a10_dma_tag ; + int a10_dma_ndesc; + void* a10_dma_desc ; + }; static struct resource_spec a10_mmc_res_spec[] = { @@ -91,13 +96,14 @@ static int a10_mmc_probe(device_t); 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_detach(device_t); 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_data *, int read) ; /* Not defined yet */ -static void a10_mmc_dma_callback(void *, bus_dma_segment_t *,int , int) ; +static void a10_dma_cb(void*, bus_dma_segment_t*, int, int) ; static int a10_mmc_update_ios(device_t, device_t); static int a10_mmc_request(device_t, device_t, struct mmc_request *); static int a10_mmc_get_ro(device_t, device_t); @@ -111,7 +117,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) { @@ -124,7 +130,7 @@ return (BUS_PROBE_DEFAULT); } - static int +static int a10_mmc_attach(device_t dev) { device_t child; @@ -133,6 +139,7 @@ struct sysctl_oid_list *tree; sc = device_get_softc(dev); + sc->a10_use_dma = 1 ; sc->a10_dev = dev; sc->a10_req = NULL; sc->a10_id = device_get_unit(dev); @@ -147,8 +154,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); @@ -157,7 +164,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); @@ -167,9 +174,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. */ @@ -195,27 +202,10 @@ goto fail; } - /* 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(sc->a10_use_dma == 1) - { - /* 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"); + if(sc->a10_use_dma == 1) { + if(a10_mmc_setup_dma(sc,dev) != 0) { + device_printf(sc->a10_dev, "Couldn't setup DMA!\n") ; sc->a10_use_dma = 0 ; - goto fail ; } } return (0); @@ -229,20 +219,143 @@ return (ENXIO); } - static int +/*TODO :- Add the dismantling DMA part also with goto statements */ +static int +a10_mmc_setup_dma(struct a10_mmc_softc* sc, device_t dev) +{ + sc->a10_dma_ndesc = A10_MMC_NDESC ; + sc->a10_dma_size = sizeof(struct a10_mmc_dma_desc)*(sc->a10_dma_ndesc) ; + + uint32_t error ; + /* First create the tag */ + error = bus_dma_tag_create(bus_get_dma_tag(dev),1, + sc->a10_dma_size,BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, + NULL,NULL,sc->a10_dma_size, + 1,sc->a10_dma_size,0, + NULL,NULL,&sc->a10_dma_tag) ; + if(error) + return (error) ; + + /* Allocate the memory and map at kva sc->a10_dma_desc*/ + + error = bus_dmamem_alloc(sc->a10_dma_tag,&sc->a10_dma_desc,BUS_DMA_WAITOK,&sc->a10_dma_map) ; + if(error) + return (error) ; + + /* Load the map */ + error = bus_dmamap_load(sc->a10_dma_tag, sc->a10_dma_map,sc->a10_dma_desc,sc->a10_dma_size,a10_dma_cb, &sc->a10_dma_cb_arg,0) ; + + if((error != 0)&&(error != EINPROGRESS)) + return (error) ; + + return(0) ; + +} + +static int +a10_mmc_prepare_dma(struct a10_mmc_softc* sc) +{ + 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 ; + 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++) + { + bus_addr_t paddr = sc->a10_dma_map->segments[seg].ds_addr; + bus_size_t len = sc->a10_dma_map->segments[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].config = htole32(A10_MMC_DMA_CONFIG_CH|A10_MMC_DMA_CONFIG_OWN) ; + + cmd->data->len -= len ; + rem -= len ; + off += len ; + if(desc == 0) { + dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_FD) ; + } + + if(cmd->data->len == 0) { + dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_LD) ; + dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_ER) ; + dma[desc].next = 0 ; + } + else { + dma[desc].config |= htole32(A10_MMC_DMA_CONFIG_DIC) ; + dma[desc].next = htole32(desc_paddr + ((desc+1)*sizeof(struct a10_mmc_dma_desc))) + } + desc++ ; + } + } + + if(desc == sc->a10_dma_ndesc) { + device_printf(sc->a10_dev, "Couldn't find enough descriptors for DMA transfer") ; + } + + val = A10_MMC_READ_4(sc, A10_MMC_GCTRL) ; + val |= A10_MMC_DMA_ENABLE ; + val |= A10_MMC_INT_ENABLE ; + A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,val) ; + val |= A10_MMC_DMA_RESET ; + A10_MMC_WRITE_4(sc, A10_MMC_GCTRL,val) ; + A10_MMC_WRITE_4(sc, A10_MMC_DMAC,A10_MMC_IDMAC_SOFT_RST) ; + A10_MMC_WRITE_4(sc, A10_MMC_DMAC,A10_MMC_IDMAC_IDMA_ON | A10_MMC_IDMAC_FIX_BURST) ; + val = A10_MMC_READ_4(sc,A10_MMC_IDIE) ; + val &= ~(A10_MMC_IDMAC_RECEIVE_INT | A10_MMC_IDMAC_TRANSMIT_INT) ; + + if(read == 1) { + val |= A10_MMC_IDMAC_RECEIVE_INT ; + } + else { + val |= A10_MMC_IDMAC_TRANSMIT_INT ; + } + + A10_MMC_WRITE_4(sc, A10_MMC_IDIE,val) ; + A10_MMC_WRITE_4(sc, A10_MMC_DLBA,desc_paddr) ; + A10_MMC_WRITE_4(sc, A10_MMC_FTRGL,A10_MMC_DMA_FTRGLEVEL_A20) ; + + return (0) ; +} + + +static void +a10_dma_cb(void* arg, bus_dma_segment_t* segs, int nsegs, int error) +{ + if(error) { + printf("a10_mmc: Error in a10_dma_callback function, code = %d\n",error) ; + return ; + } + + /* This is because, we can't get the number of segments alloted from bus_dmamap_t */ + *(int*)arg = nsegs ; +} + +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,24 +372,23 @@ 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. */ @@ -285,7 +397,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); @@ -296,14 +408,13 @@ 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); @@ -332,29 +443,27 @@ 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; @@ -371,7 +480,7 @@ return (0); } - static void +static void a10_mmc_intr(void *arg) { struct a10_mmc_softc *sc; @@ -379,7 +488,6 @@ 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); @@ -392,8 +500,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; @@ -413,19 +521,20 @@ 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) { + 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); + else { + a10_mmc_prepare_dma(sc) ; + } + 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; @@ -434,7 +543,6 @@ 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); @@ -473,120 +581,120 @@ 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; int retry; cmdreg = A10_MMC_START | A10_MMC_UPCLK_ONLY | - A10_MMC_WAIT_PREOVER; + A10_MMC_WAIT_PREOVER; A10_MMC_WRITE_4(sc, A10_MMC_CMDR, cmdreg); retry = 0xfffff; while (--retry > 0) { @@ -602,39 +710,7 @@ return (ETIMEDOUT); } -/* 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_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) ; -} - -static void -a10_mmc_dma_callback(void* arg, bus_dma_segment_t* segs, int nsegs, int error) -{ - if(error) { - printf("a10_mmc : Error in the callback function code = %d\n", error) ; - return ; - } - 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; @@ -643,7 +719,6 @@ 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. */ @@ -678,35 +753,34 @@ /* 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); @@ -721,13 +795,12 @@ 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 Sat Jun 6 01:18:28 2015 (r286706) +++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h Sat Jun 6 03:47:59 2015 (r286707) @@ -29,8 +29,6 @@ #ifndef _A10_MMC_H_ #define _A10_MMC_H_ -#define A10_MMC_BASE 0x01c0f000 /* Base module address */ - #define A10_MMC_GCTRL 0x00 /* Global Control Register */ #define A10_MMC_CLKCR 0x04 /* Clock Control Register */ #define A10_MMC_TIMEOUT 0x08 /* Timeout Register */ @@ -60,8 +58,6 @@ #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) @@ -74,7 +70,6 @@ #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) @@ -181,11 +176,18 @@ #define A10_MMC_IDMAC_WR (7U << 13) #define A10_MMC_IDMAC_DESC_CLOSE (8U << 13) +/* Used to make the descriptor table for suppoting DMA Access */ struct a10_mmc_dma_desc { - uint32_t dma_config ; - uint32_t size ; - uint32_t addr ; - uint32_t next ; + uint32_t config ; +#define A10_MMC_DMA_CONFIG_DIC (1U << 1) +#define A10_MMC_DMA_CONFIG_LD (1U << 2) +#define A10_MMC_DMA_CONFIG_FD (1U << 3) +#define A10_MMC_DMA_CONFIG_CH (1U << 4) +#define A10_MMC_DMA_CONFIG_ER (1U << 5) +#define A10_MMC_DMA_CONFIG_CES (1U << 30) +#define A10_MMC_DMA_CONFIG_OWN (1U << 31) + uint32_t buff_size ; + uint32_t buff_addr ; + uint32_t next; } ; - #endif /* _A10_MMC_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506060347.t563lxdQ077718>