socsvn commit: r285910 - in soc2015/pratiksinghal/cubie-head/sys: arm/allwinner arm/conf boot/fdt/dts/arm
pratiksinghal at FreeBSD.org
pratiksinghal at FreeBSD.org
Sat May 23 04:51:08 UTC 2015
Author: pratiksinghal
Date: Sat May 23 04:51:01 2015
New Revision: 285910
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=285910
Log:
Added the dma files with preliminary code
Added:
soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c
soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h
Modified:
soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/files.allwinner
soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD
soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/cubieboard.dts
soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
Added: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.c Sat May 23 04:51:01 2015 (r285910)
@@ -0,0 +1,210 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "a10_dma.h"
+
+/*Total no of channels for Dedicated and Nomal DMA */
+#define NNDMA 8
+#define NDDMA 8
+
+enum a10_dma_channel_type {
+ NDMA,
+ DDMA
+} ;
+
+
+struct a10_dma_softc {
+ device_t a10_dma_dev ;
+ struct mtx a10_dma_mtx ;
+ bus_space_tag_t a10_dma_bst ;
+ bus_space_handle_t a10_dma_bsh ;
+ struct resource* a10_dma_mem_resource ;
+ struct resource* a10_dma_irq_resource ;
+ int a10_dma_mem_rid ;
+ int a10_dma_irq_rid ;
+ void* a10_dma_intrhand ;
+ #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 ;
+ enum a10_dma_channel_type a10_dma_channel_type ;
+ uint8_t in_use ;
+} ;
+
+struct a10_dma_controller {
+ struct a10_dma_softc* sc ;
+ struct a10_dma_channel ddma_channels[NDDMA] ;
+ struct a10_dma_channel ndma_channels[NNDMA] ;
+ uint32_t nndma_channels_in_use ;
+ uint32_t nddma_channels_in_use ;
+} ;
+
+static struct a10_dma_controller* a10_dma_cnt;
+
+static MALLOC_DEFINE(M_DMA_CONT, "memory for dma controller", "memory for dma controller") ;
+
+static int a10_dma_probe(device_t) ;
+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_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)
+{
+ if(!ofw_bus_status_okay(dev))
+ return (ENXIO) ;
+ if(!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-dma"))
+ return (ENXIO) ;
+
+ device_set_desc(dev, "Allwinner DMA Controller") ;
+
+ return (BUS_PROBE_DEFAULT) ;
+}
+
+static int a10_dma_attach(device_t dev)
+{
+ struct a10_dma_softc* sc;
+ sc = device_get_softc(dev) ;
+ sc->a10_dma_dev = dev ;
+
+ mtx_init(&sc->a10_dma_mtx, device_get_nameunit(sc->a10_dma_dev),"a10_dma", MTX_DEF) ;
+
+ sc->a10_dma_mem_resource = bus_alloc_resource_any(sc->a10_dma_dev, SYS_RES_MEMORY, &sc->a10_dma_mem_rid, RF_ACTIVE) ;
+
+ if(sc->a10_dma_mem_resource == NULL) {
+ device_printf(dev, "Cannot allocate memory resource !\n") ;
+ a10_dma_release_resources(dev) ;
+ return (ENXIO) ;
+ }
+
+ sc->a10_dma_bst = rman_get_bustag(sc->a10_dma_mem_resource) ;
+ 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) ;
+ return (ENXIO) ;
+ }
+
+ if(bus_setup_intr(sc->a10_dma_dev, sc->a10_dma_irq_resource, INTR_MPSAFE | INTR_TYPE_MISC, NULL,a10_dma_intr, sc, &sc->a10_dma_intrhand)) {
+ device_printf(dev, "Cannot setup interrupt handler!\n") ;
+ a10_dma_release_resources(dev) ;
+ return (ENXIO) ;
+ }
+
+
+ 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 ;
+
+ return (0) ;
+}
+
+/* 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)
+{
+ a10_dma_release_resources(dev) ;
+ return (0) ;
+}
+
+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) ;
+
+ if(sc->a10_dma_irq_resource != NULL) {
+ bus_teardown_intr(dev, sc->a10_dma_mem_resource, sc->a10_dma_intrhand) ;
+ bus_release_resource(dev, SYS_RES_IRQ, sc->a10_dma_irq_rid, sc->a10_dma_irq_resource) ;
+ }
+
+ 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 ;
+ return ;
+}
+
+uint8_t a10_get_dma_channel(void *auto_config(bus_space_tag_t, bus_space_handle_t, uint8_t))
+{
+ if(a10_dma_cnt->nddma_channels_in_use >= NDDMA)
+ return (NDDMA + 1) ;
+ uint8_t pos = NDDMA+1 ;
+ for(int i=0; i<NDDMA; i++) {
+ if(a10_dma_cnt->ddma_channels[i].in_use == 0)
+ pos = i ;
+ }
+ 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))
+{
+ 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) ;
+}
+
+static device_method_t a10_dma_methods[] = {
+ DEVMETHOD(device_probe, a10_dma_probe),
+ DEVMETHOD(device_attach, a10_dma_attach),
+ DEVMETHOD(device_detach, a10_dma_detach),
+
+ DEVMETHOD_END
+} ;
+
+static devclass_t a10_dma_devclass ;
+
+static driver_t a10_dma_driver = {
+ "a10_dma",
+ a10_dma_methods,
+ sizeof(struct a10_dma_softc)
+} ;
+
+DRIVER_MODULE(a10_dma, simplebus, a10_dma_driver ,a10_dma_devclass,0,0) ;
Added: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/a10_dma.h Sat May 23 04:51:01 2015 (r285910)
@@ -0,0 +1,49 @@
+#ifndef AWIN_DMA_H
+#define AWIN_DMA_H
+
+#include <sys/mutex.h>
+#include <sys/lock.h>
+
+#include <machine/bus.h>
+
+/* 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)
+#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)
+#define NDMA_BC_REG(n) (0x100 + ((n)*0x20) + 0x0C )
+
+/* 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_BC_REG(n) (0x300 + ((n)*0x20 ) + 0x0C )
+#define DDMA_PARA_REG(n) (0x300 + ((n)*0x20) + 0x18)
+
+
+/* Macros to manipulate DMA_IRQ_EN_REG */
+
+#define DDMA_IRQ_FULL_ENABLE(n) (1 << (17 + (2*(n))))
+#define DDMA_IRQ_FULL_DISABLE(n) (~(1 << (17 + (2*(n)))))
+#define DDMA_IRQ_HALF_ENABLE(n) (1 << (16 + (2*(n))))
+#define DDMA_IRQ_HALF_DISABLE(n) (~(1 << (16 + (2*(n)))))
+
+#define NDMA_IRQ_FULL_ENABLE(n) (1 << (1 + (2*(n))))
+#define NDMA_IRQ_FULL_DISABLE(n) (~(1 << (1 + (2*(n)))))
+#define NDMA_IRQ_HALF_ENABLE(n) (1 << (16 + (2*(n))))
+#define NDMA_IRQ_HALF_DISABLE(n) (~(1 << (16 + 2*(n))))
+
+#define DMA_READ(_sc, reg) \
+ bus_space_read_4((_sc)->a10_dma_bst, (_sc)->a10_dma_bsh, (reg))
+#define DMA_WRITE(_sc, reg, val) \
+ bus_space_write_4((_sc)->a10_dma_bst, (_sc)->a10_dma_bsh, (reg), (val))
+
+#define a10_dma_lock(_sc) mtx_lock(&(_sc)->a10_dma_mtx)
+#define a10_dma_unlock(_sc) mtx_unlock(&(_sc)->a10_dma_mtx)
+
+#endif
Modified: soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/files.allwinner
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/files.allwinner Sat May 23 02:25:03 2015 (r285909)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/allwinner/files.allwinner Sat May 23 04:51:01 2015 (r285910)
@@ -7,6 +7,7 @@
arm/allwinner/a10_clk.c standard
arm/allwinner/a10_common.c standard
+arm/allwinner/a10_dma.c optional dma
arm/allwinner/a10_ehci.c optional ehci
arm/allwinner/a10_gpio.c optional gpio
arm/allwinner/a10_machdep.c standard
Modified: soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD Sat May 23 02:25:03 2015 (r285909)
+++ soc2015/pratiksinghal/cubie-head/sys/arm/conf/CUBIEBOARD Sat May 23 04:51:01 2015 (r285910)
@@ -100,6 +100,9 @@
device emac
+#DMA controller
+device dma
+
# USB ethernet support, requires miibus
device miibus
Modified: soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/cubieboard.dts
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/cubieboard.dts Sat May 23 02:25:03 2015 (r285909)
+++ soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/cubieboard.dts Sat May 23 04:51:01 2015 (r285910)
@@ -61,7 +61,11 @@
status = "okay";
};
- emac at 01c0b000 {
+ dma0: dma at 01c02000 {
+ status = "okay" ;
+ } ;
+
+emac at 01c0b000 {
status = "okay";
};
};
Modified: soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
==============================================================================
--- soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/sun4i-a10.dtsi Sat May 23 02:25:03 2015 (r285909)
+++ soc2015/pratiksinghal/cubie-head/sys/boot/fdt/dts/arm/sun4i-a10.dtsi Sat May 23 04:51:01 2015 (r285910)
@@ -111,6 +111,14 @@
status = "disabled";
};
+ dma0: dma at 01c02000 {
+ compatible = "allwinner,sun4i-a10-dma";
+ reg = <0x01c02000 0x418>;
+ interrupts = <27>;
+ interrupt-parent = <&AINTC>;
+ status = "disabled";
+ } ;
+
sata at 01c18000 {
compatible = "allwinner,sun4i-ahci";
reg = <0x01c18000 0x1000>;
More information about the svn-soc-all
mailing list