arm: tegra11x: usb_phy: Add HSIC changes from main
Venu Byravarasu [Mon, 30 Jul 2012 11:49:28 +0000 (16:49 +0530)]
Pulling in multiple changes of HSIC from main into t114.

Change-Id: Icad74fa6477fbc8d29463e52858483915d5a4a8f
Signed-off-by: Venu Byravarasu <vbyravarasu@nvidia.com>
Reviewed-on: http://git-master/r/118303
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

arch/arm/mach-tegra/tegra11x_usb_phy.c

index ad2814c..a165e50 100644 (file)
 #define   UHSIC_RPU_DATA                       (1 << 11)
 #define   UHSIC_RPU_STROBE                     (1 << 12)
 
-#define UHSIC_STAT_CFG0                        0xc28
-#define   UHSIC_CONNECT_DETECT                 (1 << 0)
+#define UHSIC_STAT_CFG0                0xc28
+#define UHSIC_CONNECT_DETECT                   (1 << 0)
+
+#define UHSIC_CMD_CFG0                                 0xc24
+#define UHSIC_PRETEND_CONNECT_DETECT   (1 << 5)
+#define UHSIC_PMC_WAKEUP0                              0xc34
+#define UHSIC_WAKE_ALARM                               (1 << 19)
+#define UHSIC_CLR_WAKE_ALARM_P0                        (1 << 15)
+#define UHSIC_MASTER_ENABLE                            (1 << 24)
+#define UHSIC_WAKE_VAL(x)                              (((x) & 0xf) << 28)
+#define UHSIC_MASTER_ENABLE_P0                 (1 << 24)
+#define UHSIC_WAKE_VAL_P0(x)                   (((x) & 0xf) << 28)
+#define UHSIC_WAKE_WALK_EN_P0                  (1 << 30)
+#define UHSIC_LINEVAL_WALK_EN                  (1 << 31)
+#define UHSIC_CLR_WALK_PTR_P0                  (1 << 3)
+#define UHSIC_CLR_WAKE_ALARM_P0                        (1 << 15)
+#define USB_USBINTR                                            0x138
+#define UHSIC_WALK_PTR_VAL                             (0x3 << 6)
+#define UHSIC_DATA_VAL_P0                              (1 << 15)
+#define UHSIC_STROBE_VAL_P0                            (1 << 14)
+#define HSIC_RESERVED_P0                               (3 << 14)
+#define STROBE_VAL_PD_P0                               (1 << 12)
+#define DATA_VAL_PD_P0                                 (1 << 13)
+#define UHSIC_PWR                                              (1 << 3)
+#define PMC_SLEEPWALK_UHSIC                            0x210
+#define UHSIC_STROBE_RPD_A                             (1 << 0)
+#define UHSIC_DATA_RPD_A                               (1 << 1)
+#define UHSIC_STROBE_RPU_A                             (1 << 2)
+#define UHSIC_DATA_RPU_A                               (1 << 3)
+#define UHSIC_STROBE_RPD_B                             (1 << 8)
+#define UHSIC_DATA_RPD_B                               (1 << 9)
+#define UHSIC_STROBE_RPU_B                             (1 << 10)
+#define UHSIC_DATA_RPU_B                               (1 << 11)
+#define UHSIC_STROBE_RPD_C                             (1 << 16)
+#define UHSIC_DATA_RPD_C                               (1 << 17)
+#define UHSIC_STROBE_RPU_C                             (1 << 18)
+#define UHSIC_DATA_RPU_C                               (1 << 19)
+#define UHSIC_STROBE_RPD_D                             (1 << 24)
+#define UHSIC_DATA_RPD_D                               (1 << 25)
+#define UHSIC_STROBE_RPU_D                             (1 << 26)
+#define UHSIC_DATA_RPU_D                               (1 << 27)
+#define UHSIC_LINE_DEB_CNT(x)                  (((x) & 0xf) << 20)
+#define   WAKE_VAL_SD10                                        0x2
 
 #define PMC_USB_DEBOUNCE                       0xec
 #define   UTMIP_LINE_DEB_CNT(x)                        (((x) & 0xf) << 16)
@@ -909,77 +950,6 @@ static void utmip_powerup_pmc_wake_detect(struct tegra_usb_phy *phy)
        mdelay(1);
 }
 
