All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
To: Felipe Balbi <balbi@ti.com>
Cc: "Ivan T. Ivanov" <iivanov@mm-sol.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-msm@vger.kernel.org, Tim Bird <tim.bird@sonymobile.com>,
	Mayank Rana <mrana@codeaurora.org>
Subject: [PATCH v6 14/19] usb: phy: msm: Correct USB PHY Reset sequence for newer platform
Date: Tue, 22 Apr 2014 12:20:33 +0300	[thread overview]
Message-ID: <1398158438-21579-15-git-send-email-iivanov@mm-sol.com> (raw)
In-Reply-To: <1398158438-21579-1-git-send-email-iivanov@mm-sol.com>

From: "Ivan T. Ivanov" <iivanov@mm-sol.com>

On few legacy platforms, USB PHY is having dedicated reset clk.
It is used to reset USB PHY after putting USB PHY into low power
mode and for calibration of USB PHY. Putting USB PHY into low
power mode is causing ulpi read/write timeout as expected. USB PHY
reset clk is not available on newer platform.

For 28nm PHY, reset USB PHY after resestting USB LINK.
Also reset USB PHY using USB_PHY_PON bit with USB_OTG_HS_PHY_CTRL
register after programming USB PHY Override registers as suggested
with hardware programming guidelines.

Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Signed-off-by: Tim Bird <tim.bird@sonymobile.com>
Cc: Mayank Rana <mrana@codeaurora.org>
---
 drivers/usb/phy/phy-msm-usb.c    | 140 ++++++++++++++++++++++++---------------
 include/linux/usb/msm_hsusb_hw.h |   5 ++
 2 files changed, 93 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index b03d7f1..dababf9 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -48,6 +48,7 @@
 #define DRIVER_NAME	"msm_otg"

 #define ULPI_IO_TIMEOUT_USEC	(10 * 1000)
+#define LINK_RESET_TIMEOUT_USEC	(250 * 1000)

 #define USB_PHY_3P3_VOL_MIN	3050000 /* uV */
 #define USB_PHY_3P3_VOL_MAX	3300000 /* uV */
@@ -267,77 +268,35 @@ static int msm_otg_phy_clk_reset(struct msm_otg *motg)
 	return ret;
 }

-static int msm_otg_phy_reset(struct msm_otg *motg)
+static int msm_link_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->phy, 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;
+	/* wait for 1ms delay as suggested in HPG. */
+	usleep_range(1000, 1200);

-	/* This reset calibrates the phy, if the above write succeeded */
-	ret = msm_otg_phy_clk_reset(motg);
+	ret = msm_otg_link_clk_reset(motg, 0);
 	if (ret)
 		return ret;

-	for (retries = 3; retries > 0; retries--) {
-		ret = ulpi_read(&motg->phy, ULPI_DEBUG);
-		if (ret != -ETIMEDOUT)
-			break;
-		ret = msm_otg_phy_clk_reset(motg);
-		if (ret)
-			return ret;
-	}
-	if (!retries)
-		return -ETIMEDOUT;
-
 	if (motg->phy_number)
 		writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);

-	dev_info(motg->phy.dev, "phy_reset: success\n");
+	val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK;
+	writel(val | PORTSC_PTS_ULPI, USB_PORTSC);
+
 	return 0;
 }

