1 /*
2  * Copyright (c) 2024 ~ 2025, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbh_core.h"
8 #include "fsl_common.h"
9 #include "fsl_cache.h"
10 #include "usb_chipidea_reg.h"
11 
USBD_IRQHandler(uint8_t busid)12 __WEAK void USBD_IRQHandler(uint8_t busid)
13 {
14 }
15 
USBH_IRQHandler(uint8_t busid)16 __WEAK void USBH_IRQHandler(uint8_t busid)
17 {
18 }
19 
20 #if !defined(CONFIG_USB_EHCI_NXP)
21 #error "mcx ehci must config CONFIG_USB_EHCI_NXP"
22 #endif
23 
24 #if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100
25 #error "mcx ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100"
26 #endif
27 
28 #define USB_DEVICE_CONFIG_EHCI 1
29 
30 /*! @brief USB controller ID */
31 typedef enum _usb_controller_index {
32     kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
33     kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
34                                   to be used in the future. */
35     kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
36     kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved
37                                   to be used in the future. */
38 
39     kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
40     kUSB_ControllerLpcIp3511Fs1 = 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511
41                                         IPs, this is reserved to be used in the future. */
42 
43     kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
44     kUSB_ControllerLpcIp3511Hs1 = 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511
45                                         IPs, this is reserved to be used in the future. */
46 
47     kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */
48     kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved
49                                   to be used in the future. */
50 
51     kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
52     kUSB_ControllerIp3516Hs1 = 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs,
53                                   this is reserved to be used in the future. */
54     kUSB_ControllerDwc30 = 12U,     /*!< DWC3 0U */
55     kUSB_ControllerDwc31 = 13U,     /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved
56                               to be used in the future.*/
57 } usb_controller_index_t;
58 
59 /* USB PHY condfiguration */
60 #define BOARD_USB_PHY_D_CAL     (0x04U)
61 #define BOARD_USB_PHY_TXCAL45DP (0x07U)
62 #define BOARD_USB_PHY_TXCAL45DM (0x07U)
63 #define BOARD_XTAL0_CLK_HZ      24000000U /*!< Board xtal0 frequency in Hz */
64 
65 typedef struct _usb_phy_config_struct {
66     uint8_t D_CAL;     /* Decode to trim the nominal 17.78mA current source */
67     uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */
68     uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */
69 } usb_phy_config_struct_t;
70 
USB_EhciPhyGetBase(uint8_t controllerId)71 void *USB_EhciPhyGetBase(uint8_t controllerId)
72 {
73     void *usbPhyBase = NULL;
74 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
75 #if defined(USBPHY_STACK_BASE_ADDRS)
76     uint32_t usbphy_base[] = USBPHY_STACK_BASE_ADDRS;
77 #else
78     uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
79 #endif
80     uint32_t *temp;
81     if (controllerId < (uint8_t)kUSB_ControllerEhci0) {
82         return NULL;
83     }
84 
85     if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1)) {
86         controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
87     } else if ((controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs0) ||
88                (controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs1)) {
89         controllerId = controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0;
90     } else if ((controllerId == (uint8_t)kUSB_ControllerIp3516Hs0) || (controllerId == (uint8_t)kUSB_ControllerIp3516Hs1)) {
91         controllerId = controllerId - (uint8_t)kUSB_ControllerIp3516Hs0;
92     } else {
93         return NULL;
94     }
95 
96     if (controllerId < (sizeof(usbphy_base) / sizeof(usbphy_base[0]))) {
97         temp = (uint32_t *)usbphy_base[controllerId];
98         usbPhyBase = (void *)temp;
99     } else {
100         return NULL;
101     }
102 #endif
103     return usbPhyBase;
104 }
105 
106 /*!
107  * @brief ehci phy initialization.
108  *
109  * This function initialize ehci phy IP.
110  *
111  * @param[in] controllerId   ehci controller id, please reference to #usb_controller_index_t.
112  * @param[in] freq            the external input clock.
113  *                            for example: if the external input clock is 16M, the parameter freq should be 16000000.
114  *
115  * @retval 0      cancel successfully.
116  * @retval -1        the freq value is incorrect.
117  */
USB_EhciPhyInit(uint8_t controllerId,uint32_t freq,usb_phy_config_struct_t * phyConfig)118 uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
119 {
120 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
121     USBPHY_Type *usbPhyBase;
122 
123     usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
124     if (NULL == usbPhyBase) {
125         return (uint8_t)-1;
126     }
127 
128 #if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
129     ANATOP->HW_ANADIG_REG_3P0.RW =
130         (ANATOP->HW_ANADIG_REG_3P0.RW &
131          (~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
132         ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
133     ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
134         ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
135 #endif
136 
137 #if (defined USB_ANALOG)
138     USB_ANALOG->INSTANCE[controllerId - (uint8_t)kUSB_ControllerEhci0].CHRG_DETECT_SET =
139         USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
140 #endif
141 
142 #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
143 
144     usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
145 #endif
146     usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
147     usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
148     /* PWD register provides overall control of the PHY power state */
149     usbPhyBase->PWD = 0U;
150     if (((uint8_t)kUSB_ControllerIp3516Hs0 == controllerId) || ((uint8_t)kUSB_ControllerIp3516Hs1 == controllerId) ||
151         ((uint8_t)kUSB_ControllerLpcIp3511Hs0 == controllerId) ||
152         ((uint8_t)kUSB_ControllerLpcIp3511Hs1 == controllerId)) {
153         usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
154         usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
155     }
156     if (NULL != phyConfig) {
157         /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
158         usbPhyBase->TX =
159             ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
160              (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
161               USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
162     }
163 #endif
164 
165     return (uint8_t)0;
166 }
167 
168 /*!
169  * @brief ehci phy initialization for suspend and resume.
170  *
171  * This function initialize ehci phy IP for suspend and resume.
172  *
173  * @param[in] controllerId   ehci controller id, please reference to #usb_controller_index_t.
174  * @param[in] freq            the external input clock.
175  *                            for example: if the external input clock is 16M, the parameter freq should be 16000000.
176  *
177  * @retval 0      cancel successfully.
178  * @retval -1        the freq value is incorrect.
179  */
USB_EhciLowPowerPhyInit(uint8_t controllerId,uint32_t freq,usb_phy_config_struct_t * phyConfig)180 uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
181 {
182 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
183     USBPHY_Type *usbPhyBase;
184 
185     usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
186     if (NULL == usbPhyBase) {
187         return (uint8_t)-1;
188     }
189 
190 #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
191     usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
192 #endif
193 
194 #if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
195     usbPhyBase->CTRL_CLR |= USBPHY_CTRL_AUTORESUME_EN_MASK;
196 #else
197     usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
198 #endif
199     usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
200     usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
201     usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
202     /* PWD register provides overall control of the PHY power state */
203     usbPhyBase->PWD = 0U;
204 #if (defined USBPHY_ANACTRL_PFD_CLKGATE_MASK)
205     /* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
206      * pfd clock = 480MHz*18/N, where N=18~35
207      * Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
208      */
209     usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24);   /* N=24 */
210     usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
211 
212     usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
213     usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
214     while (0U == (usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK)) {
215     }
216 #endif
217     if (NULL != phyConfig) {
218         /* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
219         usbPhyBase->TX =
220             ((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
221              (USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
222               USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
223     }
224 #endif
225 
226     return (uint8_t)0;
227 }
228 
229 /*!
230  * @brief ehci phy de-initialization.
231  *
232  * This function de-initialize ehci phy IP.
233  *
234  * @param[in] controllerId   ehci controller id, please reference to #usb_controller_index_t.
235  */
USB_EhciPhyDeinit(uint8_t controllerId)236 void USB_EhciPhyDeinit(uint8_t controllerId)
237 {
238 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
239     USBPHY_Type *usbPhyBase;
240 
241     usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
242     if (NULL == usbPhyBase) {
243         return;
244     }
245 #if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
246     usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK;       /* power down PLL */
247     usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
248 #endif
249     usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
250 #endif
251 }
252 
253 /*!
254  * @brief ehci phy disconnect detection enable or disable.
255  *
256  * This function enable/disable host ehci disconnect detection.
257  *
258  * @param[in] controllerId   ehci controller id, please reference to #usb_controller_index_t.
259  * @param[in] enable
260  *            1U - enable;
261  *            0U - disable;
262  */
USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId,uint8_t enable)263 void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
264 {
265 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
266     USBPHY_Type *usbPhyBase;
267 
268     usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
269     if (NULL == usbPhyBase) {
270         return;
271     }
272 
273     if (0U != enable) {
274         usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
275     } else {
276         usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
277     }
278 #endif
279 }
280 
281 #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
282 #if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
USB_PhyDeviceForceEnterFSMode(uint8_t controllerId,uint8_t enable)283 void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable)
284 {
285     USBPHY_Type *usbPhyBase;
286 
287     usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
288     if (NULL == usbPhyBase) {
289         return;
290     }
291 
292     if (0U != enable) {
293         uint32_t delay = 1000000;
294         usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
295         while ((0U != (usbPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK)) && (0U != delay)) {
296             delay--;
297         }
298         usbPhyBase->USB1_LOOPBACK_SET = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
299     } else {
300         usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
301         usbPhyBase->USB1_LOOPBACK_CLR = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
302     }
303 }
304 #endif
305 #endif
306 
USB_ClockInit(void)307 void USB_ClockInit(void)
308 {
309     usb_phy_config_struct_t phyConfig = {
310         BOARD_USB_PHY_D_CAL,
311         BOARD_USB_PHY_TXCAL45DP,
312         BOARD_USB_PHY_TXCAL45DM,
313     };
314 
315     SPC0->ACTIVE_VDELAY = 0x0500;
316     /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */
317     SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK;
318     SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) |
319                         SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u);
320     /* Wait until it is done */
321     while (SPC0->SC & SPC_SC_BUSY_MASK)
322         ;
323     if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) {
324         SCG0->TRIM_LOCK = 0x5a5a0001U;
325         SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK;
326         /* wait LDO ready */
327         while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK))
328             ;
329     }
330     SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK;
331     SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK);
332     /* xtal = 20 ~ 30MHz */
333     SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT);
334     SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK;
335     while (1) {
336         if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) {
337             break;
338         }
339     }
340     SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK;
341     CLOCK_EnableClock(kCLOCK_UsbHs);
342     CLOCK_EnableClock(kCLOCK_UsbHsPhy);
343     CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U);
344     CLOCK_EnableUsbhsClock();
345     USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig);
346 }
347 
348 void (*g_usb_nxp_irq)(uint8_t busid);
349 
usb_dc_low_level_init(uint8_t busid)350 void usb_dc_low_level_init(uint8_t busid)
351 {
352     USB_ClockInit();
353 
354     g_usb_nxp_irq = USBD_IRQHandler;
355 
356     /* Install isr, set priority, and enable IRQ. */
357     NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3);
358     EnableIRQ((IRQn_Type)USB1_HS_IRQn);
359 }
360 
usb_dc_low_level_deinit(uint8_t busid)361 void usb_dc_low_level_deinit(uint8_t busid)
362 {
363     DisableIRQ((IRQn_Type)USB1_HS_IRQn);
364 }
365 
usb_host_mode_init(CHIPIDEA_TypeDef * ptr)366 static void usb_host_mode_init(CHIPIDEA_TypeDef *ptr)
367 {
368     /* Set mode to host, must be set immediately after reset */
369     ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
370     ptr->USBMODE |= USB_USBMODE_CM_SET(3);
371 
372     /* Set the endian */
373     ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
374 
375     /* Set parallel interface signal */
376     ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
377 
378     /* Set parallel transceiver width */
379     ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
380 
381     /* Not use interrupt threshold. */
382     ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
383 }
384 
usb_hc_low_level_init(struct usbh_bus * bus)385 void usb_hc_low_level_init(struct usbh_bus *bus)
386 {
387     USB_ClockInit();
388 
389     g_usb_nxp_irq = USBH_IRQHandler;
390 
391     /* Install isr, set priority, and enable IRQ. */
392     NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3);
393     EnableIRQ((IRQn_Type)USB1_HS_IRQn);
394 }
395 
usb_hc_low_level2_init(struct usbh_bus * bus)396 void usb_hc_low_level2_init(struct usbh_bus *bus)
397 {
398     usb_host_mode_init((CHIPIDEA_TypeDef *)(bus->hcd.reg_base));
399 }
400 
usb_hc_low_level_deinit(struct usbh_bus * bus)401 void usb_hc_low_level_deinit(struct usbh_bus *bus)
402 {
403     DisableIRQ((IRQn_Type)USB1_HS_IRQn);
404 }
405 
usbh_get_port_speed(struct usbh_bus * bus,const uint8_t port)406 uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
407 {
408     (void)port;
409     uint8_t speed;
410 
411     CHIPIDEA_TypeDef *ptr = (CHIPIDEA_TypeDef *)bus->hcd.reg_base;
412 
413     speed = USB_PORTSC1_PSPD_GET(ptr->PORTSC1);
414 
415     if (speed == 0x00) {
416         return USB_SPEED_FULL;
417     }
418     if (speed == 0x01) {
419         return USB_SPEED_LOW;
420     }
421     if (speed == 0x02) {
422         USB_EhcihostPhyDisconnectDetectCmd(kUSB_ControllerEhci0, 1);
423         return USB_SPEED_HIGH;
424     }
425 
426     return 0;
427 }
428 
USB1_HS_IRQHandler(void)429 void USB1_HS_IRQHandler(void)
430 {
431     g_usb_nxp_irq(0);
432 }
433 
434 #ifdef CONFIG_USB_DCACHE_ENABLE
usb_dcache_clean(uintptr_t addr,size_t size)435 void usb_dcache_clean(uintptr_t addr, size_t size)
436 {
437     DCACHE_CleanByRange(addr, size);
438 }
439 
usb_dcache_invalidate(uintptr_t addr,size_t size)440 void usb_dcache_invalidate(uintptr_t addr, size_t size)
441 {
442     DCACHE_InvalidateByRange(addr, size);
443 }
444 
usb_dcache_flush(uintptr_t addr,size_t size)445 void usb_dcache_flush(uintptr_t addr, size_t size)
446 {
447     DCACHE_CleanInvalidateByRange(addr, size);
448 }
449 #endif