summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-03-09 22:59:35 -0800
committerGary King <gking@nvidia.com>2010-03-10 15:20:16 -0800
commit22ecfcb44f6e31c3357aec1b6ac2e614387dc9e0 (patch)
tree5f8c55dbebe26641d4c91d499583f5371cb8641d
parentb54fb83786bf9c0807577cdb912b016a9f012f3a (diff)
tegra RM: Fixed CPU PowerGood timer settings.
Loaded CPU PowerGood timer on entry to LP1 with count value for 32kHz system bus clock. Restored original count (which was set by DVFS at run time) on LP1 exit. Reduced margin of DVFS PowerGood calculations. Change-Id: I7f61c568dd6c81edea12b9965f7758d9bd496798 Reviewed-on: http://git-master/r/819 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c4
-rw-r--r--arch/arm/mach-tegra/power-t2.c22
2 files changed, 23 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
index 5883bffdaea7..a7778cebad9c 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c
@@ -1165,8 +1165,8 @@ Ap20SetCpuPowerGoodDelay(
NV_ASSERT(s_Ap20CpuConfig.CpuPowerGoodUs);
// AP20 CPU power good delay is counted by h/w in APB clocks (use
- // 1/1000 ~ 5/4096 with 20% margin)
- reg = ((ApbKHz * 5) >> 12) * s_Ap20CpuConfig.CpuPowerGoodUs;
+ // 1/1000 ~ 17/16384 with 3% margin)
+ reg = ((ApbKHz * 17) >> 14) * s_Ap20CpuConfig.CpuPowerGoodUs;
reg = NV_DRF_NUM(APBDEV_PMC, CPUPWRGOOD_TIMER, DATA, reg);
NV_REGW(hRmDevice, NvRmModuleID_Pmif, 0,
APBDEV_PMC_CPUPWRGOOD_TIMER_0, reg);
diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c
index 2275f628cba2..b756fbb5c147 100644
--- a/arch/arm/mach-tegra/power-t2.c
+++ b/arch/arm/mach-tegra/power-t2.c
@@ -52,6 +52,7 @@ NvU32 g_wakeupCcbp = 0, g_NumActiveCPUs, g_Sync = 0, g_ArmPerif = 0;
NvU32 g_enterLP2PA = 0;
NvU32 g_localTimerLoadRegister, g_localTimerCntrlRegister;
NvU32 g_coreSightClock, g_currentCcbp;
+NvU32 g_lp1CpuPwrGoodCnt, g_currentCpuPwrGoodCnt;
volatile void *g_pPMC, *g_pAHB, *g_pCLK_RST_CONTROLLER;
volatile void *g_pEMC, *g_pMC, *g_pAPB_MISC, *g_pTimerus;
volatile void *g_pIRAM;
@@ -249,6 +250,12 @@ void cpu_ap20_do_lp1(void)
//Disable the Statistics interrupt
NvPrivAp20MaskIrq(irq);
do_suspend_prep();
+
+ // Set/save CPU power good count
+ g_currentCpuPwrGoodCnt = NV_REGR(s_hRmGlobal,
+ NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWRGOOD_TIMER_0);
+ NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
+ APBDEV_PMC_CPUPWRGOOD_TIMER_0, g_lp1CpuPwrGoodCnt);
}
printk("entering lp1\n");
@@ -274,6 +281,10 @@ void cpu_ap20_do_lp1(void)
//Restore the CoreSight clock source.
NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0,
CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, g_coreSightClock);
+
+ // Restore CPU power good count
+ NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0,
+ APBDEV_PMC_CPUPWRGOOD_TIMER_0, g_currentCpuPwrGoodCnt);
}
NvOsMemcpy((void*)g_pIRAM, (void*)g_iramContextSaveVA,
@@ -393,10 +404,19 @@ void power_lp0_init(void)
}
}
- //Program the power good timer
+ //Program the core power good timer
NV_PMC_REGW(g_pPMC,PWRGOOD_TIMER,PmuProperty.PowerGoodCount);
}
+ // Get ready CPU power good count in 32.768 kHz clocks (don't set timer
+ // until actual LP1 entry; at run time it is on clock, scaled by DVFS)
+ // Calculate count as 32.768 * TimeUS / 1000 = 4096 * TimeUS / 125000
+ // and round it up.
+ g_lp1CpuPwrGoodCnt = HasPmuProperty ?
+ PmuProperty.CpuPowerGoodUs : 2000; // Use 2ms by default
+ g_lp1CpuPwrGoodCnt =
+ (4096 * PmuProperty.CpuPowerGoodUs + 124999) / 125000;
+
//Create the list of wakeup IRQs.
create_wakeup_irqs();
return;