diff options
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c | 34 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c | 17 |
3 files changed, 58 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c index 405a7eeff267..f22650ce9b0c 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c @@ -233,6 +233,40 @@ void NvRmPrivPmuDeinit(NvRmDeviceHandle hRmDevice) NvOsMemset(&s_Pmu, 0, sizeof(NvRmPmu)); s_PmuSupportedEnv = NV_FALSE; } + +void NvRmPrivPmuLPxStateConfig( + NvRmDeviceHandle hRmDevice, + NvOdmSocPowerState state, + NvBool enter) +{ + NvOdmPmuProperty PmuProperty = {0}; + NvBool HasPmuProperty = NvOdmQueryGetPmuProperty(&PmuProperty); + const NvOdmPeripheralConnectivity* pCoreRail = + NvOdmPeripheralGetGuid(NV_VDD_CORE_ODM_ID); + + NV_ASSERT(hRmDevice); + NV_ASSERT(pCoreRail); + NV_ASSERT(pCoreRail->NumAddress); + + // On platforms with combined cpu/core power request core power rail + // should be controlled by the combined request only during deep sleep + // - enable the On/Off control on entry, and disable on exit + if (state == NvOdmSocPowerState_DeepSleep) + { + if (HasPmuProperty && PmuProperty.CombinedPowerReq) + { + NvU32 level = enter ? + ODM_VOLTAGE_ENABLE_EXT_ONOFF : ODM_VOLTAGE_DISABLE_EXT_ONOFF; + NvRmPmuSetVoltage(hRmDevice, pCoreRail->AddressList[0].Address, + level, NULL); + } + } + // Mask/Unmask PMU interrupt on entry/exit to/from suspend or deep sleep + if ((state == NvOdmSocPowerState_Suspend) || + (state == NvOdmSocPowerState_DeepSleep)) + NvRmPrivPmuInterruptMask(hRmDevice, enter); +} + /*****************************************************************************/ void NvRmPmuGetCapabilities( diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h index 79c818d21838..6a16c5e4de02 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h @@ -82,6 +82,18 @@ void NvRmPrivPmuDeinit(NvRmDeviceHandle hRmDevice); /** + * Configures PMU on entry/exit to/from low power state. + * + * @param hRmDevice The RM device handle + * @param state - Low Power state the SoC is entering to, or exiting from + * @param enter - Set NV_TRUE on entry, and NV_FALSE on exit + */ +void NvRmPrivPmuLPxStateConfig( + NvRmDeviceHandle hRmDevice, + NvOdmSocPowerState state, + NvBool enter); + +/** * Sets new voltage level for the specified PMU voltage rail. * Private interface for diagnostic mode only. * diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c index e748aa2e563d..aeba057740fe 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c @@ -1476,10 +1476,13 @@ NvRmPowerActivityHint ( NvError NvRmKernelPowerSuspend( NvRmDeviceHandle hRmDeviceHandle ) { + NvOdmSocPowerState state = + NvOdmQueryLowestSocPowerState()->LowestPowerState; - NvRmPrivPmuInterruptMask(hRmDeviceHandle, NV_TRUE); - NvRmPrivDfsSuspend(NvOdmQueryLowestSocPowerState()->LowestPowerState); - NvRmPrivPowerGroupSuspend(hRmDeviceHandle); + NvRmPrivDfsSuspend(state); + if (state == NvOdmSocPowerState_Suspend) + NvRmPrivPowerGroupSuspend(hRmDeviceHandle); + NvRmPrivPmuLPxStateConfig(hRmDeviceHandle, state, NV_TRUE); #if NVRM_POWER_DEBUG_SUSPEND_ENTRY NvOsMutexLock(s_hPowerClientMutex); @@ -1525,8 +1528,12 @@ NvRmKernelPowerSuspend( NvRmDeviceHandle hRmDeviceHandle ) NvError NvRmKernelPowerResume( NvRmDeviceHandle hRmDeviceHandle ) { - NvRmPrivPmuInterruptMask(hRmDeviceHandle, NV_FALSE); - NvRmPrivPowerGroupResume(hRmDeviceHandle); + NvOdmSocPowerState state = + NvOdmQueryLowestSocPowerState()->LowestPowerState; + + NvRmPrivPmuLPxStateConfig(hRmDeviceHandle, state, NV_FALSE); + if (state == NvOdmSocPowerState_Suspend) + NvRmPrivPowerGroupResume(hRmDeviceHandle); return NvSuccess; } |