|
32 | 32 | #include <linux/pci.h>
|
33 | 33 | #include <asm/smp_plat.h>
|
34 | 34 | #include <asm/cacheflush.h>
|
| 35 | +#include <asm/mach/map.h> |
35 | 36 | #include "armada-370-xp.h"
|
36 | 37 | #include "coherency.h"
|
37 | 38 | #include "mvebu-soc-id.h"
|
@@ -309,9 +310,47 @@ static void __init armada_370_coherency_init(struct device_node *np)
|
309 | 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 | + */ |
| 319 | +static void __iomem * |
| 320 | +armada_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 | + |
312 | 333 | static void __init armada_375_380_coherency_init(struct device_node *np)
|
313 | 334 | {
|
| 335 | + struct device_node *cache_dn; |
| 336 | + |
314 | 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 |
|
317 | 356 | static int coherency_type(void)
|
|
0 commit comments