diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-03-09 08:32:21 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-03-09 08:32:21 +0100 |
commit | 4680b375b9dd32e6558ae2ee8a15b27819c70e73 (patch) | |
tree | 945cd90ff3557de600e6e208596c7ef846fb603e /arch | |
parent | 5544581e98d09c7c9008f9cac8cd25dbb6a14d6e (diff) | |
parent | 0e06a77f5b93d4479ff1b88bc32003ceaa37d152 (diff) | |
download | barebox-4680b375b9dd32e6558ae2ee8a15b27819c70e73.tar.gz barebox-4680b375b9dd32e6558ae2ee8a15b27819c70e73.tar.xz |
Merge branch 'for-next/streaming-dma'
Conflicts:
drivers/mci/dw_mmc.c
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/mmu.c | 55 | ||||
-rw-r--r-- | arch/arm/include/asm/dma.h | 35 | ||||
-rw-r--r-- | arch/arm/include/asm/io.h | 15 | ||||
-rw-r--r-- | arch/arm/include/asm/mmu.h | 45 | ||||
-rw-r--r-- | arch/arm/mach-bcm2835/mbox.c | 8 | ||||
-rw-r--r-- | arch/mips/include/asm/dma-mapping.h | 6 | ||||
-rw-r--r-- | arch/mips/include/asm/dma.h | 2 | ||||
-rw-r--r-- | arch/nios2/include/asm/dma-mapping.h | 13 | ||||
-rw-r--r-- | arch/nios2/include/asm/types.h | 2 |
9 files changed, 105 insertions, 76 deletions
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 299ebdb51c..37bfa058a5 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -18,6 +18,7 @@ #define pr_fmt(fmt) "mmu: " fmt #include <common.h> +#include <dma-dir.h> #include <init.h> #include <asm/mmu.h> #include <errno.h> @@ -156,6 +157,20 @@ static u32 *find_pte(unsigned long adr) return &table[(adr >> PAGE_SHIFT) & 0xff]; } +static void dma_flush_range(unsigned long start, unsigned long end) +{ + if (outer_cache.flush_range) + outer_cache.flush_range(start, end); + __dma_flush_range(start, end); +} + +static void dma_inv_range(unsigned long start, unsigned long end) +{ + if (outer_cache.inv_range) + outer_cache.inv_range(start, end); + __dma_inv_range(start, end); +} + void remap_range(void *_start, size_t size, uint32_t flags) { unsigned long start = (unsigned long)_start; @@ -377,12 +392,14 @@ static int mmu_init(void) } mmu_initcall(mmu_init); -void *dma_alloc_coherent(size_t size) +void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) { void *ret; size = PAGE_ALIGN(size); ret = xmemalign(PAGE_SIZE, size); + if (dma_handle) + *dma_handle = (dma_addr_t)ret; dma_inv_range((unsigned long)ret, (unsigned long)ret + size); @@ -401,7 +418,7 @@ void *phys_to_virt(unsigned long phys) return (void *)phys; } -void dma_free_coherent(void *mem, size_t size) +void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size) { size = PAGE_ALIGN(size); remap_range(mem, size, pte_flags_cached); @@ -409,24 +426,26 @@ void dma_free_coherent(void *mem, size_t size) free(mem); } -void dma_clean_range(unsigned long start, unsigned long end) +void dma_sync_single_for_cpu(unsigned long address, size_t size, + enum dma_data_direction dir) { - if (outer_cache.clean_range) - outer_cache.clean_range(start, end); - __dma_clean_range(start, end); -} - -void dma_flush_range(unsigned long start, unsigned long end) -{ - if (outer_cache.flush_range) - outer_cache.flush_range(start, end); - __dma_flush_range(start, end); + if (dir != DMA_TO_DEVICE) { + if (outer_cache.inv_range) + outer_cache.inv_range(address, address + size); + __dma_inv_range(address, address + size); + } } -void dma_inv_range(unsigned long start, unsigned long end) +void dma_sync_single_for_device(unsigned long address, size_t size, + enum dma_data_direction dir) { - if (outer_cache.inv_range) - outer_cache.inv_range(start, end); - __dma_inv_range(start, end); + if (dir == DMA_FROM_DEVICE) { + __dma_inv_range(address, address + size); + if (outer_cache.inv_range) + outer_cache.inv_range(address, address + size); + } else { + __dma_clean_range(address, address + size); + if (outer_cache.clean_range) + outer_cache.clean_range(address, address + size); + } } - diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index cb9cd1b4ea..d9bce3d70e 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -5,4 +5,37 @@ * */ -#include <asm/mmu.h> +#include <common.h> + +#define dma_alloc dma_alloc +static inline void *dma_alloc(size_t size) +{ + return xmemalign(64, ALIGN(size, 64)); +} + +#ifndef CONFIG_MMU +static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + void *ret = xmemalign(4096, size); + if (dma_handle) + *dma_handle = (dma_addr_t)ret; + + return ret; +} + +static inline void dma_free_coherent(void *mem, dma_addr_t dma_handle, + size_t size) +{ + free(mem); +} + +static inline void dma_sync_single_for_cpu(unsigned long address, size_t size, + enum dma_data_direction dir) +{ +} + +static inline void dma_sync_single_for_device(unsigned long address, size_t size, + enum dma_data_direction dir) +{ +} +#endif diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 850a99c6d9..eebf0938b0 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -69,4 +69,19 @@ extern void memset_io(volatile void __iomem *, int, size_t); #define setbits_8(addr, set) setbits(8, addr, set) #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) +#ifdef CONFIG_MMU +void *phys_to_virt(unsigned long phys); +unsigned long virt_to_phys(volatile void *virt); +#else +static inline void *phys_to_virt(unsigned long phys) +{ + return (void *)phys; +} + +static inline unsigned long virt_to_phys(volatile void *mem) +{ + return (unsigned long)mem; +} +#endif + #endif /* __ASM_ARM_IO_H */ diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index c6e425f02d..97bb0dbeb6 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -26,58 +26,13 @@ static inline void setup_dma_coherent(unsigned long offset) { } -#define dma_alloc dma_alloc -static inline void *dma_alloc(size_t size) -{ - return xmemalign(64, ALIGN(size, 64)); -} - #ifdef CONFIG_MMU -void *dma_alloc_coherent(size_t size); -void dma_free_coherent(void *mem, size_t size); - -void dma_clean_range(unsigned long, unsigned long); -void dma_flush_range(unsigned long, unsigned long); -void dma_inv_range(unsigned long, unsigned long); -unsigned long virt_to_phys(volatile void *virt); -void *phys_to_virt(unsigned long phys); void remap_range(void *_start, size_t size, uint32_t flags); void *map_io_sections(unsigned long physaddr, void *start, size_t size); uint32_t mmu_get_pte_cached_flags(void); uint32_t mmu_get_pte_uncached_flags(void); #else -static inline void *dma_alloc_coherent(size_t size) -{ - return xmemalign(4096, size); -} - -static inline void dma_free_coherent(void *mem, size_t size) -{ - free(mem); -} - -static inline void *phys_to_virt(unsigned long phys) -{ - return (void *)phys; -} - -static inline unsigned long virt_to_phys(volatile void *mem) -{ - return (unsigned long)mem; -} - -static inline void dma_clean_range(unsigned long s, unsigned long e) -{ -} - -static inline void dma_flush_range(unsigned long s, unsigned long e) -{ -} - -static inline void dma_inv_range(unsigned long s, unsigned long e) -{ -} static inline void remap_range(void *_start, size_t size, uint32_t flags) { diff --git a/arch/arm/mach-bcm2835/mbox.c b/arch/arm/mach-bcm2835/mbox.c index 1a8077182a..9d69bc8ea7 100644 --- a/arch/arm/mach-bcm2835/mbox.c +++ b/arch/arm/mach-bcm2835/mbox.c @@ -7,9 +7,9 @@ */ #include <asm/io.h> -#include <asm/mmu.h> #include <common.h> #include <clock.h> +#include <dma.h> #include <mach/mbox.h> @@ -55,7 +55,8 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer, /* Send the request */ val = BCM2835_MBOX_PACK(chan, send); debug("mbox: TX raw: 0x%08x\n", val); - dma_flush_range(send, send + buffer->buf_size); + dma_sync_single_for_device((unsigned long)send, buffer->buf_size, + DMA_BIDIRECTIONAL); writel(val, ®s->write); /* Wait for the response */ @@ -72,7 +73,8 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer, /* Read the response */ val = readl(®s->read); debug("mbox: RX raw: 0x%08x\n", val); - dma_inv_range(send, send + buffer->buf_size); + dma_sync_single_for_cpu((unsigned long)send, buffer->buf_size, + DMA_BIDIRECTIONAL); /* Validate the response */ if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) { diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 555efa5773..639511226d 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -12,12 +12,14 @@ static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) ret = xmemalign(PAGE_SIZE, size); - *dma_handle = CPHYSADDR(ret); + if (dma_handle) + *dma_handle = CPHYSADDR(ret); return (void *)CKSEG1ADDR(ret); } -static inline void dma_free_coherent(void *vaddr) +static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, + size_t size) { free(vaddr); } diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h index 27d269f491..30a58c78b9 100644 --- a/arch/mips/include/asm/dma.h +++ b/arch/mips/include/asm/dma.h @@ -8,6 +8,6 @@ #ifndef __ASM_DMA_H #define __ASM_DMA_H -/* empty */ +#include "asm/dma-mapping.h" #endif /* __ASM_DMA_H */ diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h index 620c207a03..5ecc1ed21e 100644 --- a/arch/nios2/include/asm/dma-mapping.h +++ b/arch/nios2/include/asm/dma-mapping.h @@ -14,24 +14,25 @@ */ #if (DCACHE_SIZE != 0) -static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) +static inline void *dma_alloc_coherent(size_t len, dma_addr_t *handle) { void *addr = malloc(len + DCACHE_LINE_SIZE); if (!addr) return 0; flush_dcache_range((unsigned long)addr,(unsigned long)addr + len + DCACHE_LINE_SIZE); - *handle = ((unsigned long)addr + - (DCACHE_LINE_SIZE - 1)) & - ~(DCACHE_LINE_SIZE - 1) & ~(IO_REGION_BASE); + if (handle) + *handle = ((dma_addr_t)addr + (DCACHE_LINE_SIZE - 1)) & + ~(DCACHE_LINE_SIZE - 1) & ~(IO_REGION_BASE); return (void *)(*handle | IO_REGION_BASE); } #else -static inline void *dma_alloc_coherent(size_t len, unsigned long *handle) +static inline void *dma_alloc_coherent(size_t len, dma_addr_t *handle) { void *addr = malloc(len); if (!addr) return 0; - *handle = (unsigned long)addr; + if (handle) + *handle = (dma_addr_t)addr; return (void *)(*handle | IO_REGION_BASE); } #endif diff --git a/arch/nios2/include/asm/types.h b/arch/nios2/include/asm/types.h index 1f613d1cb9..21c3415f93 100644 --- a/arch/nios2/include/asm/types.h +++ b/arch/nios2/include/asm/types.h @@ -3,5 +3,7 @@ #include <asm/int-ll64.h> +typedef u32 dma_addr_t; + #endif |