NvError NvRmPwmOpen( NvRmDeviceHandle hDevice, NvRmPwmHandle *phPwm) { NvError status = NvSuccess; NvU32 PwmPhysAddr = 0, i = 0, PmcPhysAddr = 0; NvRmModuleCapability caps[4]; NvRmModuleCapability *pCap = NULL; NV_ASSERT(hDevice); NV_ASSERT(phPwm); NvOsMutexLock(s_hPwmMutex); if (s_hPwm) { s_hPwm->RefCount++; goto exit; } // Allcoate the memory for the pwm handle s_hPwm = NvOsAlloc(sizeof(NvRmPwm)); if (!s_hPwm) { status = NvError_InsufficientMemory; goto fail; } NvOsMemset(s_hPwm, 0, sizeof(NvRmPwm)); // Set the pwm handle parameters s_hPwm->RmDeviceHandle = hDevice; // Get the pwm physical and virtual base address NvRmModuleGetBaseAddress(hDevice, NVRM_MODULE_ID(NvRmModuleID_Pwm, 0), &PwmPhysAddr, &(s_hPwm->PwmBankSize)); s_hPwm->PwmBankSize = PWM_BANK_SIZE; for (i = 0; i < NvRmPwmOutputId_Num-2; i++) { status = NvRmPhysicalMemMap( PwmPhysAddr + i*s_hPwm->PwmBankSize, s_hPwm->PwmBankSize, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void**)&s_hPwm->VirtualAddress[i]); if (status != NvSuccess) { NvOsFree(s_hPwm); goto fail; } } // Get the pmc physical and virtual base address NvRmModuleGetBaseAddress(hDevice, NVRM_MODULE_ID(NvRmModuleID_Pmif, 0), &PmcPhysAddr, &(s_hPwm->PmcBankSize)); s_hPwm->PmcBankSize = PMC_BANK_SIZE; status = NvRmPhysicalMemMap( PmcPhysAddr, s_hPwm->PmcBankSize, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void**)&s_hPwm->VirtualAddress[NvRmPwmOutputId_Num-2]); if (status != NvSuccess) { NvOsFree(s_hPwm); goto fail; } caps[0].MajorVersion = 1; caps[0].MinorVersion = 0; caps[0].EcoLevel = 0; caps[0].Capability = &caps[0]; caps[1].MajorVersion = 1; caps[1].MinorVersion = 1; caps[1].EcoLevel = 0; caps[1].Capability = &caps[1]; caps[2].MajorVersion = 1; caps[2].MinorVersion = 2; caps[2].EcoLevel = 0; caps[2].Capability = &caps[2]; caps[3].MajorVersion = 2; caps[3].MinorVersion = 0; caps[3].EcoLevel = 0; caps[3].Capability = &caps[3]; NV_ASSERT_SUCCESS(NvRmModuleGetCapabilities( hDevice, NvRmModuleID_Pwm, caps, sizeof(caps)/sizeof(caps[0]), (void**)&pCap)); if ((pCap->MajorVersion > 1) || ((pCap->MajorVersion == 1) && (pCap->MinorVersion > 0))) s_IsFreqDividerSupported = NV_TRUE; s_hPwm->RefCount++; exit: *phPwm = s_hPwm; NvOsMutexUnlock(s_hPwmMutex); return NvSuccess; fail: NvOsMutexUnlock(s_hPwmMutex); return status; }
NvError NvDdkUsbPhyOpen( NvRmDeviceHandle hRm, NvU32 Instance, NvDdkUsbPhyHandle *hUsbPhy) { NvError e; NvU32 MaxInstances = 0; NvDdkUsbPhy *pUsbPhy = NULL; NvOsMutexHandle UsbPhyMutex = NULL; NvRmModuleInfo info[MAX_USB_INSTANCES]; NvU32 j; NV_ASSERT(hRm); NV_ASSERT(hUsbPhy); NV_ASSERT(Instance < MAX_USB_INSTANCES); NV_CHECK_ERROR(NvRmModuleGetModuleInfo( hRm, NvRmModuleID_Usb2Otg, &MaxInstances, NULL )); if (MaxInstances > MAX_USB_INSTANCES) { // Ceil "instances" to MAX_USB_INSTANCES MaxInstances = MAX_USB_INSTANCES; } NV_CHECK_ERROR(NvRmModuleGetModuleInfo( hRm, NvRmModuleID_Usb2Otg, &MaxInstances, info )); for (j = 0; j < MaxInstances; j++) { // Check whether the requested instance is present if(info[j].Instance == Instance) break; } // No match found return if (j == MaxInstances) { return NvError_ModuleNotPresent; } if (!s_UsbPhyMutex) { e = NvOsMutexCreate(&UsbPhyMutex); if (e!=NvSuccess) return e; if (NvOsAtomicCompareExchange32( (NvS32*)&s_UsbPhyMutex, 0, (NvS32)UsbPhyMutex)!=0) { NvOsMutexDestroy(UsbPhyMutex); } } NvOsMutexLock(s_UsbPhyMutex); if (!s_pUsbPhy) { s_pUsbPhy = NvOsAlloc(MaxInstances * sizeof(NvDdkUsbPhy)); if (s_pUsbPhy) NvOsMemset(s_pUsbPhy, 0, MaxInstances * sizeof(NvDdkUsbPhy)); } NvOsMutexUnlock(s_UsbPhyMutex); if (!s_pUsbPhy) return NvError_InsufficientMemory; NvOsMutexLock(s_UsbPhyMutex); if (!s_pUtmiPadConfig) { s_pUtmiPadConfig = NvOsAlloc(sizeof(NvDdkUsbPhyUtmiPadConfig)); if (s_pUtmiPadConfig) { NvRmPhysAddr PhyAddr; NvOsMemset(s_pUtmiPadConfig, 0, sizeof(NvDdkUsbPhyUtmiPadConfig)); NvRmModuleGetBaseAddress( hRm, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, 0), &PhyAddr, &s_pUtmiPadConfig->BankSize); NV_CHECK_ERROR_CLEANUP( NvRmPhysicalMemMap( PhyAddr, s_pUtmiPadConfig->BankSize, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&s_pUtmiPadConfig->pVirAdr)); } } NvOsMutexUnlock(s_UsbPhyMutex); if (!s_pUtmiPadConfig) return NvError_InsufficientMemory; pUsbPhy = &s_pUsbPhy[Instance]; NvOsMutexLock(s_UsbPhyMutex); if (!pUsbPhy->RefCount) { NvRmPhysAddr PhysAddr; NvOsMutexHandle ThreadSafetyMutex = NULL; NvOsMemset(pUsbPhy, 0, sizeof(NvDdkUsbPhy)); pUsbPhy->Instance = Instance; pUsbPhy->hRmDevice = hRm; pUsbPhy->RefCount = 1; pUsbPhy->IsPhyPoweredUp = NV_FALSE; pUsbPhy->pUtmiPadConfig = s_pUtmiPadConfig; pUsbPhy->pProperty = NvOdmQueryGetUsbProperty( NvOdmIoModule_Usb, pUsbPhy->Instance); pUsbPhy->TurnOffPowerRail = UsbPhyTurnOffPowerRail(MaxInstances); NV_CHECK_ERROR_CLEANUP(NvOsMutexCreate(&ThreadSafetyMutex)); if (NvOsAtomicCompareExchange32( (NvS32*)&pUsbPhy->ThreadSafetyMutex, 0, (NvS32)ThreadSafetyMutex)!=0) { NvOsMutexDestroy(ThreadSafetyMutex); } NvRmModuleGetBaseAddress( pUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, pUsbPhy->Instance), &PhysAddr, &pUsbPhy->UsbBankSize); NV_CHECK_ERROR_CLEANUP( NvRmPhysicalMemMap( PhysAddr, pUsbPhy->UsbBankSize, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&pUsbPhy->UsbVirAdr)); NvRmModuleGetBaseAddress( pUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Misc, 0), &PhysAddr, &pUsbPhy->MiscBankSize); NV_CHECK_ERROR_CLEANUP( NvRmPhysicalMemMap( PhysAddr, pUsbPhy->MiscBankSize, NVOS_MEM_READ_WRITE, NvOsMemAttribute_Uncached, (void **)&pUsbPhy->MiscVirAdr)); if ( ( pUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiNullPhy) || ( pUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiExternalPhy)) { if (NvRmSetModuleTristate( pUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, pUsbPhy->Instance), NV_FALSE) != NvSuccess ) return NvError_NotSupported; } // Register with Power Manager NV_CHECK_ERROR_CLEANUP( NvOsSemaphoreCreate(&pUsbPhy->hPwrEventSem, 0)); pUsbPhy->RmPowerClientId = NVRM_POWER_CLIENT_TAG('U','S','B','p'); NV_CHECK_ERROR_CLEANUP( NvRmPowerRegister(pUsbPhy->hRmDevice, pUsbPhy->hPwrEventSem, &pUsbPhy->RmPowerClientId)); // Open the H/W interface UsbPhyOpenHwInterface(pUsbPhy); // Initialize the USB Phy NV_CHECK_ERROR_CLEANUP(UsbPhyInitialize(pUsbPhy)); } else { pUsbPhy->RefCount++; } *hUsbPhy = pUsbPhy; NvOsMutexUnlock(s_UsbPhyMutex); return NvSuccess; fail: NvDdkUsbPhyClose(pUsbPhy); NvOsMutexUnlock(s_UsbPhyMutex); return e; }