summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-02-10 13:40:49 -0800
committerGerrit Code Review <gerrit2@git-master-01.nvidia.com>2010-02-10 13:40:49 -0800
commit5fbdc8c7d777cc97b6f745d1afc49cafa00f1619 (patch)
tree4415daa910b0a02cc43dd7920caf9173dae159b7 /arch
parent14d292446f6e6813a4e218ed14af1109454f7757 (diff)
parent5d7c2834d49119854c0226dba05d47f735b9a10d (diff)
Merge "tegra RM: Deferred core voltage downward scaling." into android-tegra-2.6.29
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power.c2
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_pmu_private.h3
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c21
3 files changed, 24 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power.c
index 04a6952442ff..116e4148a474 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_power.c
@@ -560,6 +560,8 @@ void NvRmPrivCoreVoltageInit(NvRmDeviceHandle hRmDevice)
NvRmPmuGetCapabilities(hRmDevice, CpuRailAddress, &cap);
NominalCpuMv = NV_MAX(NominalCpuMv, cap.MinMilliVolts);
NvRmPmuSetVoltage(hRmDevice, CpuRailAddress, NominalCpuMv, NULL);
+ if (CurrentCoreMv > NominalCoreMv)
+ NvOsWaitUS(NVRM_CPU_TO_CORE_DOWN_US); // delay if core to go down
}
// If core voltage is going down, update it after CPU voltage
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 8884a1157c57..441344fab5ca 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
@@ -40,6 +40,9 @@ extern "C"
{
#endif /* __cplusplus */
+// CPU rail lowering voltage delay (applicable only to the platforms
+// with dedicated CPU rail, and PMU default core voltage above nominal)
+#define NVRM_CPU_TO_CORE_DOWN_US (10000)
// Default voltage returned in environment with no PMU support
#define NVRM_NO_PMU_DEFAULT_VOLTAGE (1)
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
index 756c806cc759..74c28a5f9c42 100644
--- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
@@ -42,6 +42,7 @@
#include "nvrm_power_dfs.h"
#include "nvrm_pmu.h"
+#include "nvrm_pmu_private.h"
#include "nvassert.h"
#include "nvrm_hwintf.h"
#include "nvodm_query_discovery.h"
@@ -2335,19 +2336,29 @@ void NvRmPrivDvsInit(void)
pDvs->RtcRailAddress = pDvs->CoreRailAddress = 0;
return;
}
- DvsChangeCoreVoltage(pDfs->hRm, pDvs, pDvs->NominalCoreMv);
if (NvRmPrivIsCpuRailDedicated(pDfs->hRm))
{
+ // If core voltage is going up, update it before CPU and vice versa
+ if (pDvs->CurrentCoreMv <= pDvs->NominalCoreMv)
+ {
+ DvsChangeCoreVoltage(pDfs->hRm, pDvs, pDvs->NominalCoreMv);
+ }
DvsChangeCpuVoltage(pDfs->hRm, pDvs, pDvs->NominalCpuMv);
pDvs->DvsCorner.CpuMv = pDvs->NominalCpuMv;
+ if (pDvs->CurrentCoreMv > pDvs->NominalCoreMv)
+ {
+ NvOsWaitUS(NVRM_CPU_TO_CORE_DOWN_US); // delay if core to go down
+ DvsChangeCoreVoltage(pDfs->hRm, pDvs, pDvs->NominalCoreMv);
+ }
// No core scaling if CPU voltage is not preserved across LPx
if (pDvs->VCpuOTPOnWakeup)
pDvs->MinCoreMv = pDvs->NominalCoreMv;
}
else
{
+ DvsChangeCoreVoltage(pDfs->hRm, pDvs, pDvs->NominalCoreMv);
pDvs->DvsCorner.CpuMv = pDvs->NominalCoreMv;
}
pDvs->DvsCorner.SystemMv = pDvs->NominalCoreMv;
@@ -2435,8 +2446,14 @@ void NvRmPrivVoltageScale(
else
{
if (pDvs->CurrentCpuMv > CpuMv)
+ {
DvsChangeCpuVoltage(pDfs->hRm, pDvs, CpuMv);
- if (pDvs->CurrentCoreMv > TargetMv)
+ // Defer core voltage change to the next DVFS tick to account
+ // for CPU capacitors discharge
+ if (pDvs->CurrentCoreMv > TargetMv)
+ pDvs->UpdateFlag = NV_TRUE;
+ }
+ else if (pDvs->CurrentCoreMv > TargetMv)
DvsChangeCoreVoltage(pDfs->hRm, pDvs, TargetMv);
}
}