summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortkasivajhula <tkasivajhula@nvidia.com>2010-01-27 15:09:33 -0800
committertkasivajhula <tkasivajhula@nvidia.com>2010-02-05 11:59:47 -0800
commiteac3c8be27c6ebafa25995b0158d793fea3e2b85 (patch)
tree1f0f0f48cc8ef90052e6a6ad715eb9beb7a1fa9b
parent0835535d3153952fb3fe13f8be30d6e2dc0524a4 (diff)
tegra power: Fix various LP0 (deep sleep) bugs.
Change-Id: Ie35fa84abe09c260827052a0facdee2e220334d4
-rw-r--r--arch/arm/mach-tegra/idle-t2.c15
-rwxr-xr-xarch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c2
-rw-r--r--arch/arm/mach-tegra/power-context-t2.c6
-rw-r--r--arch/arm/mach-tegra/power-lp.S59
-rw-r--r--arch/arm/mach-tegra/power-t2.c13
-rw-r--r--arch/arm/mach-tegra/power.h26
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) \