From: Yu Chen <cheny...@huawei.com> 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 <gre...@linuxfoundation.org> Cc: Rob Herring <robh...@kernel.org> Cc: Mark Rutland <mark.rutl...@arm.com> CC: ShuFan Lee <shufan_...@richtek.com> Cc: Heikki Krogerus <heikki.kroge...@linux.intel.com> Cc: Suzuki K Poulose <suzuki.poul...@arm.com> Cc: Chunfeng Yun <chunfeng....@mediatek.com> Cc: Yu Chen <cheny...@huawei.com> Cc: Felipe Balbi <ba...@kernel.org> Cc: Hans de Goede <hdego...@redhat.com> Cc: Andy Shevchenko <andy.shevche...@gmail.com> Cc: Jun Li <lijun.ker...@gmail.com> Cc: Valentin Schneider <valentin.schnei...@arm.com> Cc: Jack Pham <ja...@codeaurora.org> Cc: linux-...@vger.kernel.org Cc: devicet...@vger.kernel.org Signed-off-by: Yu Chen <cheny...@huawei.com> Signed-off-by: John Stultz <john.stu...@linaro.org> --- 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); + dwc3_set_prtcap(dwc, dwc->desired_dr_role); spin_unlock_irqrestore(&dwc->lock, flags); -- 2.17.1