diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.c index c56c6cdd5..1b89e99c6 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.c @@ -108,6 +108,7 @@ int dwc3_core_init(struct dwc3 *dwc) goto err0; } dwc->revision = reg; + USB_LOG_DBG("%s dwc revision=%08x\n", __func__, dwc->revision); /* Handle USB2.0-only core configuration */ if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == @@ -297,7 +298,120 @@ void dwc3_core_num_eps(struct dwc3 *dwc) } -void dwc3_phy_setup(struct dwc3 *dwc){ +void dwc3_phy_setup(struct dwc3 *dwc) +{ + uint32_t reg; + + reg = dwc3_readl(dwc->regs_vir, DWC3_GUSB3PIPECTL(0)); + + /* + * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY + * to '0' during coreConsultant configuration. So default value + * will be '0' when the core is reset. Application needs to set it + * to '1' after the core initialization is completed. + */ + if (dwc->revision > DWC3_REVISION_194A) + reg |= DWC3_GUSB3PIPECTL_SUSPHY; + + if (dwc->u2ss_inp3_quirk) + reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; + + if (dwc->req_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_REQP1P2P3; + + if (dwc->del_p1p2p3_quirk) + reg |= DWC3_GUSB3PIPECTL_DEP1P2P3_EN; + + if (dwc->del_phy_power_chg_quirk) + reg |= DWC3_GUSB3PIPECTL_DEPOCHANGE; + + if (dwc->lfps_filter_quirk) + reg |= DWC3_GUSB3PIPECTL_LFPSFILT; + + if (dwc->rx_detect_poll_quirk) + reg |= DWC3_GUSB3PIPECTL_RX_DETOPOLL; + + if (dwc->tx_de_emphasis_quirk) + reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis); + + /* + * RK3568 uboot: For some Rokchip SoCs like RK3588, if the USB3 PHY is suspended + * in U-Boot would cause the PHY initialize abortively in Linux Kernel, + * so disable the DWC3_GUSB3PIPECTL_SUSPHY feature here to fix it. + */ + /*if (dwc->dis_u3_susphy_quirk || CONFIG_IS_ENABLED(ARCH_ROCKCHIP)) + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;*/ + /* + * Linux: Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be + * cleared after power-on reset, and it can be set after core + * initialization. + */ + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; + + dwc3_writel(dwc->regs_vir, DWC3_GUSB3PIPECTL(0), reg); + + dwc3_hsphy_mode_setup(dwc); + + usb_osal_msleep(100); + + reg = dwc3_readl(dwc->regs_vir, DWC3_GUSB2PHYCFG(0)); + + /* + * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to + * '0' during coreConsultant configuration. So default value will + * be '0' when the core is reset. Application needs to set it to + * '1' after the core initialization is completed. + */ + if (dwc->revision > DWC3_REVISION_194A) + reg |= DWC3_GUSB2PHYCFG_SUSPHY; + + if (dwc->dis_u2_susphy_quirk) + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + + if (dwc->dis_enblslpm_quirk) + reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; + + if (dwc->dis_u2_freeclk_exists_quirk) + reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS; + + if (dwc->usb2_phyif_utmi_width == 16) { + reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK | + DWC3_GUSB2PHYCFG_USBTRDTIM_MASK); + reg |= DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT); + reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT); + } + dwc3_writel(dwc->regs_vir, DWC3_GUSB2PHYCFG(0), reg); + + usb_osal_msleep(100); +} + + +void dwc3_hsphy_mode_setup(struct dwc3 *dwc) +{ + enum usb_phy_interface hsphy_mode = dwc->hsphy_mode; + uint32_t reg; + + /* Set dwc3 usb2 phy config */ + reg = dwc3_readl(dwc->regs_vir, DWC3_GUSB2PHYCFG(0)); + + switch (hsphy_mode) { + case USBPHY_INTERFACE_MODE_UTMI: + reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK | + DWC3_GUSB2PHYCFG_USBTRDTIM_MASK); + reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) | + DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT); + break; + case USBPHY_INTERFACE_MODE_UTMIW: + reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK | + DWC3_GUSB2PHYCFG_USBTRDTIM_MASK); + reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) | + DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT); + break; + default: + break; + } + + dwc3_writel(dwc->regs_vir, DWC3_GUSB2PHYCFG(0), reg); } diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.h index e01ea78bf..8d9d00c30 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/dwc3/dwc3.h @@ -896,6 +896,8 @@ void dwc3_core_num_eps(struct dwc3 *dwc); void dwc3_phy_setup(struct dwc3 *dwc); +void dwc3_hsphy_mode_setup(struct dwc3 *dwc); + int dwc3_alloc_scratch_buffers(struct dwc3 *dwc); int dwc3_setup_scratch_buffers(struct dwc3 *dwc);