[0/4] musb host improvments mostly for omap2430 glue
mbox series

Message ID 20190830232058.53414-1-tony@atomide.com
Headers show
Series
  • musb host improvments mostly for omap2430 glue
Related show

Message

Tony Lindgren Aug. 30, 2019, 11:20 p.m. UTC
Hi all,

So I ended up cleaning up omap2430 glue layer a bit for host mode with the
various reproducable errors I was seeing docking droid4 to a lapdock. There
are a few fixes, and then we end up removing all the devctl register tinkering
for omap2430 glue layer.

Regards,

Tony


Tony Lindgren (4):
  usb: musb: omap2430: Wait on enable to avoid babble
  usb: musb: omap2430: Handle multiple ID ground interrupts
  usb: musb: Add musb_set_host and peripheral and use them for omap2430
  usb: musb: omap2430: Clean up enable and remove devctl tinkering

 drivers/usb/musb/musb_core.c | 103 ++++++++++++++++++++++++++++++
 drivers/usb/musb/musb_core.h |   3 +
 drivers/usb/musb/omap2430.c  | 118 +++++++++++++----------------------
 3 files changed, 149 insertions(+), 75 deletions(-)

Comments

Pavel Machek Sept. 1, 2019, 7:39 p.m. UTC | #1
Hi!

> So I ended up cleaning up omap2430 glue layer a bit for host mode with the
> various reproducable errors I was seeing docking droid4 to a lapdock. There
> are a few fixes, and then we end up removing all the devctl register tinkering
> for omap2430 glue layer.

I thought I'd test this, so I took

commit 6d028043b55e54f48fbdf62ea8ce11a4ad830cac
    Add linux-next specific files for 20190830

Series (and the other two patches you sent around it) applies ok, but
the result does not boot.

Hmm.

I guess I'll need to resurrect the serial port cable.

Best regards,
									Pavel
Pavel Machek Sept. 1, 2019, 7:49 p.m. UTC | #2
On Sun 2019-09-01 21:39:25, Pavel Machek wrote:
> Hi!
> 
> > So I ended up cleaning up omap2430 glue layer a bit for host mode with the
> > various reproducable errors I was seeing docking droid4 to a lapdock. There
> > are a few fixes, and then we end up removing all the devctl register tinkering
> > for omap2430 glue layer.
> 
> I thought I'd test this, so I took
> 
> commit 6d028043b55e54f48fbdf62ea8ce11a4ad830cac
>     Add linux-next specific files for 20190830
> 
> Series (and the other two patches you sent around it) applies ok, but
> the result does not boot.

Hmm. Maybe I'm just having problem with the backlight. I do see
regulator failure:

[    2.143920] cpcap-usb-phy cpcap-usb-phy.0: using device tree for
GPIO lookup
[    2.151031] of_get_named_gpiod_flags: parsed 'mode-gpios' property
of node ')
[    2.166015] gpio gpiochip2: Persistence not supported for GPIO 28
214935] ------------[ cut here ]------------
[    2.219604] WARNING: CPU: 0 PID: 1 at drivers/regulator/core.c:2040
_regulat0
[    2.228118] Modules linked in:
[    2.231201] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
5.3.0-rc6-next-20190834
[    2.238800] Hardware name: Generic OMAP4 (Flattened Device Tree)
[    2.244873] [<c010f224>] (unwind_backtrace) from [<c010b4fc>]
(show_stack+0x)
[    2.252655] [<c010b4fc>] (show_stack) from [<c08ca584>]
(dump_stack+0xa8/0xc)

and some drm problems:

[   59.303253] omap-mcbsp 40124000.mcbsp: CLKS: could not clk_get()
prcm_fck
[   59.311492] ------------[ cut here ]------------
[   59.314666] WARNING: CPU: 0 PID: 2704 at
drivers/gpu/drm/omapdrm/dss/hdmi4.c0
[   59.325866] Modules linked in:
[   59.328948] CPU: 0 PID: 2704 Comm: alsa-sink-HDMI  Tainted: G
W      4
[   59.337982] Hardware name: Generic OMAP4 (Flattened Device Tree)
[   59.344757] [<c010f224>] (unwind_backtrace) from [<c010b4fc>]
(show_stack+0x)
[   59.352569] [<c010b4fc>] (show_stack) from [<c08ca584>]
(dump_stack+0xa8/0xc)
[   59.359832] [<c08ca584>] (dump_stack) from [<c012de94>]
(__warn+0xc8/0xf0)

But I get login prompt on the serial. And after I do:

root@devuan:/sys/class/leds/lm3532::backlight# echo 255 > brightness

I can even see X are running.

Good so far :-).

Best regards,							Pavel
Pavel Machek Sept. 2, 2019, 9:23 a.m. UTC | #3
Hi!

