diff options
author | Abhishek Aggarwal <aaggarwal@nvidia.com> | 2010-06-22 15:26:42 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-06-22 11:32:56 -0700 |
commit | f977a657fc6552a20d9ca0205f8b75239bda2d78 (patch) | |
tree | 8c953fcd4623ebf6b902db1a17e3d6a66b11a886 | |
parent | 04d466815e7dbc2a3c34b9279fba182b92c1a8b3 (diff) |
usb phy: correcting the power down sequence for USB2 and 3 controllers
As suggested by h/w, the SUSP bit(7:7) in PORTSC1 register must be set
to 1 to suspend the port before setting the PHCD bit to put the PHY in
suspend mode.
PHCD bit is being used for USB2 and 3 controllers only. Implemented the
suggested changes.
Bug: 695655
Change-Id: I9ddca4f11ec4ac753a3bd6d19fe2c4aa8bbb920f
Reviewed-on: http://git-master.nvidia.com/r/2930
Tested-by: Abhishek Aggarwal <aaggarwal@nvidia.com>
Reviewed-by: Narendra Damahe <ndamahe@nvidia.com>
Tested-by: Narendra Damahe <ndamahe@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c index 15211a6697d0..d59bd2a534f8 100644 --- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c +++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c @@ -360,6 +360,44 @@ Ap20UsbPhyUlpiViewPortProgramData( } static NvError +Ap20UsbPhySuspendPort( + NvDdkUsbPhy *pUsbPhy) +{ + NvU32 RegVal = 0x0; + NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US; + + // Set the SUSP bit (7:7) in the PORTSC1 reg to suspend the port. + //This bit is RW in host mode only. + if (pUsbPhy->pProperty->UsbMode != NvOdmUsbModeType_Host) + { + return NvError_NotSupported; + } + + // Do nothing if port is disabled + if (!USB_REG_READ_VAL(PORTSC1, PE)) + { + return NvError_NotSupported; + } + + RegVal = USB_REG_RD(PORTSC1); + RegVal = USB_FLD_SET_DRF_DEF(PORTSC1, SUSP, SUSPEND, RegVal); + USB_REG_WR(PORTSC1, RegVal); + // Wait until port suspend completes + do + { + if (USB_REG_READ_VAL(PORTSC1, SUSP)) + { + return NvSuccess; + } + + NvOsWaitUS(1); + TimeOut--; + } while (TimeOut); + + return NvError_Timeout; +} + +static NvError Ap20UsbPhyUtmiConfigure( NvDdkUsbPhy *pUsbPhy) { @@ -563,6 +601,8 @@ Ap20UsbPhyUtmiPowerControl( // Put the Phy in the suspend mode if (pUsbPhy->Instance == 2) { + // Suspend port before setting PHCD bit + Ap20UsbPhySuspendPort(pUsbPhy); RegVal = USB_REG_RD(PORTSC1); RegVal = USB_FLD_SET_DRF_DEF(PORTSC1, PHCD, ENABLE, RegVal); USB_REG_WR(PORTSC1, RegVal); @@ -875,6 +915,8 @@ Ap20UsbPhyUlpiPowerControl( else { // Put the Phy in the suspend mode + // Suspend port before setting PHCD bit + Ap20UsbPhySuspendPort(pUsbPhy); RegVal = USB_REG_RD(PORTSC1); RegVal = USB_FLD_SET_DRF_DEF(PORTSC1, PHCD, ENABLE, RegVal); USB_REG_WR(PORTSC1, RegVal); @@ -1497,17 +1539,9 @@ Ap20PhyRestoreContext( NvOsWaitUS(1); TimeOut--; } while (TimeOut); - TimeOut = USB_PHY_HW_TIMEOUT_US; + // Put controller in suspend mode by writing 1 to SUSP bit of PORTSC - USB_REG_UPDATE_DEF(PORTSC1, SUSP, SUSPEND); - // Wait until port suspend completes - do - { - if (USB_REG_READ_VAL(PORTSC1, SUSP)) - break; - NvOsWaitUS(1); - TimeOut--; - } while (TimeOut); + Ap20UsbPhySuspendPort(pUsbPhy); if (pUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiExternalPhy) { |