public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Roger Quadros <rogerq@ti.com>
To: <lee.jones@linaro.org>, <sameo@linux.intel.com>
Cc: <tomi.valkeinen@ti.com>, <balbi@ti.com>, <sr@denx.de>,
	<ljkenny.mailinglists@gmail.com>, <linux-omap@vger.kernel.org>,
	<linux-usb@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Roger Quadros <rogerq@ti.com>, <stable@vger.kernel.org>
Subject: [PATCH 1/1] mfd: omap-usb-host: Fix USB device detection problems on OMAP4 Panda
Date: Fri, 29 Nov 2013 15:01:58 +0200	[thread overview]
Message-ID: <1385730118-26402-2-git-send-email-rogerq@ti.com> (raw)
In-Reply-To: <1385730118-26402-1-git-send-email-rogerq@ti.com>

With u-boot 2013.10, USB devices are sometimes not detected
on OMAP4 Panda. To make us independent of what bootloader does
with the USB Host module, we must RESET it to get it to a known
good state. This patch Soft RESETs the USB Host module.

Reported-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: <stable@vger.kernel.org> # 3.10+
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mfd/omap-usb-host.c | 115 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 109 insertions(+), 6 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 142650f..d4bd464 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -43,14 +43,18 @@
 /* UHH Register Set */
 #define	OMAP_UHH_REVISION				(0x00)
 #define	OMAP_UHH_SYSCONFIG				(0x10)
-#define	OMAP_UHH_SYSCONFIG_MIDLEMODE			(1 << 12)
+#define	OMAP_UHH_SYSCONFIG_MIDLEMASK			(3 << 12)
+#define OMAP_UHH_SYSCONFIG_MIDLESHIFT			(12)
 #define	OMAP_UHH_SYSCONFIG_CACTIVITY			(1 << 8)
-#define	OMAP_UHH_SYSCONFIG_SIDLEMODE			(1 << 3)
+#define	OMAP_UHH_SYSCONFIG_SIDLEMASK			(3 << 3)
+#define	OMAP_UHH_SYSCONFIG_SIDLESHIFT			(3)
 #define	OMAP_UHH_SYSCONFIG_ENAWAKEUP			(1 << 2)
 #define	OMAP_UHH_SYSCONFIG_SOFTRESET			(1 << 1)
 #define	OMAP_UHH_SYSCONFIG_AUTOIDLE			(1 << 0)
 
 #define	OMAP_UHH_SYSSTATUS				(0x14)
+#define OMAP_UHH_SYSSTATUS_RESETDONE			(1 << 0)
+
 #define	OMAP_UHH_HOSTCONFIG				(0x40)
 #define	OMAP_UHH_HOSTCONFIG_ULPI_BYPASS			(1 << 0)
 #define	OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS		(1 << 0)
@@ -66,10 +70,10 @@
 #define OMAP4_UHH_HOSTCONFIG_APP_START_CLK		(1 << 31)
 
 /* OMAP4-specific defines */
-#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR		(3 << 2)
-#define OMAP4_UHH_SYSCONFIG_NOIDLE			(1 << 2)
-#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR		(3 << 4)
-#define OMAP4_UHH_SYSCONFIG_NOSTDBY			(1 << 4)
+#define OMAP4_UHH_SYSCONFIG_MIDLEMASK			(3 << 2)
+#define OMAP4_UHH_SYSCONFIG_MIDLESHIFT			(2)
+#define OMAP4_UHH_SYSCONFIG_SIDLEMASK			(3 << 4)
+#define OMAP4_UHH_SYSCONFIG_SIDLESHIFT			(4)
 #define OMAP4_UHH_SYSCONFIG_SOFTRESET			(1 << 0)
 
 #define OMAP4_P1_MODE_CLEAR				(3 << 16)
@@ -81,6 +85,12 @@
 
 #define	OMAP_UHH_DEBUG_CSR				(0x44)
 
+/* MIDLE modes */
+#define OMAP_UHH_SYSCONFIG_MIDLE_NOSTANDBY		(1)
+
+/* SIDLE modes */
+#define OMAP_UHH_SYSCONFIG_SIDLE_NOIDLE			(1)
+
 /* Values of UHH_REVISION - Note: these are not given in the TRM */
 #define OMAP_USBHS_REV1		0x00000010	/* OMAP3 */
 #define OMAP_USBHS_REV2		0x50700100	/* OMAP4 */
@@ -474,6 +484,97 @@ static unsigned omap_usbhs_rev2_hostconfig(struct usbhs_hcd_omap *omap,
 	return reg;
 }
 