> So I ended up cleaning up omap2430 glue layer a bit for host mode with the
> various reproducable errors I was seeing docking droid4 to a lapdock. There
> are a few fixes, and then we end up removing all the devctl register tinkering
> for omap2430 glue layer.

I should have your recent patches up-to [PATCH] power: supply:
cpcap-charger: Enable vbus boost voltage applied to linux-next, -0830.

So... to get usb host to work even with stock kernel, I need a hub and
external power... and "right" cable between phone and hub.

When I plugged/unplugged it several times, I got

### usb unplug:
musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
ub0: stop stats: rx/tx 0/0, errs 0/0
l3_init_cm:clk:0040:0: failed to disable
l3_init_cm:clk:00c0:0: failed to disable
### usb plug produces nothing
### usb unplug:
musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80

Hmm. I did it two more times, and now machine rebooted, and USB was
powered from the phone for a while (3.6V).

And I reproduced the crash on the next boot.

Is there anything I may be missing in .config?

Best regards,
									Pavel
Pavel Machek Sept. 2, 2019, 9:44 a.m. UTC | #4
On Mon 2019-09-02 11:23:44, Pavel Machek wrote:
> Hi!
> 
> > So I ended up cleaning up omap2430 glue layer a bit for host mode with the
> > various reproducable errors I was seeing docking droid4 to a lapdock. There
> > are a few fixes, and then we end up removing all the devctl register tinkering
> > for omap2430 glue layer.
> 
> I should have your recent patches up-to [PATCH] power: supply:
> cpcap-charger: Enable vbus boost voltage applied to linux-next, -0830.
> 
> So... to get usb host to work even with stock kernel, I need a hub and
> external power... and "right" cable between phone and hub.
> 
> When I plugged/unplugged it several times, I got
> 
> ### usb unplug:
> musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
> musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
> ub0: stop stats: rx/tx 0/0, errs 0/0
> l3_init_cm:clk:0040:0: failed to disable
> l3_init_cm:clk:00c0:0: failed to disable
> ### usb plug produces nothing
> ### usb unplug:
> musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
> musb-hdrc.0.auto: musb_set_peripheral: already in peripheral mode: 80
> 
> Hmm. I did it two more times, and now machine rebooted, and USB was
> powered from the phone for a while (3.6V).
> 
> And I reproduced the crash on the next boot.
> 
> Is there anything I may be missing in .config?

Hmm. I guess CONFIG_USB_MUSB_DUAL_ROLE=y might be useful.

And now... if I unplug/replug the usb after the boot, USB hub and
mouse are recognized. Good!

Less than minute later:

mmusb-hdrc.0.auto: Babble
USB disconnect

I unplug, replug usb (not at the phone, between hub and dongle, and
green LED indincating charging starts blinking rapidly.

cpcap-core spi0.0: EOT timed out.

I try plug/replug, and now green led is on.

I unplug replug at the phone, and get bunch more of messages:

musm _set_peripheral: already in peripheral mode: 99
musm _set_peripheral: already in peripheral mode: 81
musm _set_peripheral: already in peripheral mode: 81

musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99
musb_set_host: could not set host: 99

Unplug/replug at host, and again, hub+mouse is detected.

I unplug power connected to one of USB hub's ports... and find out
that phone was _not_ powering it.

Ok... so something somehow works.... sometimes :-).

								Pavel
Tony Lindgren Sept. 2, 2019, 4:06 p.m. UTC | #5
* Pavel Machek <pavel@denx.de> [190902 09:44]:
> On Mon 2019-09-02 11:23:44, Pavel Machek wrote:
> Hmm. I guess CONFIG_USB_MUSB_DUAL_ROLE=y might be useful.
> 
> And now... if I unplug/replug the usb after the boot, USB hub and
> mouse are recognized. Good!
> 
> Less than minute later:
> 
> mmusb-hdrc.0.auto: Babble
> USB disconnect

The babble is most likely caused by some kind of signaling issue.

> I unplug, replug usb (not at the phone, between hub and dongle, and
> green LED indincating charging starts blinking rapidly.
> 
> cpcap-core spi0.0: EOT timed out.
> 
> I try plug/replug, and now green led is on.
> 
> I unplug replug at the phone, and get bunch more of messages:
> 
> musm _set_peripheral: already in peripheral mode: 99
> musm _set_peripheral: already in peripheral mode: 81
> musm _set_peripheral: already in peripheral mode: 81
> 
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> musb_set_host: could not set host: 99
> 
> Unplug/replug at host, and again, hub+mouse is detected.
> 
> I unplug power connected to one of USB hub's ports... and find out
> that phone was _not_ powering it.
> 
> Ok... so something somehow works.... sometimes :-).

My guess is you're missing a USB micro-B cable with ID pin
grounded, with that things should just work automagically.

So no need for hubs feeding back VBUS and no need to
try to force host mode via sysfs unlike on n900.

