diff options
author | Kasoju Mallikarjun <mkasoju@nvidia.com> | 2010-02-05 18:22:24 +0530 |
---|---|---|
committer | Kasoju Mallikarjun <mkasoju@nvidia.com> | 2010-02-10 10:07:18 +0530 |
commit | 5ffd33e8b218b28274c2b3c9ac832f8708757c95 (patch) | |
tree | 7c8d54a79009de7f57e9b2cb2385f57d4d5c994a | |
parent | b7ede6ae31fd044cd41946f4234442c5c6b25204 (diff) |
tegra : PWM disable/enable power as needed.
Added support for the PWM to turn of the power when in idle mode,
and reenable the power when back active
Bug 641675
Change-Id: I8e58375961a5e9303469e8bf2fe4ed0d112936da
-rw-r--r-- | arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm.c | 123 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_pwm_private.h | 2 |
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) |