socsvn commit: r286624 - in soc2015/pratiksinghal/cubie-head/sys/arm: allwinner broadcom/bcm2835 conf
pratiksinghal at FreeBSD.org
pratiksinghal at FreeBSD.org
Thu Jun 4 02:29:04 UTC 2015
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; i<NDDMA; i++)
+ {
+ if(val&DDMA_IRQ_FULL_ENABLE(i)) {
+ device_printf(sc->a10_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 <machine/bus.h>
+/* 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 <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
@@ -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
More information about the svn-soc-all
mailing list