static int msm_ehci_phy_reset(struct msm_hcd *mhcd)
{
	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
	struct msm_usb_host_platform_data *pdata;
	u32 val;
	int ret;

	ret = msm_ehci_link_clk_reset(mhcd, 1);
	if (ret)
		return ret;

	/* Minimum 10msec delay for block reset as per hardware spec */
	usleep_range(10000, 12000);

	ret = msm_ehci_link_clk_reset(mhcd, 0);
	if (ret)
		return ret;

	pdata = mhcd->dev->platform_data;
	if (pdata && pdata->use_sec_phy)
		/* select secondary phy if offset is set for USB operation */
		writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16),
								USB_PHY_CTRL2);
	val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
	writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);

	dev_info(mhcd->dev, "phy_reset: success\n");

	return 0;
}
Esempio n. 2
0
static int msm_ehci_phy_reset(struct msm_hcd *mhcd)
{
	struct usb_hcd *hcd = mhcd_to_hcd(mhcd);
	u32 val;
	int ret;
	int retries;

	ret = msm_ehci_link_clk_reset(mhcd, 1);
	if (ret)
		return ret;

	udelay(1);

	ret = msm_ehci_link_clk_reset(mhcd, 0);
	if (ret)
		return ret;

	val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
	writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);

	for (retries = 3; retries > 0; retries--) {
		ret = msm_ulpi_write(mhcd, ULPI_FUNC_CTRL_SUSPENDM,
				ULPI_CLR(ULPI_FUNC_CTRL));
		if (!ret)
			break;
	}
	if (!retries)
		return -ETIMEDOUT;

	/* Wakeup the PHY with a reg-access for calibration */
	for (retries = 3; retries > 0; retries--) {
		ret = msm_ulpi_read(mhcd, ULPI_DEBUG);
		if (ret != -ETIMEDOUT)
			break;
	}
	if (!retries)
		return -ETIMEDOUT;

	dev_info(mhcd->dev, "phy_reset: success\n");

	return 0;
}