void NvRmPrivSetSocRailPowerState( NvRmDeviceHandle hRmDeviceHandle, NvU32 PmuRailAddress, NvBool Enable, NvU32* pIoPwrDetectMask, NvU32* pNoIoPwrMask) { IoPowerMapRail(PmuRailAddress, pIoPwrDetectMask, pNoIoPwrMask); if ((*pIoPwrDetectMask == 0) && (*pNoIoPwrMask == 0)) return; // Exit if not mapped rail if (Enable) { // On/Off transition: activate power detect cells and keep control // masks so that the results can be latched and IO pads enabled after // the transition is completed if (*pIoPwrDetectMask != 0) NvRmPrivIoPowerDetectStart(hRmDeviceHandle, *pIoPwrDetectMask); } else { // Off/On transition: disable IO pads, and clear control masks, // as no action is required after the transition is completed if (*pNoIoPwrMask != 0) NvRmPrivIoPowerControl(hRmDeviceHandle, *pNoIoPwrMask, NV_FALSE); *pIoPwrDetectMask = *pNoIoPwrMask = 0; } }
void NvRmPrivIoPowerControlInit(NvRmDeviceHandle hRmDeviceHandle) { NvU32 i, v; NvU32 NoIoPwrMask = 0; const NvOdmPeripheralConnectivity* pPmuRail = NULL; if (NvRmPrivGetExecPlatform(hRmDeviceHandle) != ExecPlatform_Soc) { // Invalidate IO Power detect map if not SoC platform for (i = 0; i < NV_ARRAY_SIZE(s_IoPowerDetectMap); i++) s_IoPowerDetectMap[i].PmuRailAddress = NV_RAIL_ADDR_INVALID; return; } for (i = 0; i < NV_ARRAY_SIZE(s_IoPowerDetectMap); i++) { // Fill in PMU rail addresses in IO Power detect map pPmuRail = NvOdmPeripheralGetGuid(s_IoPowerDetectMap[i].PowerRailId); NV_ASSERT(pPmuRail && pPmuRail->NumAddress); s_IoPowerDetectMap[i].PmuRailAddress = pPmuRail->AddressList[0].Address; // Find all unpowered rails v = NvRmPrivPmuRailGetVoltage( hRmDeviceHandle, s_IoPowerDetectMap[i].PowerRailId); if (v == ODM_VOLTAGE_OFF) NoIoPwrMask |= s_IoPowerDetectMap[i].DisableRailMask; } // Latch already powered IO rails NvRmPrivIoPowerDetectLatch(hRmDeviceHandle); // Disable IO pads for unpowered rails if (NoIoPwrMask) NvRmPrivIoPowerControl(hRmDeviceHandle, NoIoPwrMask, NV_FALSE); }
void NvRmPmuSetVoltage( NvRmDeviceHandle hDevice, NvU32 vddId, NvU32 MilliVolts, NvU32 * pSettleMicroSeconds) { NvU32 i; NvU32 t = NVRM_PWR_DET_DELAY_US; NV_ASSERT(hDevice); if (pSettleMicroSeconds) *pSettleMicroSeconds = 0; if (!s_PmuSupportedEnv) return; // This API is blocked if diagnostic is in progress for any module if (NvRmPrivIsDiagMode(NvRmModuleID_Invalid)) return; #if PMU_RAILS_NEVER_OFF if (MilliVolts == ODM_VOLTAGE_OFF) return; #endif NV_ASSERT(s_Pmu.hMutex); NvOsMutexLock(s_Pmu.hMutex); // Set voltage and latch IO level sampling results for (i = 0; i < VOLTAGE_CONTROL_RETRY_CNT; i++) { if (NvOdmPmuSetVoltage(s_Pmu.hOdmPmu, vddId, MilliVolts, pSettleMicroSeconds)) break; } NV_ASSERT(i < VOLTAGE_CONTROL_RETRY_CNT); if (s_Pmu.IoPwrDetectMask || s_Pmu.NoIoPwrMask) { NV_ASSERT(MilliVolts != ODM_VOLTAGE_OFF); if (pSettleMicroSeconds) { t += (*pSettleMicroSeconds); *pSettleMicroSeconds = 0; // Don't wait twice } NvOsWaitUS(t); if (s_Pmu.IoPwrDetectMask) // Latch just powered IO rails NvRmPrivIoPowerDetectLatch(hDevice); if (s_Pmu.NoIoPwrMask) // Enable just powered IO rails NvRmPrivIoPowerControl(hDevice, s_Pmu.NoIoPwrMask, NV_TRUE); s_Pmu.IoPwrDetectMask = s_Pmu.NoIoPwrMask = 0; } NvOsMutexUnlock(s_Pmu.hMutex); }