summaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev/fsl_rio.c
diff options
context:
space:
mode:
authorchenhui zhao <chenhui.zhao@freescale.com>2012-03-08 16:42:20 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-03-27 21:09:46 (GMT)
commit3f72dce9f4649b9d8ae88a00b673c5615d3b21d1 (patch)
tree0d88aa5f409f0d806b525fe15233e45f76de5b73 /arch/powerpc/sysdev/fsl_rio.c
parent6d724aef9ad18862e746f503a6416f42493f91f0 (diff)
downloadlinux-fsl-qoriq-3f72dce9f4649b9d8ae88a00b673c5615d3b21d1.tar.xz
powerpc/mpc8548: Add workaround for erratum NMG_SRIO135
Issue: Applications using lwarx/stwcx instructions in the core to compete for a software lock or semaphore with a device on RapidIO using read atomic set, clr, inc, or dec in a similar manner may falsely result in both masters seeing the lock as "available". This could result in data corruption as both masters try to modify the same piece of data protected by the lock. Workaround: Set bits 13 and 29 of CCSR offset 0x01010 (EEBPCR register of the ECM) during initialization and leave them set indefinitely. This may slightly degrade overall system performance. Refer to SRIO39 in MPC8548 errata document. Signed-off-by: Gong Chen <g.chen@freescale.com> Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com> Signed-off-by: Li Yang <leoli@freescale.com> (cherry picked from commit bf51c182808e86fad869a295e23caadc0c90fa9f) Change-Id: Ia7eea3e0496dabb0a6ad527f4b0d1bb954c78363 Reviewed-on: http://git.am.freescale.net:8181/515 Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com> Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'arch/powerpc/sysdev/fsl_rio.c')
-rw-r--r--arch/powerpc/sysdev/fsl_rio.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index e2fb317..e9f4556 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -35,6 +35,8 @@
#include <linux/io.h>
#include <linux/uaccess.h>
#include <asm/machdep.h>
+#include <asm/mpc85xx.h>
+#include <sysdev/fsl_soc.h>
#include "fsl_rio.h"
@@ -321,6 +323,37 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr)
}
}
+#define CCSR_ECM_EEBPCR_OFF 0x10
+/*
+ * fixup_erratum_srio135 - Fix Serial RapidIO atomic operation erratum
+ */
+static int fixup_erratum_srio135(struct device *dev)
+{
+ struct device_node *np;
+ void __iomem *ecm;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc8548-ecm");
+ if (!np) {
+ dev_err(dev, "no ECM node found.\n");
+ return -ENODEV;
+ }
+
+ ecm = of_iomap(np, 0);
+ of_node_put(np);
+ if (!ecm) {
+ dev_err(dev, "failed to map ECM register base.\n");
+ return -ENODEV;
+ }
+ /*
+ * Set bits 13 and 29 of the EEBPCR register in the ECM
+ * during initialization and leave them set indefinitely.
+ */
+ setbits32(ecm + CCSR_ECM_EEBPCR_OFF, 0x00040004);
+ iounmap(ecm);
+
+ return 0;
+}
+
/**
* fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
* @dev: platform_device pointer
@@ -358,6 +391,17 @@ int fsl_rio_setup(struct platform_device *dev)
dev->dev.of_node->full_name);
return -EFAULT;
}
+
+ /* Fix erratum NMG_SRIO135 */
+ if (fsl_svr_is(SVR_8548) || fsl_svr_is(SVR_8548_E)) {
+ rc = fixup_erratum_srio135(&dev->dev);
+ if (rc) {
+ dev_err(&dev->dev,
+ "failed to fix the erratum NMG_SRIO135.");
+ return rc;
+ }
+ }
+
dev_info(&dev->dev, "Of-device full name %s\n",
dev->dev.of_node->full_name);
dev_info(&dev->dev, "Regs: %pR\n", &regs);