summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2015-03-09 08:32:21 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2015-03-09 08:32:21 +0100
commit4680b375b9dd32e6558ae2ee8a15b27819c70e73 (patch)
tree945cd90ff3557de600e6e208596c7ef846fb603e /arch
parent5544581e98d09c7c9008f9cac8cd25dbb6a14d6e (diff)
parent0e06a77f5b93d4479ff1b88bc32003ceaa37d152 (diff)
downloadbarebox-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.c55
-rw-r--r--arch/arm/include/asm/dma.h35
-rw-r--r--arch/arm/include/asm/io.h15
-rw-r--r--arch/arm/include/asm/mmu.h45
-rw-r--r--arch/arm/mach-bcm2835/mbox.c8
-rw-r--r--arch/mips/include/asm/dma-mapping.h6
-rw-r--r--arch/mips/include/asm/dma.h2
-rw-r--r--arch/nios2/include/asm/dma-mapping.h13
-rw-r--r--arch/nios2/include/asm/types.h2
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, &regs->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(&regs->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