aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mvebu/coherency.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 5723178f6589..a2225070ac3d 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -32,6 +32,7 @@
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <asm/smp_plat.h> 33#include <asm/smp_plat.h>
34#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
35#include <asm/mach/map.h>
35#include "armada-370-xp.h" 36#include "armada-370-xp.h"
36#include "coherency.h" 37#include "coherency.h"
37#include "mvebu-soc-id.h" 38#include "mvebu-soc-id.h"
@@ -309,9 +310,47 @@ static void __init armada_370_coherency_init(struct device_node *np)
309 set_cpu_coherent(); 310 set_cpu_coherent();
310} 311}
311 312
313/*
314 * This ioremap hook is used on Armada 375/38x to ensure that PCIe
315 * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
316 * is needed as a workaround for a deadlock issue between the PCIe
317 * interface and the cache controller.
318 */
319static void __iomem *
320armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
321 unsigned int mtype, void *caller)
322{
323 struct resource pcie_mem;
324
325 mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
326
327 if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
328 mtype = MT_UNCACHED;
329
330 return __arm_ioremap_caller(phys_addr, size, mtype, caller);
331}
332
312static void __init armada_375_380_coherency_init(struct device_node *np) 333static void __init armada_375_380_coherency_init(struct device_node *np)
313{ 334{
335 struct device_node *cache_dn;
336
314 coherency_cpu_base = of_iomap(np, 0); 337 coherency_cpu_base = of_iomap(np, 0);
338 arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
339
340 /*
341 * Add the PL310 property "arm,io-coherent". This makes sure the
342 * outer sync operation is not used, which allows to
343 * workaround the system erratum that causes deadlocks when
344 * doing PCIe in an SMP situation on Armada 375 and Armada
345 * 38x.
346 */
347 for_each_compatible_node(cache_dn, NULL, "arm,pl310-cache") {
348 struct property *p;
349
350 p = kzalloc(sizeof(*p), GFP_KERNEL);
351 p->name = kstrdup("arm,io-coherent", GFP_KERNEL);
352 of_add_property(cache_dn, p);
353 }
315} 354}
316 355
317static int coherency_type(void) 356static int coherency_type(void)