summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortkasivajhula <tkasivajhula@nvidia.com>2010-03-19 13:49:35 -0700
committerGary King <gking@nvidia.com>2010-03-26 16:23:25 -0800
commit5054b24952cdcef10819fe6137de46450d440bbe (patch)
tree5a919805430b2d52ec09774173026032e3d7f84d
parent474b9025e42b454df1c381416a3d9ef8ee1a7754 (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.c2
-rw-r--r--arch/arm/mach-tegra/power-lp.S49
-rw-r--r--arch/arm/mach-tegra/power-t2.c11
-rw-r--r--arch/arm/mach-tegra/power.h11
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.