summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/nvrm
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-02-10 21:45:30 -0800
committerGerrit Code Review <gerrit2@git-master-01.nvidia.com>2010-02-10 21:45:30 -0800
commit423c5318facfff78e1351bf64e9abacd1f0d8f84 (patch)
tree2ca1b8a3de049b03d50adb6e43c934a2b20aecab /arch/arm/mach-tegra/nvrm
parentfbcae0ffbb8dc80f8cb9e8dcd220a20143ad9b1c (diff)
parent5ffd33e8b218b28274c2b3c9ac832f8708757c95 (diff)
Merge "tegra : PWM disable/enable power as needed." into android-tegra-2.6.29
Diffstat (limited to 'arch/arm/mach-tegra/nvrm')
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c123
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h2
2 files changed, 91 insertions, 34 deletions
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c
index b18b9000a393..cddeb792ce0a 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c
@@ -70,52 +70,83 @@ static NvRmPwmHandle s_hPwm = NULL;
static NvBool s_IsPwmFirstConfig = NV_FALSE;
static NvBool s_IsFreqDividerSupported = NV_FALSE;
+// Checks whether all the PWM channels are disabled or not.
+// Returns NV_FALSE if any of the channels are enabled
+// else returns NV_TRUE
+static NvBool IsPwmDisabled(NvRmPwmHandle hPwm);
+
+static NvBool IsPwmDisabled(NvRmPwmHandle hPwm)
+{
+ NvU32 RegValue = 0;
+ NvU32 i = 0;
+ NvBool PwmDisabled = NV_TRUE;
+
+ for (i = 0; i < NvRmPwmOutputId_Num-2; i++)
+ {
+ RegValue = PWM_REGR( hPwm->VirtualAddress[i], 0 );
+ if (PWM_GET(CSR_0, ENB, RegValue))
+ {
+ PwmDisabled = NV_FALSE;
+ break;
+ }
+ }
+ return PwmDisabled;
+}
+
static NvError PwmPowerConfigure(NvRmPwmHandle hPwm, NvBool IsEnablePower)
{
NvError status = NvSuccess;
if (IsEnablePower == NV_TRUE)
{
- // Enable power
- status = NvRmPowerVoltageControl(hPwm->RmDeviceHandle,
- NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
- s_PwmPowerID,
- NvRmVoltsUnspecified,
- NvRmVoltsUnspecified,
- NULL,
- 0,
- NULL);
- if (status == NvSuccess)
- {
- // Enable the clock to the pwm controller
- status = NvRmPowerModuleClockControl(hPwm->RmDeviceHandle,
- NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
- s_PwmPowerID,
- NV_TRUE);
+ if (!hPwm->PowerEnabled)
+ {
+ // Enable power
+ status = NvRmPowerVoltageControl(hPwm->RmDeviceHandle,
+ NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
+ s_PwmPowerID,
+ NvRmVoltsUnspecified,
+ NvRmVoltsUnspecified,
+ NULL,
+ 0,
+ NULL);
+ if (status == NvSuccess)
+ {
+ // Enable the clock to the pwm controller
+ status = NvRmPowerModuleClockControl(hPwm->RmDeviceHandle,
+ NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
+ s_PwmPowerID,
+ NV_TRUE);
+ hPwm->PowerEnabled = NV_TRUE;
+ }
}
}
else
{
- // Disable the clock to the pwm controller
- status = NvRmPowerModuleClockControl(hPwm->RmDeviceHandle,
- NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
- s_PwmPowerID,
- NV_FALSE);
-
- if(status == NvSuccess)
+ if (hPwm->PowerEnabled)
{
- // Disable power
- status = NvRmPowerVoltageControl(hPwm->RmDeviceHandle,
+ // Disable the clock to the pwm controller
+ status = NvRmPowerModuleClockControl(hPwm->RmDeviceHandle,
NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
s_PwmPowerID,
- NvRmVoltsOff,
- NvRmVoltsOff,
- NULL,
- 0,
- NULL);
+ NV_FALSE);
+
+ if(status == NvSuccess)
+ {
+ // Disable power
+ status = NvRmPowerVoltageControl(hPwm->RmDeviceHandle,
+ NVRM_MODULE_ID(NvRmModuleID_Pwm, 0),
+ s_PwmPowerID,
+ NvRmVoltsOff,
+ NvRmVoltsOff,
+ NULL,
+ 0,
+ NULL);
+ hPwm->PowerEnabled = NV_FALSE;
+ }
}
}
-
+
return status;
}
@@ -343,6 +374,7 @@ NvError NvRmPwmConfig(
{
if (!s_IsPwmFirstConfig)
{
+ hPwm->PowerEnabled = NV_FALSE;
// Register with RM power
status = NvRmPowerRegister(hPwm->RmDeviceHandle, NULL, &s_PwmPowerID);
if (status != NvSuccess)
@@ -382,6 +414,15 @@ NvError NvRmPwmConfig(
s_IsPwmFirstConfig = NV_TRUE;
}
+ // Enable power
+ status = PwmPowerConfigure(hPwm, NV_TRUE);
+ if (status != NvSuccess)
+ {
+ NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID);
+ goto fail;
+ }
+
+
// Validate PWM output and pin map config
status = PwmCheckValidConfig(hPwm, OutputId, Mode);
if (status != NvSuccess)
@@ -438,6 +479,23 @@ NvError NvRmPwmConfig(
}
PWM_REGW(hPwm->VirtualAddress[OutputId-1], 0, RegValue);
+
+ // If PWM mode is disabled and all pwd channels are disabled then
+ // disable power to PWM
+ if (!PwmMode)
+ {
+ if (IsPwmDisabled(hPwm))
+ {
+ // Disable power
+ status = PwmPowerConfigure(hPwm, NV_FALSE);
+ if (status != NvSuccess)
+ {
+ NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID);
+ goto fail;
+ }
+ }
+ }
+
}
else
{
@@ -503,6 +561,3 @@ fail:
return status;
}
-
-
-
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h
index dadffcb14efe..46ce0f3a2c3d 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h
@@ -69,6 +69,8 @@ typedef struct NvRmPwmRec
// Pmc bank size
NvU32 PmcBankSize;
+ // pmu powerEnabled flag
+ NvBool PowerEnabled;
} NvRmPwm;
#define PWM_RESET(r) NV_RESETVAL(PWM_CONTROLLER_PWM,r)