void NvRmPrivAp20DttPolicyUpdate( NvRmDeviceHandle hRmDevice, NvRmDtt* pDtt) { NvBool Throttle = NvOdmTmonThrottle(pDtt->hOdmTcore); // CPU throttling limits are set at 50% of CPU frequency range (no // throttling below this value), and at CPU frequency boundary that // matches specified voltage throttling limit. if ((!s_CpuThrottleMaxKHz) || (!s_CpuThrottleMinKHz)) { NvU32 steps; const NvRmFreqKHz* p = NvRmPrivModuleVscaleGetMaxKHzList( hRmDevice, NvRmModuleID_Cpu, &steps); NV_ASSERT(p && steps); for (; steps != 0 ; steps--) { if (NVRM_DTT_VOLTAGE_THROTTLE_MV >= NvRmPrivModuleVscaleGetMV( hRmDevice, NvRmModuleID_Cpu, p[steps-1])) break; } NV_ASSERT(steps); s_CpuThrottleMaxKHz = NV_MIN( NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz, p[steps-1]); s_CpuThrottleMinKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz / NVRM_DTT_RATIO_MAX; NV_ASSERT(s_CpuThrottleMaxKHz > s_CpuThrottleMinKHz); NV_ASSERT(s_CpuThrottleMinKHz > NVRM_DTT_CPU_DELTA_KHZ); s_CpuThrottleKHz = s_CpuThrottleMaxKHz; } pDtt->TcorePolicy.PolicyRange = Throttle ? NvRmDttAp20PolicyRange_ThrottleDown : NvRmDttAp20PolicyRange_FreeRunning; pDtt->TcorePolicy.UpdateIntervalUs = Throttle ? NVRM_DTT_POLL_MS_CRITICAL * 1000 : NV_WAIT_INFINITE; }
void NvRmPrivAp20DttPolicyUpdate( NvRmDeviceHandle hRmDevice, NvS32 TemperatureC, NvRmDtt* pDtt) { NvRmDttAp20PolicyRange Range; // CPU throttling limits are set at 50% of CPU frequency range (no // throttling below this value), and at CPU frequency boundary that // matches specified voltage throttling limit. if ((!s_CpuThrottleMaxKHz) || (!s_CpuThrottleMinKHz)) { NvU32 steps; const NvRmFreqKHz* p = NvRmPrivModuleVscaleGetMaxKHzList( hRmDevice, NvRmModuleID_Cpu, &steps); NV_ASSERT(p && steps); for (; steps != 0 ; steps--) { if (NVRM_DTT_VOLTAGE_THROTTLE_MV >= NvRmPrivModuleVscaleGetMV( hRmDevice, NvRmModuleID_Cpu, p[steps-1])) break; } NV_ASSERT(steps); s_CpuThrottleMaxKHz = NV_MIN( NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz, p[steps-1]); s_CpuThrottleMinKHz = NvRmPrivGetSocClockLimits(NvRmModuleID_Cpu)->MaxKHz / NVRM_DTT_RATIO_MAX; NV_ASSERT(s_CpuThrottleMaxKHz > s_CpuThrottleMinKHz); NV_ASSERT(s_CpuThrottleMinKHz > NVRM_DTT_CPU_DELTA_KHZ); s_CpuThrottleKHz = s_CpuThrottleMaxKHz; NV_ASSERT(pDtt->TcoreCaps.Tmin < (NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS)); NV_ASSERT(pDtt->TcoreCaps.Tmax > NVRM_DTT_DEGREES_HIGH); } // Advanced policy range state machine (one step at a time) Range = (NvRmDttAp20PolicyRange)pDtt->TcorePolicy.PolicyRange; switch (Range) { case NvRmDttAp20PolicyRange_Unknown: Range = NvRmDttAp20PolicyRange_FreeRunning; // fall through case NvRmDttAp20PolicyRange_FreeRunning: if (TemperatureC >= NVRM_DTT_DEGREES_LOW) Range = NvRmDttAp20PolicyRange_LimitVoltage; break; case NvRmDttAp20PolicyRange_LimitVoltage: if (TemperatureC <= (NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS)) Range = NvRmDttAp20PolicyRange_FreeRunning; else if (TemperatureC >= NVRM_DTT_DEGREES_HIGH) Range = NvRmDttAp20PolicyRange_ThrottleDown; break; case NvRmDttAp20PolicyRange_ThrottleDown: if (TemperatureC <= (NVRM_DTT_DEGREES_HIGH - NVRM_DTT_DEGREES_HYSTERESIS)) Range = NvRmDttAp20PolicyRange_LimitVoltage; break; default: break; } /* * Fill in new policy. Temperature limits are set around current * temperature for the next out-of-limit interrupt (possible exception * - temperature "jump" over two ranges would result in two interrupts * in a row before limits cover the temperature). Polling time is set * always in ThrottleDown range, and only for poll mode in other ranges. */ pDtt->CoreTemperatureC = TemperatureC; switch (Range) { case NvRmDttAp20PolicyRange_FreeRunning: pDtt->TcorePolicy.LowLimit = pDtt->TcoreLowLimitCaps.MinValue; pDtt->TcorePolicy.HighLimit = NVRM_DTT_DEGREES_LOW; pDtt->TcorePolicy.UpdateIntervalUs = pDtt->UseIntr ? NV_WAIT_INFINITE : (NVRM_DTT_POLL_MS_SLOW * 1000); break; case NvRmDttAp20PolicyRange_LimitVoltage: pDtt->TcorePolicy.LowLimit = NVRM_DTT_DEGREES_LOW - NVRM_DTT_DEGREES_HYSTERESIS; pDtt->TcorePolicy.HighLimit = NVRM_DTT_DEGREES_HIGH; pDtt->TcorePolicy.UpdateIntervalUs = pDtt->UseIntr ? NV_WAIT_INFINITE : (NVRM_DTT_POLL_MS_FAST * 1000); break; case NvRmDttAp20PolicyRange_ThrottleDown: pDtt->TcorePolicy.LowLimit = NVRM_DTT_DEGREES_HIGH - NVRM_DTT_DEGREES_HYSTERESIS; pDtt->TcorePolicy.HighLimit = pDtt->TcoreHighLimitCaps.MaxValue; pDtt->TcorePolicy.UpdateIntervalUs = NVRM_DTT_POLL_MS_CRITICAL * 1000; break; default: NV_ASSERT(!"Invalid DTT policy range"); NvOsDebugPrintf("DTT: Invalid Range = %d\n", Range); pDtt->TcorePolicy.HighLimit = ODM_TMON_PARAMETER_UNSPECIFIED; pDtt->TcorePolicy.LowLimit = ODM_TMON_PARAMETER_UNSPECIFIED; pDtt->TcorePolicy.PolicyRange = NvRmDttAp20PolicyRange_Unknown; return; } pDtt->TcorePolicy.PolicyRange = (NvU32)Range; }