Commit 9ba3aca8 authored by Thinh Nguyen's avatar Thinh Nguyen Committed by Felipe Balbi
Browse files

usb: dwc3: Disable phy suspend after power-on reset



For DRD controllers, the programming guide recommended that
GUSB3PIPECTL.SUSPENDABLE and GUSB2PHYCFG.SUSPHY to be cleared after
power-on reset and only set after the controller initialization is
completed. This can be done after device soft-reset in dwc3_core_init().
This patch makes sure to clear GUSB3PIPECTL.SUSPENDABLE and
GUSB2PHYCFG.SUSPHY before core initialization and only set them after
the device soft-reset is completed.

Reference: DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section
1.2.49 and 1.2.45

Signed-off-by: default avatarThinh Nguyen <thinhn@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 7d194c21
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -567,8 +567,11 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc)
 */
static int dwc3_phy_setup(struct dwc3 *dwc)
{
	unsigned int hw_mode;
	u32 reg;

	hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);

	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));

	/*
@@ -586,6 +589,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	if (dwc->revision > DWC3_REVISION_194A)
		reg |= DWC3_GUSB3PIPECTL_SUSPHY;

	/*
	 * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after
	 * power-on reset, and it can be set after core initialization, which is
	 * after device soft-reset during initialization.
	 */
	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
		reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;

	if (dwc->u2ss_inp3_quirk)
		reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;

@@ -669,6 +680,14 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
	if (dwc->revision > DWC3_REVISION_194A)
		reg |= DWC3_GUSB2PHYCFG_SUSPHY;

	/*
	 * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after
	 * power-on reset, and it can be set after core initialization, which is
	 * after device soft-reset during initialization.
	 */
	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

	if (dwc->dis_u2_susphy_quirk)
		reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;

@@ -903,9 +922,12 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
 */
static int dwc3_core_init(struct dwc3 *dwc)
{
	unsigned int		hw_mode;
	u32			reg;
	int			ret;

	hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);

	/*
	 * Write Linux Version Code to our GUID register so it's easy to figure
	 * out which kernel version a bug was found.
@@ -941,6 +963,21 @@ static int dwc3_core_init(struct dwc3 *dwc)
	if (ret)
		goto err0a;

	if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
	    dwc->revision > DWC3_REVISION_194A) {
		if (!dwc->dis_u3_susphy_quirk) {
			reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
			reg |= DWC3_GUSB3PIPECTL_SUSPHY;
			dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
		}

		if (!dwc->dis_u2_susphy_quirk) {
			reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
			reg |= DWC3_GUSB2PHYCFG_SUSPHY;
			dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
		}
	}

	dwc3_core_setup_global_control(dwc);
	dwc3_core_num_eps(dwc);