The Ouya (tegra30) hard locks when the emc clock drops below 400mhz. Discovered while testing the devfreq and emc drivers. This patch resolves that issue. Tested-by: Peter Geis <pgwipeout@xxxxxxxxx> On Tue, Jul 30, 2019 at 2:10 PM Dmitry Osipenko <digetx@xxxxxxxxx> wrote: > > Turned out that WFI doesn't work reliably on Tegra30 as a trigger for > the power-gating, it causes CPU hang under some circumstances like having > memory controller running of PLLP. The TRM doc states that WFI should be > used for the Big-Little "Cluster Switch", while WFE for the power-gating. > Hence let's use the WFE for CPU0 power-gating, like it is done for the > power-gating of a secondary cores. This fixes CPU hang after entering LP2 > with memory running off PLLP. > > Acked-by: Peter De Schrijver <pdeschrijver@xxxxxxxxxx> > Signed-off-by: Dmitry Osipenko <digetx@xxxxxxxxx> > --- > arch/arm/mach-tegra/sleep-tegra30.S | 4 +++- > drivers/soc/tegra/flowctrl.c | 19 +++++++++++++++++-- > 2 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S > index 6c28395d8c75..17f7a2a6a494 100644 > --- a/arch/arm/mach-tegra/sleep-tegra30.S > +++ b/arch/arm/mach-tegra/sleep-tegra30.S > @@ -683,10 +683,12 @@ tegra30_enter_sleep: > dsb > ldr r0, [r6, r2] /* memory barrier */ > > + cmp r10, #TEGRA30 > halted: > isb > dsb > - wfi /* CPU should be power gated here */ > + wfine /* CPU should be power gated here */ > + wfeeq > > /* !!!FIXME!!! Implement halt failure handler */ > b halted > diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c > index b6bdeef33db1..eb96a3086d6d 100644 > --- a/drivers/soc/tegra/flowctrl.c > +++ b/drivers/soc/tegra/flowctrl.c > @@ -91,8 +91,23 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid) > reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; > /* clear wfi bitmap */ > reg &= ~TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP; > - /* pwr gating on wfi */ > - reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; > + > + if (tegra_get_chip_id() == TEGRA30) { > + /* > + * The wfi doesn't work well on Tegra30 because > + * CPU hangs under some odd circumstances after > + * power-gating (like memory running off PLLP), > + * hence use wfe that is working perfectly fine. > + * Note that Tegra30 TRM doc clearly stands that > + * wfi should be used for the "Cluster Switching", > + * while wfe for the power-gating, just like it > + * is done on Tegra20. > + */ > + reg |= TEGRA20_FLOW_CTRL_CSR_WFE_CPU0 << cpuid; > + } else { > + /* pwr gating on wfi */ > + reg |= TEGRA30_FLOW_CTRL_CSR_WFI_CPU0 << cpuid; > + } > break; > } > reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ > -- > 2.22.0 >