-#if 0
-static int uhsic_powerdown_pmc_wake_detect(struct tegra_usb_phy *phy)
-{
-       unsigned long val;
-       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-       /* turn on pad detectors for HSIC*/
-       val = readl(pmc_base + PMC_USB_AO);
-       val |= (HSIC_RESERVED_P0 | HSIC_STOBE_VAL_PD_P0 | HSIC_DATA_VAL_PD_P0);
-       writel(val, pmc_base + PMC_USB_AO);
-
-       /* enable pull downs on HSIC PMC */
-       val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B |
-               UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C |
-               UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D;
-       writel(val, pmc_base + UHSIC_SLEEPWALK_REG);
-
-       /* Turn over pad configuration to PMC */
-       val = readl(pmc_base + PMC_SLEEP_CFG);
-       val &= ~UHSIC_WAKE_VAL_P0(~0);
-       val |= UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) | UHSIC_MASTER_ENABLE_P0;
-       writel(val, pmc_base + PMC_SLEEP_CFG);
-
-       return 0;
-}
-
-static void usb_phy_power_down_pmc(void)
-{
-       unsigned long val;
-       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
-
-       /* power down all 3 UTMIP interfaces */
-       val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG);
-       val |= UTMIP_PWR(0) | UTMIP_PWR(1) | UTMIP_PWR(2);
-       writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG);
-
-       /* turn on pad detectors */
-       writel(PMC_POWER_DOWN_MASK, pmc_base + PMC_USB_AO);
-
-       /* setup sleep walk fl all 3 usb controllers */
-       val = UTMIP_USBOP_RPD_A | UTMIP_USBON_RPD_A | UTMIP_HIGHZ_A |
-               UTMIP_USBOP_RPD_B | UTMIP_USBON_RPD_B | UTMIP_HIGHZ_B |
-               UTMIP_USBOP_RPD_C | UTMIP_USBON_RPD_C | UTMIP_HIGHZ_C |
-               UTMIP_USBOP_RPD_D | UTMIP_USBON_RPD_D | UTMIP_HIGHZ_D;
-       writel(val, pmc_base + PMC_SLEEPWALK_REG(0));
-       writel(val, pmc_base + PMC_SLEEPWALK_REG(1));
-       writel(val, pmc_base + PMC_SLEEPWALK_REG(2));
-
-       /* enable pull downs on HSIC PMC */
-       val = UHSIC_STRB_RPD_A | UHSIC_DATA_RPD_A | UHSIC_STRB_RPD_B |
-               UHSIC_DATA_RPD_B | UHSIC_STRB_RPD_C | UHSIC_DATA_RPD_C |
-               UHSIC_STRB_RPD_D | UHSIC_DATA_RPD_D;
-       writel(val, pmc_base + UHSIC_SLEEPWALK_REG);
-
-       /* Turn over pad configuration to PMC */
-       val = readl(pmc_base + PMC_SLEEP_CFG);
-       val &= ~UTMIP_WAKE_VAL(0, ~0);
-       val &= ~UTMIP_WAKE_VAL(1, ~0);
-       val &= ~UTMIP_WAKE_VAL(2, ~0);
-       val &= ~UHSIC_WAKE_VAL_P0(~0);
-       val |= UTMIP_WAKE_VAL(0, WAKE_VAL_NONE) | UHSIC_WAKE_VAL_P0(WAKE_VAL_NONE) |
-       UTMIP_WAKE_VAL(1, WAKE_VAL_NONE) | UTMIP_WAKE_VAL(2, WAKE_VAL_NONE) |
-       UTMIP_RCTRL_USE_PMC(0) | UTMIP_RCTRL_USE_PMC(1) | UTMIP_RCTRL_USE_PMC(2) |
-       UTMIP_TCTRL_USE_PMC(0) | UTMIP_TCTRL_USE_PMC(1) | UTMIP_TCTRL_USE_PMC(2) |
-       UTMIP_FSLS_USE_PMC(0) | UTMIP_FSLS_USE_PMC(1) | UTMIP_FSLS_USE_PMC(2) |
-       UTMIP_MASTER_ENABLE(0) | UTMIP_MASTER_ENABLE(1) | UTMIP_MASTER_ENABLE(2) |
-       UHSIC_MASTER_ENABLE_P0;
-       writel(val, pmc_base + PMC_SLEEP_CFG);
-}
-#endif
-
 static void uhsic_powerup_pmc_wake_detect(struct tegra_usb_phy *phy)
 {
        unsigned long val;
@@ -1681,6 +1651,283 @@ static bool utmi_phy_charger_detect(struct tegra_usb_phy *phy)
        return status;
 }
 
