ARM: tegra: Use WFE for power-gating on Tegra30

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@nvidia.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Tested-by: Peter Geis <pgwipeout@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Dmitry Osipenko 2019-07-30 20:23:40 +03:00 committed by Thierry Reding
parent d70f7d31a9
commit 91d7ff5aa7
2 changed files with 20 additions and 3 deletions

View file

@ -682,10 +682,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

View file

@ -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 */