diff options
author | tkasivajhula <tkasivajhula@nvidia.com> | 2010-03-19 13:49:35 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-26 16:23:25 -0800 |
commit | 5054b24952cdcef10819fe6137de46450d440bbe (patch) | |
tree | 5a919805430b2d52ec09774173026032e3d7f84d | |
parent | 474b9025e42b454df1c381416a3d9ef8ee1a7754 (diff) |
tegra power: Clean up LP0 code and shuffle around scratch regs.
The scratch registers had to be shuffled around a bit
to match the bootrom's scratch map.
Change-Id: Iddcefbd23fdaccb2215b70bc5f188fadaf8ec194
Reviewed-on: http://git-master/r/918
Reviewed-by: Gary King <gking@nvidia.com>
Tested-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/idle-t2.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-lp.S | 49 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power.h | 11 |
4 files changed, 50 insertions, 23 deletions
diff --git a/arch/arm/mach-tegra/idle-t2.c b/arch/arm/mach-tegra/idle-t2.c index d9c4ea398b9f..27c3ff4f8acc 100644 --- a/arch/arm/mach-tegra/idle-t2.c +++ b/arch/arm/mach-tegra/idle-t2.c @@ -317,7 +317,7 @@ void mach_tegra_idle(void) tegra_lp2_set_trigger(0); /* add the actual amount of time spent in lp2 to the timers */ sleep_time = NV_REGR(s_hRmGlobal, NvRmModuleID_Pmif, - 0, APBDEV_PMC_SCRATCH1_0); + 0, APBDEV_PMC_SCRATCH39_0); sleep_time -= NV_REGR(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH38_0); diff --git a/arch/arm/mach-tegra/power-lp.S b/arch/arm/mach-tegra/power-lp.S index 71fe72486c40..f7e65d74b74d 100644 --- a/arch/arm/mach-tegra/power-lp.S +++ b/arch/arm/mach-tegra/power-lp.S @@ -372,11 +372,11 @@ skip_cpu0_restore: //Only get the timer for CPU0 bne skip_lp2_time //Get the microsecond count after LP2 - str r11, [r5, #APBDEV_PMC_SCRATCH1_0] + str r11, [r5, #APBDEV_PMC_SCRATCH39_0] skip_lp2_time: //Set lr to the resume function - ldr lr, [r5, #APBDEV_PMC_SCRATCH33_0] + ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] bx lr TempStoreArea: @@ -667,7 +667,7 @@ is_auto: //Store the LP1 exit time and restore return addr ldr lr, [r5, #APBDEV_PMC_SCRATCH1_0] - str r11, [r5, #APBDEV_PMC_SCRATCH1_0] + str r11, [r5, #APBDEV_PMC_SCRATCH39_0] bx lr lp1_literals: .word 0x7000f400 @@ -703,11 +703,16 @@ exit_lp1_end: ENDPROC(exit_lp1) ENTRY(enter_lp0) - 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 + add r4, pc, #lp0_literals-(.+8) //EMC base + ldr r4, [r4] + add r5, pc, #lp0_literals-(.+4) //PMC base + ldr r5, [r5] + add r6, pc, #lp0_literals-(.+0) //FLOW base + ldr r6, [r6] + add r7, pc, #lp0_literals-(.-4) //TIMERUS base + ldr r7, [r7] + add r8, pc, #lp0_literals-(.-8) //RTC base + ldr r8, [r8] //Flush the write buffer dmb @@ -740,14 +745,14 @@ is_self: str r2, [r5, #0x20] //Set SIDE_EFFECT_LP0 - ldr r2, [r5] - orr r2, r2, #1, 18 - str r2, [r5] + ldr r2, [r5, #APBDEV_PMC_CNTRL_0] + orr r2, r2, #0x4000 + str r2, [r5, #APBDEV_PMC_CNTRL_0] //Set CPU island to power gate when halted - ldr r2, [r6, #8] + ldr r2, [r6, #FLOW_CTLR_CPU_CSR_0] orr r2, r2, #1 - str r2, [r6, #8] + str r2, [r6, #FLOW_CTLR_CPU_CSR_0] //r0 = RTC_BASE mov r0, r8 @@ -772,21 +777,22 @@ rtc_idle3: ldr r1, [r0, #0x4] tst r1, #0x1 bne rtc_idle3 - //Save the microsecond count before LP0 + //Save the microsecond count before LP0 in SCRATCH38 ldr r2, [r7] - str r2, [r5, #0x134] + str r2, [r5, #APBDEV_PMC_SCRATCH38_0] //Halt the CPU without any wakeup events mov r2, #1, 2 str r2, [r6] do_wfi: dsb - wfi + wfe b do_wfi - andvc pc, r0, r0, lsl #8 - andvc lr, r0, r0, lsl #8 - andvs r7, r0, r0 - andvs r5, r0, r0, lsl r0 +lp0_literals: + .word 0x7000f400 + .word 0x7000e400 + .word 0x60007000 + .word 0x60005010 .word 0x7000e000 enter_lp0_end: ENDPROC(enter_lp0) @@ -835,7 +841,8 @@ ArmCortexA9PhysicalRestored: ldr r1, [r1] //Read from LP0 exit time from SCRATCH1 - ldr r2, [r0, #0x54] + //The warmboot code filled this value in + ldr r2, [r0, #APBDEV_PMC_SCRATCH1_0] add r2, r2, #300 pll_wait: ldr r3, [r1] diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index db255cd8a1d9..1916e1663a65 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -67,6 +67,7 @@ void cpu_ap20_do_lp0(void) //and exit immediately as soon the PMC samples it and the //power good timer expires. NvU32 Reg; + NvU32 StoreScratch1; NvOdmPmuProperty PmuProperty; NvBool HasPmuProperty = NvOdmQueryGetPmuProperty(&PmuProperty); @@ -90,6 +91,10 @@ void cpu_ap20_do_lp0(void) CPUPWRREQ_OE, DISABLE, Reg); } + //Store the scratch1 value first. This scratch is clobbered + //by LP0, but is still used by CPU hotplug + StoreScratch1 = NV_REGR(s_hRmGlobal, NvRmModuleID_Pmif, 0, + APBDEV_PMC_SCRATCH1_0); //Enter low power LP0 mode prepare_for_wb0(); shadow_lp0_scratch_regs(); @@ -98,6 +103,10 @@ void cpu_ap20_do_lp0(void) printk("LP0: Exited...\n"); shadow_runstate_scratch_regs(); + //Restore the scratch1 register + NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, + APBDEV_PMC_SCRATCH1_0, StoreScratch1); + if (HasPmuProperty && PmuProperty.CombinedPowerReq) { //Enable CPU power request and tristate core power request outputs @@ -198,7 +207,7 @@ void cpu_ap20_do_lp2(void) //Save our context ptrs to scratch regs NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, - APBDEV_PMC_SCRATCH33_0, g_resume); + APBDEV_PMC_SCRATCH1_0, g_resume); NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH37_0, g_contextSavePA); diff --git a/arch/arm/mach-tegra/power.h b/arch/arm/mach-tegra/power.h index 36cf04b93121..81a1130fa2da 100644 --- a/arch/arm/mach-tegra/power.h +++ b/arch/arm/mach-tegra/power.h @@ -143,6 +143,17 @@ extern NvRmDeviceHandle s_hRmGlobal; NV_SDRF_NUM(s,d,r,f,n)) +/****SCRATCH REGISTER USAGE FOR POWER STATES**** + * | Scratch1 | Scatch37 | Scratch38 | Scratch39 | + * -----------|----------- |--------------|-------------|-------------| + * LP2 | CpuResumePtr| CtxtSaveAddr | LP2EnterTime| LP2ExitTime | + * -----------|-------------|--------------|-------------|-------------| + * LP1 | CpuResumePtr| CtxtSaveAddr | LP1EnterTime| LP1ExitTime | + * -----------|-------------|--------------|-------------|-------------| + * LP0 | LP0ExitTime | CtxtSaveAddr | LP0EnterTime| AvpResumePtr| + * -----------|-------------|--------------|-------------|-------------| + */ + /** SHADOW_REGS() - Shadowed PMC scratch registers that must be saved/restored across low power transitions because they are used by RM for other purposes. |