Re: [RFC PATCH 3/4] usb: dwc3: add quirk to be compatible for AMD NL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Sun, Sep 28, 2014 at 05:18:58PM +0800, Huang Rui wrote:
> > > > From: Felipe Balbi [mailto:balbi@xxxxxx]
> > > > Sent: Friday, September 26, 2014 5:54 PM
> > > > 
> > > > On Fri, Sep 26, 2014 at 11:18:48PM +0000, Paul Zimmerman wrote:
> > > > > > From: Felipe Balbi [mailto:balbi@xxxxxx]
> > > > > > Sent: Friday, September 26, 2014 2:40 PM
> > > > > >
> > > > > > On Fri, Sep 26, 2014 at 08:57:19PM +0000, Paul Zimmerman wrote:
> > > > > > > > > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> > > > > > > > > index 0fcc0a3..8277065 100644
> > > > > > > > > --- a/drivers/usb/dwc3/gadget.c
> > > > > > > > > +++ b/drivers/usb/dwc3/gadget.c
> > > > > > > > > @@ -2635,6 +2635,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
> > > > > > > > >   */
> > > > > > > > >  int dwc3_gadget_init(struct dwc3 *dwc)
> > > > > > > > >  {
> > > > > > > > > +	u32					reg;
> > > > > > > > >  	int					ret;
> > > > > > > > >
> > > > > > > > >  	dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
> > > > > > > > > @@ -2689,6 +2690,13 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> > > > > > > > >  	if (ret)
> > > > > > > > >  		goto err4;
> > > > > > > > >
> > > > > > > > > +	if (dwc->quirks & DWC3_AMD_NL_PLAT) {
> > > > > > > > > +		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
> > > > > > > > > +		reg |= DWC3_DCTL_LPM_ERRATA(0xf);
> > > > > > > >
> > > > > > > > weird, why would Synopsys put this here ? It seems like this is only
> > > > > > > > useful when LPM Errata is enabled and that's, apparently, a host-side
> > > > > > > > thing.
> > > > > > > >
> > > > > > > > Paul, can you comment ?
> > > > > > >
> > > > > > > These bits contribute to how the device responds to an LPM transaction
> > > > > > > from the host. If DCFG.LPMCap=1, they set the BESL value above which
> > > > > > > the core will send a NYET. If DCFG.LPMCap=0, they have no effect. So
> > > > > > > it's definitely a device-side thing, but only if the core is configured
> > > > > > > with LPM Errata support enabled.
> > > > > >
> > > > > > right, and how can SW detect if LPM Errata was enabled ? From the host
> > > > > > point of view, we can check bit 20 of xHCI capability register. What
> > > > > > about device ? I can't seem to find anything :-s
> > > > >
> > > > > I just talked to one of our RTL designers. You're right, there is no
> > > > > way to tell from the Device registers alone whether the controller is
> > > > > configured with LPM Errata support or not.
> > > > >
> > > > > You can tell for sure if it is *not* enabled, by checking GSNPSID, and
> > > > > if the version is earlier than 2.40a, the feature wasn't available.
> > > > 
> > > > alright, we can use this for something like:
> > > > 
> > > > WARN(rev < 2.40a && (flags & LPM_ERRATA || of_property_read_bool("lpm-errata")),
> > > > 	"LPM Errata not available on dwc3 revisions <= 2.40a\n");
> > > > 
> > > > > So for Device-mode only controllers, I guess you will need a DT property
> > > > > for this.
> > > > 
> > > > right, DT property and platform_data feature flag, or something. I don't
> > > > wanna call it a quirk though, although it _is_ an erratum WRT LPM
> > > > support. Dunno. Any strong feelings ?
> > > 
> > > Well, it's called LPM Errata because the feature was added to the USB
> > > spec as an erratum. It's not an erratum to our controller. But I don't
> > > have any strong feelings about how the driver support is implemented.
> > 
> > how about adding a "has_lpm_erratum" to struct dwc3 which gets
> > initialized either through pdata or DT ? Then above WARN() would become:
> > 
> > WARN(dwc->revision < DWC3_REVISION_240A && dwc->has_lpm_erratum",
> > 	"LPM Erratum not available on dwc3 revisisions < 2.40a\n");
> > 
> > Then we're not really calling it a quirk. In fact Huang, when respining
> > your series, let's convert your quirk bits into single-bit fields inside
> > struct dwc3 and struct platform_data. Like so:
> > 
> 
> Looks like a good suggestion.
> 
> > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
> > index 4d4e854..e233ce1 100644
> > --- a/drivers/usb/dwc3/core.c
> > +++ b/drivers/usb/dwc3/core.c
> > @@ -695,11 +695,13 @@ static int dwc3_probe(struct platform_device *pdev)
> >  
> >  	if (node) {
> >  		dwc->maximum_speed = of_usb_get_maximum_speed(node);
> > +		dwc->has_lpm_erratum = of_property_read_bool(node, "snps,has-lpm-erratum");
> >  
> >  		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
> >  		dwc->dr_mode = of_usb_get_dr_mode(node);
> >  	} else if (pdata) {
> >  		dwc->maximum_speed = pdata->maximum_speed;
> > +		dwc->has_lpm_erratum = pdata->has_lpm_erratum; >  
> >  		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
> >  		dwc->dr_mode = pdata->dr_mode;
> > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> > index 66f6256..23e1504 100644
> > --- a/drivers/usb/dwc3/core.h
> > +++ b/drivers/usb/dwc3/core.h
> > @@ -661,6 +661,8 @@ struct dwc3_scratchpad_array {
> >   * @ep0_bounced: true when we used bounce buffer
> >   * @ep0_expect_in: true when we expect a DATA IN transfer
> >   * @has_hibernation: true when dwc3 was configured with Hibernation
> > + * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that
> > + *			there's now way for software to detect this in runtime.
> >   * @is_selfpowered: true when we are selfpowered
> >   * @needs_fifo_resize: not all users might want fifo resizing, flag it
> >   * @pullups_connected: true when Run/Stop bit is set
> > @@ -764,6 +766,7 @@ struct dwc3 {
> >  	unsigned		ep0_bounced:1;
> >  	unsigned		ep0_expect_in:1;
> >  	unsigned		has_hibernation:1;
> > +	unsigned		has_lpm_erratum:1;
> >  	unsigned		is_selfpowered:1;
> >  	unsigned		needs_fifo_resize:1;
> >  	unsigned		pullups_connected:1;
> > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> > index 68497b3..112352e 100644
> > --- a/drivers/usb/dwc3/gadget.c
> > +++ b/drivers/usb/dwc3/gadget.c
> > @@ -1577,6 +1577,13 @@ static int dwc3_gadget_start(struct usb_gadget *g,
> >  	}
> >  	dwc3_writel(dwc->regs, DWC3_DCFG, reg);
> >  
> > +	if (dwc->has_lpm_erratum) {
> > +		reg = dwc3_readl(dwc->regs, DWC3_DCTL);
> > +		/* REVISIT should this be configurable ? */
> > +		reg |= DWC3_DCTL_LPM_ERRATA(0xf);
> > +		dwc3_writel(dwc->regs, DWC3_DCTL, reg);
> > +	}
> > +
> >  	dwc->start_config_issued = false;
> >  
> >  	/* Start with SuperSpeed Default */
> > diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
> > index 7db34f0..4bcec7c 100644
> > --- a/drivers/usb/dwc3/platform_data.h
> > +++ b/drivers/usb/dwc3/platform_data.h
> > @@ -24,4 +24,6 @@ struct dwc3_platform_data {
> >  	enum usb_device_speed maximum_speed;
> >  	enum usb_dr_mode dr_mode;
> >  	bool tx_fifo_resize;
> > +
> > +	unsigned has_lpm_erratum:1;
> >  };
> > 
> > note that I have also moved DCTL access from gadget_init to
> > gadget_start.
> > 
> 
> Yes, I see. Will update it into V2.
> 
> A question, the dwc3 controller is the PCI-E device in my platform,
> but the class code of PCI header is 0x0c0330, the same with xHC.
> That's because it need to meet the windows enviroment. The dwc3
> controller acted as only host mode to bind with windows xhci driver.
> But on linux, sometimes, we auto-bind with xhci driver as well (class
> code 0x0c0330) despite we use Pid/Vid on dwc3 driver. Then I need
> rmmod xhci_hcd module and modprobe dwc3_pci module manually.
> 
> Any idea to resolve this issue?

that probably won't be the case on final Silicon. I reckon you're using
Synopsys' HAPS for development, right ? That's just how Synopsys
designed the PCIe wrapper to make it easy to test with xHCI. Please make
sure to not use the same PCI header as xHCI on final silicon, otherwise
SW engineers' lifes will become more difficult :-)

Meanwhile, you can just blacklist xhci under /etc/modprobe.d/. Create a
new file (say xhci-blacklist.conf) and add this to it:

blacklist xhci-hcd

Save and restart. xhci-hcd will never load by default anymore, but you
can still manually load it.

Heikki, can you confirm if your DWC3 incarnations present this same
"feature" ? :-)

-- 
balbi

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux