socsvn commit: r286131 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner
pratiksinghal at FreeBSD.org
pratiksinghal at FreeBSD.org
Mon May 25 14:12:58 UTC 2015
Author: pratiksinghal
Date: Mon May 25 14:12:56 2015
New Revision: 286131
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=286131
Log:
Made changes in DMA API, dma transfer not working though
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
Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c Mon May 25 13:51:13 2015 (r286130)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c Mon May 25 14:12:56 2015 (r286131)
@@ -17,10 +17,6 @@
#include "a10_dma.h"
-/*Total no of channels for Dedicated and Normal DMA */
-#define NNDMA 8
-#define NDDMA 8
-
enum a10_dma_channel_type {
NDMA,
DDMA
@@ -65,15 +61,11 @@
static int a10_dma_attach(device_t) ;
static int a10_dma_detach(device_t) ;
static void a10_dma_release_resources(device_t) ;
-static void a10_temp_setup_dma() ;
static void a10_dma_intr(void*) ;
-/* Currently these two methods are implemented for only DDMA */
-uint8_t a10_get_dma_channel(void *fp(bus_space_tag_t, bus_space_handle_t, uint8_t)) ;
-void a10_free_dma_channel(uint8_t, void *fp(bus_space_tag_t, bus_space_handle_t, uint8_t)) ;
-
-static int a10_dma_probe(device_t dev)
+static int
+a10_dma_probe(device_t dev)
{
if(!ofw_bus_status_okay(dev))
return (ENXIO) ;
@@ -85,7 +77,8 @@
return (BUS_PROBE_DEFAULT) ;
}
-static int a10_dma_attach(device_t dev)
+static int
+a10_dma_attach(device_t dev)
{
struct a10_dma_softc* sc;
sc = device_get_softc(dev) ;
@@ -130,13 +123,15 @@
/* It is the responsibility of the allocater of DMA channel to deallocate its resources by making a call to the functions provided by our interface.
*/
-static int a10_dma_detach(device_t dev)
+static int
+a10_dma_detach(device_t dev)
{
a10_dma_release_resources(dev) ;
return (0) ;
}
-static void a10_dma_release_resources(device_t dev)
+static void
+a10_dma_release_resources(device_t dev)
{
struct a10_dma_softc* sc = device_get_softc(dev) ;
@@ -152,7 +147,8 @@
}
/* Not implemented yet. */
-static void a10_dma_intr(void* ptr)
+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))
@@ -162,45 +158,74 @@
return ;
}
-uint8_t a10_get_dma_channel(void *auto_config(bus_space_tag_t, bus_space_handle_t, uint8_t))
+uint8_t
+a10_get_ddma_channel()
{
+ uint8_t pos = NDDMA + 1 ;
+
if(a10_dma_cnt->nddma_channels_in_use >= NDDMA)
- return (NDDMA + 1) ;
- uint8_t pos = NDDMA+1 ;
+ return (pos) ;
+
for(int i=0; i<NDDMA; i++) {
- if(a10_dma_cnt->ddma_channels[i].in_use == 0)
+ if(a10_dma_cnt->ddma_channels[i].in_use == 0) {
pos = i ;
+ break ;
}
+ }
+
if(pos > NDDMA)
return (pos) ;
- auto_config(a10_dma_cnt->sc->a10_dma_bst, a10_dma_cnt->sc->a10_dma_bsh,pos) ;
a10_dma_cnt->ddma_channels[pos].in_use = 1 ;
a10_dma_cnt->nddma_channels_in_use++ ;
a10_dma_cnt->ddma_channels[pos].a10_dma_channel_type = DDMA ;
- device_printf(a10_dma_cnt->sc->a10_dma_dev, "Autoconfiguring of DDMA channel %u done.\n", pos) ;
return pos ;
}
-void a10_free_dma_channel(uint8_t pos, void* auto_config(bus_space_tag_t, bus_space_handle_t, uint8_t))
+void
+a10_free_dma_channel(uint8_t pos)
{
if((pos >= 8) || (pos < 0)) {
device_printf(a10_dma_cnt->sc->a10_dma_dev, "Invalid position %u while freeing dma channel!\n",pos) ;
return ;
}
-
- auto_config(a10_dma_cnt->sc->a10_dma_bst, a10_dma_cnt->sc->a10_dma_bsh, pos) ;
-
a10_dma_cnt->ddma_channels[pos].in_use = 0 ;
a10_dma_cnt->nddma_channels_in_use-- ;
device_printf(a10_dma_cnt->sc->a10_dma_dev, "Freed DDMA Channel no %u\n", pos) ;
}
-void a10_temp_setup_dma()
+/*
+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 */
+uint8_t
+a10_ddma_config_channel(uint8_t pos, void* src, void* dest, int32_t count, int32_t cfg)
+{
+ 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) ;
+ return 1 ;
+ }
+ if(a10_dma_cnt->ddma_channels[pos].in_use != 1) {
+ 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) ;
+ DMA_WRITE(a10_dma_cnt->sc, DDMA_BC_REG(pos), count) ;
+ DMA_WRITE(a10_dma_cnt->sc, DDMA_CFG_REG(pos), cfg) ;
+ return (0) ;
}
+
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 Mon May 25 13:51:13 2015 (r286130)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h Mon May 25 14:12:56 2015 (r286131)
@@ -6,13 +6,18 @@
#include <machine/bus.h>
+/*Total no of channels for Dedicated and Normal DMA */
+#define NNDMA 8
+#define NDDMA 8
+
/* module base address. */
#define DMA (0x01C02000)
-
-/* These are macros of Normal DMA. */
+
#define DMA_IRQ_EN_REG (0x0000)
#define DMA_IRQ_PEND_STA_REG (0x0004)
+
+/* These are macros of Normal DMA. */
#define NDMA_CTRL_REG(n) (0x100 + ((n)*0x20))
#define NDMA_SRC_ADDR_REG(n) (0x100 + ((n)*0x20) + 4)
#define NDMA_DEST_ADDR_REG(n) (0x100 + ((n)*0x20) + 8)
@@ -45,5 +50,15 @@
#define a10_dma_lock(_sc) mtx_lock(&(_sc)->a10_dma_mtx)
#define a10_dma_unlock(_sc) mtx_unlock(&(_sc)->a10_dma_mtx)
-
+
+/* Helper Macros */
+
+#define SET_BIT(n) (1 << (n))
+
+/* 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) ;
+void a10_free_dma_channel(uint8_t) ;
+
#endif
Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Mon May 25 13:51:13 2015 (r286130)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.c Mon May 25 14:12:56 2015 (r286131)
@@ -51,6 +51,10 @@
#include <arm/allwinner/a10_clk.h>
#include <arm/allwinner/a10_mmc.h>
+#include <vm/pmap.h>
+
+#include "a10_dma.h"
+
#define A10_MMC_MEMRES 0
#define A10_MMC_IRQRES 1
#define A10_MMC_RESSZ 2
@@ -70,6 +74,8 @@
struct resource * a10_res[A10_MMC_RESSZ];
uint32_t a10_intr;
uint32_t a10_intr_wait;
+ uint8_t ddma_channel ;
+ uint8_t use_dma ;
void * a10_intrhand;
};
@@ -182,7 +188,8 @@
device_delete_child(dev, child);
goto fail;
}
-
+ sc->ddma_channel = NDDMA + 1 ;
+ sc->use_dma = 0 ;
return (0);
fail:
@@ -327,15 +334,21 @@
if (write)
A10_MMC_WRITE_4(sc, A10_MMC_FIFO, buf[i]);
else
- buf[i] = A10_MMC_READ_4(sc, A10_MMC_FIFO);
+ {
+ uint32_t* p1 = (uint32_t*) A10_MMC_FIFO + A10_MMC_BASE ;
+ uint32_t* p2 = (uint32_t*) vtophys(buf + i) ;
+ a10_ddma_config_channel(sc->ddma_channel,p1, p2, 4, SET_BIT(31)|SET_BIT(30)|SET_BIT(29)|SET_BIT(28)|SET_BIT(26)|SET_BIT(15)|SET_BIT(12)|SET_BIT(10)|SET_BIT(0) ) ;
+ //buf[i] = A10_MMC_READ_4(sc, A10_MMC_FIFO);
+ }
sc->a10_resid = i + 1;
}
- if(!write)
- {
+ if(sc->use_dma == 1) {
+ device_printf(sc->a10_dev, "DMA channel no %d allocated.\n", sc->ddma_channel) ;
+ }
+ if(!write) {
device_printf(sc->a10_dev, "Transferred %d bytes from the card\n", (i-old_resid)*4 ) ;
}
- else
- {
+ else {
device_printf(sc->a10_dev, "Wrote %d bytes to the card\n", (i-old_resid)*4 ) ;
}
return (0);
@@ -401,6 +414,14 @@
sc = device_get_softc(bus);
A10_MMC_LOCK(sc);
+ if(sc->ddma_channel == NDDMA + 1) {
+ sc->ddma_channel = a10_get_ddma_channel() ;
+ if(sc->ddma_channel != NDDMA + 1)
+ sc->use_dma = 1 ;
+ else
+ sc->use_dma = 0 ;
+ }
+
if (sc->a10_req) {
A10_MMC_UNLOCK(sc);
return (EBUSY);
Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h Mon May 25 13:51:13 2015 (r286130)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_mmc.h Mon May 25 14:12:56 2015 (r286131)
@@ -29,6 +29,8 @@
#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 */
More information about the svn-soc-all
mailing list