summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/indirect_pci.c6
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c5
-rw-r--r--include/asm-powerpc/pci-bridge.h3
3 files changed, 14 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index cfbd2aae93e8..7fd49c97501a 100644
--- a/arch/powerpc/sysdev/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
@@ -123,6 +123,12 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
(bus->number == hose->first_busno))
val &= 0xffffff00;
+ /* Workaround for PCI_28 Errata in 440EPx/GRx */
+ if ((hose->indirect_type & PPC_INDIRECT_TYPE_BROKEN_MRM) &&
+ offset == PCI_CACHE_LINE_SIZE) {
+ val = 0;
+ }
+
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 76886cf0e6dc..fb368dfde5d4 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -75,6 +75,11 @@ static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev)
!of_device_is_compatible(hose->dn, "ibm,plb-pci"))
return;
+ if (of_device_is_compatible(hose->dn, "ibm,plb440epx-pci") ||
+ of_device_is_compatible(hose->dn, "ibm,plb440grx-pci")) {
+ hose->indirect_type |= PPC_INDIRECT_TYPE_BROKEN_MRM;
+ }
+
/* Hide the PCI host BARs from the kernel as their content doesn't
* fit well in the resource management
*/
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index b95d033ae6e6..ae2ea803a0f2 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -92,12 +92,15 @@ struct pci_controller {
* anything but the PHB. Only allow talking to the PHB if this is
* set.
* BIG_ENDIAN - cfg_addr is a big endian register
+ * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on
+ * the PLB4. Effectively disable MRM commands by setting this.
*/
#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
+#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020
u32 indirect_type;
#endif /* !CONFIG_PPC64 */
/* Currently, we limit ourselves to 1 IO range and 3 mem