diff options
author | Venkat Moganty <vmoganty@nvidia.com> | 2010-05-20 20:26:21 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-20 17:50:38 -0700 |
commit | e25477a0cfb318f5030e4479b13f6d0722838d9c (patch) | |
tree | 58ea3b3e83358794a37a05e54d38c1404edb9b8d | |
parent | c91243547a3c1b1d4a25b92582db7cd3b78b394f (diff) |
tegra usb-phy: Enable/disable Clock Over On bit for all controllers
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.
Bug 679959
Tested on Ap20/Harmony.
Change-Id: I3219946e6351c8ddf5e036dfc3a3f2b3693e99a6
Reviewed-on: http://git-master/r/1455
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: Gary King <gking@nvidia.com>
-rwxr-xr-x | arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c | 123 |
1 files changed, 83 insertions, 40 deletions
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c index de6d4a388ff8..4ce0d0529119 100755 --- a/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c +++ b/arch/arm/mach-tegra/nvddk/nvddk_usbphy_ap20.c @@ -276,6 +276,57 @@ 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( @@ -350,16 +401,6 @@ Ap20UsbPhyUtmiConfigure( USB1_IF_REG_WR(USB1_LEGACY_CTRL, RegVal); } - if (pUsbPhy->Instance == 2) - { - RegVal = NV_REGR(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, - CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0); - RegVal = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, LVL2_CLK_GATE_OVRB, - USB3_CLK_OVR_ON, 1, RegVal); - NV_REGW(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, - CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0, RegVal); - } - // Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT // Setting these fields, together with default values of the other // fields, results in programming the registers below as follows: @@ -419,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) @@ -525,18 +568,16 @@ Ap20UsbPhyUtmiPowerControl( USB_REG_WR(PORTSC1, RegVal); } - //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"); - - // 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); + // wait untill phy in suspend.. + Ap20UsbPhyWaitForInValidPhyClock(pUsbPhy); + + if (pUsbPhy->pProperty->UsbMode == NvOdmUsbModeType_Device) + { + // 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); @@ -711,15 +752,10 @@ Ap20UsbPhyUlpiLinkModeConfigure( NvDdkUsbPhy *pUsbPhy, NvBool Enable) { NvU32 RegVal; + NvU32 TimeOut = USB_PHY_HW_TIMEOUT_US; + if (Enable) { - RegVal = NV_REGR(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, - CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0); - RegVal = NV_FLD_SET_DRF_NUM(CLK_RST_CONTROLLER, LVL2_CLK_GATE_OVRB, - USB2_CLK_OVR_ON, 1, RegVal); - NV_REGW(pUsbPhy->hRmDevice, NvRmPrivModuleID_ClockAndReset, 0, - CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRB_0, RegVal); - // Put the UHSIC in the reset USB_IF_REG_UPDATE_DEF(SUSP_CTRL, UHSIC_RESET, ENABLE); @@ -762,8 +798,16 @@ Ap20UsbPhyUlpiLinkModeConfigure( RegVal = USB_FLD_SET_DRF_NUM(ULPI_VIEWPORT, ULPI_PORT, 0, RegVal); USB_REG_WR(ULPI_VIEWPORT, RegVal); + // wait for ULPI wake up is cleared do { RegVal = USB_REG_RD(ULPI_VIEWPORT); + 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 @@ -835,9 +879,7 @@ Ap20UsbPhyUlpiPowerControl( RegVal = USB_FLD_SET_DRF_DEF(PORTSC1, PHCD, ENABLE, RegVal); USB_REG_WR(PORTSC1, RegVal); // Wait for phy clock to go down - do { - NvOsWaitUS(1); - } while (USB_IF_REG_READ_VAL(SUSP_CTRL, USB_PHY_CLK_VALID)); + Ap20UsbPhyWaitForInValidPhyClock(pUsbPhy); } } } @@ -1233,6 +1275,8 @@ Ap20UsbPhyPowerUp( { NvError ErrVal = NvSuccess; + Ap20UsbPhyConfigUsbClockOverOn(pUsbPhy, NV_TRUE); + switch (pUsbPhy->pProperty->UsbInterfaceType) { case NvOdmUsbInterfaceType_UlpiNullPhy: @@ -1290,6 +1334,8 @@ Ap20UsbPhyPowerDown( break; } + Ap20UsbPhyConfigUsbClockOverOn(pUsbPhy, NV_FALSE); + return NvSuccess; } @@ -1330,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 |