summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGerrit Code Review <gerrit2@git-master.nvidia.com>2010-01-23 01:30:17 +0200
committerGerrit Code Review <gerrit2@git-master.nvidia.com>2010-01-23 01:30:17 +0200
commitf3f5d5d4ede2e5a295e4016e6fd40aff9653e674 (patch)
tree4d4776a8360b446c741492b6dd730d84a6fda03d /arch
parent8aeb9598c52279d0127d8e567df2f2bdff6fc15e (diff)
parent35c12140b5de4640d10625668f5b2e799d019518 (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.c75
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_clock_config.c3
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c14
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;