+static void uhsic_setup_pmc_wake_detect(struct tegra_usb_phy *phy)
+{
+       unsigned long val;
+       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+       void __iomem *base = phy->regs;
+       bool port_connected;
+
+       DBG("%s:%d\n", __func__, __LINE__);
+
+       /* check for port connect status */
+       val = readl(base + USB_PORTSC);
+       port_connected = val & USB_PORTSC_CCS;
+
+       if (!port_connected)
+               return;
+
+       /*Set PMC MASTER bits to do the following
+       * a. Take over the hsic drivers
+       * b. set up such that it will take over resume
+       *        if remote wakeup is detected
+       * Prepare PMC to take over suspend-wake detect-drive resume until USB
+       * controller ready
+       */
+
+       /* disable master enable in PMC */
+       val = readl(pmc_base + PMC_SLEEP_CFG);
+       val &= ~UHSIC_MASTER_ENABLE_P0;
+       writel(val, pmc_base + PMC_SLEEP_CFG);
+
+       /* UTMIP_PWR_PX=1 for power savings mode */
+       val = readl(pmc_base + PMC_UTMIP_MASTER_CONFIG);
+       val |= UHSIC_PWR;
+       writel(val, pmc_base + PMC_UTMIP_MASTER_CONFIG);
+
+       /* Enable which type of event can trigger a walk,
+       * in this case usb_line_wake */
+       val = readl(pmc_base + PMC_SLEEPWALK_CFG);
+       val |= UHSIC_LINEVAL_WALK_EN;
+       writel(val, pmc_base + PMC_SLEEPWALK_CFG);
+
+       /* program walk sequence, maintain a J, followed by a driven K
+       * to signal a resume once an wake event is detected */
+
+       val = readl(pmc_base + PMC_SLEEPWALK_UHSIC);
+
+       val &= ~UHSIC_DATA_RPU_A;
+       val |=  UHSIC_DATA_RPD_A;
+       val &= ~UHSIC_STROBE_RPD_A;
+       val |=  UHSIC_STROBE_RPU_A;
+       writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
+
+       val &= ~UHSIC_DATA_RPD_B;
+       val |=  UHSIC_DATA_RPU_B;
+       val &= ~UHSIC_STROBE_RPU_B;
+       val |=  UHSIC_STROBE_RPD_B;
+       writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
+
+       val &= ~UHSIC_DATA_RPD_C;
+       val |=  UHSIC_DATA_RPU_C;
+       val &= ~UHSIC_STROBE_RPU_C;
+       val |=  UHSIC_STROBE_RPD_C;
+       writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
+
+       val &= ~UHSIC_DATA_RPD_D;
+       val |=  UHSIC_DATA_RPU_D;
+       val &= ~UHSIC_STROBE_RPU_D;
+       val |=  UHSIC_STROBE_RPD_D;
+       writel(val, pmc_base + PMC_SLEEPWALK_UHSIC);
+
+       /* turn on pad detectors */
+       val = readl(pmc_base + PMC_USB_AO);
+       val &= ~(STROBE_VAL_PD_P0 | DATA_VAL_PD_P0);
+       writel(val, pmc_base + PMC_USB_AO);
+       /* Add small delay before usb detectors provide stable line values */
+       udelay(1);
+
+       phy->remote_wakeup = false;
+
+       /* Turn over pad configuration to PMC  for line wake events*/
+       val = readl(pmc_base + PMC_SLEEP_CFG);
+       val &= ~UHSIC_WAKE_VAL(~0);
+       val |= UHSIC_WAKE_VAL(WAKE_VAL_SD10);
+       val |= UHSIC_MASTER_ENABLE;
+       writel(val, pmc_base + PMC_SLEEP_CFG);
+
+       val = readl(base + UHSIC_PMC_WAKEUP0);
+       val |= EVENT_INT_ENB;
+       writel(val, base + UHSIC_PMC_WAKEUP0);
+
+       DBG("%s:PMC enabled for HSIC remote wakeup\n", __func__);
+}
+
+static void uhsic_phy_disable_pmc_bus_ctrl(struct tegra_usb_phy *phy)
+{
+       unsigned long val;
+       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+       void __iomem *base = phy->regs;
+
+       DBG("%s (%d)\n", __func__, __LINE__);
+       val = readl(pmc_base + PMC_SLEEP_CFG);
+       val &= ~UHSIC_WAKE_VAL(0x0);
+       val |= UHSIC_WAKE_VAL(WAKE_VAL_NONE);
+       writel(val, pmc_base + PMC_SLEEP_CFG);
+
+       val = readl(pmc_base + PMC_TRIGGERS);
+       val |= UHSIC_CLR_WAKE_ALARM_P0 | UHSIC_CLR_WALK_PTR_P0;
+       writel(val, pmc_base + PMC_TRIGGERS);
+
+       val = readl(base + UHSIC_PMC_WAKEUP0);
+       val &= ~EVENT_INT_ENB;
+       writel(val, base + UHSIC_PMC_WAKEUP0);
+
+       /* Disable PMC master mode by clearing MASTER_EN */
+       val = readl(pmc_base + PMC_SLEEP_CFG);
+       val &= ~(UHSIC_MASTER_ENABLE);
+       writel(val, pmc_base + PMC_SLEEP_CFG);
+
+       /* turn off pad detectors */
+       val = readl(pmc_base + PMC_USB_AO);
+       val |= (STROBE_VAL_PD_P0 | DATA_VAL_PD_P0);
+       writel(val, pmc_base + PMC_USB_AO);
+
+       phy->remote_wakeup = false;
+}
+
+static int uhsic_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
+{
+       DBG("%s(%d)\n", __func__, __LINE__);
+
+       if (!remote_wakeup)
+               usb_phy_wait_for_sof(phy);
+
+       return 0;
+}
+
+static int uhsic_phy_post_resume(struct tegra_usb_phy *phy)
+{
+       unsigned long val;
+       void __iomem *base = phy->regs;
+
+       DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+       val = readl(base + USB_TXFILLTUNING);
+       if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) {
+               val = USB_FIFO_TXFILL_THRES(0x10);
+               writel(val, base + USB_TXFILLTUNING);
+       }
+
+       return 0;
+}
+
+static void uhsic_phy_restore_start(struct tegra_usb_phy *phy)
+{
+       unsigned long val;
+       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+       void __iomem *base = phy->regs;
+
+       val = readl(pmc_base + UTMIP_UHSIC_STATUS);
+
+       /* check whether we wake up from the remote resume */
+       if (UHSIC_WALK_PTR_VAL & val) {
+               phy->remote_wakeup = true;
+               pr_info("%s: uhsic remote wakeup detected\n", __func__);
+       } else {
+               if (!((UHSIC_STROBE_VAL_P0 | UHSIC_DATA_VAL_P0) & val)) {
+                               uhsic_phy_disable_pmc_bus_ctrl(phy);
+               } else {
+                       DBG("%s(%d): setting pretend connect\n", __func__, __LINE__);
+                       val = readl(base + UHSIC_CMD_CFG0);
+                       val |= UHSIC_PRETEND_CONNECT_DETECT;
+                       writel(val, base + UHSIC_CMD_CFG0);
+               }
+       }
+}
+
+static void uhsic_phy_restore_end(struct tegra_usb_phy *phy)
+{
+
+       unsigned long val;
+       void __iomem *base = phy->regs;
+       int wait_time_us = 3000; /* FPR should be set by this time */
+
+       DBG("%s(%d)\n", __func__, __LINE__);
+
+       /* check whether we wake up from the remote resume */
+       if (phy->remote_wakeup) {
+               /* wait until FPR bit is set automatically on remote resume */
+               do {
+                       val = readl(base + USB_PORTSC);
+                       udelay(1);
+                       if (wait_time_us == 0) {
+                               uhsic_phy_disable_pmc_bus_ctrl(phy);
+                               uhsic_phy_post_resume(phy);
+                               return;
+                       }
+                       wait_time_us--;
+               } while (!(val & USB_PORTSC_RESUME));
+               /* wait for 25 ms to port resume complete */
+               msleep(25);
+               /* disable PMC master control */
+               uhsic_phy_disable_pmc_bus_ctrl(phy);
+
+               /* Clear PCI and SRI bits to avoid an interrupt upon resume */
+               val = readl(base + USB_USBSTS);
+               writel(val, base + USB_USBSTS);
+               /* wait to avoid SOF if there is any */
+               if (usb_phy_reg_status_wait(base + USB_USBSTS,
+                       USB_USBSTS_SRI, USB_USBSTS_SRI, 2500)) {
+                       pr_warn("%s: timeout waiting for SOF\n", __func__);
+               }
+               uhsic_phy_post_resume(phy);
+       } else {
+               uhsic_phy_disable_pmc_bus_ctrl(phy);
+       }
+
+       /* Set RUN bit */
+       val = readl(base + USB_USBCMD);
+       val |= USB_USBCMD_RS;
+       writel(val, base + USB_USBCMD);
+       if (usb_phy_reg_status_wait(base + USB_USBCMD, USB_USBCMD_RS,
+                                                USB_USBCMD_RS, 2000)) {
+               pr_err("%s: timeout waiting for USB_USBCMD_RS\n", __func__);
+               return;
+       }
+}
+
+static bool uhsic_phy_remotewake_detected(struct tegra_usb_phy *phy)
+{
+       void __iomem *pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+       void __iomem *base = phy->regs;
+       u32 val;
+
+       val = readl(base + UHSIC_PMC_WAKEUP0);
+       if (val & EVENT_INT_ENB) {
+               val = readl(pmc_base + UTMIP_UHSIC_STATUS);
+               if (UHSIC_WAKE_ALARM & val) {
+                       val = readl(pmc_base + PMC_SLEEP_CFG);
+                       val &= ~UHSIC_WAKE_VAL(0x0);
+                       val |= UHSIC_WAKE_VAL(WAKE_VAL_NONE);
+                       writel(val, pmc_base + PMC_SLEEP_CFG);
+
+                       val = readl(pmc_base + PMC_TRIGGERS);
+                       val |= UHSIC_CLR_WAKE_ALARM_P0 | UHSIC_CLR_WALK_PTR_P0;
+                       writel(val, pmc_base + PMC_TRIGGERS);
+
+                       val = readl(base + UHSIC_PMC_WAKEUP0);
+                       val &= ~EVENT_INT_ENB;
+                       writel(val, base + UHSIC_PMC_WAKEUP0);
+                       phy->remote_wakeup = true;
+                       DBG("%s:PMC remote wakeup detected for HSIC\n", __func__);
+                       return true;
+               }
+       }
+       return false;
+}
+
+static void usb_phy_fence_read(struct tegra_usb_phy *phy)
+{
+       /* Fence read for coherency of AHB master intiated writes */
+       if (phy->inst == 0)
+               readb(IO_ADDRESS(IO_PPCS_PHYS + USB1_PREFETCH_ID));
+       else if (phy->inst == 1)
+               readb(IO_ADDRESS(IO_PPCS_PHYS + USB2_PREFETCH_ID));
+       else if (phy->inst == 2)
+               readb(IO_ADDRESS(IO_PPCS_PHYS + USB3_PREFETCH_ID));
+
+       return;
+}
+
+static int uhsic_phy_irq(struct tegra_usb_phy *phy)
+{
+       usb_phy_fence_read(phy);
+       /* check if there is any remote wake event */
+       if (uhsic_phy_remotewake_detected(phy))
+               pr_info("%s: uhsic remote wake detected\n", __func__);
+       return IRQ_HANDLED;
+}
+
 static int uhsic_phy_open(struct tegra_usb_phy *phy)
 {
        unsigned long parent_rate;
@@ -1721,9 +1968,9 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
        }
 
        val = readl(base + UHSIC_PADS_CFG1);
