usb: dwc2: platform: Fix dwc2 resume failed for RK3506 OTG1

The utmi iddig signal of RK3506 OTG1 is left floating by default.
Even when the system is suspended and the logic is powered off,
once the system resume and the clock is enabled, the controller's
current mode will be set to Host mode by default, causing dwc2
fail to reinitialize.

To resolve this issue, we found that the ForceHstMode bit in the
GUSBCFG register returns to its default value of 0 after the logic
is powered off. Once the logic power is restored, this bit does not
automatically return to 1. Therefore, we can use this bit to
determine whether the logic has been powered off when dr_mode is
set to Host.

Change-Id: I76c46c9ca7bb9f51f455a6835d3161a3edbeeebb
Signed-off-by: Jianwei Zheng <jianwei.zheng@rock-chips.com>
This commit is contained in:
Jianwei Zheng
2025-07-09 09:45:32 +08:00
committed by Tao Huang
parent dce355282d
commit 1d2414b4d1
2 changed files with 7 additions and 1 deletions

View File

@@ -1387,6 +1387,11 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg)
return (dwc2_readl(hsotg, GINTSTS) & GINTSTS_CURMODE_HOST) == 0;
}
static inline int dwc2_is_force_host_mode(struct dwc2_hsotg *hsotg)
{
return (dwc2_readl(hsotg, GUSBCFG) & GUSBCFG_FORCEHOSTMODE) != 0;
}
int dwc2_drd_init(struct dwc2_hsotg *hsotg);
void dwc2_drd_suspend(struct dwc2_hsotg *hsotg);
void dwc2_drd_resume(struct dwc2_hsotg *hsotg);

View File

@@ -796,7 +796,8 @@ static int __maybe_unused dwc2_resume(struct device *dev)
dwc2_drd_resume(dwc2);
}
if (dwc2->dr_mode == USB_DR_MODE_HOST && dwc2_is_device_mode(dwc2)) {
if (dwc2->dr_mode == USB_DR_MODE_HOST && (dwc2_is_device_mode(dwc2) ||
!dwc2_is_force_host_mode(dwc2))) {
/* Reinit for Host mode if lost power */
dwc2_force_mode(dwc2, true);