On Thu, May 15, 2014 at 11:18:39AM +0200, Thomas Petazzoni wrote:
> The Marvell Armada 375 and Armada 38x SOCs, which use the Cortex-A9
> CPU core, the PL310 cache and the Marvell PCIe hardware block are
> affected a L2/PCIe deadlock caused by a system erratum when hardware
> I/O coherency is used.
> 
> This deadlock can be avoided by mapping the PCIe memory areas as
> strongly-ordered (note: MT_UNCACHED is strongly-ordered), and by
> removing the outer cache sync done in software. This is done in this
> patch, thanks to the new bits of infrastructure added in 'ARM: mm:
> allow sub-architectures to override PCI I/O memory type' and 'ARM: mm:
> add support for HW coherent systems in PL310' respectively.
> 
> Signed-off-by: Thomas Petazzoni <[email protected]>
> ---
>  arch/arm/mach-mvebu/board-v7.c | 51 
> ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c
> index 01cfce6..5016c58 100644
> --- a/arch/arm/mach-mvebu/board-v7.c
> +++ b/arch/arm/mach-mvebu/board-v7.c
> @@ -71,6 +71,49 @@ static int armada_375_external_abort_wa(unsigned long 
> addr, unsigned int fsr,
>       return 1;
>  }
>  
> +/*
> + * This ioremap hook is used on Armada 375/38x to ensure that PCIe
> + * memory areas are mapped as MT_MEMORY_RW_SO instead of
> + * MT_DEVICE. This is needed as a workaround for a deadlock issue
> + * between the PCIe interface and the cache controller.
> + */
> +static void __iomem *
> +armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
> +                           unsigned int mtype, void *caller)
> +{
> +     struct resource pcie_mem;
> +
> +     mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
> +
> +     if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
> +             mtype = MT_UNCACHED;
> +
> +     return __arm_ioremap_caller(phys_addr, size, mtype, caller);
> +}
> +
> +/*
> + * When we are I/O coherent and we use the PL310 cache controller, we
> + * add the PL310 property "dma-coherent". This makes sure the outer
> + * sync operation is not used, which allows to workaround the system
> + * erratum that causes deadlocks when doing PCIe in an SMP situation
> + * on Armada 375 and Armada 38x.
> + */
> +static void __init mvebu_l2x0_pl310_coherent(void)
> +{
> +     struct device_node *np;
> +
> +     if (!coherency_available())
> +             return;
> +
> +     for_each_compatible_node(np, NULL, "arm,pl310-cache") {
> +             struct property *p;
> +
> +             p = kzalloc(sizeof(*p), GFP_KERNEL);
> +             p->name = kstrdup("dma-coherent", GFP_KERNEL);
> +             of_add_property(np, p);
> +     }
> +}
> +
>  static void __init mvebu_timer_and_clk_init(void)
>  {
>       of_clk_init(NULL);
> @@ -78,6 +121,14 @@ static void __init mvebu_timer_and_clk_init(void)
>       mvebu_scu_enable();
>       coherency_init();
>       BUG_ON(mvebu_mbus_dt_init(coherency_available()));
> +
> +     if (of_machine_is_compatible("marvell,armada375") ||
> +         of_machine_is_compatible("marvell,armada38x")) {
> +             arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
> +             pci_ioremap_set_mem_type(MT_UNCACHED);

iiuc, this patch depends on 1/3.  So how would you like to handle it?

thx,

Jason.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to