-       val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX |
+       val &= ~(UHSIC_PD_BG | UHSIC_PD_TRK | UHSIC_PD_RX |
                        UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE);
-       val |= UHSIC_RX_SEL;
+       val |= (UHSIC_RX_SEL | UHSIC_PD_TX);
        writel(val, base + UHSIC_PADS_CFG1);
        udelay(2);
 
@@ -1769,7 +2016,11 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
        val = readl(base + USB_SUSP_CTRL);
        val &= ~(UHSIC_RESET);
        writel(val, base + USB_SUSP_CTRL);
-       udelay(2);
+       udelay(1);
+
+       val = readl(base + UHSIC_PADS_CFG1);
+       val &= ~(UHSIC_PD_TX);
+       writel(val, base + UHSIC_PADS_CFG1);
 
        val = readl(base + USB_USBMODE);
        val |= USB_USBMODE_HOST;
@@ -1781,6 +2032,7 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
        val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
        val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
        val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
+       val &= ~HOSTPC1_DEVLC_STS;
        writel(val, base + HOSTPC1_DEVLC);
 
        val = readl(base + USB_TXFILLTUNING);
@@ -1809,6 +2061,15 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
        phy->phy_clk_on = true;
        phy->hw_accessible = true;
 
+       if (phy->pmc_sleepwalk) {
+               DBG("%s(%d) inst:[%d] restore phy\n", __func__, __LINE__,
+                                       phy->inst);
+               uhsic_phy_restore_start(phy);
+               usb_phy_bringup_host_controller(phy);
+               uhsic_phy_restore_end(phy);
+               phy->pmc_sleepwalk = false;
+       }
+
        return 0;
 }
 
