From 017f11f68ef543e866be033bcb7b8058a8a380d8 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:40 -0500 Subject: 8xxx: Break out DMA code to a common file DMA support is now enabled via the CONFIG_FSL_DMA define instead of the previous CONFIG_DDR_ECC Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/Makefile | 1 + drivers/dma/fsl_dma.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 drivers/dma/fsl_dma.c (limited to 'drivers') diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index cf29efa..36d99f9 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libdma.a COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o +COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c new file mode 100644 index 0000000..a9989ee --- /dev/null +++ b/drivers/dma/fsl_dma.c @@ -0,0 +1,92 @@ +/* + * Copyright 2004,2007,2008 Freescale Semiconductor, Inc. + * (C) Copyright 2002, 2003 Motorola Inc. + * Xianghua Xiao (X.Xiao@motorola.com) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#if defined(CONFIG_MPC85xx) +volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); +#elif defined(CONFIG_MPC86xx) +volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); +#else +#error "Freescale DMA engine not supported on your processor" +#endif + +static void dma_sync(void) +{ +#if defined(CONFIG_MPC85xx) + asm("sync; isync; msync"); +#elif defined(CONFIG_MPC86xx) + asm("sync; isync"); +#endif +} + +static uint dma_check(void) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + volatile uint status = dma->sr; + + /* While the channel is busy, spin */ + while (status & 4) + status = dma->sr; + + /* clear MR[CS] channel start bit */ + dma->mr &= 1; + dma_sync(); + + if (status != 0) + printf ("DMA Error: status = %x\n", status); + + return status; +} + +void dma_init(void) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + + dma->satr = 0x00040000; + dma->datr = 0x00040000; + dma->sr = 0xffffffff; /* clear any errors */ + dma_sync(); +} + +int dma_xfer(void *dest, uint count, void *src) { + volatile fsl_dma_t *dma = &dma_base->dma[0]; + + dma->dar = (uint) dest; + dma->sar = (uint) src; + dma->bcr = count; + + /* Disable bandwidth control, use direct transfer mode */ + dma->mr = 0xf000004; + dma_sync(); + + /* Start the transfer */ + dma->mr = 0xf000005; + dma_sync(); + + return dma_check(); +} -- cgit v1.1 From 9c06071a6077ba95e9d43226156e39567d5d064a Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:41 -0500 Subject: fsl_dma: Add bitfield definitions for common registers Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index a9989ee..baf2942 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -51,11 +51,11 @@ static uint dma_check(void) { volatile uint status = dma->sr; /* While the channel is busy, spin */ - while (status & 4) + while (status & FSL_DMA_SR_CB) status = dma->sr; /* clear MR[CS] channel start bit */ - dma->mr &= 1; + dma->mr &= FSL_DMA_MR_CS; dma_sync(); if (status != 0) @@ -67,8 +67,8 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - dma->satr = 0x00040000; - dma->datr = 0x00040000; + dma->satr = FSL_DMA_SATR_SREAD_NO_SNOOP; + dma->datr = FSL_DMA_DATR_DWRITE_NO_SNOOP; dma->sr = 0xffffffff; /* clear any errors */ dma_sync(); } @@ -81,11 +81,11 @@ int dma_xfer(void *dest, uint count, void *src) { dma->bcr = count; /* Disable bandwidth control, use direct transfer mode */ - dma->mr = 0xf000004; + dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT; dma_sync(); /* Start the transfer */ - dma->mr = 0xf000005; + dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_CS; dma_sync(); return dma_check(); -- cgit v1.1 From a730393a362741c318b21771b8d7b2647e546c3e Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:42 -0500 Subject: fsl_dma: Use proper I/O access functions Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index baf2942..33ea828 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -27,12 +27,13 @@ #include #include +#include #include #if defined(CONFIG_MPC85xx) -volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); #elif defined(CONFIG_MPC86xx) -volatile ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); #else #error "Freescale DMA engine not supported on your processor" #endif @@ -48,14 +49,15 @@ static void dma_sync(void) static uint dma_check(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - volatile uint status = dma->sr; + uint status; /* While the channel is busy, spin */ - while (status & FSL_DMA_SR_CB) - status = dma->sr; + do { + status = in_be32(&dma->sr); + } while (status & FSL_DMA_SR_CB); /* clear MR[CS] channel start bit */ - dma->mr &= FSL_DMA_MR_CS; + out_be32(&dma->mr, in_be32(&dma->mr) & FSL_DMA_MR_CS); dma_sync(); if (status != 0) @@ -67,25 +69,27 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - dma->satr = FSL_DMA_SATR_SREAD_NO_SNOOP; - dma->datr = FSL_DMA_DATR_DWRITE_NO_SNOOP; - dma->sr = 0xffffffff; /* clear any errors */ + out_be32(&dma->satr, FSL_DMA_SATR_SREAD_NO_SNOOP); + out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_NO_SNOOP); + out_be32(&dma->sr, 0xffffffff); /* clear any errors */ dma_sync(); } int dma_xfer(void *dest, uint count, void *src) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - dma->dar = (uint) dest; - dma->sar = (uint) src; - dma->bcr = count; + out_be32(&dma->dar, (uint) dest); + out_be32(&dma->sar, (uint) src); + out_be32(&dma->bcr, count); /* Disable bandwidth control, use direct transfer mode */ - dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT; + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); dma_sync(); /* Start the transfer */ - dma->mr = FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_CS; + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | + FSL_DMA_MR_CTM_DIRECT | + FSL_DMA_MR_CS); dma_sync(); return dma_check(); -- cgit v1.1 From 51402ac12be9a0025f16db51fbde7c050a54e5fe Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:43 -0500 Subject: fsl_dma: Add support for arbitrarily large transfers Support DMA transfers larger than the DMA controller's limit of (2 ^ 26 - 1) bytes Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 33ea828..f3575af 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -30,6 +30,9 @@ #include #include +/* Controller can only transfer 2^26 - 1 bytes at a time */ +#define FSL_DMA_MAX_SIZE (0x3ffffff) + #if defined(CONFIG_MPC85xx) ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); #elif defined(CONFIG_MPC86xx) @@ -77,20 +80,33 @@ void dma_init(void) { int dma_xfer(void *dest, uint count, void *src) { volatile fsl_dma_t *dma = &dma_base->dma[0]; + uint xfer_size; - out_be32(&dma->dar, (uint) dest); - out_be32(&dma->sar, (uint) src); - out_be32(&dma->bcr, count); + while (count) { + xfer_size = MIN(FSL_DMA_MAX_SIZE, count); - /* Disable bandwidth control, use direct transfer mode */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); - dma_sync(); + out_be32(&dma->dar, (uint) dest); + out_be32(&dma->sar, (uint) src); + out_be32(&dma->bcr, xfer_size); - /* Start the transfer */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | - FSL_DMA_MR_CTM_DIRECT | - FSL_DMA_MR_CS); - dma_sync(); + /* Disable bandwidth control, use direct transfer mode */ + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); + dma_sync(); + + /* Start the transfer */ + out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | + FSL_DMA_MR_CTM_DIRECT | + FSL_DMA_MR_CS); + + count -= xfer_size; + src += xfer_size; + dest += xfer_size; + + dma_sync(); + + if (dma_check()) + return -1; + } - return dma_check(); + return 0; } -- cgit v1.1 From 484919cf3351212ebf748b9b13ece1ddaf7e7d1c Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:44 -0500 Subject: fsl_dma: Fix Channel Start bug in dma_check() The Channel Start (CS) bit in the Mode Register (MR) should actually be cleared as the comment in the code suggests. Previously, CS was being set, not cleared. Assuming normal operation of the DMA engine, this change shouldn't have any real affect. Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f3575af..f058802 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -60,7 +60,7 @@ static uint dma_check(void) { } while (status & FSL_DMA_SR_CB); /* clear MR[CS] channel start bit */ - out_be32(&dma->mr, in_be32(&dma->mr) & FSL_DMA_MR_CS); + out_be32(&dma->mr, in_be32(&dma->mr) & ~FSL_DMA_MR_CS); dma_sync(); if (status != 0) -- cgit v1.1 From 7892f619d40f4196e41e7114c5dfee9fad0f572f Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:45 -0500 Subject: 8xxx: Rename dma_xfer() to dmacpy() Also update dmacpy()'s argument order to match memcpy's and use phys_addr_t/phy_size_t for address/size arguments Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index f058802..49ea8f1 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -78,7 +78,7 @@ void dma_init(void) { dma_sync(); } -int dma_xfer(void *dest, uint count, void *src) { +int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { volatile fsl_dma_t *dma = &dma_base->dma[0]; uint xfer_size; -- cgit v1.1 From 0d595f76bc9c7c8dff5bd31dffed87a840a03c56 Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:48 -0500 Subject: fsl_dma: Break out common memory initialization function Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index 49ea8f1..e103c91 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -110,3 +110,35 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { return 0; } + +#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) +void dma_meminit(uint val, uint size) +{ + uint *p = 0; + uint i = 0; + + for (*p = 0; p < (uint *)(8 * 1024); p++) { + if (((uint)p & 0x1f) == 0) + ppcDcbz((ulong)p); + + *p = (uint)CONFIG_MEM_INIT_VALUE; + + if (((uint)p & 0x1c) == 0x1c) + ppcDcbf((ulong)p); + } + + dmacpy(0x002000, 0, 0x002000); /* 8K */ + dmacpy(0x004000, 0, 0x004000); /* 16K */ + dmacpy(0x008000, 0, 0x008000); /* 32K */ + dmacpy(0x010000, 0, 0x010000); /* 64K */ + dmacpy(0x020000, 0, 0x020000); /* 128K */ + dmacpy(0x040000, 0, 0x040000); /* 256K */ + dmacpy(0x080000, 0, 0x080000); /* 512K */ + dmacpy(0x100000, 0, 0x100000); /* 1M */ + dmacpy(0x200000, 0, 0x200000); /* 2M */ + dmacpy(0x400000, 0, 0x400000); /* 4M */ + + for (i = 1; i < size / 0x800000; i++) + dmacpy((0x800000 * i), 0, 0x800000); +} +#endif -- cgit v1.1 From 6af015b86b86d94de7ca1b23a3890bc93a50c2ab Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:49 -0500 Subject: fsl_dma: Make DMA transactions snoopable Make DMA transactions snoopable so that CPUs can keep caches up-to-date. This allows dma transactions to be used for operations such as memory copies without any additional cache control operations. Signed-off-by: Peter Tyser Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index e103c91..cba5d5b 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -72,8 +72,8 @@ static uint dma_check(void) { void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - out_be32(&dma->satr, FSL_DMA_SATR_SREAD_NO_SNOOP); - out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_NO_SNOOP); + out_be32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP); + out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP); out_be32(&dma->sr, 0xffffffff); /* clear any errors */ dma_sync(); } -- cgit v1.1 From e94e460c6e8741f42dab6d8dd4b596ba5d9d79ae Mon Sep 17 00:00:00 2001 From: Peter Tyser Date: Tue, 30 Jun 2009 17:15:51 -0500 Subject: 83xx: Add support for fsl_dma driver Signed-off-by: Peter Tyser Reviewed-by: Ira W. Snyder Tested-by: Ira W. Snyder Acked-by: Kim Phillips Signed-off-by: Kumar Gala --- drivers/dma/fsl_dma.c | 64 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/fsl_dma.c b/drivers/dma/fsl_dma.c index cba5d5b..df33e7a 100644 --- a/drivers/dma/fsl_dma.c +++ b/drivers/dma/fsl_dma.c @@ -33,7 +33,16 @@ /* Controller can only transfer 2^26 - 1 bytes at a time */ #define FSL_DMA_MAX_SIZE (0x3ffffff) -#if defined(CONFIG_MPC85xx) +#if defined(CONFIG_MPC83xx) +#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN) +#else +#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT) +#endif + + +#if defined(CONFIG_MPC83xx) +dma83xx_t *dma_base = (void *)(CONFIG_SYS_MPC83xx_DMA_ADDR); +#elif defined(CONFIG_MPC85xx) ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); #elif defined(CONFIG_MPC86xx) ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); @@ -50,17 +59,35 @@ static void dma_sync(void) #endif } +static void out_dma32(volatile unsigned *addr, int val) +{ +#if defined(CONFIG_MPC83xx) + out_le32(addr, val); +#else + out_be32(addr, val); +#endif +} + +static uint in_dma32(volatile unsigned *addr) +{ +#if defined(CONFIG_MPC83xx) + return in_le32(addr); +#else + return in_be32(addr); +#endif +} + static uint dma_check(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; uint status; /* While the channel is busy, spin */ do { - status = in_be32(&dma->sr); + status = in_dma32(&dma->sr); } while (status & FSL_DMA_SR_CB); /* clear MR[CS] channel start bit */ - out_be32(&dma->mr, in_be32(&dma->mr) & ~FSL_DMA_MR_CS); + out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS); dma_sync(); if (status != 0) @@ -69,14 +96,16 @@ static uint dma_check(void) { return status; } +#if !defined(CONFIG_MPC83xx) void dma_init(void) { volatile fsl_dma_t *dma = &dma_base->dma[0]; - out_be32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP); - out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP); - out_be32(&dma->sr, 0xffffffff); /* clear any errors */ + out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP); + out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP); + out_dma32(&dma->sr, 0xffffffff); /* clear any errors */ dma_sync(); } +#endif int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { volatile fsl_dma_t *dma = &dma_base->dma[0]; @@ -85,18 +114,17 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { while (count) { xfer_size = MIN(FSL_DMA_MAX_SIZE, count); - out_be32(&dma->dar, (uint) dest); - out_be32(&dma->sar, (uint) src); - out_be32(&dma->bcr, xfer_size); + out_dma32(&dma->dar, (uint) dest); + out_dma32(&dma->sar, (uint) src); + out_dma32(&dma->bcr, xfer_size); + dma_sync(); - /* Disable bandwidth control, use direct transfer mode */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT); + /* Prepare mode register */ + out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT); dma_sync(); /* Start the transfer */ - out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | - FSL_DMA_MR_CTM_DIRECT | - FSL_DMA_MR_CS); + out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS); count -= xfer_size; src += xfer_size; @@ -111,7 +139,13 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { return 0; } -#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) +/* + * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER + * while 83xx uses dma to initialize SDRAM when CONFIG_DDR_ECC_INIT_VIA_DMA + */ +#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) && \ + !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) || \ + (defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA))) void dma_meminit(uint val, uint size) { uint *p = 0; -- cgit v1.1