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

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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+17 −2
Original line number Diff line number Diff line
@@ -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;

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