NvU32 NvRmPrivAp20GetExternalClockSourceFreq( NvRmDeviceHandle hDevice, struct tegra_pingroup_config *pin_config, int len) { NvU32 ClockFreqInKHz = 0; if (len != 1) return 0; switch(pin_config[0].pingroup) { case TEGRA_PINGROUP_CDEV1: if (pin_config[0].func == TEGRA_MUX_PLLA_OUT) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllA0); else if (pin_config[0].func == TEGRA_MUX_OSC) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_ClkM); break; case TEGRA_PINGROUP_CDEV2: if (pin_config[0].func == TEGRA_MUX_AHB_CLK) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_Ahb); else if (pin_config[0].func == TEGRA_MUX_OSC) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_ClkM); else if (pin_config[0].func == TEGRA_MUX_PLLP_OUT4) ClockFreqInKHz = NvRmPrivGetClockSourceFreq(NvRmClockSource_PllP4); break; case TEGRA_PINGROUP_CSUS: if (pin_config[0].func == TEGRA_MUX_VI_SENSOR_CLK) { if (NvRmPowerModuleClockConfig(hDevice, NvRmModuleID_Vi, 0, 0, 0, NULL, 0, &ClockFreqInKHz, NvRmClockConfig_SubConfig) != NvSuccess) { ClockFreqInKHz = 0; } } break; default: ClockFreqInKHz = 0; break; } return ClockFreqInKHz; }
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 {
static NvError UsbPhyInitialize( NvDdkUsbPhyHandle hUsbPhy) { NvError e = NvSuccess; NvRmFreqKHz CurrentFreq = 0; NvRmFreqKHz PrefFreqList[3] = {12000, 60000, NvRmFreqUnspecified}; // NvOsDebugPrintf("UsbPhyInitialize::VOLTAGE ON, instance %d\n", // hUsbPhy->Instance); // request power NV_CHECK_ERROR_CLEANUP( NvRmPowerVoltageControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NvRmVoltsUnspecified, NvRmVoltsUnspecified, NULL, 0, NULL)); // Enable clock to the USB controller and Phy NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NV_TRUE)); if (!hUsbPhy->Caps.PhyRegInController) { if (hUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiNullPhy) { /* Request for 60MHz clk */ NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockConfig(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, PrefFreqList[1], PrefFreqList[1], &PrefFreqList[1], 1, &CurrentFreq, 0)); } else { /* Request for 12 MHz clk */ NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockConfig(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, PrefFreqList[0], PrefFreqList[0], &PrefFreqList[0], 1, &CurrentFreq, 0)); } } // else { /* No need for actual clock configuration - all USB PLL frequencies are available concurrently in this case. */ } // Reset controller NvRmModuleReset(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance)); // On AP20 H-CLK should not be turned off // This is required to detect the sensor interrupts. // However, phy can be programmed to put in the low power mode if (!hUsbPhy->Caps.PhyRegInController) { // Disable the clock NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NV_FALSE)); } // Disable power NV_CHECK_ERROR_CLEANUP( NvRmPowerVoltageControl(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NvRmVoltsOff, NvRmVoltsOff, NULL, 0, NULL)); // if we are not turning off the power rail during power up and down // then turn on only once during the initalization. if (!hUsbPhy->TurnOffPowerRail) { NvOdmEnableUsbPhyPowerRail(NV_TRUE); } fail: return e; }
static NvError UsbPhyDfsBusyHint( NvDdkUsbPhyHandle hUsbPhy, NvBool DfsOn, NvU32 BoostDurationMs) { NvRmDfsBusyHint pUsbHintOn[] = { { NvRmDfsClockId_Emc, NV_WAIT_INFINITE, USB_HW_MIN_SYSTEM_FREQ_KH, NV_TRUE }, { NvRmDfsClockId_Ahb, NV_WAIT_INFINITE, USB_HW_MIN_SYSTEM_FREQ_KH, NV_TRUE }, { NvRmDfsClockId_Cpu, NV_WAIT_INFINITE, USB_HW_MIN_CPU_FREQ_KH, NV_TRUE } }; NvRmDfsBusyHint pUsbHintOff[] = { { NvRmDfsClockId_Emc, 0, 0, NV_TRUE }, { NvRmDfsClockId_Ahb, 0, 0, NV_TRUE }, { NvRmDfsClockId_Cpu, 0, 0, NV_TRUE } }; NvError e = NvSuccess; NvU32 NumHints; if (hUsbPhy->IsHostMode) { // Do not enable busy hints for cpu clock in host mode NumHints = NV_ARRAY_SIZE(pUsbHintOn) - 1; } else { NumHints = NV_ARRAY_SIZE(pUsbHintOn); } pUsbHintOn[0].BoostDurationMs = BoostDurationMs; pUsbHintOn[1].BoostDurationMs = BoostDurationMs; pUsbHintOn[2].BoostDurationMs = BoostDurationMs; if (DfsOn) { if (hUsbPhy->Caps.PhyRegInController) { // Indicate USB controller is active NvRmFreqKHz PrefFreq = NvRmPowerModuleGetMaxFrequency( hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance)); NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockConfig(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, PrefFreq, PrefFreq, &PrefFreq, 1, NULL, 0)); } return NvRmPowerBusyHintMulti(hUsbPhy->hRmDevice, hUsbPhy->RmPowerClientId, pUsbHintOn, NumHints, NvRmDfsBusyHintSyncMode_Async); } else { if (hUsbPhy->Caps.PhyRegInController) { // Indicate USB controller is idle NvRmFreqKHz PrefFreq = USBC_IDLE_KHZ; NV_CHECK_ERROR_CLEANUP( NvRmPowerModuleClockConfig(hUsbPhy->hRmDevice, NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, PrefFreq, PrefFreq, &PrefFreq, 1, NULL, 0)); } return NvRmPowerBusyHintMulti(hUsbPhy->hRmDevice, hUsbPhy->RmPowerClientId, pUsbHintOff, NumHints, NvRmDfsBusyHintSyncMode_Async); } fail: return e; }