summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-05-17 23:21:30 -0700
committerGary King <gking@nvidia.com>2010-05-22 10:45:59 -0700
commitbe03533498089ea4b434a868752eb938b50cd158 (patch)
treeaf71f3609ffe572f61c457e449cadab78521292b
parentc5ede35df6fe567e36499cf3673fc2128e69e042 (diff)
tegra RM: added busy hints pool (bug 686569).
Change-Id: Ic018767fff54472f97ab74ab71988ab3cdf5b981 Reviewed-on: http://git-master/r/1426 Reviewed-by: Venkata (Muni) Anda <vanda@nvidia.com> Tested-by: Venkata (Muni) Anda <vanda@nvidia.com> Reviewed-by: Daehyoung Ko <dko@nvidia.com> Tested-by: Daehyoung Ko <dko@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_power.c53
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)
{