@@ -1834,7 +2095,20 @@ static int uhsic_phy_power_off(struct tegra_usb_phy *phy)
        writel(val, base + USB_SUSP_CTRL);
        udelay(30);
 
-       utmip_powerdown_pmc_wake_detect(phy);
+       phy->port_speed = (readl(base + HOSTPC1_DEVLC) >> 25) &
+                       HOSTPC1_DEVLC_PSPD_MASK;
+
+       /* Disable interrupts */
+       writel(0, base + USB_USBINTR);
+
+       if (phy->pmc_sleepwalk == false) {
+               uhsic_setup_pmc_wake_detect(phy);
+               phy->pmc_sleepwalk = true;
+       }
+
+       val = readl(base + HOSTPC1_DEVLC);
+       val |= HOSTPC1_DEVLC_PHCD;
+       writel(val, base + HOSTPC1_DEVLC);
 
        phy->phy_clk_on = false;
        phy->hw_accessible = false;
@@ -1906,6 +2180,7 @@ static int uhsic_phy_bus_reset(struct tegra_usb_phy *phy)
        val |= HOSTPC1_DEVLC_PTS(HOSTPC1_DEVLC_PTS_HSIC);
        val &= ~HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_MASK);
        val |= HOSTPC1_DEVLC_PSPD(HOSTPC1_DEVLC_PSPD_HIGH_SPEED);
