diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2019-07-30 20:23:40 +0300 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2019-10-29 14:32:01 +0100 |
commit | 91d7ff5aa7e3edd9ab99a424099476ed5667b152 (patch) | |
tree | 2998c7783986f45ffcf8f1d9b6912220d5c74053 /drivers/soc/tegra | |
parent | d70f7d31a9e2088e8a507194354d41ea10062994 (diff) | |
download | linux-91d7ff5aa7e3edd9ab99a424099476ed5667b152.tar.gz linux-91d7ff5aa7e3edd9ab99a424099476ed5667b152.tar.bz2 linux-91d7ff5aa7e3edd9ab99a424099476ed5667b152.zip |
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>
Diffstat (limited to 'drivers/soc/tegra')
-rw-r--r-- | drivers/soc/tegra/flowctrl.c | 19 |
1 files changed, 17 insertions, 2 deletions
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 */ |