Date: Mon, 25 May 2015 14:12:56 GMT From: pratiksinghal@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r286131 - soc2015/pratiksinghal/cubie-head/sys/arm/allwinner Message-ID: <201505251412.t4PECu3p072914@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505251412.t4PECu3p072914>