+       val &= ~HOSTPC1_DEVLC_STS;
        writel(val, base + HOSTPC1_DEVLC);
        /* wait here, otherwise HOSTPC1_DEVLC_PSPD will timeout */
        mdelay(5);
@@ -1980,16 +2255,6 @@ static int uhsic_phy_bus_reset(struct tegra_usb_phy *phy)
        return 0;
 }
 
-
-static int uhsic_phy_pre_resume(struct tegra_usb_phy *phy, bool remote_wakeup)
-{
-       DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
-
-       usb_phy_wait_for_sof(phy);
-
-       return 0;
-}
-
 static int uhsic_phy_resume(struct tegra_usb_phy *phy)
 {
        void __iomem *base = phy->regs;
@@ -2030,21 +2295,6 @@ static int uhsic_phy_resume(struct tegra_usb_phy *phy)
        return 0;
 }
 
-static int uhsic_phy_post_resume(struct tegra_usb_phy *phy)
-{
-       unsigned long val;
-       void __iomem *base = phy->regs;
-
-       DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
-       val = readl(base + USB_TXFILLTUNING);
-       if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) {
-               val = USB_FIFO_TXFILL_THRES(0x10);
-               writel(val, base + USB_TXFILLTUNING);
-       }
-
-       return 0;
-}
-
 static void ulpi_set_trimmer(struct tegra_usb_phy *phy)
 {
        struct tegra_ulpi_config *config = &phy->pdata->u_cfg.ulpi;
@@ -2718,6 +2968,7 @@ static struct tegra_usb_phy_ops utmi_phy_ops = {
 static struct tegra_usb_phy_ops uhsic_phy_ops = {
        .init           = _usb_phy_init,
        .open           = uhsic_phy_open,
+       .irq            = uhsic_phy_irq,
        .power_on       = uhsic_phy_power_on,
        .power_off      = uhsic_phy_power_off,
        .pre_resume = uhsic_phy_pre_resume,