示例#1
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);
}