Regards,

Tony
Pavel Machek Sept. 3, 2019, 8:07 a.m. UTC | #6
Hi!

On Mon 2019-09-02 09:06:51, Tony Lindgren wrote:
> * Pavel Machek <pavel@denx.de> [190902 09:44]:
> > On Mon 2019-09-02 11:23:44, Pavel Machek wrote:
> > Hmm. I guess CONFIG_USB_MUSB_DUAL_ROLE=y might be useful.
> > 
> > And now... if I unplug/replug the usb after the boot, USB hub and
> > mouse are recognized. Good!
> > 
> > Less than minute later:
> > 
> > mmusb-hdrc.0.auto: Babble
> > USB disconnect
> 
> The babble is most likely caused by some kind of signaling issue.
> 
> > I unplug, replug usb (not at the phone, between hub and dongle, and
> > green LED indincating charging starts blinking rapidly.
> > 
> > cpcap-core spi0.0: EOT timed out.
> > 
> > I try plug/replug, and now green led is on.
> > 
> > I unplug replug at the phone, and get bunch more of messages:
> > 
> > musm _set_peripheral: already in peripheral mode: 99
> > musm _set_peripheral: already in peripheral mode: 81
> > musm _set_peripheral: already in peripheral mode: 81
> > 
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > musb_set_host: could not set host: 99
> > 
> > Unplug/replug at host, and again, hub+mouse is detected.
> > 
> > I unplug power connected to one of USB hub's ports... and find out
> > that phone was _not_ powering it.
> > 
> > Ok... so something somehow works.... sometimes :-).
> 
> My guess is you're missing a USB micro-B cable with ID pin
> grounded, with that things should just work automagically.
> 
> So no need for hubs feeding back VBUS and no need to
> try to force host mode via sysfs unlike on n900.

I don't think so... I got it to run in the end (and I have to
apologize, it seems to work at least as long as it is plugged it an
boot and not touched).

So... I actually have two cables.

#1 definitely does not have ID pin grounded. That does not work, not
 even in original android.

#2 definitely has _something_, because it does work in original
 android. But not even original android provides VBUS (5V on USB) in
 that configuration. It also looks like hardware _can_ provide at
 least VBAT on VBUS, because I seen that during some of the crashes.

Thanks for the patches, BTW.

Best regards,
							Pavel
Tony Lindgren Sept. 16, 2019, 1:20 a.m. UTC | #7
Hi,

* Pavel Machek <pavel@ucw.cz> [190903 08:08]:
> On Mon 2019-09-02 09:06:51, Tony Lindgren wrote:
> #2 definitely has _something_, because it does work in original
>  android. But not even original android provides VBUS (5V on USB) in
>  that configuration. It also looks like hardware _can_ provide at
>  least VBAT on VBUS, because I seen that during some of the crashes.

I started seeing the musb hang issue you reported today
on one droid4 but not on an other one :) Turns out we have
racy .set_vbus still around that might get called.

The following patch is needed in preparation for this $subject
series as otherwise patch "[PATCH 3/4] usb: musb: Add
musb_set_host and peripheral and use them for omap2430" can
cause a hang with "scheduling while atomic" if .set_vbus
gets called from musb_stage0_irq() path.

Regards,

Tony

8< -----------------
From tony Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Sun, 15 Sep 2019 17:16:58 -0700
Subject: [PATCH] usb: musb: Get rid of musb_set_vbus()

We currently have musb_set_vbus() called from two different paths. Mostly
it gets called from the USB PHY via omap_musb_set_mailbox(), but in some
cases it can get also called from musb_stage0_irq() rather via .set_vbus:

(musb_set_host [musb_hdrc])
(omap2430_musb_set_vbus [omap2430])
(musb_stage0_irq [musb_hdrc])
(musb_interrupt [musb_hdrc])
(omap2430_musb_interrupt [omap2430])

This is racy and will not work with introducing generic helper functions
for musb_set_host() and musb_set_peripheral(). We want to get rid of the
busy loops in favor of usleep_range().

Let's just get rid of .set_vbus for omap2430 glue layer and let the PHY
code handle VBUS with musb_set_vbus(). Note that in the follow-up patch
we can completely remove omap2430_musb_set_vbus(), but let's do it in a
separate patch as this change may actually turn out to be needed as a
fix.

