static int msm_otg_phy_reset(struct msm_otg *motg) { u32 val; int ret; int retries; ret = msm_otg_link_clk_reset(motg, 1); if (ret) return ret; ret = msm_otg_phy_clk_reset(motg); if (ret) return ret; ret = msm_otg_link_clk_reset(motg, 0); if (ret) return ret; val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; writel(val | PORTSC_PTS_ULPI, USB_PORTSC); for (retries = 3; retries > 0; retries--) { ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM, ULPI_CLR(ULPI_FUNC_CTRL)); if (!ret) break; ret = msm_otg_phy_clk_reset(motg); if (ret) return ret; } if (!retries) return -ETIMEDOUT; /* This reset calibrates the phy, if the above write succeeded */ ret = msm_otg_phy_clk_reset(motg); if (ret) return ret; for (retries = 3; retries > 0; retries--) { ret = ulpi_read(&motg->otg, ULPI_DEBUG); if (ret != -ETIMEDOUT) break; ret = msm_otg_phy_clk_reset(motg); if (ret) return ret; } if (!retries) return -ETIMEDOUT; dev_info(motg->otg.dev, "phy_reset: success\n"); return 0; }
static void msm_phy_reset(struct msm_otg *motg) { void __iomem *addr; if (motg->pdata->phy_type != SNPS_28NM_INTEGRATED_PHY) { msm_otg_phy_clk_reset(motg); return; } addr = USB_PHY_CTRL; if (motg->phy_number) addr = USB_PHY_CTRL2; /* Assert USB PHY_POR */ writel(readl(addr) | PHY_POR_ASSERT, addr); /* * wait for minimum 10 microseconds as suggested in HPG. * Use a slightly larger value since the exact value didn't * work 100% of the time. */ udelay(12); /* Deassert USB PHY_POR */ writel(readl(addr) & ~PHY_POR_ASSERT, addr); }