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/arm/cpu | |
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/arm/cpu')
-rw-r--r-- | arch/arm/cpu/mmu.c | 55 |
1 files changed, 37 insertions, 18 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); + } } - |