Hi, John Stultz writes: > From: Yu Chen > > On the HiKey960, we need to do a GCTL soft reset when > switching modes. > > Jack Pham also noted that in the Synopsys databook it > mentions performing a GCTL CoreSoftReset when changing the > PrtCapDir between device & host modes. > > So this patch always does a GCTL Core Soft Reset when > changing the mode. > > Cc: Greg Kroah-Hartman > Cc: Rob Herring > Cc: Mark Rutland > CC: ShuFan Lee > Cc: Heikki Krogerus > Cc: Suzuki K Poulose > Cc: Chunfeng Yun > Cc: Yu Chen > Cc: Felipe Balbi > Cc: Hans de Goede > Cc: Andy Shevchenko > Cc: Jun Li > Cc: Valentin Schneider > Cc: Jack Pham > Cc: linux-usb@vger.kernel.org > Cc: devicetree@vger.kernel.org > Signed-off-by: Yu Chen > Signed-off-by: John Stultz > --- > v3: Remove quirk conditional, as Jack Pham noted the > Synopsis databook states this should be done generally. > Also, at Jacks' suggestion, make the reset call before > changing the prtcap direction. > --- > drivers/usb/dwc3/core.c | 16 ++++++++++++++++ > 1 file changed, 16 insertions(+) > > diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c > index 999ce5e84d3c..a039e35ec7ad 100644 > --- a/drivers/usb/dwc3/core.c > +++ b/drivers/usb/dwc3/core.c > @@ -112,6 +112,19 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode) > dwc->current_dr_role = mode; > } > > +static void dwc3_gctl_core_soft_reset(struct dwc3 *dwc) > +{ > + u32 reg; > + > + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > + reg |= DWC3_GCTL_CORESOFTRESET; > + dwc3_writel(dwc->regs, DWC3_GCTL, reg); > + > + reg = dwc3_readl(dwc->regs, DWC3_GCTL); > + reg &= ~DWC3_GCTL_CORESOFTRESET; > + dwc3_writel(dwc->regs, DWC3_GCTL, reg); > +} > + > static void __dwc3_set_mode(struct work_struct *work) > { > struct dwc3 *dwc = work_to_dwc(work); > @@ -154,6 +167,9 @@ static void __dwc3_set_mode(struct work_struct *work) > > spin_lock_irqsave(&dwc->lock, flags); > > + /* Execute a GCTL Core Soft Reset when switch mode */ > + dwc3_gctl_core_soft_reset(dwc); > + This is totally unnecessary. We have several platforms supporting dual role *without* this trick. The only reason why the databook mentions a reset is because some registers are shadowed, meaning that they share the same physical space and just appear as different things for SW. The reason being that Synopsys wanted to reduce the area of the IP and decided to shadow registers which are mutually exclusive. -- balbi