diff options
author | Alex Frid <afrid@nvidia.com> | 2010-05-21 21:44:54 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-27 13:00:50 -0700 |
commit | 04766fad54fbc0dda7d726fc1e678c5cbb85171a (patch) | |
tree | c4f5e4bca45ad249df331c41a637542d7eb3138a | |
parent | c3be44e23d3a57643cb12f8369cf26e9ad339988 (diff) |
tegra ODM: Added PMU power off properties.
Added support for wake event delay, and CPU power off time controls.
Exposed the respective settings as ODM PMU properties (bug 690326).
Change-Id: I8a544546e8d65f3006bae2dfa4cebe8858610dd3
Reviewed-on: http://git-master/r/1568
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/include/nvodm_query.h | 9 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap20/ap20rm_clock_config.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c | 2 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/power-t2.c | 20 |
5 files changed, 41 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_query.h b/arch/arm/mach-tegra/include/nvodm_query.h index a7656cfc7cae..9bc66d4f44a9 100644 --- a/arch/arm/mach-tegra/include/nvodm_query.h +++ b/arch/arm/mach-tegra/include/nvodm_query.h @@ -844,6 +844,15 @@ typedef struct NvOdmPmuPropertyRec /// Specifies PMU Core and CPU voltage regulation accuracy in percent NvU32 AccuracyPercent; + /// Specifies the minimum time required for core power request to be + /// inactive (in 32 kHz counts). + NvU32 PowerOffCount; + + /// Specifies the minimum time required for CPU power request to be + /// inactive (in US). Relevant for SoC with separate CPU and core power + /// request outputs. + NvU32 CpuPowerOffUs; + } NvOdmPmuProperty; /** 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 b28aac4e1b10..d02f68674d99 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 @@ -191,8 +191,9 @@ static struct Ap20CpuConfigRec // PLLX frequency steps table pointer const NvRmFreqKHz* pPllXStepsKHz; - // CPU power good delay in microseconds + // CPU power good and power off delays in microseconds NvU32 CpuPowerGoodUs; + NvU32 CpuPowerOffUs; // Core over CPU voltage dependency parameters: // Vcore >= CoreOverCpuSlope * Vcpu + CoreOverCpuOffset @@ -1174,6 +1175,13 @@ Ap20SetCpuPowerGoodDelay( reg = NV_DRF_NUM(APBDEV_PMC, CPUPWRGOOD_TIMER, DATA, reg); NV_REGW(hRmDevice, NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWRGOOD_TIMER_0, reg); + + // AP20 CPU power off delay is counted by h/w in APB clocks (use + // 1/1000 ~ 17/16384 with 3% margin) + reg = ((ApbKHz * 17) >> 14) * s_Ap20CpuConfig.CpuPowerOffUs; + reg = NV_DRF_NUM(APBDEV_PMC, CPUPWROFF_TIMER, DATA, reg); + NV_REGW(hRmDevice, NvRmModuleID_Pmif, 0, + APBDEV_PMC_CPUPWROFF_TIMER_0, reg); } /*****************************************************************************/ @@ -1196,12 +1204,14 @@ static void Ap20CpuConfigInit(NvRmDeviceHandle hRmDevice) // parameters based on PMU property. if (!NvOdmQueryGetPmuProperty(&PmuProperty)) { + PmuProperty.CpuPowerOffUs = 0; // No power off delay by default PmuProperty.CpuPowerGoodUs = NVRM_DEFAULT_CPU_PWRGOOD_US; PmuProperty.AccuracyPercent = NVRM_DEFAULT_PMU_ACCURACY_PCT; } NV_ASSERT(PmuProperty.CpuPowerGoodUs && PmuProperty.AccuracyPercent); NV_ASSERT(PmuProperty.AccuracyPercent < 5); // 5% is a must for PMU + s_Ap20CpuConfig.CpuPowerOffUs = PmuProperty.CpuPowerOffUs; s_Ap20CpuConfig.CpuPowerGoodUs = PmuProperty.CpuPowerGoodUs; s_Ap20CpuConfig.CoreOverCpuOffset = (NV_AP20_CORE_OVER_CPU_MV * 100) / (100 - PmuProperty.AccuracyPercent); diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c index 454a53c82bd6..5040e7004a77 100644 --- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c @@ -677,6 +677,8 @@ NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) pPmuProperty->CpuPowerGoodUs = 2000; pPmuProperty->AccuracyPercent = 3; pPmuProperty->VCpuOTPOnWakeup = NV_FALSE; + pPmuProperty->PowerOffCount = 0; + pPmuProperty->CpuPowerOffUs = 0; return NV_TRUE; } 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 9041be0a2c19..85cfc0918ee7 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 @@ -1189,6 +1189,8 @@ NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) else pPmuProperty->VCpuOTPOnWakeup = NV_TRUE; + pPmuProperty->PowerOffCount = 0; + pPmuProperty->CpuPowerOffUs = 0; return NV_TRUE; } diff --git a/arch/arm/mach-tegra/power-t2.c b/arch/arm/mach-tegra/power-t2.c index 2a15fc48e84a..d9235a8ca1ac 100644 --- a/arch/arm/mach-tegra/power-t2.c +++ b/arch/arm/mach-tegra/power-t2.c @@ -55,6 +55,7 @@ NvU32 g_wakeupCcbp = 0, g_ArmPerif = 0; NvU32 g_enterLP2PA = 0; NvU32 g_coreSightClock, g_currentCcbp, g_currentCcdiv; NvU32 g_lp1CpuPwrGoodCnt, g_currentCpuPwrGoodCnt; +NvU32 g_lp1CpuPwrOffCnt, g_currentCpuPwrOffCnt; 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, *g_pRtc, *g_pPL310; @@ -176,11 +177,16 @@ void cpu_ap20_do_lp1(void) disable_irq(INT_SYS_STATS_MON); do_suspend_prep(); - // Set/save CPU power good count + // Set/save CPU power good and power off counts 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); + + g_currentCpuPwrOffCnt = NV_REGR(s_hRmGlobal, + NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWROFF_TIMER_0); + NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, + APBDEV_PMC_CPUPWROFF_TIMER_0, g_lp1CpuPwrOffCnt); } printk("entering lp1\n"); @@ -206,9 +212,11 @@ void cpu_ap20_do_lp1(void) NV_REGW(s_hRmGlobal, NvRmPrivModuleID_ClockAndReset, 0, CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0, g_coreSightClock); - // Restore CPU power good count + // Restore CPU power good and power Off counts NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, APBDEV_PMC_CPUPWRGOOD_TIMER_0, g_currentCpuPwrGoodCnt); + NV_REGW(s_hRmGlobal, NvRmModuleID_Pmif, 0, + APBDEV_PMC_CPUPWROFF_TIMER_0, g_currentCpuPwrOffCnt); } NvOsMemcpy((void*)g_pIRAM, (void*)g_iramContextSaveVA, @@ -338,8 +346,9 @@ void power_lp0_init(void) } } - //Program the core power good timer + //Program the core power good and power off timers NV_PMC_REGW(g_pPMC,PWRGOOD_TIMER,PmuProperty.PowerGoodCount); + NV_PMC_REGW(g_pPMC,WAKE_DELAY,PmuProperty.PowerOffCount); } // Get ready CPU power good count in 32.768 kHz clocks (don't set timer @@ -351,6 +360,11 @@ void power_lp0_init(void) g_lp1CpuPwrGoodCnt = (4096 * g_lp1CpuPwrGoodCnt + 124999) / 125000; + // Similarly get ready CPU power off count in 32.768 kHz clocks + g_lp1CpuPwrOffCnt = HasPmuProperty ? + PmuProperty.CpuPowerOffUs : 0; // No delay by default + g_lp1CpuPwrOffCnt = + (4096 * g_lp1CpuPwrOffCnt + 124999) / 125000; } //Generate definitions of local variables to hold scratch register values. |