ARM: Optionally allow ARMv6 to use 'normal, bufferable' memory for DMA
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 15 May 2010 10:02:43 +0000 (11:02 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 17 May 2010 10:52:11 +0000 (11:52 +0100)
Provide a configuration option to allow the ARMv6 to use normal
bufferable memory for coherent DMA.  This option is forced to 'y'
for ARMv7, and offered as a configuration option on ARMv6.

Enabling this option requires drivers to have the necessary barriers
to ensure that data in DMA coherent memory is visible prior to the
DMA operation commencing.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/system.h
arch/arm/mm/Kconfig

index 11397687f42c56578ae2d7be2135efcdf44a8b9f..ab68cf1ef80fe7ccad28bfdd5d5084bb6f1b61dc 100644 (file)
@@ -314,7 +314,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
 #define pgprot_writecombine(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
-#if __LINUX_ARM_ARCH__ >= 7
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
 #else
index ca88e6a84707350bad0b1ab3bd7eefcd116be506..02f5d99adbc04de0562178f76f16a39fdda9053a 100644 (file)
@@ -137,7 +137,7 @@ extern unsigned int user_debug;
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#if defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
 #define mb()           dmb()
 #define rmb()          dmb()
 #define wmb()          dmb()
index c4ed9f93f646be93fbdcc048a326c5d7db995bcd..573528d9c6d81b01000771e4af605f7042cb2292 100644 (file)
@@ -781,3 +781,22 @@ config ARM_L1_CACHE_SHIFT
        int
        default 6 if ARM_L1_CACHE_SHIFT_6
        default 5
+
+config ARM_DMA_MEM_BUFFERABLE
+       bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
+       default y if CPU_V6 || CPU_V7
+       help
+         Historically, the kernel has used strongly ordered mappings to
+         provide DMA coherent memory.  With the advent of ARMv7, mapping
+         memory with differing types results in unpredictable behaviour,
+         so on these CPUs, this option is forced on.
+
+         Multiple mappings with differing attributes is also unpredictable
+         on ARMv6 CPUs, but since they do not have aggressive speculative
+         prefetch, no harm appears to occur.
+
+         However, drivers may be missing the necessary barriers for ARMv6,
+         and therefore turning this on may result in unpredictable driver
+         behaviour.  Therefore, we offer this as an option.
+
+         You are recommended say 'Y' here and debug any affected drivers.