[RFC PATCH] usb: dwc3: core: allow vendor drivers to check probe status

Felipe Balbi balbi at ti.com
Tue Jul 22 08:04:45 PDT 2014


On Tue, Jul 22, 2014 at 02:55:34PM +0100, Peter Griffin wrote:
> Hi Felipe,
> 
> Sorry for the delay in replying. I've been trying to get to the root cause
> of this problem so I could reply which took longer than I had hoped.
> 
> The problem manifested itself as a hang on register read/write access if dwc3-st 
> probed before the usb3 phy. Even though dwc3 core would bail and return 
> -EPROBE_DEFER that is not propogated up through of_platform_populate.
> 
> <snip>
> > 
> > yeah, because glue layers are not supposed to know. There should be no
> > coupling what so ever between glue layer and core driver, other than the
> > fact that glue layer is the one which triggers platform_device creation
> > through of_platform_population(). But the glue layer has (or should
> > have) no interest in exactly when the core driver finishes probing.
> 
> Thanks for this clue :-) As it got me debugging why there was this dependency
> between the usb3 phy IP and the ST glue register wrapper around the dwc3 usb core.
> 
> The reason for the depedency / hang is that there is a shared reset signal
> for the dwc3 core, glue registers and usb3 phy. This reset signal was only
> being managed in the USB3 phy driver, which is why if dwc3-st or dwc3 did
> any register access it would cause a hang.
> 
> So the solution is in addition to taking the devm_reset_control for the powerdown
> signal, in V3 of the dwc3-st glue layer, it also gets the softreset signal,
> and deasserts this before any register accesses.
> 
> This is now working properly without any init ordering hacks etc.

AWESOME! :-) Thanks for finding that out, it really helps us keep dwc3
clean without platform-specific hacks ;-)

> > > commit message, another way of ensuring the PHYs are available is to
> > > request them, but this would mean an awful lot of code duplication.
> > > 
> > > In your opinion, what's the best way to handle this?
> > 
> > How can I know ? You still haven't fully explained what you need. All
> > you said was that you're trying to "configure through the glue-layer".
> 
> We can forget about this now. Having dwc3-st take a reference on the usb3 phys was
> just another method I was experimenting with to find out whether the usb3 
> PHY had probed or not.
> 
> > 
> > Care to further explain what the problem really is ? I'm assuming below
> > is what you're concerned about which I had to go dig in the archives
> > because there was no reference to that patch anywhere here.
> 
> Hopefully I have now above, and the proposed solution.
> 
> > 
> > > +static void st_dwc3_init(struct st_dwc3 *dwc3_data)
> > > +{
> > > +	u32 reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
> > > +
> > > +	reg |= aux_clk_en(1) | ext_cfg_reset_n(1) | xhci_revision(1);
> > 
> > so you have auxiliary clock, an external config reset, what's this
> > xhci_revision ?
> 
> xhci_revision is an input signal to the dwc3 core, if it is asserted
> then the host controller compiles with the xHCI revision 1.0 spec, if
> not it complies with xHCI revision 0.96 spec. This input signal to
> dwc3 core is exposed in the CLKRST_CTRL glue register wrapped around
> the controller by ST.

I wonder why would HW folks give SW access to that, though. Oh well,
I've seen weirder things ;-)

> Looking through the docs, it was present until 2.40a, then removed as
> an input signal to the core from 2.50a onwards.
> 
> To make this clearer I have also added a comment above the
> xhci_revision macro in V3 of the dwc3-st patches explaining the
> bitfield and what it does.

thanks

> > looks like it should be split between a CCF and reset drivers. Or maybe
> > a single driver which does both. Do you have a clock/reset control for
> > all IPs ?
> 
> Yes most IPs which have reset or powerdown signals are already
> controlled by a driver in drivers/reset/sti. These reset and powerdown
> signals are all exposed in the sysconfig registers of the SoC. Indeed
> it was a shared reset signal which wasn't being properly managed and
> causing the hang.
> 
> However the reset signal and clock gate here is controlling a small
> piece of wrapper IP called pipew which sits between the dwc3 core and
> usb3 phy.  I believe this pipew protocol wrapper hardware is designed
> internally by ST, and has some special contriants which is why these
> reset signals are being exposed here in the glue logic (see below).
> 
> >  That might be a good way to hide stuff, driver would simply
> > call clk_get()/clk_prepare_enable() and reset_assert()/deassert() when
> > necessary (sure, this doesn't solve the 'when has that guy probe' but
> > you still haven't explained why you need it).
> > 
> > > +	reg = st_dwc3_readl(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1);
> > > +	reg |= SEL_OVERRIDE_VBUSVALID(1) | SEL_OVERRIDE_POWERPRESENT(1) |
> > > +	    SEL_OVERRIDE_BVALID(1);
> > 
> > this is not correct. You don't know if VBUS is really valid at this
> > time. We have used a gpio which gets pull high/low depending on the
> > state of VBUS/ID.
> 
> This isn't stating that VBUS is valid, it is configuring a mux to
> select where the vbus / bvalid / powerpresent signals will be selected
> from.

/me now notices the "SEL_" prefix :-)

> I have added a better comment in V3 which hopefully makes the function
> of VBUS_MNGMNT_SEL register clearer.

thanks

> > > +	st_dwc3_writel(dwc3_data->glue_base, USB2_VBUS_MNGMNT_SEL1, reg);
> > > +	udelay(100);
> > > +
> > > +	reg = st_dwc3_readl(dwc3_data->glue_base, USB2_CLKRST_CTRL);
> > > +	reg |= sw_pipew_reset_n(1);
> > > +	st_dwc3_writel(dwc3_data->glue_base, USB2_CLKRST_CTRL, reg);
> > 
> > let me ask you something else. Isn't the DWC3_GUSB3PIPECTL_PHYSOFTRST
> > bit functional for you guys ? This sw_pipe2_reset_n looks suspicious.
> 
> Your right to be suspicious ;-)
> 
> Due to a constriant on the pipew hardware, they have provided two
> extra software controlled  resets ext_cfg_reset and sw_pipew_reset in
> the CLKRST_CTRL glue reg.
> 
> These two software controlled resets are ANDED with the nominal
> cfg_reset_n and pipe_reset_n resets to the pipew hardware.
> 
> So yes DWC3_GUSB3PIPECTL_PHYSOFTRST is functional, but it will only
> actually issue a reset to pipew and then onto MiPHY if
> sw_pipew_reset_n is also set in the glue. The same goes with the
> global bus_reset_n signal which is subsystem wide reset, it will only
> bepropogated to pipew if ext_cfg_reset is also set in CLKRST_CTRL.

oh man, what a mess :-)

> Hopefully that makes things clearer and I've answered everything.  I
> intend to send a V3 shortly.

sure, thanks

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140722/5eba7994/attachment.sig>


More information about the linux-arm-kernel mailing list