-#define LINK_RESET_TIMEOUT_USEC		(250 * 1000)
 static int msm_otg_reset(struct usb_phy *phy)
 {
 	struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
-	struct msm_otg_platform_data *pdata = motg->pdata;
 	int cnt = 0;
-	int ret;
-	u32 val = 0;
-	u32 ulpi_val = 0;
-
-	ret = msm_otg_phy_reset(motg);
-	if (ret) {
-		dev_err(phy->dev, "phy_reset failed\n");
-		return ret;
-	}
-
-	ulpi_init(motg);

 	writel(USBCMD_RESET, USB_USBCMD);
 	while (cnt < LINK_RESET_TIMEOUT_USEC) {
@@ -351,11 +310,86 @@ static int msm_otg_reset(struct usb_phy *phy)

 	/* select ULPI phy */
 	writel(0x80000000, USB_PORTSC);
+	writel(0x0, USB_AHBBURST);
+	writel(0x08, USB_AHBMODE);
+
+	if (motg->phy_number)
+		writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
+	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);
+}
+
+static int msm_usb_reset(struct usb_phy *phy)
+{
+	struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
+	int ret;
+
+	if (!IS_ERR(motg->core_clk))
+		clk_prepare_enable(motg->core_clk);
+
+	ret = msm_link_reset(motg);
+	if (ret) {
+		dev_err(phy->dev, "phy_reset failed\n");
+		return ret;
+	}
+
+	ret = msm_otg_reset(&motg->phy);
+	if (ret) {
+		dev_err(phy->dev, "link reset failed\n");
+		return ret;
+	}

 	msleep(100);

-	writel(0x0, USB_AHBBURST);
-	writel(0x00, USB_AHBMODE);
+	/* Reset USB PHY after performing USB Link RESET */
+	msm_phy_reset(motg);
+
+	if (!IS_ERR(motg->core_clk))
+		clk_disable_unprepare(motg->core_clk);
+
+	return 0;
+}
+
+static int msm_phy_init(struct usb_phy *phy)
+{
+	struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
+	struct msm_otg_platform_data *pdata = motg->pdata;
+	u32 val, ulpi_val = 0;
+
+	/* Program USB PHY Override registers. */
+	ulpi_init(motg);
+
+	/*
+	 * It is recommended in HPG to reset USB PHY after programming
+	 * USB PHY Override registers.
+	 */
+	msm_phy_reset(motg);

 	if (pdata->otg_control == OTG_PHY_CONTROL) {
 		val = readl(USB_OTGSC);
@@ -1571,7 +1605,7 @@ static int msm_otg_probe(struct platform_device *pdev)
 		goto disable_ldo;
 	}

-	phy->init = msm_otg_reset;
+	phy->init = msm_phy_init;
 	phy->set_power = msm_otg_set_power;

 	phy->io_ops = &msm_otg_io_ops;
@@ -1580,6 +1614,8 @@ static int msm_otg_probe(struct platform_device *pdev)
 	phy->otg->set_host = msm_otg_set_host;
 	phy->otg->set_peripheral = msm_otg_set_peripheral;

+	msm_usb_reset(phy);
+
 	ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2);
 	if (ret) {
 		dev_err(&pdev->dev, "usb_add_phy failed\n");
diff --git a/include/linux/usb/msm_hsusb_hw.h b/include/linux/usb/msm_hsusb_hw.h
index e6d7035..575c743 100644
--- a/include/linux/usb/msm_hsusb_hw.h
+++ b/include/linux/usb/msm_hsusb_hw.h
@@ -42,9 +42,14 @@
 #define ULPI_DATA(n)          ((n) & 255)
 #define ULPI_DATA_READ(n)     (((n) >> 8) & 255)

+/* synopsys 28nm phy registers */
+#define ULPI_PWR_CLK_MNG_REG	0x88
+#define OTG_COMP_DISABLE	BIT(0)
+
 #define ASYNC_INTR_CTRL         (1 << 29) /* Enable async interrupt */
 #define ULPI_STP_CTRL           (1 << 30) /* Block communication with PHY */
 #define PHY_RETEN               (1 << 1) /* PHY retention enable/disable */
+#define PHY_POR_ASSERT		(1 << 0) /* USB2 28nm PHY POR ASSERT */

 /* OTG definitions */
 #define OTGSC_INTSTS_MASK	(0x7f << 16)
--
1.8.3.2

  parent reply	other threads:[~2014-04-22  9:20 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-22  9:20 [PATCH v6 00/19] usb: phy: msm: Fixes, cleanups and DT support Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 01/19] usb: phy: msm: Make driver selectable on ARCH_QCOM Ivan T. Ivanov
     [not found]   ` <1398158438-21579-2-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-04-22 14:57     ` Felipe Balbi
2014-04-22 14:57       ` Felipe Balbi
2014-04-22 15:16       ` Ivan T. Ivanov
2014-04-22 15:24         ` Felipe Balbi
2014-04-22 15:24           ` Felipe Balbi
     [not found]           ` <20140422152425.GL5524-HgARHv6XitL9zxVx7UNMDg@public.gmane.org>
2014-04-23  8:48             ` Ivan T. Ivanov
2014-04-23  8:48               ` Ivan T. Ivanov
2014-04-23 15:02               ` Felipe Balbi
2014-04-23 15:02                 ` Felipe Balbi
2014-04-22  9:20 ` [PATCH v6 02/19] usb: phy: msm: Remove __init macro from driver probe method Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 06/19] usb: phy: msm: Fix checkpatch.pl warnings Ivan T. Ivanov
2014-04-22 15:30   ` Srinivas Kandagatla
2014-04-23  6:51     ` Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 07/19] usb: phy: msm: Replace custom enum usb_mode_type with enum usb_dr_mode Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 08/19] usb: phy: msm: Remove unused pclk_src_name Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 10/19] usb: phy: msm: Properly check result from platform_get_irq() Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 11/19] usb: phy: msm: Add device tree support and binding information Ivan T. Ivanov
     [not found]   ` <1398158438-21579-12-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-04-22 16:05     ` Srinivas Kandagatla
