From 0de8eb33344ed2d4b36d3c82babdef6cd1ff1fb2 Mon Sep 17 00:00:00 2001 From: Alex Frid Date: Mon, 19 Apr 2010 21:43:52 -0700 Subject: 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 Reviewed-by: Narendra Damahe Reviewed-by: Gary King --- arch/arm/mach-tegra/power-lp.S | 13 ++++++++++++- 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. -- cgit v1.2.3