summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorVenkat Moganty <vmoganty@nvidia.com>2010-04-29 20:44:29 +0530
committerYu-Huan Hsu <yhsu@nvidia.com>2010-05-02 17:58:43 -0700
commit1b8406f6f9556f8d205ebf01035350e587c11764 (patch)
tree4086f6d63860feb729938e6e44d79973981e632c /arch
parent7eb7a42ddadfe5dbcb529e7d0e908dbb0c1c2b18 (diff)
tegra usb:Modifications to usb power up/down sequence
Removed helper thread and replaced it with Worker Queues in udc and ehci drivers to handle usbphy power up/down sequence. Made changes to turn off usb power rail based on vbus detection mechanism is selected as PMU. Fixed usb host LP0 exit sequence. Bug 667912: AVDD_USB_Power is consuming 3.82mW of power in OSIdle and ULP audio playback case. Change-Id: I3a77d0ecb4f0b81dafe705100451c42641f0bfb9 Reviewed-on: http://git-master/r/1221 Tested-by: Hanumanth Venkateswa Moganty <vmoganty@nvidia.com> Tested-by: Dara Ramesh <dramesh@nvidia.com> Reviewed-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Tested-by: Seshendra Gadagottu <sgadagottu@nvidia.com> Reviewed-by: Narendra Damahe <ndamahe@nvidia.com> Tested-by: Narendra Damahe <ndamahe@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/include/nvodm_services.h7
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_usbphy.c298
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_usbphy_priv.h10
-rwxr-xr-xarch/arm/mach-tegra/nvodm/nvodm_services.c83
4 files changed, 229 insertions, 169 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_services.h b/arch/arm/mach-tegra/include/nvodm_services.h
index 904821ca8049..53b4fa5eecd7 100644
--- a/arch/arm/mach-tegra/include/nvodm_services.h
+++ b/arch/arm/mach-tegra/include/nvodm_services.h
@@ -1684,6 +1684,13 @@ NvBool NvOdmUsbIsConnected(void);
*/
NvOdmUsbChargerType NvOdmUsbChargingType(NvU32 Instance);
+/**
+ * Enables/Disables the USB power rail.
+ *
+ * @param Enable NV_TRUE to enable, or NV_FALSE to disable.
+ */
+void NvOdmEnableUsbPhyPowerRail(NvBool Enable);
+
#if defined(__cplusplus)
}
#endif
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c b/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c
index 05827683bfce..7f15b34f6b9c 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c
+++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy.c
@@ -44,6 +44,7 @@
#include "nvrm_pmu.h"
#include "nvrm_hardware_access.h"
#include "nvddk_usbphy_priv.h"
+#include "nvodm_services.h"
#define MAX_USB_INSTANCES 5
@@ -53,31 +54,8 @@
static NvDdkUsbPhy *s_pUsbPhy = NULL;
static NvDdkUsbPhyUtmiPadConfig *s_pUtmiPadConfig = NULL;
+static NvOsMutexHandle s_UsbPhyMutex = NULL;
-static NvBool
-UsbPhyDiscover(
- NvDdkUsbPhy *pUsbPhy)
-{
- NvU64 guid = NV_VDD_USB_ODM_ID;
- NvOdmPeripheralConnectivity const *pConnectivity;
-
- if( pUsbPhy->pConnectivity )
- {
- return NV_TRUE;
- }
-
- /* get the connectivity info */
- pConnectivity = NvOdmPeripheralGetGuid( guid );
- if( !pConnectivity )
- {
- return NV_FALSE;
- }
-
- pUsbPhy->Guid = guid;
- pUsbPhy->pConnectivity = pConnectivity;
-
- return NV_TRUE;
-}
static void UsbPrivEnableVbus(NvDdkUsbPhy *pUsbPhy, NvBool Enable)
{
@@ -125,62 +103,42 @@ static void UsbPrivEnableVbus(NvDdkUsbPhy *pUsbPhy, NvBool Enable)
}
}
-static void
-UsbPhyPowerRailEnable(
- NvDdkUsbPhy *pUsbPhy,
- NvBool Enable)
+static NvBool UsbPhyTurnOffPowerRail(NvU32 MaxInstances)
{
- NvU32 i;
- NvOdmPeripheralConnectivity const *pConnectivity;
- NvU32 settle_time_us;
+ NvBool TurnOff = NV_FALSE;
+ NvU32 instance = 0;
+ const NvOdmUsbProperty *pProperty = NULL;
- /* get the peripheral config */
- if( !UsbPhyDiscover( pUsbPhy ) )
+ for (instance = 0; instance < MaxInstances; instance++)
{
- // Do nothing if no power rail info is discovered
- return;
- }
-
- /* enable the power rail */
- pConnectivity = pUsbPhy->pConnectivity;
+ pProperty = NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, instance);
- if (Enable)
- {
- for( i = 0; i < pConnectivity->NumAddress; i++ )
+ if (pProperty)
{
- if( pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd )
+ if (pProperty->UsbMode == NvOdmUsbModeType_None)
{
- NvRmPmuVddRailCapabilities cap;
-
- /* address is the vdd rail id */
- NvRmPmuGetCapabilities(
- pUsbPhy->hRmDevice,
- pConnectivity->AddressList[i].Address, &cap );
-
- /* set the rail volatage to the recommended */
- NvRmPmuSetVoltage(
- pUsbPhy->hRmDevice, pConnectivity->AddressList[i].Address,
- cap.requestMilliVolts, &settle_time_us );
-
- /* wait for the rail to settle */
- NvOsWaitUS( settle_time_us );
+ continue;
}
- }
- }
- else
- {
- for( i = 0; i < pConnectivity->NumAddress; i++ )
- {
- if( pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd )
+ else if (((pProperty->UsbMode == NvOdmUsbModeType_Device) ||
+ (pProperty->UsbMode == NvOdmUsbModeType_OTG)) &&
+ (!pProperty->UseInternalPhyWakeup))
+ {
+ TurnOff = NV_TRUE;
+ }
+ else if (((pProperty->UsbMode == NvOdmUsbModeType_Host) &&
+ (pProperty->IdPinDetectionType == NvOdmUsbIdPinType_CableId)) &&
+ (!pProperty->UseInternalPhyWakeup))
{
- /* set the rail volatage to the recommended */
- NvRmPmuSetVoltage(
- pUsbPhy->hRmDevice, pConnectivity->AddressList[i].Address,
- ODM_VOLTAGE_OFF, 0 );
+ TurnOff = NV_TRUE;
+ }
+ else
+ {
+ TurnOff = NV_FALSE;
}
}
}
+ return TurnOff;
}
@@ -370,10 +328,32 @@ UsbPhyInitialize(
NvRmModuleReset(hUsbPhy->hRmDevice,
NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance));
- // Power Up the USB Phy
- NV_CHECK_ERROR_CLEANUP(hUsbPhy->PowerUp(hUsbPhy));
- hUsbPhy->IsPhyPoweredUp = NV_TRUE;
+ // 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:
@@ -395,42 +375,6 @@ UsbPhyIoctlUsbBisuHintsOnOff(
return UsbPhyDfsBusyHint(pUsbPhy, pOnOff->OnOff, pOnOff->BoostDurationMs);
}
-/*
- * NvDdkUsbPhyHelperThread() - Thread to control the Busy hints and Vbus.
- *
- * Busy hints and Vbus are controlled based on the USB cable connection status.
- * USB cable status change(connect/disconnect) is identified in the ISR.
- * Busy hints function cannot be called from ISR as NvRmPowerBusyHintMulti()
- * uses vfree and vmalloc functions which are not supposed to call from the
- * ISR context. This helper thread is signaled from the ISR by calling Phy
- * suspend/resume APIs to control the busy hints and VBUS.
- */
-static void
-NvDdkUsbPhyHelperThread(
- void* pArgs)
-{
- NvDdkUsbPhyHandle hUsbPhy = (NvDdkUsbPhyHandle)pArgs;
-
- hUsbPhy->Stopped = NV_FALSE;
-
- while (!hUsbPhy->Stopped)
- {
- /* wait for the signal to turn on/off the busy hints and vbus */
- NvOsSemaphoreWaitTimeout(hUsbPhy->HelperThreadSema, NV_WAIT_INFINITE);
-
- if (!(hUsbPhy->IsPhyPoweredUp && hUsbPhy->IsHostMode))
- {
- /* Turn on/off the USB busy hints */
- UsbPhyDfsBusyHint(hUsbPhy, hUsbPhy->IsPhyPoweredUp, NV_WAIT_INFINITE);
- }
- /* Turn on/off the vbus for host mode */
- if (hUsbPhy->IsHostMode)
- {
- UsbPrivEnableVbus(hUsbPhy, hUsbPhy->IsPhyPoweredUp);
- }
- }
-}
-
NvError
NvDdkUsbPhyOpen(
NvRmDeviceHandle hRm,
@@ -440,6 +384,7 @@ NvDdkUsbPhyOpen(
NvError e;
NvU32 MaxInstances = 0;
NvDdkUsbPhy *pUsbPhy = NULL;
+ NvOsMutexHandle UsbPhyMutex = NULL;
NvRmModuleInfo info[MAX_USB_INSTANCES];
NvU32 j;
@@ -466,15 +411,32 @@ NvDdkUsbPhyOpen(
return NvError_ModuleNotPresent;
}
+ if (!s_UsbPhyMutex)
+ {
+ e = NvOsMutexCreate(&UsbPhyMutex);
+ if (e!=NvSuccess)
+ return e;
+
+ if (NvOsAtomicCompareExchange32(
+ (NvS32*)&s_UsbPhyMutex, 0, (NvS32)UsbPhyMutex)!=0)
+ {
+ NvOsMutexDestroy(UsbPhyMutex);
+ }
+ }
+
+ NvOsMutexLock(s_UsbPhyMutex);
if (!s_pUsbPhy)
{
s_pUsbPhy = NvOsAlloc(MaxInstances * sizeof(NvDdkUsbPhy));
if (s_pUsbPhy)
NvOsMemset(s_pUsbPhy, 0, MaxInstances * sizeof(NvDdkUsbPhy));
- else
- return NvError_InsufficientMemory;
}
+ NvOsMutexUnlock(s_UsbPhyMutex);
+
+ if (!s_pUsbPhy)
+ return NvError_InsufficientMemory;
+ NvOsMutexLock(s_UsbPhyMutex);
if (!s_pUtmiPadConfig)
{
s_pUtmiPadConfig = NvOsAlloc(sizeof(NvDdkUsbPhyUtmiPadConfig));
@@ -493,17 +455,19 @@ NvDdkUsbPhyOpen(
PhyAddr, s_pUtmiPadConfig->BankSize, NVOS_MEM_READ_WRITE,
NvOsMemAttribute_Uncached, (void **)&s_pUtmiPadConfig->pVirAdr));
}
- else
- {
- return NvError_InsufficientMemory;
- }
}
+ NvOsMutexUnlock(s_UsbPhyMutex);
+
+ if (!s_pUtmiPadConfig)
+ return NvError_InsufficientMemory;
pUsbPhy = &s_pUsbPhy[Instance];
+ NvOsMutexLock(s_UsbPhyMutex);
if (!pUsbPhy->RefCount)
{
NvRmPhysAddr PhysAddr;
+ NvOsMutexHandle ThreadSafetyMutex = NULL;
NvOsMemset(pUsbPhy, 0, sizeof(NvDdkUsbPhy));
pUsbPhy->Instance = Instance;
@@ -513,6 +477,15 @@ NvDdkUsbPhyOpen(
pUsbPhy->pUtmiPadConfig = s_pUtmiPadConfig;
pUsbPhy->pProperty = NvOdmQueryGetUsbProperty(
NvOdmIoModule_Usb, pUsbPhy->Instance);
+ pUsbPhy->TurnOffPowerRail = UsbPhyTurnOffPowerRail(MaxInstances);
+
+ NV_CHECK_ERROR_CLEANUP(NvOsMutexCreate(&ThreadSafetyMutex));
+ if (NvOsAtomicCompareExchange32(
+ (NvS32*)&pUsbPhy->ThreadSafetyMutex, 0,
+ (NvS32)ThreadSafetyMutex)!=0)
+ {
+ NvOsMutexDestroy(ThreadSafetyMutex);
+ }
NvRmModuleGetBaseAddress(
pUsbPhy->hRmDevice,
@@ -555,32 +528,9 @@ NvDdkUsbPhyOpen(
NvRmPowerRegister(pUsbPhy->hRmDevice,
pUsbPhy->hPwrEventSem, &pUsbPhy->RmPowerClientId));
- NV_CHECK_ERROR_CLEANUP(
- NvOsSemaphoreCreate(&pUsbPhy->HelperThreadSema, 0));
-
- NV_CHECK_ERROR_CLEANUP(
- NvOsThreadCreate(&NvDdkUsbPhyHelperThread,
- (void*)pUsbPhy, &pUsbPhy->hThreadId));
-
- if ((pUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Host) ||
- (pUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_OTG))
- {
- UsbPrivEnableVbus(pUsbPhy, NV_TRUE);
- }
-
- #if !NV_OAL
- UsbPhyPowerRailEnable(pUsbPhy, NV_TRUE);
- #endif
-
// Open the H/W interface
UsbPhyOpenHwInterface(pUsbPhy);
- /* Enable the busy hints for USB device mode, for host mode *
- * transaction based busy hints are on/off mechanism is present */
- if (pUsbPhy->pProperty->UsbMode != NvOdmUsbModeType_Host)
- {
- UsbPhyDfsBusyHint(pUsbPhy, NV_TRUE, NV_WAIT_INFINITE);
- }
// Initialize the USB Phy
NV_CHECK_ERROR_CLEANUP(UsbPhyInitialize(pUsbPhy));
}
@@ -590,13 +540,14 @@ NvDdkUsbPhyOpen(
}
*hUsbPhy = pUsbPhy;
+ NvOsMutexUnlock(s_UsbPhyMutex);
return NvSuccess;
fail:
NvDdkUsbPhyClose(pUsbPhy);
-
+ NvOsMutexUnlock(s_UsbPhyMutex);
return e;
}
@@ -608,13 +559,19 @@ NvDdkUsbPhyClose(
if (!hUsbPhy)
return;
+ NvOsMutexLock(s_UsbPhyMutex);
+
if (!hUsbPhy->RefCount)
+ {
+ NvOsMutexUnlock(s_UsbPhyMutex);
return;
+ }
--hUsbPhy->RefCount;
if (hUsbPhy->RefCount)
{
+ NvOsMutexUnlock(s_UsbPhyMutex);
return;
}
@@ -623,6 +580,7 @@ NvDdkUsbPhyClose(
NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance),
NV_TRUE);
+ NvOsMutexLock(hUsbPhy->ThreadSafetyMutex);
if (hUsbPhy->RmPowerClientId)
{
if (hUsbPhy->IsPhyPoweredUp)
@@ -646,6 +604,9 @@ NvDdkUsbPhyClose(
NvRmPowerUnRegister(hUsbPhy->hRmDevice, hUsbPhy->RmPowerClientId);
NvOsSemaphoreDestroy(hUsbPhy->hPwrEventSem);
}
+ NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex);
+
+ NvOsMutexDestroy(hUsbPhy->ThreadSafetyMutex);
if (hUsbPhy->CloseHwInterface)
{
@@ -658,11 +619,7 @@ NvDdkUsbPhyClose(
UsbPrivEnableVbus(hUsbPhy, NV_FALSE);
}
- UsbPhyPowerRailEnable(hUsbPhy, NV_FALSE);
-
- hUsbPhy->Stopped = NV_TRUE;
- NvOsThreadJoin(hUsbPhy->hThreadId);
- NvOsSemaphoreDestroy(hUsbPhy->HelperThreadSema);
+ NvOdmEnableUsbPhyPowerRail(NV_FALSE);
NvRmPhysicalMemUnmap(
(void*)hUsbPhy->UsbVirAdr, hUsbPhy->UsbBankSize);
@@ -671,6 +628,7 @@ NvDdkUsbPhyClose(
(void*)hUsbPhy->MiscVirAdr, hUsbPhy->MiscBankSize);
NvOsMemset(hUsbPhy, 0, sizeof(NvDdkUsbPhy));
+ NvOsMutexUnlock(s_UsbPhyMutex);
}
@@ -684,14 +642,16 @@ NvDdkUsbPhyPowerUp(
NV_ASSERT(hUsbPhy);
+ NvOsMutexLock(hUsbPhy->ThreadSafetyMutex);
if (hUsbPhy->IsPhyPoweredUp)
+ {
+ NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex);
return e;
+ }
- // On wake up from Deep power down mode turn on the rails based on odm query
- if (IsDpd)
+ if (hUsbPhy->TurnOffPowerRail)
{
- if (hUsbPhy->pProperty->UsbRailPoweOffInDeepSleep)
- UsbPhyPowerRailEnable(hUsbPhy, NV_TRUE);
+ NvOdmEnableUsbPhyPowerRail(NV_TRUE);
}
// Enable power for USB module
@@ -709,21 +669,30 @@ NvDdkUsbPhyPowerUp(
NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, hUsbPhy->Instance),
hUsbPhy->RmPowerClientId, NV_TRUE));
}
+
// Power up the Phy
NV_CHECK_ERROR_CLEANUP(hUsbPhy->PowerUp(hUsbPhy));
- hUsbPhy->IsPhyPoweredUp = NV_TRUE;
- hUsbPhy->IsHostMode = IsHostMode;
+
if (hUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Host)
{
hUsbPhy->RestoreContext(hUsbPhy);
}
- // signal to set the busy hints and vbus
- NvOsSemaphoreSignal(hUsbPhy->HelperThreadSema);
- //NvOsDebugPrintf("NvDdkUsbPhyPowerUp::VOLTAGE ON\n");
+ if (hUsbPhy->IsHostMode = IsHostMode)
+ {
+ UsbPrivEnableVbus(hUsbPhy, NV_TRUE);
+ }
+ else
+ {
+ /* Turn on the USB busy hints */
+ UsbPhyDfsBusyHint(hUsbPhy, NV_TRUE, NV_WAIT_INFINITE);
+ }
+ hUsbPhy->IsPhyPoweredUp = NV_TRUE;
+
fail:
+ NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex);
return e;
}
@@ -738,12 +707,23 @@ NvDdkUsbPhyPowerDown(
NV_ASSERT(hUsbPhy);
+ NvOsMutexLock(hUsbPhy->ThreadSafetyMutex);
if (!hUsbPhy->IsPhyPoweredUp)
+ {
+ NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex);
return e;
+ }
+
if (hUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Host)
{
hUsbPhy->SaveContext(hUsbPhy);
}
+
+ /* Turn on/off the vbus for host mode */
+ if (hUsbPhy->IsHostMode = IsHostMode)
+ {
+ UsbPrivEnableVbus(hUsbPhy, NV_FALSE);
+ }
// Power down the USB Phy
NV_CHECK_ERROR_CLEANUP(hUsbPhy->PowerDown(hUsbPhy));
@@ -766,21 +746,20 @@ NvDdkUsbPhyPowerDown(
hUsbPhy->RmPowerClientId, NvRmVoltsOff, NvRmVoltsOff,
NULL, 0, NULL));
- // In Deep power down mode turn off the rails based on odm query
- if (IsDpd)
+ /* Turn off the USB busy hints */
+ UsbPhyDfsBusyHint(hUsbPhy, NV_FALSE, NV_WAIT_INFINITE);
+
+ if (hUsbPhy->TurnOffPowerRail)
{
- if (hUsbPhy->pProperty->UsbRailPoweOffInDeepSleep)
- UsbPhyPowerRailEnable(hUsbPhy, NV_FALSE);
+ NvOdmEnableUsbPhyPowerRail(NV_FALSE);
+ NvOdmEnableOtgCircuitry(NV_FALSE);
}
hUsbPhy->IsPhyPoweredUp = NV_FALSE;
- hUsbPhy->IsHostMode = IsHostMode;
- NvOsSemaphoreSignal(hUsbPhy->HelperThreadSema);
-
- //NvOsDebugPrintf("NvDdkUsbPhyPowerDown::VOLTAGE OFF\n");
fail:
+ NvOsMutexUnlock(hUsbPhy->ThreadSafetyMutex);
return e;
}
@@ -818,4 +797,3 @@ NvDdkUsbPhyIoctl(
}
return ErrStatus;
}
-
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_priv.h b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_priv.h
index d4199b45983b..8088eb63a1f9 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_priv.h
+++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_priv.h
@@ -172,12 +172,10 @@ typedef struct NvDdkUsbPhyRec
NvDdkUsbPhyUtmiPadConfig *pUtmiPadConfig;
// Usb Controller context
NvDdkUsbPhyControllerContext Context;
- // Thread ID for the helper thread
- NvOsThreadHandle hThreadId;
- // semphore for signaling the thread
- NvOsSemaphoreHandle HelperThreadSema;
- // variable to control the thread loop
- NvBool Stopped;
+ // Contains the mutex for providing the thread safety
+ NvOsMutexHandle ThreadSafetyMutex;
+ // Indicator for turning off the USB power rail
+ NvBool TurnOffPowerRail;
// Indicates phy powered up for the host mode
NvBool IsHostMode;
// Set of function pointers to access the usb phy hardware interface.
diff --git a/arch/arm/mach-tegra/nvodm/nvodm_services.c b/arch/arm/mach-tegra/nvodm/nvodm_services.c
index 97e950e59d9b..c965cdd9fdbc 100755
--- a/arch/arm/mach-tegra/nvodm/nvodm_services.c
+++ b/arch/arm/mach-tegra/nvodm/nvodm_services.c
@@ -935,13 +935,90 @@ NvOdmPwmConfig(NvOdmServicesPwmHandle hOdmPwm,
pCurrentFreqHzOrPeriod);
}
+void
+NvOdmEnableUsbPhyPowerRail(
+ NvBool Enable)
+{
+ NvU32 i;
+ NvU32 settle_time_us;
+ NvU64 guid = NV_VDD_USB_ODM_ID;
+ NvOdmPeripheralConnectivity const *pConnectivity;
+ NvRmDeviceHandle hRmDevice;
+ /* get the connectivity info */
+ pConnectivity = NvOdmPeripheralGetGuid( guid );
+ if( !pConnectivity )
+ {
+ // Do nothing if no power rail info is discovered
+ return;
+ }
+
+ if (NvRmOpen(&hRmDevice, 0) != NvSuccess)
+ {
+ return;
+ }
+
+ /* enable the power rail */
+ if (Enable)
+ {
+ for( i = 0; i < pConnectivity->NumAddress; i++ )
+ {
+ if( pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd )
+ {
+ NvRmPmuVddRailCapabilities cap;
+
+ /* address is the vdd rail id */
+ NvRmPmuGetCapabilities(
+ hRmDevice,
+ pConnectivity->AddressList[i].Address, &cap );
+
+ /* set the rail volatage to the recommended */
+ NvRmPmuSetVoltage(
+ hRmDevice, pConnectivity->AddressList[i].Address,
+ cap.requestMilliVolts, &settle_time_us );
+
+ /* wait for the rail to settle */
+ NvOsWaitUS( settle_time_us );
+ }
+ }
+ }
+ else
+ {
+ for( i = 0; i < pConnectivity->NumAddress; i++ )
+ {
+ if( pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd )
+ {
+ /* set the rail volatage to the recommended */
+ NvRmPmuSetVoltage(
+ hRmDevice, pConnectivity->AddressList[i].Address,
+ ODM_VOLTAGE_OFF, 0 );
+ }
+ }
+ }
+
+
+ NvRmClose(hRmDevice);
+}
+
+
void NvOdmEnableOtgCircuitry(NvBool Enable)
{
- // Rm analog interface calls related to usb are deleted. This API does nothing.
- // This API should not be called for usb phy related operations
- return;
+ const NvOdmUsbProperty *pProperty = NULL;
+ static NvBool s_PowerEnabled = NV_FALSE;
+
+ if ((s_PowerEnabled && Enable) || (!s_PowerEnabled && !Enable))
+ return;
+
+ pProperty = NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, 0);
+
+ if (pProperty && (!pProperty->UseInternalPhyWakeup) &&
+ ((pProperty->UsbMode == NvOdmUsbModeType_Device) ||
+ (pProperty->UsbMode == NvOdmUsbModeType_OTG)))
+ {
+ NvOdmEnableUsbPhyPowerRail(s_PowerEnabled = Enable);
+ }
}
+
NvBool NvOdmUsbIsConnected(void)
{
NV_ASSERT("Not Supported ");