2014-04-22 16:05       ` Srinivas Kandagatla
2014-04-23  7:48       ` Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 12/19] usb: phy: msm: Use reset framework for LINK and PHY resets Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 13/19] usb: phy: msm: Add support for secondary PHY control Ivan T. Ivanov
2014-04-22  9:20 ` Ivan T. Ivanov [this message]
2014-04-22  9:20 ` [PATCH v6 15/19] usb: phy: msm: Fix PTS definitions for MSM USB controller Ivan T. Ivanov
     [not found]   ` <1398158438-21579-16-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-04-22 13:09     ` Sergei Shtylyov
2014-04-22 13:09       ` Sergei Shtylyov
2014-04-23 13:24       ` Ivan T. Ivanov
2014-04-23 13:35         ` Ivan T. Ivanov
2014-04-23 13:45           ` Sergei Shtylyov
2014-04-23 13:45             ` Sergei Shtylyov
2014-04-23 13:53             ` Ivan T. Ivanov
2014-04-23 14:09               ` Sergei Shtylyov
     [not found]                 ` <5357C99F.6070009-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
2014-04-23 14:14                   ` Ivan T. Ivanov
2014-04-23 14:14                     ` Ivan T. Ivanov
2014-04-23 14:31                     ` Sergei Shtylyov
2014-04-22  9:20 ` [PATCH v6 17/19] usb: phy: msm: Handle disconnect events Ivan T. Ivanov
     [not found] ` <1398158438-21579-1-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-04-22  9:20   ` [PATCH v6 03/19] usb: phy: msm: Move global regulators variables to driver state Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
2014-04-22 14:57     ` Felipe Balbi
2014-04-22 14:57       ` Felipe Balbi
     [not found]       ` <20140422145745.GJ5524-HgARHv6XitL9zxVx7UNMDg@public.gmane.org>
2014-04-22 15:12         ` Ivan T. Ivanov
2014-04-22 15:12           ` Ivan T. Ivanov
2014-04-22 15:14           ` Felipe Balbi
2014-04-22 15:14             ` Felipe Balbi
2014-04-22  9:20   ` [PATCH v6 04/19] usb: phy: msm: Migrate to Managed Device Resource allocation Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
     [not found]     ` <1398158438-21579-5-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-04-22 15:07       ` Srinivas Kandagatla
2014-04-22 15:07         ` Srinivas Kandagatla
2014-04-22 15:19         ` Ivan T. Ivanov
2014-04-22  9:20   ` [PATCH v6 05/19] usb: phy: msm: Remove unnecessarily check for valid regulators Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
2014-04-22  9:20   ` [PATCH v6 09/19] usb: phy: msm: Remove HSUSB prefix from regulator names Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
2014-04-22  9:20   ` [PATCH v6 16/19] usb: phy: msm: Select secondary PHY via TCSR Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
2014-04-22  9:20   ` [PATCH v6 18/19] usb: phy: msm: Vote for corner of VDD CX instead of voltage of VDD CX Ivan T. Ivanov
2014-04-22  9:20     ` Ivan T. Ivanov
2014-04-22  9:20 ` [PATCH v6 19/19] usb: phy: msm: Use usb_add_phy_dev() to register device Ivan T. Ivanov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1398158438-21579-15-git-send-email-iivanov@mm-sol.com \
    --to=iivanov@mm-sol.com \
    --cc=balbi@ti.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mrana@codeaurora.org \
    --cc=tim.bird@sonymobile.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.