コード例 #1
0
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;
}
コード例 #2
0
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
    {
コード例 #3
0
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;
}
コード例 #4
0
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;
}