Message ID | 1331025056-15983-4-git-send-email-chenhui.zhao@freescale.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Kumar Gala |
Headers | show |
> 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. Might be worth actually saying what these bits do, and why/when overall performance is affected. Is the problem trying to do locked read-write cycles on a slow peripheral bus? Might be a case for just 'not doing that'. David
On Tue, Mar 06, 2012 at 05:10:56PM +0800, chenhui zhao wrote: > From: chenhui zhao <chenhui.zhao@freescale.com> > > 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> > > --- > arch/powerpc/sysdev/fsl_rio.c | 44 +++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 44 insertions(+), 0 deletions(-) [snip] > @@ -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; > + } > + } This needs to be respun based on the current tree. -Scott
OK. I will do. -Chenhui
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index a4c4f4a..78a0c3d 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", ®s);