diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-08-07 11:51:29 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2015-08-07 15:42:55 +0200 |
commit | 3c76d02aeb552aea1a61f25114476275b6e04a6b (patch) | |
tree | 14b5d8b8c8c0bfaf690911c9d8e61b43041aff2d | |
parent | 77ac6b4786612d56acb5513831a46276a995ac36 (diff) | |
download | barebox-3c76d02aeb552aea1a61f25114476275b6e04a6b.tar.gz barebox-3c76d02aeb552aea1a61f25114476275b6e04a6b.tar.xz |
implement dma_alloc_writecombine
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | arch/arm/cpu/mmu.c | 20 | ||||
-rw-r--r-- | include/dma.h | 1 |
2 files changed, 21 insertions, 0 deletions
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 37bfa058a5..2d00fa7594 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -66,6 +66,7 @@ static inline void tlb_invalidate(void) } #define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE) +#define PTE_FLAGS_WC_V7 PTE_EXT_TEX(1) #define PTE_FLAGS_UNCACHED_V7 (0) #define PTE_FLAGS_CACHED_V4 (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE) #define PTE_FLAGS_UNCACHED_V4 PTE_SMALL_AP_UNO_SRW @@ -75,6 +76,7 @@ static inline void tlb_invalidate(void) * This will be determined at runtime. */ static uint32_t pte_flags_cached; +static uint32_t pte_flags_wc; static uint32_t pte_flags_uncached; #define PTE_MASK ((1 << 12) - 1) @@ -325,9 +327,11 @@ static int mmu_init(void) if (cpu_architecture() >= CPU_ARCH_ARMv7) { pte_flags_cached = PTE_FLAGS_CACHED_V7; + pte_flags_wc = PTE_FLAGS_WC_V7; pte_flags_uncached = PTE_FLAGS_UNCACHED_V7; } else { pte_flags_cached = PTE_FLAGS_CACHED_V4; + pte_flags_wc = PTE_FLAGS_UNCACHED_V4; pte_flags_uncached = PTE_FLAGS_UNCACHED_V4; } @@ -408,6 +412,22 @@ void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) return ret; } +void *dma_alloc_writecombine(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); + + remap_range(ret, size, pte_flags_wc); + + return ret; +} + unsigned long virt_to_phys(volatile void *virt) { return (unsigned long)virt; diff --git a/include/dma.h b/include/dma.h index 800d8b155f..4d31797968 100644 --- a/include/dma.h +++ b/include/dma.h @@ -39,5 +39,6 @@ void dma_sync_single_for_device(unsigned long address, size_t size, void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle); void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size); +void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle); #endif /* __DMA_H */ |