summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Aggarwal <aaggarwal@nvidia.com>2010-06-22 15:26:42 +0530
committerGary King <gking@nvidia.com>2010-06-22 11:32:56 -0700
commitf977a657fc6552a20d9ca0205f8b75239bda2d78 (patch)
tree8c953fcd4623ebf6b902db1a17e3d6a66b11a886
parent04d466815e7dbc2a3c34b9279fba182b92c1a8b3 (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.c54
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)
{