Commit 91d7ff5a authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Thierry Reding

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: default avatarPeter De Schrijver <pdeschrijver@nvidia.com>
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Tested-by: default avatarPeter Geis <pgwipeout@gmail.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent d70f7d31
...@@ -682,10 +682,12 @@ tegra30_enter_sleep: ...@@ -682,10 +682,12 @@ tegra30_enter_sleep:
dsb dsb
ldr r0, [r6, r2] /* memory barrier */ ldr r0, [r6, r2] /* memory barrier */
cmp r10, #TEGRA30
halted: halted:
isb isb
dsb dsb
wfi /* CPU should be power gated here */ wfine /* CPU should be power gated here */
wfeeq
/* !!!FIXME!!! Implement halt failure handler */ /* !!!FIXME!!! Implement halt failure handler */
b halted b halted
......
...@@ -91,8 +91,23 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid) ...@@ -91,8 +91,23 @@ void flowctrl_cpu_suspend_enter(unsigned int cpuid)
reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP; reg &= ~TEGRA30_FLOW_CTRL_CSR_WFE_BITMAP;
/* clear wfi bitmap */ /* clear wfi bitmap */
reg &= ~TEGRA30_FLOW_CTRL_CSR_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; break;
} }
reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */ reg |= FLOW_CTRL_CSR_INTR_FLAG; /* clear intr flag */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment