This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d2344ee915c0d7928c9a900f6a0595ec2d92b953 Author: Alan Carvalho de Assis <acas...@gmail.com> AuthorDate: Sat Aug 30 17:53:25 2025 -0300 boards/arcx-socket-grid: Add support to two USBs This patch adds support to both USB controllers. Signed-off-by: Alan C. Assis <acas...@gmail.com> --- .../imxrt/arcx-socket-grid/src/arcx-socket-grid.h | 3 +- .../arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c | 15 +++- .../arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c | 91 ++++++++++++++++++---- 3 files changed, 90 insertions(+), 19 deletions(-) diff --git a/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h b/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h index 4426396fd4..c211cbeb05 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h +++ b/boards/arm/imxrt/arcx-socket-grid/src/arcx-socket-grid.h @@ -199,11 +199,12 @@ int imxrt_gpio_initialize(void); * Name: imxrt_usbhost_initialize * * Description: + * Initialize the USB Host EHCI Controller * ****************************************************************************/ #ifdef CONFIG_USBHOST -int imxrt_usbhost_initialize(void); +int imxrt_usbhost_initialize(int ctrid); #endif #endif /* __ASSEMBLY__ */ diff --git a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c index eb9dc2e43d..1c6748e780 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c +++ b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_bringup.c @@ -126,11 +126,20 @@ int imxrt_bringup(void) } #endif -#if defined(CONFIG_IMXRT_USBOTG) || defined(CONFIG_USBHOST) - ret = imxrt_usbhost_initialize(); +#if defined(CONFIG_IMXRT_USBOTG1) && defined(CONFIG_USBHOST) + ret = imxrt_usbhost_initialize(0); if (ret != OK) { - syslog(LOG_ERR, "ERROR: Failed to start USB host services: %d\n", ret); + syslog(LOG_ERR, "ERROR: Failed to start USB1 Host: %d\n", ret); + return ret; + } +#endif + +#if defined(CONFIG_IMXRT_USBOTG2) && defined(CONFIG_USBHOST) + ret = imxrt_usbhost_initialize(1); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: Failed to start USB2 Host: %d\n", ret); return ret; } #endif diff --git a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c index 6dad72e675..26251e734c 100644 --- a/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c +++ b/boards/arm/imxrt/arcx-socket-grid/src/imxrt_usbhost.c @@ -43,8 +43,10 @@ #include "hardware/imxrt_pinmux.h" #include "hardware/imxrt_usbotg.h" +#include "hardware/imxrt_usbphy.h" #include "imxrt_periphclks.h" #include "arcx-socket-grid.h" +#include "arm_internal.h" #include <arch/board/board.h> /* Must always be included last */ @@ -77,18 +79,51 @@ * ****************************************************************************/ -int imxrt_usbhost_initialize(void) +int imxrt_usbhost_initialize(int ctrid) { - struct usbhost_connection_s *ehciconn; + struct usbhost_connection_s *ehciconn_usb1 = NULL; + struct usbhost_connection_s *ehciconn_usb2 = NULL; + uint32_t regval; + static bool usb1_initialized = false; + static bool usb2_initialized = false; int ret; + /* Check if each USB was initialized already */ + + if (ctrid == 0 && usb1_initialized) + { + return OK; + } + + if (ctrid == 1 && usb2_initialized) + { + return OK; + } + imxrt_clockall_usboh3(); - /* Make sure we don't accidentally switch on USB bus power */ + /* Leave from reset */ + + regval = getreg32(IMXRT_USBPHY_CTRL(ctrid)); + regval &= ~USBPHY_CTRL_SFTRST; + putreg32(regval, IMXRT_USBPHY_CTRL(ctrid)); - *((uint32_t *)IMXRT_USBNC_USB_OTG1_CTRL) = USBNC_PWR_POL; - *((uint32_t *)0x400d9030) = (1 << 21); - *((uint32_t *)0x400d9000) = 0; + /* Enable the clock */ + + regval = getreg32(IMXRT_USBPHY_CTRL(ctrid)); + regval &= ~USBPHY_CTRL_CLKGATE; + putreg32(regval, IMXRT_USBPHY_CTRL(ctrid)); + + /* Power up the PHY */ + + putreg32(0, IMXRT_USBPHY_PWD(ctrid)); + + /* Enable PHY Negotiation */ + + regval = getreg32(IMXRT_USBPHY_CTRL(ctrid)); + regval |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD | USBPHY_CTRL_ENAUTOCLR_CLKGATE | + USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3; + putreg32(regval, IMXRT_USBPHY_CTRL(ctrid)); /* Setup pins, with power initially off */ @@ -144,10 +179,11 @@ int imxrt_usbhost_initialize(void) } #endif +#ifdef CONFIG_IMXRT_USBOTG1 /* Then get an instance of the USB EHCI interface. */ - ehciconn = imxrt_ehci_initialize(0); - if (!ehciconn) + ehciconn_usb1 = imxrt_ehci_initialize(ctrid); + if (!ehciconn_usb1) { uerr("ERROR: imxrt_ehci_initialize failed\n"); return -ENODEV; @@ -155,13 +191,38 @@ int imxrt_usbhost_initialize(void) /* Initialize waiter */ - ret = usbhost_waiter_initialize(ehciconn); + ret = usbhost_waiter_initialize(ehciconn_usb1); if (ret < 0) { uerr("ERROR: Failed to create ehci_waiter task: %d\n", ret); return -ENODEV; } + usb1_initialized = true; +#endif + +#ifdef CONFIG_IMXRT_USBOTG2 + /* Then get an instance of the USB EHCI interface. */ + + ehciconn_usb2 = imxrt_ehci_initialize(ctrid); + if (!ehciconn_usb2) + { + uerr("ERROR: imxrt_ehci_initialize failed\n"); + return -ENODEV; + } + + /* Initialize waiter */ + + ret = usbhost_waiter_initialize(ehciconn_usb2); + if (ret < 0) + { + uerr("ERROR: Failed to create ehci_waiter task: %d\n", ret); + return -ENODEV; + } + + usb2_initialized = true; +#endif + return OK; } @@ -184,28 +245,28 @@ int imxrt_usbhost_initialize(void) * ****************************************************************************/ -#define HCOR ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE) +#define HCOR(n) ((volatile struct ehci_hcor_s *)IMXRT_USBOTG_HCOR_BASE(n)) -void imxrt_usbhost_vbusdrive(int rhport, bool enable) +void imxrt_usbhost_vbusdrive(int ctrid, int rhport, bool enable) { uint32_t regval; uinfo("RHPort%d: enable=%d\n", rhport + 1, enable); - /* The IMXRT has only a single root hub port */ + /* The IMXRT has two root hub ports */ - if (rhport == 0) + if (rhport == 0 || rhport == 1) { /* Then enable or disable VBUS power */ - regval = HCOR->portsc[rhport]; + regval = HCOR(rhport)->portsc[ctrid]; regval &= ~EHCI_PORTSC_PP; if (enable) { regval |= EHCI_PORTSC_PP; } - HCOR->portsc[rhport] = regval; + HCOR(rhport)->portsc[ctrid] = regval; } }