Reported-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/usb/musb/omap2430.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -312,8 +312,6 @@ static const struct musb_platform_ops omap2430_ops = {
 	.init		= omap2430_musb_init,
 	.exit		= omap2430_musb_exit,
 
-	.set_vbus	= omap2430_musb_set_vbus,
-
 	.enable		= omap2430_musb_enable,
 	.disable	= omap2430_musb_disable,
Tony Lindgren Sept. 16, 2019, 1:26 a.m. UTC | #8
* Tony Lindgren <tony@atomide.com> [190916 01:21]:
> Let's just get rid of .set_vbus for omap2430 glue layer and let the PHY
> code handle VBUS with musb_set_vbus(). Note that in the follow-up patch
> we can completely remove omap2430_musb_set_vbus(), but let's do it in a
> separate patch as this change may actually turn out to be needed as a
> fix.

FYI, below is a quick take at dropping omap2430_musb_set_vbus(),
needs more testing though. I'm still seeing some errors on
disconnect with this one like:

VBUS_ERROR in b_idle (80, <SessEnd), retry #0, port1 00000100

Other than that, things seems to work just fine for host and
peripheral.

Regards,

Tony

8< -------------------From tony Mon Sep 17 00:00:00 2001
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -38,41 +38,6 @@ struct omap2430_glue {
 
 static struct omap2430_glue	*_glue;
 
-/*
- * HDRC controls CPEN, but beware current surges during device connect.
- * They can trigger transient overcurrent conditions that must be ignored.
- *
- * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
- * as set by musb_set_peripheral().
- */
-static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
-{
-	struct usb_otg *otg = musb->xceiv->otg;
-	int error;
-
-	if (is_on) {
-		switch (musb->xceiv->otg->state) {
-		case OTG_STATE_A_IDLE:
-			error = musb_set_host(musb);
-			if (!error) {
-				musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
-				otg_set_vbus(otg, 1);
-			}
-			break;
-		default:
-			otg_set_vbus(otg, 1);
-			break;
-		}
-	} else {
-		error = musb_set_peripheral(musb);
-		otg_set_vbus(otg, 0);
-	}
-
-	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
-		usb_otg_state_string(musb->xceiv->otg->state),
-		musb_readb(musb->mregs, MUSB_DEVCTL));
-}
-
 static inline void omap2430_low_level_exit(struct musb *musb)
 {
 	u32 l;
@@ -112,27 +77,42 @@ static int omap2430_musb_mailbox(enum musb_vbus_id_status status)
 	return 0;
 }
 
+/*
+ * HDRC controls CPEN, but beware current surges during device connect.
+ * They can trigger transient overcurrent conditions that must be ignored.
+ *
+ * Note that we're skipping A_WAIT_VFALL -> A_IDLE and jumping right to B_IDLE
+ * as set by musb_set_peripheral().
+ */
 static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 {
 	struct musb *musb = glue_to_musb(glue);
-	struct musb_hdrc_platform_data *pdata =
-		dev_get_platdata(musb->controller);
-	struct omap_musb_board_data *data = pdata->board_data;
+	int error;
 
 	pm_runtime_get_sync(musb->controller);
+
+	dev_dbg(musb->controller, "VBUS %s, devctl %02x\n",
+		usb_otg_state_string(musb->xceiv->otg->state),
+		musb_readb(musb->mregs, MUSB_DEVCTL));
+
 	switch (glue->status) {
 	case MUSB_ID_GROUND:
 		dev_dbg(musb->controller, "ID GND\n");
 		switch (musb->xceiv->otg->state) {
+		case OTG_STATE_A_IDLE:
+			error = musb_set_host(musb);
+			if (error)
+				break;
+			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
+			/* Fall through */
 		case OTG_STATE_A_WAIT_VRISE:
 		case OTG_STATE_A_WAIT_BCON:
 		case OTG_STATE_A_HOST:
-		case OTG_STATE_A_IDLE:
 			/*
 			 * On multiple ID ground interrupts just keep enabling
 			 * VBUS. At least cpcap VBUS shuts down otherwise.
 			 */
-			omap2430_musb_set_vbus(musb, 1);
+			otg_set_vbus(musb->xceiv->otg, 1);
 			break;
 		default:
 			musb->xceiv->otg->state = OTG_STATE_A_IDLE;
@@ -140,7 +120,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 			if (musb->gadget_driver) {
 				omap_control_usb_set_mode(glue->control_otghs,
 							  USB_MODE_HOST);
-				omap2430_musb_set_vbus(musb, 1);
+				otg_set_vbus(musb->xceiv->otg, 1);
 			}
 			break;
 		}
@@ -159,14 +139,10 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
 		dev_dbg(musb->controller, "VBUS Disconnect\n");
 
 		musb->xceiv->last_event = USB_EVENT_NONE;
-		if (musb->gadget_driver)
-			omap2430_musb_set_vbus(musb, 0);
-
-		if (data->interface_type == MUSB_INTERFACE_UTMI)
-			otg_set_vbus(musb->xceiv->otg, 0);
-
+		otg_set_vbus(musb->xceiv->otg, 0);
 		omap_control_usb_set_mode(glue->control_otghs,
 			USB_MODE_DISCONNECT);
+		musb_set_peripheral(musb);
 		break;
 	default:
 		dev_dbg(musb->controller, "ID float\n");