summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkat Moganty <vmoganty@nvidia.com>2010-05-19 21:47:53 +0530
committerGary King <gking@nvidia.com>2010-05-28 17:49:58 -0700
commit1f8151757685553dd859d1e4c9d00d3f9c006d6c (patch)
tree56349edb7c2d0ec5477c19d12b89bdde7375fb0b
parentfc0021e42a7e7f230651fe6703fc83cb8993bf88 (diff)
[ARM/tegra] usb-phy: integrate LP0 fixes from 2.6.29
Change-Id: I6519568f20c4cd859c198d82c2a3007305a61317 UTMIP pads were turned off before the UTMI phy is set in to the suspend mode. This is corrected by turning off the UTMIP power control pads after phy is suspended. Added workaround for ULPI to bring out of suspend by setting USB2_CLK_OVR_ON bit in CLK_RST_CONTROLLER register. Change-Id: I3219946e6351c8ddf5e036dfc3a3f2b3693e99a6 Enable Clock Over On bit for all three controllers during phy resume and disable during the suspend. Added timeout for the phy clock wait loops. Change-Id: I71324cc89b4e3031ecc94ee5c05ba6193bab6533 add timeouts to all infinite polling loops to prevent soft lockups when restoring the phy Change-Id: I067d50fe26c8e951d92e4e36814d20d9ad2022f2 Reviewed-on: http://git-master/r/1836 Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c368
1 files changed, 183 insertions, 185 deletions
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c
index 245e447327c7..15211a6697d0 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c
+++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c
@@ -47,6 +47,7 @@
#include "nvddk_usbphy_priv.h"
#include "nvodm_query.h"
#include "ap20/arahb_arbc.h"
+#include "ap20/arclk_rst.h"
/* Defines for USB register read and writes */
#define USB_REG_RD(reg)\
@@ -77,7 +78,7 @@
#define USB_REG_READ_VAL(reg, field) \
USB_DRF_VAL(reg, field, USB_REG_RD(reg))
-#define USB_REG_SET_DRF_NUM(reg, field, num, value) \
+#define USB_FLD_SET_DRF_NUM(reg, field, num, value) \
NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_2_USB2D, reg, field, num, value);
/* Defines for USB IF register read and writes */
@@ -275,6 +276,88 @@ static const NvU8 s_UtmipElasticLimit = 16;
//UTMIP High Speed Sync Start Delay
static const NvU8 s_UtmipHsSyncStartDelay = 0;
+static void
+Ap20UsbPhyConfigUsbClockOverOn(
+ NvDdkUsbPhy *pUsbPhy,
+ NvBool EnableOverOn)
+{
+ NvU32 RegVal = 0x0;
+
+ RegVal = NV_REGR(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0,
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0);
+ switch (pUsbPhy->Instance)
+ {
+ case 0:
+ RegVal = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, LVL2_CLK_GATE_OVRB,
+ USB1_CLK_OVR_ON, EnableOverOn, RegVal);
+ break;
+ case 1:
+ RegVal = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, LVL2_CLK_GATE_OVRB,
+ USB2_CLK_OVR_ON, EnableOverOn, RegVal);
+ break;
+ case 2:
+ RegVal = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, LVL2_CLK_GATE_OVRB,
+ USB3_CLK_OVR_ON, EnableOverOn, RegVal);
+ break;
+ default:
+ NV_ASSERT(!"Unable to enable/disable USB Clock Over On");
+ return;
+ }
+ NV_REGW(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0,
+ CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0, RegVal);
+
+}
+
+static NvError
+Ap20UsbPhyWaitForInValidPhyClock(
+ NvDdkUsbPhy *pUsbPhy)
+{
+ NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US;
+
+ // Wait for the phy clock to become in valid or hardware timeout
+ do {
+ if (!USB_IF_REG_READ_VAL(SUSP_CTRL, USB_PHY_CLK_VALID))
+ return NvSuccess;
+ NvOsWaitUS(1);
+ TimeOut--;
+ } while (TimeOut);
+
+ NvOsDebugPrintf("Phy Clock is not stopped and timed out\n");
+
+ return NvError_Timeout;
+}
+
+
+static void
+Ap20UsbPhyUlpiViewPortProgramData(
+ NvDdkUsbPhy *pUsbPhy,
+ NvU32 Addr,
+ NvU32 Data)
+{
+ NvU32 RegVal = 0x0;
+ NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US;
+
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_PORT, 0, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, Addr, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, Data, RegVal);
+ USB_REG_WR(ULPI_VIEWPORT, RegVal);
+
+ // wait for run bit to be cleared
+ do
+ {
+ RegVal = USB_REG_RD(ULPI_VIEWPORT);
+ if (!TimeOut)
+ {
+ NvOsDebugPrintf(" !!!Error in accessing ULPI !!! \n");
+ return;
+ }
+ NvOsWaitUS(1);
+ TimeOut--;
+ } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+}
static NvError
Ap20UsbPhyUtmiConfigure(
@@ -377,9 +460,11 @@ Ap20UsbPhyUtmiPowerControl(
if (Enable)
{
- // Disable the automatic phy enable on wakeup event
- USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_DISCON_EN_DEV, DISABLE);
- USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_CNNT_EN_DEV, DISABLE);
+ if (pUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Device)
+ {
+ // Disable the automatic phy enable on wakeup event
+ USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_CNNT_EN_DEV, DISABLE);
+ }
// USB Power Up sequence
if (!pUsbPhy->pUtmiPadConfig->PadOnRefCount)
@@ -473,12 +558,6 @@ Ap20UsbPhyUtmiPowerControl(
USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_SUSP_SET, SET);
NvOsWaitUS(10);
USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_SUSP_SET, UNSET);
- //NvOsDebugPrintf("Waiting for Phy Clock to stop \n");
- // check for phy in suspend..
- do {
- NvOsWaitUS(1);
- } while (USB_IF_REG_READ_VAL(SUSP_CTRL, USB_PHY_CLK_VALID));
- //NvOsDebugPrintf("Phy Clock stopped successfully \n");
}
// Put the Phy in the suspend mode
@@ -489,24 +568,21 @@ Ap20UsbPhyUtmiPowerControl(
USB_REG_WR(PORTSC1, RegVal);
}
- // Setup debounce time for wakeup event 5 HCLK cycles
- USB_IF_REG_UPDATE_NUM(SUSP_CTRL, USB_WAKEUP_DEBOUNCE_COUNT, 5);
- // ENABLE the automatic phy enable on wakeup event
- USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_CNNT_EN_DEV, ENABLE);
- USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_DISCON_EN_DEV, ENABLE);
- // USB Power down sequence
- /* decrement the pad control refernce count */
- pUsbPhy->pUtmiPadConfig->PadOnRefCount--;
- if (!pUsbPhy->pUtmiPadConfig->PadOnRefCount)
+ // wait untill phy in suspend..
+ Ap20UsbPhyWaitForInValidPhyClock(pUsbPhy);
+
+ if (pUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Device)
{
- /* since there is no reference to the pads turn off */
- RegVal = NV_READ32(pUsbPhy->pUtmiPadConfig->pVirAdr + ((USB1_UTMIP_BIAS_CFG0_0)/4));
- // Power down OTG and Bias circuitry
- RegVal = USB_UTMIP_FLD_SET_DRF_DEF(BIAS_CFG0, UTMIP_OTGPD, 1, RegVal);
- RegVal = USB_UTMIP_FLD_SET_DRF_DEF(BIAS_CFG0, UTMIP_BIASPD, 1, RegVal);
- NV_WRITE32(pUsbPhy->pUtmiPadConfig->pVirAdr + ((USB1_UTMIP_BIAS_CFG0_0)/4),
- RegVal);
+ // Setup debounce time for wakeup event 5 HCLK cycles
+ USB_IF_REG_UPDATE_NUM(SUSP_CTRL, USB_WAKEUP_DEBOUNCE_COUNT, 5);
+ // ENABLE the automatic phy enable on wakeup event
+ USB1_IF_REG_UPDATE_DEF(USB_SUSP_CTRL, USB_WAKE_ON_CNNT_EN_DEV, ENABLE);
}
+ // Hold UTMIP in reset
+ RegVal =USB_IF_REG_RD(SUSP_CTRL);
+ RegVal = USB3_IF_FLD_SET_DRF_DEF(SUSP_CTRL, UTMIP_RESET, ENABLE, RegVal);
+ USB_IF_REG_WR(SUSP_CTRL, RegVal);
+
// Disable Batery charge enabling bit set to '1' for disable
USB_UTMIP_REG_UPDATE_NUM(BAT_CHRG_CFG0, UTMIP_PD_CHRG, 1);
@@ -529,10 +605,20 @@ Ap20UsbPhyUtmiPowerControl(
XCVR_CFG1, UTMIP_FORCE_PDDR_POWERDOWN, 1, RegVal);
USB_UTMIP_REG_WR(XCVR_CFG1, RegVal);
- // Hold UTMIP in reset
- RegVal =USB_IF_REG_RD(SUSP_CTRL);
- RegVal = USB3_IF_FLD_SET_DRF_DEF(SUSP_CTRL, UTMIP_RESET, ENABLE, RegVal);
- USB_IF_REG_WR(SUSP_CTRL, RegVal);
+
+ // USB Power down sequence
+ /* decrement the pad control refernce count */
+ pUsbPhy->pUtmiPadConfig->PadOnRefCount--;
+ if (!pUsbPhy->pUtmiPadConfig->PadOnRefCount)
+ {
+ /* since there is no reference to the pads turn off */
+ RegVal = NV_READ32(pUsbPhy->pUtmiPadConfig->pVirAdr + ((USB1_UTMIP_BIAS_CFG0_0)/4));
+ // Power down OTG and Bias circuitry
+ RegVal = USB_UTMIP_FLD_SET_DRF_DEF(BIAS_CFG0, UTMIP_OTGPD, 1, RegVal);
+ RegVal = USB_UTMIP_FLD_SET_DRF_DEF(BIAS_CFG0, UTMIP_BIASPD, 1, RegVal);
+ NV_WRITE32(pUsbPhy->pUtmiPadConfig->pVirAdr + ((USB1_UTMIP_BIAS_CFG0_0)/4),
+ RegVal);
+ }
}
}
@@ -666,6 +752,8 @@ Ap20UsbPhyUlpiLinkModeConfigure(
NvDdkUsbPhy *pUsbPhy, NvBool Enable)
{
NvU32 RegVal;
+ NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US;
+
if (Enable)
{
// Put the UHSIC in the reset
@@ -704,46 +792,29 @@ Ap20UsbPhyUlpiLinkModeConfigure(
ULPI_IF_DRF_NUM(TIMING_CTRL_1, ULPI_DIR_TRIMMER_LOAD, 1) |
ULPI_IF_DRF_NUM(TIMING_CTRL_1, ULPI_DIR_TRIMMER_SEL, 4));
-
- // fix VbusValid for Harmony due to floating VBUS
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
-
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x8, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x40, RegVal);
-
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, SET, 0xFFFFFFFF);
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, CLEAR, RegVal);
+ RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_PORT, 0, RegVal);
USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
+ // wait for ULPI wake up is cleared
+ do {
RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
-
+ if (!TimeOut)
+ {
+ NvOsDebugPrintf("Error accessing ULPI view port\n");
+ break;
+ }
+ NvOsWaitUS(1);
+ TimeOut--;
+ } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_WAKEUP, RegVal));
+ // fix VbusValid for Harmony due to floating VBUS
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x08, 0x40);
// set UseExternalVbusIndicator to 1
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
-
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0xB, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x80, RegVal);
-
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x0B, 0x80);
// enabling WKCN/WKDS/WKOC bit
RegVal = USB_REG_RD(PORTSC1);
@@ -754,117 +825,26 @@ Ap20UsbPhyUlpiLinkModeConfigure(
}
else
{
- // Resetting the ULPI register IndicatorPassThru
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x9, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x40, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
-
- // Resetting ULPI register UseExternalVbusIndicator
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0xC, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x80, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
+ // Programming the ULPI register function control
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x04, 0x4D);
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ // Resetting the ULPI register IndicatorPassThru
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x09, 0x40);
// USB Interrupt Rising - making sure vbus comparator and id are off
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x0d, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x00, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x0D, 0x00);
// USB Interrupt Falling
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x10, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x00, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x10, 0x00);
//Carkit Control
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x19, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x00, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x19, 0x00);
// Disabling ID float Rise/Fall (Carkit Enable)
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x1D, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x00, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x1D, 0x00);
// USB I/O and power
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RUN, SET, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_RD_WR, WRITE, RegVal);
- RegVal = USB_FLD_SET_DRF_DEF(ULPI_VIEWPORT, ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_REG_ADDR, 0x39, RegVal);
- RegVal = USB_REG_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_DATA_WR, 0x00, RegVal);
- USB_REG_WR(ULPI_VIEWPORT, RegVal);
-
- // wait for run bit to be cleared
- do
- {
- RegVal = USB_REG_RD(ULPI_VIEWPORT);
- } while (USB_DRF_VAL(ULPI_VIEWPORT, ULPI_RUN, RegVal));
+ Ap20UsbPhyUlpiViewPortProgramData(pUsbPhy, 0x39, 0x00);
// clear WKCN/WKDS/WKOC wake-on events that can cause the USB
// Controller to immediately bring the ULPI PHY out of low power mode
@@ -898,6 +878,8 @@ Ap20UsbPhyUlpiPowerControl(
RegVal = USB_REG_RD(PORTSC1);
RegVal = USB_FLD_SET_DRF_DEF(PORTSC1, PHCD, ENABLE, RegVal);
USB_REG_WR(PORTSC1, RegVal);
+ // Wait for phy clock to go down
+ Ap20UsbPhyWaitForInValidPhyClock(pUsbPhy);
}
}
}
@@ -1293,6 +1275,8 @@ Ap20UsbPhyPowerUp(
{
NvError ErrVal = NvSuccess;
+ Ap20UsbPhyConfigUsbClockOverOn(pUsbPhy, NV_TRUE);
+
switch (pUsbPhy->pProperty->UsbInterfaceType)
{
case NvOdmUsbInterfaceType_UlpiNullPhy:
@@ -1320,8 +1304,8 @@ Ap20UsbPhyPowerUp(
Ap20UsbPhySelectUsbMode(pUsbPhy);
if (pUsbPhy->pProperty->UsbInterfaceType ==
- NvOdmUsbInterfaceType_UlpiNullPhy)
- pUsbPhy->hOdmUlpi = NvOdmUsbUlpiOpen(pUsbPhy->Instance);
+ NvOdmUsbInterfaceType_UlpiNullPhy)
+ pUsbPhy->hOdmUlpi = NvOdmUsbUlpiOpen(pUsbPhy->Instance);
}
return ErrVal;
@@ -1350,6 +1334,8 @@ Ap20UsbPhyPowerDown(
break;
}
+ Ap20UsbPhyConfigUsbClockOverOn(pUsbPhy, NV_FALSE);
+
return NvSuccess;
}
@@ -1390,11 +1376,8 @@ Ap20PhyRemoveTristate(
RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, TRISTATE_REG_B, Z_UAB, NORMAL, RegVal);
RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, TRISTATE_REG_B, Z_UAC, NORMAL, RegVal);
USB_MISC_REGW(pUsbPhy, APB_MISC_PP_TRISTATE_REG_B_0, RegVal);
- do
- {
- RegVal = USB_IF_REG_RD(SUSP_CTRL);
- RegVal = NV_DRF_VAL(USB2_IF_USB,SUSP_CTRL, USB_PHY_CLK_VALID, RegVal);
- } while (RegVal != USB2_IF_USB_SUSP_CTRL_0_USB_PHY_CLK_VALID_SET);
+
+ Ap20UsbPhyWaitForStableClock(pUsbPhy);
}
static void
@@ -1448,7 +1431,7 @@ Ap20PhyRestoreContext(
NvDdkUsbPhy *pUsbPhy)
{
NvU32 RegVal = 0;
-
+ NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US;
/* If any saved context is present, restore it */
// In case of no valid context just return
if (!pUsbPhy->Context.IsValid)
@@ -1465,15 +1448,15 @@ Ap20PhyRestoreContext(
RegVal = USB_REG_RD(PORTSC1);
if (pUsbPhy->Context.UsbPortSpeed == NvDdkUsbPhyPortSpeedType_High)
{
- RegVal = USB_REG_SET_DRF_NUM(PORTSC1, PTC, 0x05, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(PORTSC1, PTC, 0x05, RegVal);
}
else if (pUsbPhy->Context.UsbPortSpeed == NvDdkUsbPhyPortSpeedType_Full)
{
- RegVal = USB_REG_SET_DRF_NUM(PORTSC1, PTC, 0x06, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(PORTSC1, PTC, 0x06, RegVal);
}
else if (pUsbPhy->Context.UsbPortSpeed == NvDdkUsbPhyPortSpeedType_Low)
{
- RegVal = USB_REG_SET_DRF_NUM(PORTSC1, PTC, 0x07, RegVal);
+ RegVal = USB_FLD_SET_DRF_NUM(PORTSC1, PTC, 0x07, RegVal);
}
else
{
@@ -1484,33 +1467,48 @@ Ap20PhyRestoreContext(
// Disable test mode by setting PTC field to NORMAL_OP
USB_REG_UPDATE_DEF(PORTSC1, PTC, NORMAL_OP);
-
// Poll until CCS is enabled
do
{
- RegVal = USB_REG_RD(PORTSC1);
- } while (!USB_DRF_VAL(PORTSC1, CCS, RegVal));
-
+ RegVal = USB_REG_RD(PORTSC1);
+ if (USB_DRF_VAL(PORTSC1, CCS, RegVal))
+ break;
+ NvOsWaitUS(1);
+ TimeOut--;
+ } while (TimeOut);
// Poll until PE is enabled
+ TimeOut = USB_PHY_HW_TIMEOUT_US;
do
{
RegVal = USB_REG_RD(PORTSC1);
- } while (!USB_DRF_VAL(PORTSC1, PE, RegVal));
-
+ if (USB_DRF_VAL(PORTSC1, PE, RegVal))
+ break;
+ NvOsWaitUS(1);
+ TimeOut--;
+ } while (TimeOut);
// Clear the PCI status, to avoid an interrupt taken upon resume
USB_REG_UPDATE_DEF(USBSTS, PCI, PORT_CHANGE);
+ TimeOut = USB_PHY_HW_TIMEOUT_US;
do
{
RegVal = USB_REG_RD(USBSTS);
- } while (USB_DRF_VAL(USBSTS, PCI, RegVal));
-
+ if (!(USB_DRF_VAL(USBSTS, PCI, RegVal)))
+ break;
+ 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
- while (!USB_REG_READ_VAL(PORTSC1, SUSP))
+ do
{
+ if (USB_REG_READ_VAL(PORTSC1, SUSP))
+ break;
NvOsWaitUS(1);
- };
+ TimeOut--;
+ } while (TimeOut);
+
if (pUsbPhy->pProperty->UsbInterfaceType == NvOdmUsbInterfaceType_UlpiExternalPhy)
{
Ap20PhyRemoveTristate(pUsbPhy);