summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-04-19 21:43:52 -0700
committerGary King <gking@nvidia.com>2010-04-21 13:26:57 -0700
commit0de8eb33344ed2d4b36d3c82babdef6cd1ff1fb2 (patch)
tree37d5173b8057bfc34d7c0e03dbbd3a1ca0af2d21 /arch
parent35367088ddab9684ea29432ce35d2a3f117a9d6b (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.S13
-rw-r--r--arch/arm/mach-tegra/power-t2.c20
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.