diff options
-rw-r--r-- | arch/arm/mach-tegra/reset-handler.S | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sleep-tegra30.S | 4 | ||||
-rw-r--r-- | drivers/soc/tegra/flowctrl.c | 19 |
3 files changed, 23 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/reset-handler.S b/arch/arm/mach-tegra/reset-handler.S index 67b763fea005..e3f34815c9da 100644 --- a/arch/arm/mach-tegra/reset-handler.S +++ b/arch/arm/mach-tegra/reset-handler.S @@ -44,16 +44,16 @@ ENTRY(tegra_resume) cmp r6, #TEGRA20 beq 1f @ Yes /* Clear the flow controller flags for this CPU. */ - cpu_to_csr_reg r1, r0 + cpu_to_csr_reg r3, r0 mov32 r2, TEGRA_FLOW_CTRL_BASE - ldr r1, [r2, r1] + ldr r1, [r2, r3] /* Clear event & intr flag */ orr r1, r1, \ #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps @ & ext flags for CPU power mgnt bic r1, r1, r0 - str r1, [r2] + str r1, [r2, r3] 1: mov32 r9, 0xc09 diff --git a/arch/arm/mach-tegra/sleep-tegra30.S b/arch/arm/mach-tegra/sleep-tegra30.S index b408fa56eb89..3341a12bbb9c 100644 --- a/arch/arm/mach-tegra/sleep-tegra30.S +++ b/arch/arm/mach-tegra/sleep-tegra30.S @@ -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 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 */ |