summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu.c34
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h12
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c17
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;
}