From 1f4eb91259629db8266b83b7444a054072475f61 Mon Sep 17 00:00:00 2001 From: jzlv Date: Wed, 9 Feb 2022 15:18:08 +0800 Subject: [PATCH] update ehci driver --- common/usb_hc.h | 2 +- port/ehci/usb_ehci.c | 55 ++++++++++++++++++++++++++++++++++++++++---- port/ehci/usb_ehci.h | 4 +++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/common/usb_hc.h b/common/usb_hc.h index 78ad77f0..7a12a98b 100644 --- a/common/usb_hc.h +++ b/common/usb_hc.h @@ -78,7 +78,7 @@ int usbh_reset_port(const uint8_t port); * @brief get roothub port speed * * @param port port index - * @return return 0 means USB_SPEED_LOW, 1 means USB_SPEED_FULL and 2 means USB_SPEED_HIGH. + * @return return 1 means USB_SPEED_LOW, 2 means USB_SPEED_FULL and 3 means USB_SPEED_HIGH. */ uint8_t usbh_get_port_speed(const uint8_t port); diff --git a/port/ehci/usb_ehci.c b/port/ehci/usb_ehci.c index c015311c..96d78833 100644 --- a/port/ehci/usb_ehci.c +++ b/port/ehci/usb_ehci.c @@ -2192,10 +2192,11 @@ int usb_hc_init(void) usb_ehci_putreg(regval, &HCOR->usbcmd); /* Route all ports to this host controller by setting the CONFIG flag. */ - // regval = usb_ehci_getreg(&HCOR->configflag); - // regval |= EHCI_CONFIGFLAG; - // usb_ehci_putreg(regval, &HCOR->configflag); - +#ifdef CONFIG_USB_EHCI_CONFIGFLAG + regval = usb_ehci_getreg(&HCOR->configflag); + regval |= EHCI_CONFIGFLAG; + usb_ehci_putreg(regval, &HCOR->configflag); +#endif /* Wait for the EHCI to run (i.e., no longer report halted) */ ret = usb_ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100 * 1000); if (ret < 0) { @@ -2212,6 +2213,52 @@ int usb_hc_init(void) return ret; } +int usbh_reset_port(const uint8_t port) +{ + uint32_t timeout = 0; + uint32_t regval; + regval = usb_ehci_getreg(&HCOR->portsc[port - 1]); + regval &= ~EHCI_PORTSC_PE; + regval |= EHCI_PORTSC_RESET; + usb_ehci_putreg(regval, &HCOR->portsc[port - 1]); + + usb_osal_msleep(55); + + regval = usb_ehci_getreg(&HCOR->portsc[port - 1]); + regval &= ~EHCI_PORTSC_RESET; + usb_ehci_putreg(regval, &HCOR->portsc[port - 1]); + + /* Wait for the port reset to complete + * + * Paragraph 2.3.9: + * + * "Note that when software writes a zero to this bit there may be a + * delay before the bit status changes to a zero. The bit status will + * not read as a zero until after the reset has completed. If the port + * is in high-speed mode after reset is complete, the host controller + * will automatically enable this port (e.g. set the Port Enable bit + * to a one). A host controller must terminate the reset and stabilize + * the state of the port within 2 milliseconds of software transitioning + * this bit from a one to a zero ..." + */ + + while ((usb_ehci_getreg(&HCOR->portsc[port - 1]) & EHCI_PORTSC_RESET) != 0) { + usb_osal_msleep(1); + timeout++; + if (timeout > 100) { + return -ETIMEDOUT; + } + } + + return 0; +} + +__WEAK uint8_t usbh_get_port_speed(const uint8_t port) +{ + /* Defined by individual manufacturers */ + return 0; +} + int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed) { struct usb_ehci_epinfo_s *epinfo; diff --git a/port/ehci/usb_ehci.h b/port/ehci/usb_ehci.h index 1393a3b8..cf25ce30 100644 --- a/port/ehci/usb_ehci.h +++ b/port/ehci/usb_ehci.h @@ -872,7 +872,9 @@ struct ehci_hcor_s uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */ uint32_t periodiclistbase; /* 0x14: Frame List Base Address */ uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */ - // uint32_t reserved[9]; +#ifdef CONFIG_USB_ECHI_HCOR_RESERVED + uint32_t reserved[9]; +#endif uint32_t configflag; /* 0x40: Configured Flag Register */ uint32_t portsc[15]; /* 0x44: Port Status/Control */ };