From 85b2f4820c2177d3a15e7abaeeba35f58337461f Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Tue, 9 Jul 2024 18:01:09 -0700 Subject: [PATCH] usb: dwc3: dwc3-msm-core: Switch to UTMI clk during host teardown After moving the flush_work() call after the usb_phy_notify_disconnect() to address USB type C compliance issues (LFPS generated during host teardown): commit fb3c680116db ("usb: dwc3: dwc3-msm-core: Notify PHY disconnect before doing flush_work") During USB device PIPO, the notify PHY disconnect call to the QMP PHY will cause the PHY to be powered down. As part of the stop host mode routine, the DWC3 core has to be placed back into device/peripheral mode. Some parts of the device mode initialization sequence, such as the core soft reset, requires that the PIPE clk (or controller source clock) be active, otherwise the core soft reset will time out. To mitigate the side effect, temporarily switch to the UTMI as the controller clock source, so that the PIPE clock can be powered off without any consequences. Once the move to DWC3 gadget mode is complete, re-enable the PIPE clock as the controller source. (after flush_work() is complete). Change-Id: I59de803d737581c0037348498b8447f872adb62f Signed-off-by: Wesley Cheng --- drivers/usb/dwc3/dwc3-msm-core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-msm-core.c b/drivers/usb/dwc3/dwc3-msm-core.c index bb0aafb804f4..d53890a5a26c 100644 --- a/drivers/usb/dwc3/dwc3-msm-core.c +++ b/drivers/usb/dwc3/dwc3-msm-core.c @@ -7012,7 +7012,12 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) /* * Performing phy disconnect before flush work to * address TypeC certification--TD 4.7.4 failure. + * In order to avoid any controller start/halt + * sequences, switch to the UTMI as the clk source + * as the notify_disconnect() callback to the QMP + * PHY will power down the PIPE clock. */ + dwc3_msm_switch_utmi(mdwc, true); if (mdwc->ss_phy->flags & PHY_HOST_MODE) { usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER); @@ -7025,6 +7030,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) if (dwc->dr_mode == USB_DR_MODE_OTG) flush_work(&dwc->drd_work); + dwc3_msm_switch_utmi(mdwc, false); mdwc->hs_phy->flags &= ~PHY_HOST_MODE; usb_unregister_notify(&mdwc->host_nb);