Commit 7fd22e5b authored by Minas Harutyunyan's avatar Minas Harutyunyan Committed by Greg Kroah-Hartman
Browse files

usb: dwc2: Add eUSB2 PHY disconnect flow support



To support eUSB2 PHY disconnect flow required in Soft disconnect
state set GOTGCTL_EUSB2_DISC_SUPP bit, if applicable.

On Session End Detected interrupt clear PCGCTL_GATEHCLK and
PCGCTL_STOPPCLK bits if eusb2_disc parameter true.

Signed-off-by: default avatarMinas Harutyunyan <Minas.Harutyunyan@synopsys.com>
Link: https://lore.kernel.org/r/9d50b83df693cda8c391313e90048df8dd611c04.1708948356.git.Minas.Harutyunyan@synopsys.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bc5d81b8
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
	u32 gotgint;
	u32 gotgctl;
	u32 gintmsk;
	u32 pcgctl;

	gotgint = dwc2_readl(hsotg, GOTGINT);
	gotgctl = dwc2_readl(hsotg, GOTGCTL);
@@ -96,8 +97,22 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
			dwc2_op_state_str(hsotg));
		gotgctl = dwc2_readl(hsotg, GOTGCTL);

		if (dwc2_is_device_mode(hsotg))
		if (dwc2_is_device_mode(hsotg)) {
			if (hsotg->params.eusb2_disc) {
				/* Clear the Gate hclk. */
				pcgctl = dwc2_readl(hsotg, PCGCTL);
				pcgctl &= ~PCGCTL_GATEHCLK;
				dwc2_writel(hsotg, pcgctl, PCGCTL);
				udelay(5);

				/* Clear Phy Clock bit. */
				pcgctl = dwc2_readl(hsotg, PCGCTL);
				pcgctl &= ~PCGCTL_STOPPCLK;
				dwc2_writel(hsotg, pcgctl, PCGCTL);
				udelay(5);
			}
			dwc2_hsotg_disconnect(hsotg);
		}

		if (hsotg->op_state == OTG_STATE_B_HOST) {
			hsotg->op_state = OTG_STATE_B_PERIPHERAL;
@@ -117,7 +132,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg)
			 * disconnected
			 */
			/* Reset to a clean state */
			hsotg->lx_state = DWC2_L0;
			hsotg->lx_state = DWC2_L3;
		}

		gotgctl = dwc2_readl(hsotg, GOTGCTL);
@@ -286,7 +301,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
		hsotg->lx_state);

	if (dwc2_is_device_mode(hsotg)) {
		if (hsotg->lx_state == DWC2_L2) {
		if (hsotg->lx_state != DWC2_L0) {
			if (hsotg->in_ppd) {
				ret = dwc2_exit_partial_power_down(hsotg, 0,
								   true);
+4 −1
Original line number Diff line number Diff line
@@ -3420,8 +3420,11 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,

	dwc2_hsotg_init_fifo(hsotg);

	if (!is_usb_reset)
	if (!is_usb_reset) {
		dwc2_set_bit(hsotg, DCTL, DCTL_SFTDISCON);
		if (hsotg->params.eusb2_disc)
			dwc2_set_bit(hsotg, GOTGCTL, GOTGCTL_EUSB2_DISC_SUPP);
	}

	dcfg |= DCFG_EPMISCNT(1);