diff options
author | Alex Frid <afrid@nvidia.com> | 2010-06-07 15:11:47 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-06-07 17:41:25 -0700 |
commit | 87ef55a65e89177f1b04ce91ceefd0b5cecc16bb (patch) | |
tree | ab7a02e899805192d60a90a8ef324af4477135a2 /arch | |
parent | 21cfe0729a6ad3a9858371b388d3263889fd5a28 (diff) |
[ARM/tegra] RM DVFS: added busy hints pool.
Replaced dynamic busy hints allocation with busy hints pool.
bug 686569
ported from android-tegra-2.6.29
Change-Id: Ie64dfc1a060e2d574b5970018c95f61acb735e07
Reviewed-on: http://git-master/r/2225
Tested-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Trivikram Kasivajhula <tkasivajhula@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c | 53 |
1 files changed, 46 insertions, 7 deletions
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 aeba057740fe..e9f1ce7aa104 100644 --- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c +++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c @@ -202,6 +202,11 @@ static NvU32 s_StarveOnRefCounts[NvRmDfsClockId_Num]; // Heads of busy hint lists for DFS clock domain static BusyHintReq s_BusyReqHeads[NvRmDfsClockId_Num]; +// Busy requests pool +#define NVRM_BUSYREQ_POOL_SIZE (24) +static BusyHintReq s_BusyReqPool[NVRM_BUSYREQ_POOL_SIZE]; +static BusyHintReq* s_pFreeBusyReqPool[NVRM_BUSYREQ_POOL_SIZE]; +static NvU32 s_FreeBusyReqPoolSize = 0; /*****************************************************************************/ @@ -237,6 +242,12 @@ static void ReportRmPowerState(NvRmDeviceHandle hRmDeviceHandle); /* + * Manages busy request pool + */ +static BusyHintReq* BusyReqAlloc(void); +static void BusyReqFree(BusyHintReq* pBusyHintReq); + +/* * Cancels busy hints reported by the specified client for * specified domain */ @@ -369,12 +380,11 @@ static void CancelPowerRequests( /*****************************************************************************/ NvError NvRmPrivPowerInit(NvRmDeviceHandle hRmDeviceHandle) { + NvU32 i; NvError e; NV_ASSERT(hRmDeviceHandle); - // TODO: expand after clock API is completed - // Initialize registry s_PowerRegistry.pPowerClients = NULL; s_PowerRegistry.AvailableEntries = 0; @@ -388,6 +398,12 @@ NvError NvRmPrivPowerInit(NvRmDeviceHandle hRmDeviceHandle) NvOsMemset(s_StarveOnRefCounts, 0, sizeof(s_StarveOnRefCounts)); NvOsMemset(s_PowerOnRefCounts, 0, sizeof(s_PowerOnRefCounts)); + // Initialize busy requests pool + NvOsMemset(s_BusyReqPool, 0, sizeof(s_BusyReqPool)); + for (i = 0; i < NVRM_BUSYREQ_POOL_SIZE; i++) + s_pFreeBusyReqPool[i] = &s_BusyReqPool[i]; + s_FreeBusyReqPoolSize = NVRM_BUSYREQ_POOL_SIZE; + // Create the RM registry mutex and initialize RM/OAL interface s_hPowerClientMutex = NULL; NV_CHECK_ERROR_CLEANUP(NvOsMutexCreate(&s_hPowerClientMutex)); @@ -421,7 +437,7 @@ void NvRmPrivPowerDeinit(NvRmDeviceHandle hRmDeviceHandle) { BusyHintReq* pBusyHintReq = s_BusyReqHeads[i].pNext; s_BusyReqHeads[i].pNext = pBusyHintReq->pNext; - NvOsFree(pBusyHintReq); + BusyReqFree(pBusyHintReq); } } // Free RM power registry memory @@ -1157,6 +1173,29 @@ NvRmPowerStarvationHint ( /*****************************************************************************/ +static BusyHintReq* BusyReqAlloc(void) +{ + if (s_FreeBusyReqPoolSize != 0) + return s_pFreeBusyReqPool[--s_FreeBusyReqPoolSize]; + else + { + NV_ASSERT(!"Busy pool size is too small"); + return NvOsAlloc(sizeof(BusyHintReq)); + } +} + +static void BusyReqFree(BusyHintReq* pBusyHintReq) +{ + if ((pBusyHintReq >= &s_BusyReqPool[0]) && + (pBusyHintReq < &s_BusyReqPool[NVRM_BUSYREQ_POOL_SIZE])) + { + NV_ASSERT(s_FreeBusyReqPoolSize < NVRM_BUSYREQ_POOL_SIZE); + s_pFreeBusyReqPool[s_FreeBusyReqPoolSize++] = pBusyHintReq; + return; + } + NvOsFree(pBusyHintReq); +} + static void CancelBusyHints(NvRmDfsClockId ClockId, NvU32 ClientId) { BusyHintReq* pBusyHintReq = NULL; @@ -1177,7 +1216,7 @@ static void CancelBusyHints(NvRmDfsClockId ClockId, NvU32 ClientId) if ((pBusyHintNext != NULL) && (pBusyHintNext->ClientId == ClientId)) { pBusyHintReq->pNext = pBusyHintNext->pNext; - NvOsFree(pBusyHintNext); + BusyReqFree(pBusyHintNext); continue; } pBusyHintReq = pBusyHintNext; @@ -1205,7 +1244,7 @@ static void PurgeBusyHints(NvRmDfsClockId ClockId, NvU32 msec) (pBusyHintNext->IntervalMs < (msec - pBusyHintNext->StartTimeMs)) ) { pBusyHintReq->pNext = pBusyHintNext->pNext; - NvOsFree(pBusyHintNext); + BusyReqFree(pBusyHintNext); continue; } pBusyHintReq = pBusyHintNext; @@ -1278,7 +1317,7 @@ RecordBusyHints( (pInsert->pNext->BoostKHz < BoostKHz)) { // Allocate and initialize new boost hint record - pBusyHintReq = NvOsAlloc(sizeof(BusyHintReq)); + pBusyHintReq = BusyReqAlloc(); if (pBusyHintReq == NULL) { return NvError_InsufficientMemory; @@ -1365,7 +1404,7 @@ void NvRmPrivDfsGetBusyHint( } p = pBusyHintReq; pBusyHintReq = pBusyHintReq->pNext; - NvOsFree(p); + BusyReqFree(p); } if (pBusyHintReq) { |