diff options
author | Alex Frid <afrid@nvidia.com> | 2010-04-19 21:43:52 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-04-21 13:26:57 -0700 |
commit | 0de8eb33344ed2d4b36d3c82babdef6cd1ff1fb2 (patch) | |
tree | 37d5173b8057bfc34d7c0e03dbbd3a1ca0af2d21 /arch | |
parent | 35367088ddab9684ea29432ce35d2a3f117a9d6b (diff) |
tegra RM: Upadted CPU clock control in LP2 state.
Upadted CPU clock control in LP2 state:
- Disabled PLLX on entry to LP2
- Forced CPU divider 1:1 setting on entry to LP2, and restore divider
on exit (speed up LP2 entry/exit)
- Removed PLLC and PLLM from wake source consideration (commonly these
PLLs are disabled in LP2 anyway, but using them in rare case when they
are available may create dangerous over-clocking condition)
Change-Id: Ied51ebee553766e66d6007e1149270e243df0543
Reviewed-on: http://git-master/r/1155
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/power-lp.S | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 20 |
2 files changed, 31 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/power-lp.S b/arch/arm/mach-tegra/power-lp.S index 2b693afc4186..b49d6f245709 100644 --- a/arch/arm/mach-tegra/power-lp.S +++ b/arch/arm/mach-tegra/power-lp.S @@ -321,8 +321,19 @@ ENTRY(enter_lp2) orr r2, r2, #(1<<0) str r2, [r6, #FLOW_CTLR_CPU_CSR_0] - //Put the CPU on the desired clock source for wakeup. + //Put the CPU on the desired clock source for wakeup, + // wait 2us for switch to complete, and disable PLLX str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + ldr r11, [r7] +cclk_delay: + ldr r2, [r7] + sub r2, r2, r11 + cmp r2, #2 + ble cclk_delay + + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + bic r2, r2, #(1<<30) //Clear PllX ENABLE + str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] dmb //Get the microsecond count before LP2 diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index ae302a7b529d..758523d91ca2 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -54,7 +54,7 @@ NvU32 g_modifiedPlls; NvU32 g_wakeupCcbp = 0, g_NumActiveCPUs, g_Sync = 0, g_ArmPerif = 0; NvU32 g_enterLP2PA = 0; NvU32 g_localTimerLoadRegister, g_localTimerCntrlRegister; -NvU32 g_coreSightClock, g_currentCcbp; +NvU32 g_coreSightClock, g_currentCcbp, g_currentCcdiv; NvU32 g_lp1CpuPwrGoodCnt, g_currentCpuPwrGoodCnt; volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER; volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pTimerus; @@ -236,6 +236,13 @@ void cpu_ap20_do_lp2(void) //Disable the Statistics interrupt disable_irq(INT_SYS_STATS_MON); do_suspend_prep(); + + // Save/clear CPU clock divider ("voltage-safe", as scaling is + // based on source frequency before divider) + g_currentCcdiv = NV_REGR(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, + 0, CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER_0); + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER_0, 0); } //Do LP2 @@ -257,6 +264,11 @@ void cpu_ap20_do_lp2(void) enable_pll(PowerPllP, NV_TRUE); NvOsWaitUS(300); + + //Restore CPU clock divider + NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, + CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER_0, g_currentCcdiv); + //Restore burst policy NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0, g_currentCcbp); @@ -492,7 +504,13 @@ static NvU32 select_wakeup_pll(void) // Get the possible PLL clock sources for the CPU complex. Don't consider // any PLLs that were turned off and of course PLL-X is not a possibility. +#if 0 PllMask = (PowerPllC | PowerPllP | PowerPllM) & ~g_modifiedPlls; +#else + // Do not consider high frequency PLLC and PLLM either, since they may + // be too high for current voltage. + PllMask = PowerPllP & ~g_modifiedPlls; +#endif // Pick a PLL source for the CPU complex so that we don't have to // run on the oscillator which is soooo slooooow. |