void NvRmPwmClose(NvRmPwmHandle hPwm) { NvU32 i; if (!hPwm) return; NV_ASSERT(hPwm->RefCount); NvOsMutexLock(s_hPwmMutex); hPwm->RefCount--; if (hPwm->RefCount == 0) { // Unmap the pwm register virtual address space for (i = 0; i < NvRmPwmOutputId_Num-2; i++) { NvRmPhysicalMemUnmap((void*)s_hPwm->VirtualAddress[i], s_hPwm->PwmBankSize); } // Unmap the pmc register virtual address space NvRmPhysicalMemUnmap( (void*)s_hPwm->VirtualAddress[NvRmPwmOutputId_Num-2], s_hPwm->PmcBankSize); if (s_IsPwmFirstConfig) { // Disable power PwmPowerConfigure(hPwm, NV_FALSE); // Unregister with RM power NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); // Tri-state the pin-mux pins NV_ASSERT_SUCCESS(NvRmSetModuleTristate(hPwm->RmDeviceHandle, NVRM_MODULE_ID(NvRmModuleID_Pwm, 0), NV_TRUE)); s_IsPwmFirstConfig = NV_FALSE; } NvOsFree(s_hPwm); s_hPwm = NULL; } NvOsMutexUnlock(s_hPwmMutex); }
NvError NvRmPwmConfig( NvRmPwmHandle hPwm, NvRmPwmOutputId OutputId, NvRmPwmMode Mode, NvU32 DutyCycle, NvU32 RequestedFreqHzOrPeriod, NvU32 *pCurrentFreqHzOrPeriod) { NvError status = NvSuccess; NvU32 RegValue = 0, ResultFreqKHz = 0; NvU8 PwmMode = 0; NvU32 ClockFreqKHz = 0, DCycle = 0, DataOn = 0, DataOff = 0; NvU32 PmcCtrlReg = 0, PmcDpdPadsReg = 0, PmcBlinkTimerReg = 0; NvU32 RequestPeriod = 0, ResultPeriod = 0; NvU32 DataOnRegVal = 0, DataOffRegVal = 0; NvU32 *pPinMuxConfigTable = NULL; NvU32 Count = 0, divider = 1; NvOsMutexLock(s_hPwmMutex); if (OutputId != NvRmPwmOutputId_Blink) { if (!s_IsPwmFirstConfig) { hPwm->PowerEnabled = NV_FALSE; // Register with RM power s_PwmPowerID = NVRM_POWER_CLIENT_TAG('P','W','M',' '); status = NvRmPowerRegister(hPwm->RmDeviceHandle, NULL, &s_PwmPowerID); if (status != NvSuccess) goto fail; // Enable power status = PwmPowerConfigure(hPwm, NV_TRUE); if (status != NvSuccess) { NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); goto fail; } // Reset pwm module NvRmModuleReset(hPwm->RmDeviceHandle, NVRM_MODULE_ID(NvRmModuleID_Pwm, 0)); // Config pwm pinmux NvOdmQueryPinMux(NvOdmIoModule_Pwm, (const NvU32 **)&pPinMuxConfigTable, &Count); if (Count != 1) { status = NvError_NotSupported; PwmPowerConfigure(hPwm, NV_FALSE); NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); goto fail; } hPwm->PinMap = pPinMuxConfigTable[0]; status = NvRmSetModuleTristate(hPwm->RmDeviceHandle, NVRM_MODULE_ID(NvRmModuleID_Pwm, 0), NV_FALSE); if (status != NvSuccess) { PwmPowerConfigure(hPwm, NV_FALSE); NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); goto fail; } s_IsPwmFirstConfig = NV_TRUE; } // Enable power status = PwmPowerConfigure(hPwm, NV_TRUE); if (status != NvSuccess) { NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); goto fail; } // Validate PWM output and pin map config status = PwmCheckValidConfig(hPwm, OutputId, Mode); if (status != NvSuccess) goto fail; ClockFreqKHz = (RequestedFreqHzOrPeriod * PWM_FREQ_FACTOR) / 1000; if (ClockFreqKHz == 0) ClockFreqKHz = 1; if (RequestedFreqHzOrPeriod == NvRmFreqMaximum) ClockFreqKHz = NvRmFreqMaximum; status = NvRmPowerModuleClockConfig(hPwm->RmDeviceHandle, NVRM_MODULE_ID(NvRmModuleID_Pwm, 0), s_PwmPowerID, NvRmFreqUnspecified, NvRmFreqUnspecified, &ClockFreqKHz, 1, &ResultFreqKHz, 0); if (status != NvSuccess) goto fail; *pCurrentFreqHzOrPeriod = (ResultFreqKHz * 1000) / PWM_FREQ_FACTOR; if (Mode == NvRmPwmMode_Disable) PwmMode = 0; else PwmMode = 1; /* * Convert from percentage unsigned 15.16 fixed point * format to actual register value */ DCycle = (DutyCycle * MAX_DUTY_CYCLE/100)>>16; if (DCycle > MAX_DUTY_CYCLE) DCycle = MAX_DUTY_CYCLE; RegValue = PWM_SETNUM(CSR_0, ENB, PwmMode) | PWM_SETNUM(CSR_0, PWM_0, DCycle); if (s_IsFreqDividerSupported) { if ((*pCurrentFreqHzOrPeriod > RequestedFreqHzOrPeriod) && (RequestedFreqHzOrPeriod != 0)) { divider = *pCurrentFreqHzOrPeriod/RequestedFreqHzOrPeriod; if ((*pCurrentFreqHzOrPeriod%RequestedFreqHzOrPeriod)*2>RequestedFreqHzOrPeriod) divider +=1; *pCurrentFreqHzOrPeriod = *pCurrentFreqHzOrPeriod / divider; RegValue |= PWM_SETNUM(CSR_0, PFM_0, divider); } } PWM_REGW(hPwm->VirtualAddress[OutputId-1], 0, RegValue); // If PWM mode is disabled and all pwd channels are disabled then // disable power to PWM if (!PwmMode) { if (IsPwmDisabled(hPwm)) { // Disable power status = PwmPowerConfigure(hPwm, NV_FALSE); if (status != NvSuccess) { NvRmPowerUnRegister(hPwm->RmDeviceHandle, s_PwmPowerID); goto fail; } } } } else {
void NvDdkUsbPhyClose( NvDdkUsbPhyHandle hUsbPhy) { if (!hUsbPhy) return; NvOsMutexLock(s_UsbPhyMutex); if (!hUsbPhy->RefCount) { NvOsMutexUnlock(s_UsbPhyMutex); return; } --hUsbPhy->RefCount; if (hUsbPhy->RefCount) { NvOsMutexUnlock(s_UsbPhyMutex); return; } NvRmSetModuleTristate( hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), NV_TRUE); NvOsMutexLock(hUsbPhy->ThreadSafetyMutex); if (hUsbPhy->RmPowerClientId) { if (hUsbPhy->IsPhyPoweredUp) { NV_ASSERT_SUCCESS( NvRmPowerModuleClockControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NV_FALSE)); //NvOsDebugPrintf("NvDdkUsbPhyClose::VOLTAGE OFF\n"); NV_ASSERT_SUCCESS( NvRmPowerVoltageControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NvRmVoltsOff, NvRmVoltsOff, NULL, 0, NULL)); hUsbPhy->IsPhyPoweredUp = NV_FALSE; } // Unregister driver from Power Manager NvRmPowerUnRegister(hUsbPhy->hRmDevice, hUsbPhy->RmPowerClientId); NvOsSemaphoreDestroy(hUsbPhy->hPwrEventSem); } NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex); NvOsMutexDestroy(hUsbPhy->ThreadSafetyMutex); if (hUsbPhy->CloseHwInterface) { hUsbPhy->CloseHwInterface(hUsbPhy); } if ((hUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Host) || (hUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_OTG)) { UsbPrivEnableVbus(hUsbPhy, NV_FALSE); } NvOdmEnableUsbPhyPowerRail(NV_FALSE); NvRmPhysicalMemUnmap( (void*)hUsbPhy->UsbVirAdr, hUsbPhy->UsbBankSize); NvRmPhysicalMemUnmap( (void*)hUsbPhy->MiscVirAdr, hUsbPhy->MiscBankSize); NvOsMemset(hUsbPhy, 0, sizeof(NvDdkUsbPhy)); NvOsMutexUnlock(s_UsbPhyMutex); }