From: chenhui zhao <chenhui.z...@freescale.com>

Issue:
As a master, the PCI IP block can combine a memory write to the last PCI double
word (4 bytes) of a cacheline with a 4 byte memory write to the first PCI double
word of the subsequent cacheline. This affects 32-bit PCI target devices that
blindly assert STOP on memory-write transactions, without detecting that the
data beat being transferred is the last data beat of the transaction. It can
cause a hang. PCI-X operation is not affected by this erratum.

Workaround:
Setting the bit MDS in the PCI Bus Function Register will disable the combining
of crossing cacheline boundary requests into one burst transaction. Therefore,
it can prevent the errata scenario from occurring.

This errata exists in MPC8543, MPC8543E, MPC8545, MPC8545E, MPC8547, MPC8547E,
MPC8548 and MPC8548E. Refer to PCI 5 in MPC8548 errata document.

Signed-off-by: Gong Chen <g.c...@freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.z...@freescale.com>
Signed-off-by: Li Yang <le...@freescale.com>
---
Changes for v2:
 * add 8543, 8545 and 8547

 arch/powerpc/include/asm/mpc85xx.h |    1 +
 arch/powerpc/sysdev/fsl_pci.c      |   23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/mpc85xx.h 
b/arch/powerpc/include/asm/mpc85xx.h
index 451777c..fafca9f 100644
--- a/arch/powerpc/include/asm/mpc85xx.h
+++ b/arch/powerpc/include/asm/mpc85xx.h
@@ -37,6 +37,7 @@
 #define SVR_8544_E     0x803C01
 #define SVR_8545       0x803102
 #define SVR_8545_E     0x803902
+#define SVR_8547       0x803101
 #define SVR_8547_E     0x803901
 #define SVR_8548       0x803100
 #define SVR_8548_E     0x803900
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 6073288..f595117 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -31,6 +31,7 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
+#include <asm/mpc85xx.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
@@ -426,6 +427,7 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
        struct resource rsrc;
        const int *bus_range;
        u8 progif;
+       u16 temp;
 
        if (!of_device_is_available(dev)) {
                pr_warning("%s: disabled\n", dev->full_name);
@@ -476,6 +478,27 @@ int __init fsl_add_bridge(struct device_node *dev, int 
is_primary)
                        PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
                if (fsl_pcie_check_link(hose))
                        hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+       } else {
+               /*
+                * Set PBFR(PCI Bus Function Register)[10] = 1 to
+                * disable the combining of crossing cacheline
+                * boundary requests into one burst transaction.
+                * PCI-X operation is not affected.
+                * Fix erratum PCI 5 on MPC8548
+                */
+#define PCI_BUS_FUNCTION 0x44
+#define PCI_BUS_FUNCTION_MDS 0x400     /* Master disable streaming */
+               if ((fsl_svr_is(SVR_8543) || fsl_svr_is(SVR_8543_E) ||
+                    fsl_svr_is(SVR_8545) || fsl_svr_is(SVR_8545_E) ||
+                    fsl_svr_is(SVR_8547) || fsl_svr_is(SVR_8547_E) ||
+                    fsl_svr_is(SVR_8548) || fsl_svr_is(SVR_8548_E)) &&
+                   !early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX)) {
+                       early_read_config_word(hose, 0, 0,
+                                               PCI_BUS_FUNCTION, &temp);
+                       temp |= PCI_BUS_FUNCTION_MDS;
+                       early_write_config_word(hose, 0, 0,
+                                               PCI_BUS_FUNCTION, temp);
+               }
        }
 
        printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
-- 
1.6.4.1


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to