+static void omap_usbhs_rev1_reset(struct device *dev)
+{
+	struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
+	u32 reg;
+	unsigned long timeout;
+
+	reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
+
+	/* Soft Reset */
+	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
+		    reg | OMAP_UHH_SYSCONFIG_SOFTRESET);
+
+	timeout = jiffies + msecs_to_jiffies(100);
+	while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
+			& OMAP_UHH_SYSSTATUS_RESETDONE)) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout)) {
+			dev_err(dev, "Soft RESET operation timed out\n");
+			break;
+		}
+	}
+
+	/* Set No-Standby */
+	reg &= ~OMAP_UHH_SYSCONFIG_MIDLEMASK;
+	reg |= OMAP_UHH_SYSCONFIG_MIDLE_NOSTANDBY
+		<< OMAP_UHH_SYSCONFIG_MIDLESHIFT;
+
+	/* Set No-Idle */
+	reg &= ~OMAP_UHH_SYSCONFIG_SIDLEMASK;
+	reg |= OMAP_UHH_SYSCONFIG_SIDLE_NOIDLE
+		<< OMAP_UHH_SYSCONFIG_SIDLESHIFT;
+
+	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
+}
+
+static void omap_usbhs_rev2_reset(struct device *dev)
+{
+	struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
+	u32 reg;
+	unsigned long timeout;
+
+	reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
+
+	/* Soft Reset */
+	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
+		    reg | OMAP4_UHH_SYSCONFIG_SOFTRESET);
+
+	/* OMAP4: Need to wait before SYSCONFIG can be accessed */
+	udelay(2);
+	timeout = jiffies + msecs_to_jiffies(100);
+
+	/* SOFTRESET bit clears when RESET completes */
+	while (usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG)
+			& OMAP4_UHH_SYSCONFIG_SOFTRESET) {
+		cpu_relax();
+
+		if (time_after(jiffies, timeout)) {
+			dev_err(dev, "Soft RESET operation timed out\n");
+			break;
+		}
+	}
+
+	/* Set No-Standby */
+	reg &= ~OMAP4_UHH_SYSCONFIG_MIDLEMASK;
+	reg |= OMAP_UHH_SYSCONFIG_MIDLE_NOSTANDBY
+		<< OMAP4_UHH_SYSCONFIG_MIDLESHIFT;
+
+	/* Set No-Idle */
+	reg &= ~OMAP4_UHH_SYSCONFIG_SIDLEMASK;
+	reg |= OMAP_UHH_SYSCONFIG_SIDLE_NOIDLE
+		<< OMAP4_UHH_SYSCONFIG_SIDLESHIFT;
+
+	usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
+}
+
+static void omap_usbhs_softreset(struct device *dev)
+{
+	struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
+
+	switch (omap->usbhs_rev) {
+	case OMAP_USBHS_REV1:
+		omap_usbhs_rev1_reset(dev);
+		break;
+
+	default:	/* Rev 2 onwards */
+		omap_usbhs_rev2_reset(dev);
+		break;
+	}
+}
+
 static void omap_usbhs_init(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
@@ -483,6 +584,8 @@ static void omap_usbhs_init(struct device *dev)
 
 	pm_runtime_get_sync(dev);
 
+	omap_usbhs_softreset(dev);
+
 	reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
 	/* setup ULPI bypass and burst configurations */
 	reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
-- 
1.8.3.2


       reply	other threads:[~2013-11-29 13:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1385730118-26402-1-git-send-email-rogerq@ti.com>
2013-11-29 13:01 ` Roger Quadros [this message]
2013-11-29 13:17   ` [PATCH 1/1] mfd: omap-usb-host: Fix USB device detection problems on OMAP4 Panda David Laight
2013-12-02  8:39     ` Roger Quadros
2013-12-02 16:28       ` David Laight
2013-11-29 15:32   ` Michael Trimarchi
2013-12-02  9:41     ` Roger Quadros
2013-11-30  4:48   ` Michael Trimarchi
2013-11-30  5:10     ` Michael Trimarchi
2013-12-01  3:14       ` Michael Trimarchi
2013-12-02  9:39     ` Roger Quadros
2013-12-02  9:51       ` Michael Trimarchi
2013-12-02 12:05         ` Roger Quadros
2013-12-02 15:00       ` Paul Walmsley

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=1385730118-26402-2-git-send-email-rogerq@ti.com \
    --to=rogerq@ti.com \
    --cc=balbi@ti.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=ljkenny.mailinglists@gmail.com \
    --cc=sameo@linux.intel.com \
    --cc=sr@denx.de \
    --cc=stable@vger.kernel.org \
    --cc=tomi.valkeinen@ti.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox