diff options
author | Bitan Biswas <bbiswas@nvidia.com> | 2010-02-18 20:16:38 +0530 |
---|---|---|
committer | Bitan Biswas <bbiswas@nvidia.com> | 2010-02-19 17:56:08 +0530 |
commit | a35703938b944bec8c004be582180d294626a0c8 (patch) | |
tree | 4ce8c8a1e93b493e11fe4677a71ab287a206f6bc | |
parent | 2dd8af188e4dd01691f49d689bf24a4fd89927b1 (diff) |
tegra nand : active during suspend to lp1
Nand was seen as active device during suspend as Ddk Nand suspend code
was getting bypassed. Ddk Nand Suspend clocks call disables clock after
any operation. Later when suspend API found the clock disabled
RM voltage control calls were getting skipped. Modified suspend
implementation to use new suspend flag that skips suspend call
only when suspend is done once.
Tested on: harmony. Nand no longer active when entering lp1
Reviewed by: vbyravarasu
Change-Id: Iebda224a5b4eaeed77186abd096f67ee6473966e
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_nand.c | 96 |
1 files changed, 29 insertions, 67 deletions
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_nand.c b/arch/arm/mach-tegra/nvddk/nvddk_nand.c index d4abe125f772..e851eedca784 100644 --- a/arch/arm/mach-tegra/nvddk/nvddk_nand.c +++ b/arch/arm/mach-tegra/nvddk/nvddk_nand.c @@ -350,6 +350,8 @@ typedef struct NvDdkNandRec NvU8 NandBusWidth; NandParams Params; NvBool IsNandClkEnabled; + /* flag to ensure suspend is not executed twice */ + NvBool IsNandSuspended; // Flag to check if lock status is read from the device NvBool IsLockStatusAvailable; // To Hold the error threshold value. @@ -4837,8 +4839,6 @@ NvError NvDdkNandSuspendClocks(NvDdkNandHandle hNand) e = NvSuccess; goto fail; } - if (hNand->IsLockStatusAvailable) - NandLoadLockCfg(hNand); BusyHints[0].ClockId = NvRmDfsClockId_Emc; BusyHints[0].BoostDurationMs = NV_WAIT_INFINITE; BusyHints[0].BoostKHz = 0; @@ -4900,7 +4900,7 @@ NvError NvDdkNandResumeClocks(NvDdkNandHandle hNand) BusyHints, 3, NvRmDfsBusyHintSyncMode_Async); - /* Enable the power & clk to Nand controller */ + /* Enable clk to Nand controller */ NV_CHECK_ERROR_CLEANUP(EnableNandClock(hNand)); SetTimingRegVal(hNand, NV_FALSE); fail: @@ -4911,46 +4911,25 @@ fail: NvError NvDdkNandSuspend(NvDdkNandHandle hNand) { NvError e = NvSuccess; - NvRmDfsBusyHint BusyHints[3]; - NvBool BusyAttribute = NV_TRUE; - NvOsMutexLock(hNand->hMutex); - if (!hNand->IsNandClkEnabled) + if (hNand->IsNandSuspended) { - e = NvSuccess; - goto fail; + /* already in suspend state */ + return e; } + /* disable clock */ + NvDdkNandSuspendClocks(hNand); + NvOsMutexLock(hNand->hMutex); + /* save lock data */ if (hNand->IsLockStatusAvailable) NandLoadLockCfg(hNand); - BusyHints[0].ClockId = NvRmDfsClockId_Emc; - BusyHints[0].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[0].BoostKHz = 0; - BusyHints[0].BusyAttribute = BusyAttribute; - - BusyHints[1].ClockId = NvRmDfsClockId_Ahb; - BusyHints[1].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[1].BoostKHz = 0; - BusyHints[1].BusyAttribute = BusyAttribute; - - BusyHints[2].ClockId = NvRmDfsClockId_Cpu; - BusyHints[2].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[2].BoostKHz = 0; - BusyHints[2].BusyAttribute = BusyAttribute; - - NvRmPowerBusyHintMulti(hNand->RmDevHandle, - hNand->RmPowerClientId, - BusyHints, - 3, - NvRmDfsBusyHintSyncMode_Async); - /* Disable the clock */ - NV_CHECK_ERROR_CLEANUP(NvRmPowerModuleClockControl(hNand->RmDevHandle, - NvRmModuleID_Nand, hNand->RmPowerClientId, NV_FALSE)); - /* Disable the power */ + /* disable power */ NandPowerRailEnable(hNand, NV_FALSE); NV_CHECK_ERROR_CLEANUP(NvRmPowerVoltageControl(hNand->RmDevHandle, NvRmModuleID_Nand, hNand->RmPowerClientId, NvRmVoltsOff, NvRmVoltsOff, NULL, 0, NULL)); - hNand->IsNandClkEnabled = NV_FALSE; + /* enter suspend state */ + hNand->IsNandSuspended = NV_TRUE; fail: NvOsMutexUnlock(hNand->hMutex); return e; @@ -4959,45 +4938,28 @@ fail: NvError NvDdkNandResume(NvDdkNandHandle hNand) { NvError e = NvSuccess; - NvRmDfsBusyHint BusyHints[3]; - NvBool BusyAttribute = NV_TRUE; - NvOsMutexLock(hNand->hMutex); - if (hNand->IsNandClkEnabled) - { - e = NvSuccess; - goto fail; + if (!hNand->IsNandSuspended) { + /* already in resume state */ + return e; } - BusyHints[0].ClockId = NvRmDfsClockId_Emc; - BusyHints[0].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[0].BoostKHz = 80000; - BusyHints[0].BusyAttribute = BusyAttribute; - - BusyHints[1].ClockId = NvRmDfsClockId_Ahb; - BusyHints[1].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[1].BoostKHz = 80000; - BusyHints[1].BusyAttribute = BusyAttribute; - - BusyHints[2].ClockId = NvRmDfsClockId_Cpu; - BusyHints[2].BoostDurationMs = NV_WAIT_INFINITE; - BusyHints[2].BoostKHz = 240000; - BusyHints[2].BusyAttribute = BusyAttribute; - - NvRmPowerBusyHintMulti(hNand->RmDevHandle, - hNand->RmPowerClientId, - BusyHints, - 3, - NvRmDfsBusyHintSyncMode_Async); + NvOsMutexLock(hNand->hMutex); /* Enable power to the Nand controller */ NV_CHECK_ERROR_CLEANUP(EnableNandPower(hNand)); - /* Enable clk to the Nand controller */ - NV_CHECK_ERROR_CLEANUP(EnableNandClock(hNand)); - SetTimingRegVal(hNand, NV_FALSE); - hNand->IsNandClkEnabled = NV_TRUE; - if (hNand->IsLockStatusAvailable) - { + /* Restore lock data into Nand registers */ + if (hNand->IsLockStatusAvailable) { NandRestoreLocks(hNand); } + NvOsMutexUnlock(hNand->hMutex); + /* enable clock outside mutex lock */ + e = NvDdkNandResumeClocks(hNand); + if (e != NvSuccess) { + /* failed clock enable */ + return e; + } + /* enter resume state */ + hNand->IsNandSuspended = NV_FALSE; + return e; fail: NvOsMutexUnlock(hNand->hMutex); return e; |