diff options
author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2006-12-17 15:39:15 +0100 |
---|---|---|
committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-04-14 16:14:06 +0200 |
commit | d5acb95b16a0a74c643524342c3437e765426d05 (patch) | |
tree | 8668799d8bd70b82351e645d42e743715eefee73 /lib_avr32 | |
parent | 91975b0fea773c9e681fea8cf3349669f27685ee (diff) |
AVR32: Implement simple DMA memory allocator
Implement dma_alloc_coherent() which returns cache-aligned
uncacheable memory.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'lib_avr32')
-rw-r--r-- | lib_avr32/board.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib_avr32/board.c b/lib_avr32/board.c index a407bcad14d..2f16386c768 100644 --- a/lib_avr32/board.c +++ b/lib_avr32/board.c @@ -76,6 +76,50 @@ void *sbrk(ptrdiff_t increment) return ((void *)old); } +#ifdef CFG_DMA_ALLOC_LEN +#include <asm/cacheflush.h> +#include <asm/io.h> + +static unsigned long dma_alloc_start; +static unsigned long dma_alloc_end; +static unsigned long dma_alloc_brk; + +static void dma_alloc_init(void) +{ + unsigned long monitor_addr; + + monitor_addr = CFG_MONITOR_BASE + gd->reloc_off; + dma_alloc_end = monitor_addr - CFG_MALLOC_LEN; + dma_alloc_start = dma_alloc_end - CFG_DMA_ALLOC_LEN; + dma_alloc_brk = dma_alloc_start; + + printf("DMA: Using memory from 0x%08lx to 0x%08lx\n", + dma_alloc_start, dma_alloc_end); + + dcache_invalidate_range(cached(dma_alloc_start), + dma_alloc_end - dma_alloc_start); +} + +void *dma_alloc_coherent(size_t len, unsigned long *handle) +{ + unsigned long paddr = dma_alloc_brk; + + if (dma_alloc_brk + len > dma_alloc_end) + return NULL; + + dma_alloc_brk = ((paddr + len + CFG_DCACHE_LINESZ - 1) + & ~(CFG_DCACHE_LINESZ - 1)); + + *handle = paddr; + return uncached(paddr); +} +#else +static inline void dma_alloc_init(void) +{ + +} +#endif + static int init_baudrate(void) { char tmp[64]; @@ -179,6 +223,12 @@ void board_init_f(ulong board_type) /* Reserve memory for malloc() */ addr -= CFG_MALLOC_LEN; +#ifdef CFG_DMA_ALLOC_LEN + /* Reserve DMA memory (must be cache aligned) */ + addr &= ~(CFG_DCACHE_LINESZ - 1); + addr -= CFG_DMA_ALLOC_LEN; +#endif + /* Allocate a Board Info struct on a word boundary */ addr -= sizeof(bd_t); addr &= ~3UL; @@ -258,6 +308,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) timer_init(); mem_malloc_init(); malloc_bin_reloc(); + dma_alloc_init(); board_init_info(); flash_init(); |