diff options
author | Narendra Damahe <ndamahe@nvidia.com> | 2010-03-04 17:54:17 -0800 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-05 14:38:03 -0800 |
commit | 3a5eff5302d66bd471c4a4778505f5211776ecd3 (patch) | |
tree | 6e59a606dbddfaaf1845fc490aaff5959b572bf6 | |
parent | c96a771e6915bbb845c57dab78d78b3c352ae070 (diff) |
Tegra pm:disable pllp pll during system suspend. other code cleanup
Change-Id: I02aa2fd9d5a4faa830e838d2705ee81058fe001d
Change-Id: I02aa2fd9d5a4faa830e838d2705ee81058fe001d
Reviewed-on: http://git-master/r/750
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Tested-by: Narendra Damahe <ndamahe@nvidia.com>
Reviewed-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Tested-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/power-context-t2.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-lp.S | 189 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 43 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power.h | 12 |
4 files changed, 77 insertions, 179 deletions
diff --git a/arch/arm/mach-tegra/power-context-t2.c b/arch/arm/mach-tegra/power-context-t2.c index 4bed949e22ca..8f79db31b5f8 100644 --- a/arch/arm/mach-tegra/power-context-t2.c +++ b/arch/arm/mach-tegra/power-context-t2.c @@ -188,7 +188,6 @@ static NvU32* save_clockreset_context( //Get a pointer to the base address for the registers. pBase = pAnchor->clock_reset.pBase; - switch (Context) { case PowerModuleContext_Init: //Already initialized? @@ -240,11 +239,11 @@ static NvU32* save_clockreset_context( //Save module reset state *pCM++ = NV_CAR_REGR(pBase, RST_DEVICES_L); *pCM++ = NV_CAR_REGR(pBase, RST_DEVICES_H); - + *pCM++ = NV_CAR_REGR(pBase, RST_DEVICES_U); //Save module clock enable state *pCM++ = NV_CAR_REGR(pBase, CLK_OUT_ENB_L); *pCM++ = NV_CAR_REGR(pBase, CLK_OUT_ENB_H); - + *pCM++ = NV_CAR_REGR(pBase, CLK_OUT_ENB_U); //Save clock mask register *pCM++ = NV_CAR_REGR(pBase, CLK_MASK_ARM); break; @@ -289,7 +288,8 @@ static NvU32* save_clockreset_context( CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0_RESET_MASK); NV_CAR_REGW(pBase, CLK_OUT_ENB_H, CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0_RESET_MASK); - + NV_CAR_REGW(pBase, CLK_OUT_ENB_U, + CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0_RESET_MASK); //Restore clock sources for individual modules Offset = CAR_CLK_SOURCES_OFFSET_START; do @@ -319,11 +319,11 @@ static NvU32* save_clockreset_context( //Restore module reset state NV_CAR_REGW(pBase, RST_DEVICES_L, *pCM++); NV_CAR_REGW(pBase, RST_DEVICES_H, *pCM++); - + NV_CAR_REGW(pBase, RST_DEVICES_U, *pCM++); //Restore module clock enable state NV_CAR_REGW(pBase, CLK_OUT_ENB_L, *pCM++); NV_CAR_REGW(pBase, CLK_OUT_ENB_H, *pCM++); - + NV_CAR_REGW(pBase, CLK_OUT_ENB_U, *pCM++); //Restore clock mask register NV_CAR_REGW(pBase, CLK_MASK_ARM, *pCM++); break; diff --git a/arch/arm/mach-tegra/power-lp.S b/arch/arm/mach-tegra/power-lp.S index 927748b2be1c..e9ea15356030 100644 --- a/arch/arm/mach-tegra/power-lp.S +++ b/arch/arm/mach-tegra/power-lp.S @@ -176,9 +176,9 @@ transition_to_state: ldr r0, =g_modifiedPlls ldr r0, [r0] ldr r1, =g_wakeupCcbp - ldr r1, [r1] + ldr r1, [r1] - mov r10, #0 + mov r10, #0 mcr p15, 0, r10, c8, c7, 0 // invalidate TLB dsb @@ -347,51 +347,15 @@ reset_poll: //Put the CPU on the desired clock source for wakeup str r1, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] - //Enable PLL-C if we disabled it. - //tst r0, #PowerPllC - tst r0, #1 - beq no_pllc - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLC_BASE_0] - mov r3, #(1<<30) //PllC ENABLE - tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLC_BASE_0] -no_pllc: - //Enable PLL-M if we disabled it. - //tst r0, #PowerPllM - tst r0, #2 - beq no_pllm - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] - mov r3, #(1<<30) //PllM ENABLE - tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] -no_pllm: - //Enable PLL-P if we disabled it. - //tst r0, #PowerPllP - tst r0, #3 - beq no_pllp - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] - mov r3, #(1<<30) //PllP ENABLE - tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] -no_pllp: - //Enable PLL-X if we disabled it. - //NOTE: The PLLX_BASE have have been cleared so get it's value - //from the temporary save area. - //tst r0, #PowerPllX - tst r0, #4 - beq no_pllx + + //Enable PLL-X and restore the values ldr r2, [r12, #TEMP_PLLX_BASE] mov r3, #(1<<30) //PllX ENABLE orr r2, r2, r3 str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] -no_pllx: //Restore the reset vector target. - //## - //ldr r1, [r12, #TEMP_RESET_VECTOR] - //str r1, [r9, #EVP_CPU_RESET_VECTOR_0] + ldr r1, [r12, #TEMP_RESET_VECTOR] + str r1, [r9, #EVP_CPU_RESET_VECTOR_0] skip_cpu0_restore: mrc p15, 0, r2, c0, c0, 5 @@ -426,7 +390,6 @@ ENTRY(enter_lp1) ldr r9, [r9] add r12, pc, #TemporaryStore-(.+8) - orr r0, r0, #5 stmia r12!, {r0, r1} ldr r0, [r9, #EVP_CPU_RESET_VECTOR_0] @@ -472,16 +435,29 @@ is_self1: bic r2, r2, #(1<<14) str r2, [r5, #APBDEV_PMC_CNTRL_0] + //Switch CPU clocks to CLKM + mov r2, #0 + orr r2, r2, #(1<<28) + str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] + + //Switch the system clock to CLKM + mov r2, #0 + orr r2, r2, #(1<<28) + str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] + + //2 uSec delay for System Clock Switching + mov r2, #0x1 + orr r2, r2, #(1<<25) //STOP_UNTIL_Event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + //Powergate the cpu by setting the ENABLE bit ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] orr r2, r2, #(1<<0) str r2, [r6, #FLOW_CTLR_CPU_CSR_0] - mov r2, #1, 4 - str r2, [r8, #CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0] - - //Switch clocks to 32Khz - mov r2, #0x61, 4 + //Switch system clocks to 32Khz + mov r2, #6 + orr r2, r2, #(1<<28) mov r3, #0 str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] str r3, [r8, #CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER_0] @@ -491,10 +467,10 @@ is_self1: bic r2, r2, #1, 2 str r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] - //Turn off pll-p - Uncomment in real testing - //ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] - //bic r2, r2, #1, 2 - //str r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + //Turn off pll-p + ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + bic r2, r2, #1, 2 + str r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] //Get the microsecond count before LP1 ldr r2, [r7] @@ -504,7 +480,7 @@ is_self1: mov r2, #0 orr r2, r2, #(4<<29) //STOP_UNTIL_IRQ orr r2, r2, #(1<<10) //IRQ_0 event - orr r2, r2, #(1<<8) //FIQ_0 event + orr r2, r2, #(1<<8) //FIQ_0 event str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] do_wfi1: @@ -557,60 +533,34 @@ reset_poll1: ldr r0, =0xC5ACCE55 ldr r1, =CSITE_CPUDBG0_LAR_0 //R1 = CPU0 lock offset ldr r2, =CSITE_CPUDBG1_LAR_0 //R2 = CPU1 lock offset - str r0, [r10, r1] //Unlock CPU0 - str r0, [r10, r2] //Unlock CPU1 + str r0, [r10, r1] //Unlock CPU0 + str r0, [r10, r2] //Unlock CPU1 //Switch the system to CLKM - mov r2, #1, 4 + mov r2, #0 + orr r2, r2, #(1<<28) str r2, [r8, #CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0] - //Check which plls to start - ldr r0, [r12] - mov r1, #0 - tst r0, #2 - - //Enable PLL-C if we disabled it. - //tst r0, #PowerPllC - tst r0, #1 - beq no_pllc1 - ldr r2, [r8, #CLK_RST_CONTROLLER_PLLC_BASE_0] - mov r3, #(1<<30) //PllC ENABLE - tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLC_BASE_0] -no_pllc1: - //Enable PLL-M if we disabled it. - //tst r0, #PowerPllM - tst r0, #2 - beq no_pllm1 + //Enable PLL-M ldr r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] mov r3, #(1<<30) //PllM ENABLE tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] -no_pllm1: - //Enable PLL-P if we disabled it. - //tst r0, #PowerPllP - mov r0, # - tst r0, #3 - beq no_pllp1 + orreq r2, r2, r3 + streq r2, [r8, #CLK_RST_CONTROLLER_PLLM_BASE_0] + + //Enable PLL-P ldr r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] mov r3, #(1<<30) //PllP ENABLE tst r2, r3 - orreq r2, r2, r3 - streq r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] -no_pllp1: - //Enable PLL-X if we disabled it. - //NOTE: The PLLX_BASE have have been cleared so get it's value - //from the temporary save area. - //tst r0, #PowerPllX - tst r0, #4 - beq no_pllx1 - ldr r2, [r12, #TEMP_PLLX_BASE] - mov r3, #(1<<30) //PllX ENABLE - orr r2, r2, r3 - str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] -no_pllx1: + orreq r2, r2, r3 + streq r2, [r8, #CLK_RST_CONTROLLER_PLLP_BASE_0] + + //Enable PLL-X with restored values + ldr r2, [r12, #TEMP_PLLX_BASE] + mov r3, #(1<<30) //PllX ENABLE + orr r2, r2, r3 + str r2, [r8, #CLK_RST_CONTROLLER_PLLX_BASE_0] + //Configure CPU island to not be power gated ldr r2, [r6, #8] bic r2, r2, #1 @@ -620,39 +570,12 @@ no_pllx1: ldr r2, [r12, #TEMP_RESET_VECTOR] str r2, [r9, #EVP_CPU_RESET_VECTOR_0] - //Check if we started any plls - cmp r1, #0 - beq restore_clocks - - //Explicit delay for pll stabilization - mov r0, #0xFF - mov r1, #0x42, 8 - mov r2, #0x4B, 30 -delay_for_pll: - cmp r2, r0 - orrle r3, r1, r2 - orrgt r3, r1, r0 - sub r2, r2, r0 - //Do a flow control wait - str r3, [r6] -wait_for_event: - wfe - - //Check if the event is ours - ldr r3, [r6, #FLOW_CTLR_CPU_CSR_0] - tst r3, #1, 18 - strne r3, [r6, #FLOW_CTLR_CPU_CSR_0] - bne event_signalled - - //Check if we're still waiting for an event - ldr r3, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] - tst r3, #0xE, 4 - bne wait_for_event -event_signalled: - //Check if we waited long enough - cmp r2, #0 - bgt delay_for_pll -restore_clocks: + + //Explicit delay of 255 uSec for pll stabilization + mov r2, #0xfe + orr r2, r2, #(1<<25) //STOP_UNTIL_Event + str r2, [r6, #FLOW_CTLR_HALT_CPU_EVENTS_0] + //Restore the system and CPU burst, csite, clksrc registers ldr r1, [r12, #TEMP_SCLK_BURST_POLICY] ldr r2, [r12, #TEMP_CCLK_BURST_POLICY] @@ -681,9 +604,9 @@ restore_clocks: //Confirm that all chips have exited self-refresh ldr r1, [r4, #EMC_ADR_CFG_0] - ands r1, r1, #3, 8 - moveq r0, #1, 24 - movne r0, #3, 24 + ands r1, r1, #3, 8 + moveq r0, #1, 24 + movne r0, #3, 24 //Poll until all chips have exited self-refresh is_auto: diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index 63b555b8c4f9..22575b7dc3a9 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -237,14 +237,11 @@ void cpu_ap20_do_lp1(void) { //Disable the Statistics interrupt NvPrivAp20MaskIrq(irq); - do_suspend_prep(); - - g_modifiedPlls |= PowerPllM; } printk("entering lp1\n"); - //Do LP2 + //Do LP1 enter_power_state(POWER_STATE_LP1, proc_id); printk("exiting lp1\n"); @@ -254,20 +251,11 @@ void cpu_ap20_do_lp1(void) NvPrivAp20UnmaskIrq(irq); g_NumActiveCPUs = num_online_cpus(); - //We're back - //Delay if needed - - if (g_modifiedPlls & PowerPllC) + // Assembly LP1 code explicitly turn on PLLX,PLLM and PLLP so no need to enable it + if (g_modifiedPlls & PowerPllC) { enable_pll(PowerPllC, NV_TRUE); - if (g_modifiedPlls & PowerPllM) - enable_pll(PowerPllM, NV_TRUE); - if (g_modifiedPlls & PowerPllP) - enable_pll(PowerPllP, NV_TRUE); - if (g_modifiedPlls & PowerPllX) - enable_pll(PowerPllX, NV_TRUE); - - NvOsWaitUS(300); - + NvOsWaitUS(300); + } //Restore burst policy NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0, g_currentCcbp); @@ -305,9 +293,8 @@ void cpu_ap20_do_lp2(void) { //Disable the Statistics interrupt NvPrivAp20MaskIrq(irq); - do_suspend_prep(); - } + } //Do LP2 enter_power_state(POWER_STATE_LP2, proc_id); @@ -318,7 +305,6 @@ void cpu_ap20_do_lp2(void) NvPrivAp20UnmaskIrq(irq); g_NumActiveCPUs = num_online_cpus(); - //We're back //Delay if needed if (g_modifiedPlls & PowerPllC) @@ -327,11 +313,8 @@ void cpu_ap20_do_lp2(void) enable_pll(PowerPllM, NV_TRUE); if (g_modifiedPlls & PowerPllP) enable_pll(PowerPllP, NV_TRUE); - if (g_modifiedPlls & PowerPllX) - enable_pll(PowerPllX, NV_TRUE); - + NvOsWaitUS(300); - //Restore burst policy NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0, g_currentCcbp); @@ -339,7 +322,6 @@ void cpu_ap20_do_lp2(void) //Restore the CoreSight clock source. NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, g_coreSightClock); - } } @@ -748,8 +730,8 @@ void enable_pll(PowerPll pll, NvBool enable) default: break; } - } + void enable_plls(NvBool enable) { NvU32 dfsPllFlags = NvRmPrivGetDfsFlags(s_hRmGlobal); @@ -777,12 +759,6 @@ void enable_plls(NvBool enable) enable_pll(PowerPllM, NV_FALSE); g_modifiedPlls |= PowerPllM; } - - //pllx - DFS currently doesn't signal this, but it doesn't matter - //We're going to turn it off anyway - if (dfsPllFlags & NvRmDfsStatusFlags_StopPllX0) - { - } } void do_suspend_prep(void) @@ -801,12 +777,11 @@ void do_suspend_prep(void) CSITE_CLK_SRC, CLK_M); NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, reg); - //Turn off necessary PLLs enable_plls(NV_FALSE); - //Select the wakeup pll g_currentCcbp = select_wakeup_pll(); + } void reset_cpu(unsigned int cpu, unsigned int reset) diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h index dcd698033ccb..36cf04b93121 100644 --- a/arch/arm/mach-tegra/power.h +++ b/arch/arm/mach-tegra/power.h @@ -429,7 +429,6 @@ extern NvRmDeviceHandle s_hRmGlobal; #define WAKEUP_EXTERNAL(p,b)\ {NVRM_MODULE_ID(NvRmPrivModuleID_Gpio,GPIO_PORT(p)/GPIO_PORTS_PER_INSTANCE),\ (((GPIO_PORT(p) % GPIO_PORTS_PER_INSTANCE)*GPIO_BITS_PER_PORT) + (b)) } - typedef struct { NvU32 *pBase; @@ -469,11 +468,12 @@ typedef enum typedef enum { - PowerPllA = 0, - PowerPllC, - PowerPllM, - PowerPllP, - PowerPllX + PowerPllM = 0x1, // Memory + PowerPllC = 0x2, // CPU + PowerPllP = 0x4, // Peripherals + PowerPllA = 0x8, // Audio + PowerPllX = 0x10, // CPU Complex + PowerPll_Force32 = 0x7fffffff } PowerPll; typedef enum |