On Mon, Nov 2, 2020 at 1:37 AM Ran Wang <ran.wang_1@xxxxxxx> wrote: > > From: Biwen Li <biwen.li@xxxxxxx> > > Hardware issue: > - Reading register RCPM_IPPDEXPCR1 always return zero, this causes > system firmware could not get correct information and wrongly do > clock gating for all wakeup source IP during system suspend. Then > those IPs will never get chance to wake system. > > Workaround: > - Copy register RCPM_IPPDEXPCR1's setting to register SCFG_SPARECR8 > to allow system firmware's psci method read it and do things accordingly. > > Signed-off-by: Biwen Li <biwen.li@xxxxxxx> > Signed-off-by: Ran Wang <ran.wang_1@xxxxxxx> Applied for next. Thanks. > --- > Change in v4: > - Replace property 'fsl,ippdexpcr1-alt-reg' with compatible checking as the > workaround trigger condition. > > Change in v3: > - Add copy_ippdexpcr1_setting(), simplize workaournd's implementation > according to binding update. > - Minor update on commit message. > > Change in v2: > - Update commit message to be more clear. > - Replace device_property_read_u32_array() with syscon_regmap_lookup_by_phandle_args() > to make code simpler. > > drivers/soc/fsl/rcpm.c | 35 ++++++++++++++++++++++++++++++++++- > 1 file changed, 34 insertions(+), 1 deletion(-) > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c > index a093dbe..4ace28c 100644 > --- a/drivers/soc/fsl/rcpm.c > +++ b/drivers/soc/fsl/rcpm.c > @@ -2,7 +2,7 @@ > // > // rcpm.c - Freescale QorIQ RCPM driver > // > -// Copyright 2019 NXP > +// Copyright 2019-2020 NXP > // > // Author: Ran Wang <ran.wang_1@xxxxxxx> > > @@ -22,6 +22,28 @@ struct rcpm { > bool little_endian; > }; > > +#define SCFG_SPARECR8 0x051c > + > +static void copy_ippdexpcr1_setting(u32 val) > +{ > + struct device_node *np; > + void __iomem *regs; > + u32 reg_val; > + > + np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); > + if (!np) > + return; > + > + regs = of_iomap(np, 0); > + if (!regs) > + return; > + > + reg_val = ioread32be(regs + SCFG_SPARECR8); > + iowrite32be(val | reg_val, regs + SCFG_SPARECR8); > + > + iounmap(regs); > +} > + > /** > * rcpm_pm_prepare - performs device-level tasks associated with power > * management, such as programming related to the wakeup source control. > @@ -90,6 +112,17 @@ static int rcpm_pm_prepare(struct device *dev) > tmp |= ioread32be(address); > iowrite32be(tmp, address); > } > + /* > + * Workaround of errata A-008646 on SoC LS1021A: > + * There is a bug of register ippdexpcr1. > + * Reading configuration register RCPM_IPPDEXPCR1 > + * always return zero. So save ippdexpcr1's value > + * to register SCFG_SPARECR8.And the value of > + * ippdexpcr1 will be read from SCFG_SPARECR8. > + */ > + if (dev_of_node(dev) && (i == 1)) > + if (of_device_is_compatible(np, "fsl,ls1021a-rcpm")) > + copy_ippdexpcr1_setting(tmp); > } > > return 0; > -- > 2.7.4 >