diff options
author | Gerrit Code Review <gerrit2@git-master.nvidia.com> | 2010-01-23 01:30:17 +0200 |
---|---|---|
committer | Gerrit Code Review <gerrit2@git-master.nvidia.com> | 2010-01-23 01:30:17 +0200 |
commit | f3f5d5d4ede2e5a295e4016e6fd40aff9653e674 (patch) | |
tree | 4d4776a8360b446c741492b6dd730d84a6fda03d /arch | |
parent | 8aeb9598c52279d0127d8e567df2f2bdff6fc15e (diff) | |
parent | 35c12140b5de4640d10625668f5b2e799d019518 (diff) |
Merge change Iee701f8e into android-tegra-2.6.29
* changes:
tegra: Added low voltage USB PHy clock configuration.
Diffstat (limited to 'arch')
-rw-r--r--[-rwxr-xr-x] | arch/arm/mach-tegra/nvddk/nvddk_usbphy.c | 75 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c | 14 |
3 files changed, 70 insertions, 22 deletions
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c b/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c index fe3c3252d39f..435ff7dcc54c 100755..100644 --- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c +++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c @@ -47,6 +47,10 @@ #define MAX_USB_INSTANCES 5 +// On platforms that never disable USB controller clock, use 1KHz as an +// indicator that USB controller is idle, and core voltage can be scaled down +#define USBC_IDLE_KHZ (1) + static NvDdkUsbPhy *s_pUsbPhy = NULL; static NvDdkUsbPhyUtmiPadConfig *s_pUtmiPadConfig = NULL; @@ -247,22 +251,54 @@ UsbPhyDfsBusyHint( { NvRmDfsClockId_Emc, 0, 0, NV_TRUE }, { NvRmDfsClockId_Ahb, 0, 0, NV_TRUE } }; + NvError e = NvSuccess; pUsbHintOn[0].BoostDurationMs = BoostDurationMs; pUsbHintOn[1].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, NV_ARRAY_SIZE(pUsbHintOn), 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, NV_ARRAY_SIZE(pUsbHintOff), NvRmDfsBusyHintSyncMode_Async); + } + +fail: + return e; } @@ -274,7 +310,8 @@ UsbPhyInitialize( NvRmFreqKHz CurrentFreq = 0; NvRmFreqKHz PrefFreqList[3] = {12000, 60000, NvRmFreqUnspecified}; - //NvOsDebugPrintf("UsbPhyInitialize::VOLTAGE ON\n"); + // NvOsDebugPrintf("UsbPhyInitialize::VOLTAGE ON, instance %d\n", + // hUsbPhy->Instance); // request power NV_CHECK_ERROR_CLEANUP( NvRmPowerVoltageControl(hUsbPhy->hRmDevice, @@ -288,23 +325,31 @@ UsbPhyInitialize( NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance), hUsbPhy->RmPowerClientId, NV_TRUE)); - if (hUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiNullPhy) + if (!hUsbPhy->Caps.PhyRegInController) { - /* 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)); + 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 + // 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)); + /* No need for actual clock configuration - all USB PLL frequencies + are available concurrently in this case. */ } // Reset controller diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c index 198a2b20ce3d..70138eae4d7c 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c +++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c @@ -1279,7 +1279,8 @@ NvRmPrivAp15IsModuleClockException( Ap15PllUConfigure(hRmDevice, PrefFreqList[0]); pCstate->SourceClock = 0; pCstate->Divider = 1; - pCstate->actual_freq = PrefFreqList[0]; + pCstate->actual_freq = + NvRmPrivGetClockSourceFreq(pCinfo->Sources[0]); return NV_TRUE; default: diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c index 87775f87a4db..8ae5c9dfba72 100644 --- a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c +++ b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c @@ -1471,9 +1471,9 @@ NvRmPowerModuleClockConfig ( // Display configuration always at nominal voltage. UART divider is not // in CAR, and clock state contains source, rather than UART frequency. - // Hence, get ready for fastest clock. For other modules use maximum of - // target and current frequency. Make sure voltage is high enough for - // maximum module source frequency. + // Hence, get ready for fastest clock. Same for USB clock. For other + // modules use maximum of target and current frequency. Make sure that + // voltage is high enough for maximum module source frequency. if ((ModuleName == NvRmModuleID_Display) || (ModuleName == NvRmModuleID_Dsi)) { @@ -1482,7 +1482,8 @@ NvRmPowerModuleClockConfig ( } else { - if (ModuleName == NvRmModuleID_Uart) + if ((ModuleName == NvRmModuleID_Uart) || + (ModuleName == NvRmModuleID_Usb2Otg)) f = NvRmFreqMaximum; else f = NV_MAX(MaxFreq, state->actual_freq); @@ -1664,7 +1665,7 @@ leave: (ModuleName == NvRmModuleID_Dsi) || state->Vscale)) { // Tune voltage level to the actually configured frequency; for Display - // and UART, use maximum requested frequency. Make sure voltage is + // UART, and USB use maximum requested frequency. Make sure voltage is // updated after display configuration, which may change DVFS clocks. SourceClockFreq = s_ClockSourceFreq[(cinfo->Sources[state->SourceClock])]; @@ -1685,7 +1686,8 @@ leave: } else { - if (ModuleName == NvRmModuleID_Uart) + if ((ModuleName == NvRmModuleID_Uart) || + (ModuleName == NvRmModuleID_Usb2Otg)) f = MaxFreq; else f = state->actual_freq; |