From: Rob Weber <rob@gnarbox.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: "Claus H. Stovgaard" <cst@phaseone.com>,
"balbi@kernel.org" <balbi@kernel.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"mnarani@xilinx.com" <mnarani@xilinx.com>,
Michal Simek <michal.simek@xilinx.com>
Subject: Use device tree to disable U1/U2 in gadget devices based on DWC3
Date: Thu, 25 Apr 2019 13:11:03 -0700 [thread overview]
Message-ID: <20190425201103.GA26402@coops> (raw)
Hi Everyone,
On Wed, Apr 24, 2019 at 02:33:48PM -0400, Alan Stern wrote:
> On Wed, 24 Apr 2019, Claus H. Stovgaard wrote:
>
> > Hi Balbi and other USB developers.
> >
> > I am developing camera devices based on Xilinx ZynqMP, using the
> > gadget framework and the build-in dwc3 core of the ZynqMP as USB3
> > controller and the build-in Cirrus SERDES as phy.
> > Testing with a number of hosts and Windows 7, has shown sporadic
> > reconnects when leaving U2/U1, caused by failing link training, where
> > the host resets the bus. Sometime it also means it reconnect via
> > USB2.
> >
> > So to overcome this, I will like to have the option for disabling
> > U1/U2 on the core when working with those hosts.
> >
> > Currently I have made a hack in ep0.c where I return EINVAL in
> > dwc3_ep0_handle_u1 and dwc3_ep0_handle_u2 together with not setting
> > DWC3_DCTL_ACCEPTU1ENA and DWC3_DCTL_ACCEPTU2ENA in
> > dwc3_ep0_set_config
> > Will though prefer a solution possible to upstream, so was thinking
> > about adding two devicetree bindings.
> >
> > * snps,u1_disable_as_gadget: When set the core will not enable U1 if
> > requested from host, nor initiate U1.
> > * snps,u2_disable_as_gadget: When set the core will not enable U2 if
> > requested from host, nor initiate U2.
> >
> > If you think this might be something which can be upstreamed I will
> > prepare the code and send a patch for discussion.
> > On the other hand, if you think that disabling U1/U2 via device tree
> > as suggested should not be a feature no need for me to try making it
> > a feature.
>
> Speaking as an interested bystander, I would first wonder why your
> hardware fails during link training. If it is properly designed, that
> should not happen. The fact that it does happen suggests your devices
> might also experience problems during normal data transport.
I was recently debugging a similar problem where my device would
improperly transition from U2 to U0. This caused the connection to reset
and the device to be re-enumerated as a USB2 device. Our design uses an
Intel CherryTrail z8550 SoC that has an internal dwc3 USB device
controller. I worked with Felipe a couple of weeks ago [1] to come up with
the same workaround you mentioned above. I disable device-initiated U1/U2
in ep0_set_config and also return -EINVAL when handling SetFeature
requests from the USB host. I've attached my patch for kernel 4.9.115
below for reference.
Although we have applied this workaround, we still have not identified a
root cause of the issue. Intel has no known errata related to the symptoms
we are experiencing. We've done quite a bit of analysis on our design and
are pretty confident we've followed all design guidelines for USB.
Cheers,
Rob Weber
[1] https://marc.info/?t=155349935600001&r=1&w=2
---
drivers/usb/dwc3/ep0.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
--
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 2331469f943d..78b75d65b435 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -433,10 +433,13 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (set)
- reg |= DWC3_DCTL_INITU1ENA;
- else
+ if (set) {
+ /* reg |= DWC3_DCTL_INITU1ENA; */
+ dwc3_trace(trace_dwc3_ep0, "GBX: Skipping U1 Enable");
+ return -EINVAL;
+ } else {
reg &= ~DWC3_DCTL_INITU1ENA;
+ }
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
break;
@@ -448,10 +451,13 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (set)
- reg |= DWC3_DCTL_INITU2ENA;
- else
+ if (set) {
+ /* reg |= DWC3_DCTL_INITU2ENA; */
+ dwc3_trace(trace_dwc3_ep0, "GBX: Skipping U2 Enable");
+ return -EINVAL;
+ } else {
reg &= ~DWC3_DCTL_INITU2ENA;
+ }
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
break;
@@ -567,7 +573,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
enum usb_device_state state = dwc->gadget.state;
u32 cfg;
int ret;
- u32 reg;
+ /* u32 reg; */
cfg = le16_to_cpu(ctrl->wValue);
@@ -594,9 +600,9 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
* Enable transition to U1/U2 state when
* nothing is pending from application.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ /* reg = dwc3_readl(dwc->regs, DWC3_DCTL); */
+ /* reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); */
+ /* dwc3_writel(dwc->regs, DWC3_DCTL, reg); */
}
break;
WARNING: multiple messages have this Message-ID (diff)
From: Rob Weber <rob@gnarbox.com>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: "Claus H. Stovgaard" <cst@phaseone.com>,
"balbi@kernel.org" <balbi@kernel.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"mnarani@xilinx.com" <mnarani@xilinx.com>,
Michal Simek <michal.simek@xilinx.com>
Subject: Re: Use device tree to disable U1/U2 in gadget devices based on DWC3
Date: Thu, 25 Apr 2019 13:11:03 -0700 [thread overview]
Message-ID: <20190425201103.GA26402@coops> (raw)
Message-ID: <20190425201103.xa0UURF4z2qQmFATCEQSKFsxcxDGy8IOpG5yF6cS4p0@z> (raw)
In-Reply-To: <Pine.LNX.4.44L0.1904241423540.1443-100000@iolanthe.rowland.org>
Hi Everyone,
On Wed, Apr 24, 2019 at 02:33:48PM -0400, Alan Stern wrote:
> On Wed, 24 Apr 2019, Claus H. Stovgaard wrote:
>
> > Hi Balbi and other USB developers.
> >
> > I am developing camera devices based on Xilinx ZynqMP, using the
> > gadget framework and the build-in dwc3 core of the ZynqMP as USB3
> > controller and the build-in Cirrus SERDES as phy.
> > Testing with a number of hosts and Windows 7, has shown sporadic
> > reconnects when leaving U2/U1, caused by failing link training, where
> > the host resets the bus. Sometime it also means it reconnect via
> > USB2.
> >
> > So to overcome this, I will like to have the option for disabling
> > U1/U2 on the core when working with those hosts.
> >
> > Currently I have made a hack in ep0.c where I return EINVAL in
> > dwc3_ep0_handle_u1 and dwc3_ep0_handle_u2 together with not setting
> > DWC3_DCTL_ACCEPTU1ENA and DWC3_DCTL_ACCEPTU2ENA in
> > dwc3_ep0_set_config
> > Will though prefer a solution possible to upstream, so was thinking
> > about adding two devicetree bindings.
> >
> > * snps,u1_disable_as_gadget: When set the core will not enable U1 if
> > requested from host, nor initiate U1.
> > * snps,u2_disable_as_gadget: When set the core will not enable U2 if
> > requested from host, nor initiate U2.
> >
> > If you think this might be something which can be upstreamed I will
> > prepare the code and send a patch for discussion.
> > On the other hand, if you think that disabling U1/U2 via device tree
> > as suggested should not be a feature no need for me to try making it
> > a feature.
>
> Speaking as an interested bystander, I would first wonder why your
> hardware fails during link training. If it is properly designed, that
> should not happen. The fact that it does happen suggests your devices
> might also experience problems during normal data transport.
I was recently debugging a similar problem where my device would
improperly transition from U2 to U0. This caused the connection to reset
and the device to be re-enumerated as a USB2 device. Our design uses an
Intel CherryTrail z8550 SoC that has an internal dwc3 USB device
controller. I worked with Felipe a couple of weeks ago [1] to come up with
the same workaround you mentioned above. I disable device-initiated U1/U2
in ep0_set_config and also return -EINVAL when handling SetFeature
requests from the USB host. I've attached my patch for kernel 4.9.115
below for reference.
Although we have applied this workaround, we still have not identified a
root cause of the issue. Intel has no known errata related to the symptoms
we are experiencing. We've done quite a bit of analysis on our design and
are pretty confident we've followed all design guidelines for USB.
Cheers,
Rob Weber
[1] https://marc.info/?t=155349935600001&r=1&w=2
---
drivers/usb/dwc3/ep0.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 2331469f943d..78b75d65b435 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -433,10 +433,13 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (set)
- reg |= DWC3_DCTL_INITU1ENA;
- else
+ if (set) {
+ /* reg |= DWC3_DCTL_INITU1ENA; */
+ dwc3_trace(trace_dwc3_ep0, "GBX: Skipping U1 Enable");
+ return -EINVAL;
+ } else {
reg &= ~DWC3_DCTL_INITU1ENA;
+ }
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
break;
@@ -448,10 +451,13 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
return -EINVAL;
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (set)
- reg |= DWC3_DCTL_INITU2ENA;
- else
+ if (set) {
+ /* reg |= DWC3_DCTL_INITU2ENA; */
+ dwc3_trace(trace_dwc3_ep0, "GBX: Skipping U2 Enable");
+ return -EINVAL;
+ } else {
reg &= ~DWC3_DCTL_INITU2ENA;
+ }
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
break;
@@ -567,7 +573,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
enum usb_device_state state = dwc->gadget.state;
u32 cfg;
int ret;
- u32 reg;
+ /* u32 reg; */
cfg = le16_to_cpu(ctrl->wValue);
@@ -594,9 +600,9 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
* Enable transition to U1/U2 state when
* nothing is pending from application.
*/
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+ /* reg = dwc3_readl(dwc->regs, DWC3_DCTL); */
+ /* reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA); */
+ /* dwc3_writel(dwc->regs, DWC3_DCTL, reg); */
}
break;
--
next prev reply other threads:[~2019-04-25 20:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-24 16:26 Use device tree to disable U1/U2 in gadget devices based on DWC3 Claus H. Stovgaard
2019-04-24 18:33 ` Alan Stern
2019-04-25 20:11 ` Rob Weber [this message]
2019-04-25 20:11 ` Rob Weber
2019-04-26 13:15 ` Claus H. Stovgaard
2019-04-26 13:15 ` Claus H. Stovgaard
2019-04-26 12:44 ` Claus H. Stovgaard
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=20190425201103.GA26402@coops \
--to=rob@gnarbox.com \
--cc=balbi@kernel.org \
--cc=cst@phaseone.com \
--cc=linux-usb@vger.kernel.org \
--cc=michal.simek@xilinx.com \
--cc=mnarani@xilinx.com \
--cc=stern@rowland.harvard.edu \
/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