socsvn commit: r286707 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner
pratiksinghal at FreeBSD.org
pratiksinghal at FreeBSD.org
Sat Jun 6 03:48:01 UTC 2015
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_ */
More information about the svn-soc-all
mailing list