From dd4c4fe18083880d5e54cb6a909598c24c128dbf Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Mon, 12 May 2025 21:06:50 +0800 Subject: [PATCH] update(port/dwc2): check crstdone with bit29 after dwc2 4.20a version Signed-off-by: sakumisu <1203593632@qq.com> --- port/dwc2/usb_dc_dwc2.c | 26 ++++++++++++++++++++------ port/dwc2/usb_dwc2_reg.h | 4 +++- port/dwc2/usb_hc_dwc2.c | 34 +++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/port/dwc2/usb_dc_dwc2.c b/port/dwc2/usb_dc_dwc2.c index 90c3c0b0..b0e8edc4 100644 --- a/port/dwc2/usb_dc_dwc2.c +++ b/port/dwc2/usb_dc_dwc2.c @@ -114,6 +114,7 @@ struct dwc2_ep_state { /* Driver state */ USB_NOCACHE_RAM_SECTION struct dwc2_udc { + uint32_t GSNPSID; __attribute__((aligned(32))) struct usb_setup_packet setup; struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/ struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */ @@ -134,13 +135,24 @@ static inline int dwc2_reset(uint8_t busid) count = 0U; USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; - do { - if (++count > 200000U) { - break; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + if (g_dwc2_udc[busid].GSNPSID < 0x4F54420AU) { + do { + if (++count > 200000U) { + USB_LOG_ERR("DWC2 reset timeout\r\n"); + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + } else { + do { + if (++count > 200000U) { + USB_LOG_ERR("DWC2 reset timeout\r\n"); + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRSTDONE) != USB_OTG_GRSTCTL_CSRSTDONE); - USB_OTG_GLB->GRSTCTL &= ~USB_OTG_GRSTCTL_CSRST; + USB_OTG_GLB->GRSTCTL &= ~USB_OTG_GRSTCTL_CSRST; + USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRSTDONE; + } return 0; } @@ -540,6 +552,8 @@ int usb_dc_init(uint8_t busid) USB_ASSERT_MSG(endpoints >= CONFIG_USBDEV_EP_NUM, "dwc2 has less endpoints than config, please check"); + g_dwc2_udc[busid].GSNPSID = USB_OTG_GLB->GSNPSID; + USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS; USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; diff --git a/port/dwc2/usb_dwc2_reg.h b/port/dwc2/usb_dwc2_reg.h index 5f9b5f90..d479b2ea 100644 --- a/port/dwc2/usb_dwc2_reg.h +++ b/port/dwc2/usb_dwc2_reg.h @@ -460,7 +460,9 @@ typedef struct #define USB_OTG_GRSTCTL_TXFFLSH_Pos (5U) #define USB_OTG_GRSTCTL_TXFFLSH_Msk (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */ #define USB_OTG_GRSTCTL_TXFFLSH USB_OTG_GRSTCTL_TXFFLSH_Msk /*!< TxFIFO flush */ - +#define USB_OTG_GRSTCTL_CSRSTDONE_Pos (29U) +#define USB_OTG_GRSTCTL_CSRSTDONE_Msk (0x1UL << USB_OTG_GRSTCTL_CSRSTDONE_Pos) /*!< 0x20000000 */ +#define USB_OTG_GRSTCTL_CSRSTDONE USB_OTG_GRSTCTL_CSRSTDONE_Msk /*!< Core soft reset done */ #define USB_OTG_GRSTCTL_TXFNUM_Pos (6U) #define USB_OTG_GRSTCTL_TXFNUM_Msk (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */ diff --git a/port/dwc2/usb_hc_dwc2.c b/port/dwc2/usb_hc_dwc2.c index 437d8c34..a3f2e2e4 100644 --- a/port/dwc2/usb_hc_dwc2.c +++ b/port/dwc2/usb_hc_dwc2.c @@ -56,6 +56,7 @@ struct dwc2_hcd { volatile bool port_csc; volatile bool port_pec; volatile bool port_occ; + uint32_t GSNPSID; struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM]; } g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS]; @@ -65,7 +66,7 @@ struct dwc2_hcd { #define DWC2_EP0_STATE_INSTATUS 3 #define DWC2_EP0_STATE_OUTSTATUS 4 -static inline int dwc2_reset(struct usbh_bus *bus) +static inline int dwc2_reset(uint8_t busid) { volatile uint32_t count = 0U; @@ -80,11 +81,24 @@ static inline int dwc2_reset(struct usbh_bus *bus) count = 0U; USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; - do { - if (++count > 200000U) { - return -1; - } - } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + if (g_dwc2_udc[busid].GSNPSID < 0x4F54420AU) { + do { + if (++count > 200000U) { + USB_LOG_ERR("DWC2 reset timeout\r\n"); + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + } else { + do { + if (++count > 200000U) { + USB_LOG_ERR("DWC2 reset timeout\r\n"); + return -1; + } + } while ((USB_OTG_GLB->GRSTCTL & USB_OTG_GRSTCTL_CSRSTDONE) != USB_OTG_GRSTCTL_CSRSTDONE); + + USB_OTG_GLB->GRSTCTL &= ~USB_OTG_GRSTCTL_CSRST; + USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRSTDONE; + } return 0; } @@ -532,6 +546,7 @@ __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus) int usb_hc_init(struct usbh_bus *bus) { int ret; + uint8_t channels; memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd)); @@ -541,6 +556,8 @@ int usb_hc_init(struct usbh_bus *bus) usb_hc_low_level_init(bus); + channels = ((USB_OTG_GLB->GHWCFG2 & (0x0f << 14)) >> 14) + 1; + USB_LOG_INFO("========== dwc2 hcd params ==========\r\n"); USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID); USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID); @@ -549,12 +566,15 @@ int usb_hc_init(struct usbh_bus *bus) USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3); USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4); - USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n", ((USB_OTG_GLB->GHWCFG2 & (0x0f << 14)) >> 14) + 1, (USB_OTG_GLB->GHWCFG3 >> 16)); + USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n", channels, (USB_OTG_GLB->GHWCFG3 >> 16)); USB_ASSERT_MSG(((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) == 2, "This dwc2 version does not support dma mode, so stop working"); + USB_ASSERT_MSG(channels >= CONFIG_USBHOST_PIPE_NUM, "dwc2 has less channels than config, please check"); USB_ASSERT_MSG((CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE + CONFIG_USB_DWC2_PTX_FIFO_SIZE) <= (USB_OTG_GLB->GHWCFG3 >> 16), "Your fifo config is overflow, please check"); + g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID = USB_OTG_GLB->GSNPSID; + USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; /* This is vendor register */