diff options
author | tkasivajhula <tkasivajhula@nvidia.com> | 2010-01-27 15:09:33 -0800 |
---|---|---|
committer | tkasivajhula <tkasivajhula@nvidia.com> | 2010-02-05 11:59:47 -0800 |
commit | eac3c8be27c6ebafa25995b0158d793fea3e2b85 (patch) | |
tree | 1f0f0f48cc8ef90052e6a6ad715eb9beb7a1fa9b | |
parent | 0835535d3153952fb3fe13f8be30d6e2dc0524a4 (diff) |
tegra power: Fix various LP0 (deep sleep) bugs.
Change-Id: Ie35fa84abe09c260827052a0facdee2e220334d4
-rw-r--r-- | arch/arm/mach-tegra/idle-t2.c | 15 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-context-t2.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-lp.S | 59 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power.h | 26 |
6 files changed, 68 insertions, 53 deletions
diff --git a/arch/arm/mach-tegra/idle-t2.c b/arch/arm/mach-tegra/idle-t2.c index ff986f1d0456..134b477937f7 100644 --- a/arch/arm/mach-tegra/idle-t2.c +++ b/arch/arm/mach-tegra/idle-t2.c @@ -36,12 +36,13 @@ extern NvRmDeviceHandle s_hRmGlobal; extern void cpu_ap20_do_lp2(void); +extern void cpu_ap20_do_lp0(void); extern void resume(unsigned int state); extern uintptr_t g_resume, g_contextSavePA, g_contextSaveVA; extern NvU32 g_NumActiveCPUs, g_ArmPerif; extern NvU32 g_enterLP2PA; extern volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER; -extern volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pIRAM; +extern volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pIRAM, *g_pTimerus; #ifdef CONFIG_WAKELOCK extern struct wake_lock main_wake_lock; #endif @@ -187,6 +188,18 @@ void __init NvAp20InitFlowController(void) return; } + NvRmModuleGetBaseAddress(s_hRmGlobal, + NVRM_MODULE_ID(NvRmModuleID_TimerUs, 0), &pa, &len); + + if (NvRmPhysicalMemMap(pa, len, NVOS_MEM_READ_WRITE, + NvOsMemAttribute_Uncached, + (void**)&g_pTimerus)!=NvSuccess) + { + printk(KERN_INFO "failed to map iram; DVFS will not function" + " correctly as a result\n"); + return; + } + s_pFlowCtrl = pTempFc; g_ArmPerif = (NvU32)pTempArmPerif; diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c index a751b818118e..dc0bfdfaf69a 100755 --- a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c @@ -1126,7 +1126,7 @@ NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) // Not there yet, add it later ... //pPmuProperty->CpuPowerReqPolarity = ; - pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_Low; + pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_High; pPmuProperty->SysClockReqPolarity = NvOdmSysClockReqPolarity_High; pPmuProperty->CombinedPowerReq = NV_TRUE; pPmuProperty->CpuPowerGoodUs = 2000; diff --git a/arch/arm/mach-tegra/power-context-t2.c b/arch/arm/mach-tegra/power-context-t2.c index 70e21f1237d4..5cb579297682 100644 --- a/arch/arm/mach-tegra/power-context-t2.c +++ b/arch/arm/mach-tegra/power-context-t2.c @@ -58,7 +58,7 @@ static void update_registers_for_lp0(void) //SCRATCH0 : Warmbootflag Reg = NV_REGR(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH0_0); - Reg = NV_FLD_SET_DRF_NUM (APBDEV_PMC, SCRATCH0, WARM_BOOT0_FLAG, 0, Reg); + Reg = NV_FLD_SET_DRF_NUM (APBDEV_PMC, SCRATCH0, WARM_BOOT0_FLAG, 1, Reg); NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH0_0, Reg); @@ -217,7 +217,7 @@ static NvU32* save_clockreset_context( case PowerModuleContext_Save: //Register base address must have been set //by PowerModuleContext_Init. - if (pBase == NULL); + if (pBase == NULL) goto fail; //Anchor the starting point for this controller's context. @@ -252,7 +252,7 @@ static NvU32* save_clockreset_context( case PowerModuleContext_Restore: //Register base address must have been set //by PowerModuleContext_Init. - if (pBase == NULL); + if (pBase == NULL) goto fail; //We should be at the same place in the context diff --git a/arch/arm/mach-tegra/power-lp.S b/arch/arm/mach-tegra/power-lp.S index bf6f2f25ceae..ad21c95aee25 100644 --- a/arch/arm/mach-tegra/power-lp.S +++ b/arch/arm/mach-tegra/power-lp.S @@ -41,6 +41,7 @@ #define CSITE_CPUDBG0_LAR_0 0x10fb0 #define CSITE_CPUDBG1_LAR_0 0x12fb0 #define TEMP_AREA_SIZE 16 +#define DEBUG_FORCE_RTC_WAKEUP 5 #else #error "Unrecognized Tegra SoC Family" #endif @@ -52,6 +53,7 @@ ENTRY(enter_power_state) //with IRQs turned off mrs r2, CPSR stmfd sp!, {r0-r12, lr} + stmfd sp!, {r0} cmp r1, #0 bne save_arm_state @@ -93,7 +95,7 @@ ArmCortexA9Saved: bne reset_slave //Check which power state we want to enter - mov r0, #0 + ldmfd sp!, {r0} //Is it LP2? cmp r0, #0 ldreq r2, =g_enterLP2PA @@ -110,10 +112,8 @@ ArmCortexA9Saved: //Is it LP0? cmp r0, #2 - ldr r5, =enter_lp0 - ldr r6, =enter_lp0_end - - b . + ldr r5, =enter_lp0_end + ldr r6, =enter_lp0 //For LP0, the AVP stores it's continuation address at the first //location in IRAM. Before we overwrite IRAM with the LP0 entry @@ -130,7 +130,7 @@ ArmCortexA9Saved: str r1, [r3, #APBDEV_PMC_SCRATCH39_0] copy_to_iram: - //Copy the enter_lp2 function to IRAM using 8x4 block moves. + //Copy the enter_lp0 function to IRAM using 8x4 block moves. //It doesn't matter if we copy a few extra words. //IRAM has already been safely saved by the AVP at this point //R4 = destination address to copy code to @@ -173,9 +173,6 @@ transition_to_state: ldr r1, =g_wakeupCcbp ldr r1, [r1] - ldr r2, =g_enterLP2PA - ldr r2, [r2] - mov r10, #0 mcr p15, 0, r10, c8, c7, 0 // invalidate TLB dsb @@ -213,6 +210,7 @@ wait_for_master: str r3, [r2] finish_power_state: + ldmfd sp!, {r0} ldmfd sp!, {r0-r12, lr} bx lr ENDPROC(EnterPowerState) @@ -408,10 +406,11 @@ TempStoreArea: ENDPROC(exit_lp2) ENTRY(enter_lp0) - ldr r4, [pc, #0x84] //EMC base - ldr r5, [pc, #0x84] //PMC base - ldr r6, [pc, #0x84] //FLOW base - ldr r7, [pc, #0x84] //TIMERUS base + ldr r4, [pc, #0xC8] //EMC base + ldr r5, [pc, #0xC8] //PMC base + ldr r6, [pc, #0xC8] //FLOW base + ldr r7, [pc, #0xC8] //TIMERUS base + ldr r8, [pc, #0xC8] //RTC base //Flush the write buffer dmb @@ -453,6 +452,29 @@ is_self: orr r2, r2, #1 str r2, [r6, #8] + //r0 = RTC_BASE + mov r0, r8 + //setup rtc wake + ldr r2, [r0, #0x10] //milli + ldr r2, [r0, #0x8] //shadow + + add r2, r2, #DEBUG_FORCE_RTC_WAKEUP +rtc_idle1: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle1 + str r2, [r0, #0x14] +rtc_idle2: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle2 + //intr mask alarm0 + mov r2, #1 + str r2, [r0, #0x28] +rtc_idle3: + ldr r1, [r0, #0x4] + tst r1, #0x1 + bne rtc_idle3 //Save the microsecond count before LP0 ldr r2, [r7] str r2, [r5, #0x134] @@ -468,6 +490,7 @@ do_wfi: andvc lr, r0, r0, lsl #8 andvs r7, r0, r0 andvs r5, r0, r0, lsl r0 + .word 0x7000e000 enter_lp0_end: ENDPROC(enter_lp0) @@ -509,8 +532,10 @@ ArmCortexA9PhysicalRestored: //Check if power state is POWER_STATE_LP0 cmp r0, #2 bne skip_pll - ldr r0, =PMC_PA_BASE - ldr r1, =TIMERUS_PA_BASE + ldr r0, =g_pPMC + ldr r0, [r0] + ldr r1, =g_pTimerus + ldr r1, [r1] //Read from LP0 exit time from SCRATCH1 ldr r2, [r0, #0x54] @@ -521,7 +546,8 @@ pll_wait: blt pll_wait //Put CPU clock source on PLLX - ldr r0, =CLK_RST_PA_BASE + ldr r0, =g_pCLK_RST_CONTROLLER + ldr r0, [r0] ldr r1, =0x20008888 str r1, [r0, #0x20] @@ -548,6 +574,7 @@ ArmCortexA9VirtualRestored: skip_local_timer_restore: //Restore the stack registers + ldmfd sp!, {r0} ldmfd sp!, {r0-r12, lr} //Restore the CPSR stored in r2 diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index 082349380200..4559cb520778 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -50,7 +50,7 @@ NvU32 g_enterLP2PA = 0; NvU32 g_localTimerLoadRegister, g_localTimerCntrlRegister; NvU32 g_coreSightClock, g_currentCcbp; volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER; -volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC; +volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pTimerus; volatile void *g_pIRAM; // Chip external specific wakeup events list @@ -137,7 +137,9 @@ void cpu_ap20_do_lp0(void) //Enter low power LP0 mode prepare_for_wb0(); shadow_lp0_scratch_regs(); + printk("LP0: Entering...\n"); enter_power_state(POWER_STATE_LP0, 0); + printk("LP0: Exited...\n"); shadow_runstate_scratch_regs(); if (HasPmuProperty && PmuProperty.CombinedPowerReq) @@ -230,12 +232,10 @@ void power_lp0_init(void) LPStateInfo = NvOdmQueryLowestSocPowerState(); - //CPU power request must be already configured and enabled in early boot - //by now. Leave it enabled to be ready for LP2/LP1. + //Enable CPU power request. Leave it enabled to be ready for LP2/LP1. Reg = NV_PMC_REGR(g_pPMC, CNTRL); - Reg = NV_DRF_VAL(APBDEV_PMC, CNTRL, CPUPWRREQ_OE, Reg); - if (Reg != APBDEV_PMC_CNTRL_0_CPUPWRREQ_OE_ENABLE) - goto fail; + Reg = NV_FLD_SET_DRF_DEF(APBDEV_PMC, CNTRL, CPUPWRREQ_OE, ENABLE, Reg); + NV_PMC_REGW(g_pPMC, CNTRL, Reg); //If the system supports deep sleep (LP0), initialize PMC accordingly. if (LPStateInfo->LowestPowerState == NvOdmSocPowerState_DeepSleep) @@ -285,6 +285,7 @@ void power_lp0_init(void) //Create the list of wakeup IRQs. create_wakeup_irqs(); + return; fail: printk("lp0 init failed!\n"); } diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h index 53e9e9568fd2..6903b961ec67 100644 --- a/arch/arm/mach-tegra/power.h +++ b/arch/arm/mach-tegra/power.h @@ -109,18 +109,6 @@ extern NvRmDeviceHandle s_hRmGlobal; //------------------------------------------------------------------------------ //Correct name \ Broken name from nvboot_pmc_scratch_map.h -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_OSC_CTRL_0_XOBP_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_OSC_CTRL_XOBP_RANGE -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_PLLM_BASE_0_PLLM_DIVM_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_PLLM_BASE_PLLM_DIVM_RANGE -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_PLLM_BASE_0_PLLM_DIVN_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_PLLM_BASE_PLLM_DIVN_RANGE -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_PLLM_BASE_0_PLLM_DIVP_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_PLLM_BASE_PLLM_DIVP_RANGE -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_PLLM_MISC_0_PLLM_CPCON_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_PLLM_MISC_CPCON_RANGE -#define APBDEV_PMC_SCRATCH2_0_CLK_RST_CONTROLLER_PLLM_MISC_0_PLLM_LFCON_RANGE\ - APBDEV_PMC_SCRATCH2_0_CLK_RST_PLLM_MISC_LFCON_RANGE #define APBDEV_PMC_SCRATCH3_0_CLK_RST_CONTROLLER_PLLX_BASE_0_PLLX_DIVP_RANGE\ APBDEV_PMC_SCRATCH3_0_CLK_RST_PLLX_BASE_PLLX_DIVP_RANGE #define APBDEV_PMC_SCRATCH3_0_CLK_RST_CONTROLLER_PLLX_BASE_0_PLLX_DIVN_RANGE\ @@ -173,9 +161,7 @@ extern NvRmDeviceHandle s_hRmGlobal; @param s Scratch register name (APBDEV_PMC_s) */ #define SCRATCH_REGS() \ - SCRATCH_REG(SCRATCH2) \ SCRATCH_REG(SCRATCH3) \ - SCRATCH_REG(SCRATCH4) \ SCRATCH_REG(SCRATCH5) \ SCRATCH_REG(SCRATCH6) \ SCRATCH_REG(SCRATCH7) \ @@ -195,7 +181,6 @@ extern NvRmDeviceHandle s_hRmGlobal; SCRATCH_REG(SCRATCH21) \ SCRATCH_REG(SCRATCH22) \ SCRATCH_REG(SCRATCH23) \ - SCRATCH_REG(SCRATCH24) \ SCRATCH_REG(SCRATCH25) \ SCRATCH_REG(SCRATCH35) \ SCRATCH_REG(SCRATCH36) \ @@ -216,20 +201,12 @@ extern NvRmDeviceHandle s_hRmGlobal; REG(SCRATCH25, AHB, ARBITRATION_XBAR_CTRL, HOLD_DIS) \ REG(SCRATCH25, AHB, ARBITRATION_XBAR_CTRL, MEM_INIT_DONE) \ /* CLK_RST Group */ \ - REG(SCRATCH2, CLK_RST_CONTROLLER, OSC_CTRL, XOBP) \ - REG(SCRATCH2, CLK_RST_CONTROLLER, PLLM_BASE, PLLM_DIVM) \ - REG(SCRATCH2, CLK_RST_CONTROLLER, PLLM_BASE, PLLM_DIVN) \ - REG(SCRATCH2, CLK_RST_CONTROLLER, PLLM_BASE, PLLM_DIVP) \ - REG(SCRATCH2, CLK_RST_CONTROLLER, PLLM_MISC, PLLM_CPCON) \ - REG(SCRATCH2, CLK_RST_CONTROLLER, PLLM_MISC, PLLM_LFCON) \ - /**/ \ REG(SCRATCH3, CLK_RST_CONTROLLER, PLLX_BASE, PLLX_DIVP) \ REG(SCRATCH3, CLK_RST_CONTROLLER, PLLX_BASE, PLLX_DIVN) \ REG(SCRATCH3, CLK_RST_CONTROLLER, PLLX_BASE, PLLX_DIVM) \ REG(SCRATCH3, CLK_RST_CONTROLLER, PLLX_MISC, PLLX_CPCON) \ REG(SCRATCH3, CLK_RST_CONTROLLER, PLLX_MISC, PLLX_LFCON) \ /* EMC Group */ \ - REG(SCRATCH4, EMC, FBIO_SPARE, CFG_FBIO_SPARE_WB0) \ /**/ \ REG(SCRATCH5, EMC, R2W, R2W) \ REG(SCRATCH5, EMC, RAS, RAS) \ @@ -393,9 +370,6 @@ extern NvRmDeviceHandle s_hRmGlobal; /**/ \ REG(SCRATCH22, MC, LOWLATENCY_CONFIG, LL_DRAM_INTERLEAVE) \ /* APB_MISC Group */ \ - REG(SCRATCH2, APB_MISC, GP_XM2CFGAPADCTRL, CFG2TMC_XM2CFGA_PREEMP_EN) \ - REG(SCRATCH2, APB_MISC, GP_XM2CFGDPADCTRL, CFG2TMC_XM2CFGD_SCHMT_EN) \ - /**/ \ REG(SCRATCH3, APB_MISC, GP_XM2CFGCPADCTRL2, CFG2TMC_XM2CFGC_VREF_DQ) \ REG(SCRATCH3, APB_MISC, GP_XM2CFGCPADCTRL, CFG2TMC_XM2CFGC_SCHMT_EN) \ REG(SCRATCH3, APB_MISC, GP_XM2CLKCFGPADCTRL, CFG2TMC_XM2CLKCFG_PREEMP_EN) \ |