summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2010-02-01 10:45:41 -0800
committerAlex Frid <afrid@nvidia.com>2010-02-03 23:42:17 -0800
commitd4bdbdc75d837dc2e93445da26d9600374a230ff (patch)
tree5ebe694ec357c799acd56c5608bed53b8e2de187
parent80b41816eaaf74678a9e56face1542076bb54b7d (diff)
tegra ODM: Added tmon interrupt debounce delay.
Change-Id: I29b148aad0036239e3115f7f80e1b5e6eccd9b58
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c39
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c12
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h3
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h5
4 files changed, 42 insertions, 17 deletions
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
index 38b68621cd3f..756c806cc759 100644
--- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_power_dfs.c
@@ -271,6 +271,22 @@ do\
/*****************************************************************************/
+#if NVRM_DTT_RANGE_CHANGE_PRINTF
+
+#define DttRangeReport(T, pDtt) \
+do\
+{\
+ NvOsDebugPrintf("DTT: T = %d, Range = %d (%d : %d)\n", \
+ (T), (pDtt)->TcorePolicy.PolicyRange, \
+ (pDtt)->TcorePolicy.LowLimit, (pDtt)->TcorePolicy.HighLimit); \
+} while(0)
+
+#else
+#define DttRangeReport(T, pDtt)
+#endif
+
+/*****************************************************************************/
+
// DFS object
static NvRmDfs s_Dfs;
@@ -1698,8 +1714,6 @@ DttPolicyUpdate(
NvS32 TemperatureC,
NvRmDtt* pDtt)
{
- NvU32 Range = pDtt->TcorePolicy.PolicyRange;
-
if (hRm->ChipId.Id == 0x20)
{
NvRmPrivAp20DttPolicyUpdate(hRm, TemperatureC, pDtt);
@@ -1716,14 +1730,6 @@ DttPolicyUpdate(
pDtt->TcorePolicy.UpdateIntervalUs = NV_WAIT_INFINITE;
pDtt->TcorePolicy.PolicyRange = 0;
}
- if (pDtt->UseIntr || (pDtt->TcorePolicy.PolicyRange != Range))
- {
-#if NVRM_DTT_RANGE_CHANGE_PRINTF
- NvOsDebugPrintf("DTT: T = %d, Range = %d (%d : %d)\n",
- TemperatureC, pDtt->TcorePolicy.PolicyRange,
- pDtt->TcorePolicy.LowLimit, pDtt->TcorePolicy.HighLimit);
-#endif
- }
}
static NvBool
@@ -1734,6 +1740,7 @@ DttClockUpdate(
{
NvS32 TemperatureC;
NvS32 LowLimit, HighLimit;
+ NvU32 OldRange;
NvRmTzonePolicy Policy;
// Check if thermal throttling is supported
@@ -1749,6 +1756,7 @@ DttClockUpdate(
NvOdmTmonTemperatureGet(pDtt->hOdmTcore, &TemperatureC))
{
DttPolicyUpdate(pDfs->hRm, TemperatureC, pDtt);
+ DttRangeReport(TemperatureC, pDtt);
LowLimit = pDtt->TcorePolicy.LowLimit;
HighLimit = pDtt->TcorePolicy.HighLimit;
@@ -1769,6 +1777,7 @@ DttClockUpdate(
}
// Update temperature monitoring policy
+ OldRange = pDtt->TcorePolicy.PolicyRange;
if (!pDtt->UseIntr &&
NvOdmTmonTemperatureGet(pDtt->hOdmTcore, &TemperatureC))
{
@@ -1787,6 +1796,12 @@ DttClockUpdate(
pDtt->TcorePolicy.UpdateFlag = NV_FALSE;
}
NvOsIntrMutexUnlock(pDfs->hIntrMutex);
+
+ // Report range change
+ if (!pDtt->UseIntr && (OldRange != pDtt->TcorePolicy.PolicyRange))
+ {
+ DttRangeReport(TemperatureC, pDtt);
+ }
}
else
{
@@ -1828,10 +1843,8 @@ static void DttIntrCallback(void* args)
NvOdmTmonConfigParam_IntrLimitLow, &LowLimit);
(void)NvOdmTmonParameterConfig(pDtt->hOdmTcore,
NvOdmTmonConfigParam_IntrLimitHigh, &HighLimit);
+ DttRangeReport(TemperatureC, pDtt);
}
-
- NVRM_DFS_PRINTF(("Dtt Intr: T = %d, LowLimit = %d, HighLimit = %d\n",
- TemperatureC, LowLimit, HighLimit));
}
/*****************************************************************************/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c
index 9108ae399152..dc76869f6dec 100644
--- a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c
@@ -44,6 +44,8 @@
#define NVODM_ADT7461_PRINTF(x)
#endif
+#define ADT7461_ALERT_DEBOUNCE (1)
+
// ADT7461 Descrriptor
static const ADT7461Info s_Adt7461Info =
{
@@ -347,6 +349,7 @@ Adt7461ConfigureSampleInterval(
if(!Adt7461WriteReg(pPrivData, pReg, i))
return NV_FALSE;
+ pPrivData->ShadowRate = i;
}
*pTargetMs = s_Adt7461SampleIntervalsMS[i];
return NV_TRUE;
@@ -366,7 +369,13 @@ static void Adt7461Isr(void* arg)
{
Callback(CallbackArg);
}
-
+#if ADT7461_ALERT_DEBOUNCE
+ // New range limits set by callback are not guaranteed to take effect
+ // before the next temperature conversion is completed, and interrupt
+ // can not be cleared until then. Hence, the debounce delay below.
+ NvOdmOsSleepMS(s_Adt7461SampleIntervalsMS[pPrivData->ShadowRate] +
+ s_Adt7461ConversionTimesMS[pPrivData->ShadowRate] + 1);
+#endif
// Read status and ARA to finish clearing interrupt after callback
pReg = &pPrivData->pDeviceInfo->Status;
(void)Adt7461ReadReg(pPrivData, pReg, &Data);
@@ -557,6 +566,7 @@ NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon)
pReg = &pPrivData->pDeviceInfo->Rate;
if(!Adt7461WriteReg(pPrivData, pReg, Data))
goto fail;
+ pPrivData->ShadowRate = Data;
// Set remote channel offset (8-bit 2's complement value for any range)
Data = ((NvU8)ADT7461_ODM_REMOTE_OFFSET_VALUE);
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h
index 485c82523a55..ffe4bf15dbec 100644
--- a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h
@@ -125,6 +125,9 @@ typedef struct ADT7461PrivDataRec
// Shadow of ADT7461 internal configuration register
NvU8 ShadowConfig;
+ // Shadow of ADT7461 internal rate settings
+ NvU8 ShadowRate;
+
// Shadow of ADT7461 internal address pointer
NvU8 ShadowRegPtr;
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h
index 290deeb9ebf3..e0e930e79fe7 100644
--- a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h
@@ -154,7 +154,7 @@ typedef enum
ADT7461ConfigBits_IntrAutoClear = (0x1 << 5),
// If set - put device in stanby mode
- // Ig cleared - put device in running mode
+ // If cleared - put device in running mode
ADT7461ConfigBits_Standby = (0x1 << 6),
// If set - interrupt from device is disabled
@@ -165,10 +165,9 @@ typedef enum
// ADT7461 initial configuration set by adaptation:
// ADT7461 THERM1 output is dedicated for critical h/w shutdown, and ADT7461
// ALERT/THERM2 output is always configured as out of limit ALERT interrupt.
-// Range and standby onfiguration options are selected per ODM policy macros.
+// Monitor is in running mode, in the range selected per ODM policy.
#define ADT7461_INITIAL_CONFIG \
((ADT7461ConfigBits_IntrDisabled) | \
- (ADT7461_ODM_STANDBY_ENABLED ? ADT7461ConfigBits_Standby : 0) | \
(ADT7461_ODM_EXTENDED_RANGE ? ADT7461ConfigBits_ExtendedRange : 0))