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