usb_glue_mcx.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "usbh_core.h"
  7. #include "fsl_common.h"
  8. #include "usb_chipidea_reg.h"
  9. #define USB_DEVICE_CONFIG_EHCI 1
  10. /*! @brief USB controller ID */
  11. typedef enum _usb_controller_index
  12. {
  13. kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
  14. kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
  15. to be used in the future. */
  16. kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
  17. kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */
  18. } usb_controller_index_t;
  19. /* USB PHY condfiguration */
  20. #define BOARD_USB_PHY_D_CAL (0x04U)
  21. #define BOARD_USB_PHY_TXCAL45DP (0x07U)
  22. #define BOARD_USB_PHY_TXCAL45DM (0x07U)
  23. #define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
  24. #if !defined(CONFIG_USB_EHCI_NXP)
  25. #error "mcx ehci must config CONFIG_USB_EHCI_NXP"
  26. #endif
  27. #if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100
  28. #error "mcx ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100"
  29. #endif
  30. #if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
  31. #include "usb_phy.h"
  32. #endif
  33. #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U))
  34. void USB1_HS_IRQHandler(void)
  35. {
  36. extern void USBH_IRQHandler(uint8_t busid);
  37. USBH_IRQHandler(0);
  38. }
  39. #endif
  40. void USB_ClockInit(void)
  41. {
  42. #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
  43. usb_phy_config_struct_t phyConfig = {
  44. BOARD_USB_PHY_D_CAL,
  45. BOARD_USB_PHY_TXCAL45DP,
  46. BOARD_USB_PHY_TXCAL45DM,
  47. };
  48. #endif
  49. #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)
  50. SPC0->ACTIVE_VDELAY = 0x0500;
  51. /* Change the power DCDC to 1.8v (By deafult, DCDC is 1.8V), CORELDO to 1.1v (By deafult, CORELDO is 1.0V) */
  52. SPC0->ACTIVE_CFG &= ~SPC_ACTIVE_CFG_CORELDO_VDD_DS_MASK;
  53. SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_DCDC_VDD_LVL(0x3) | SPC_ACTIVE_CFG_CORELDO_VDD_LVL(0x3) |
  54. SPC_ACTIVE_CFG_SYSLDO_VDD_DS_MASK | SPC_ACTIVE_CFG_DCDC_VDD_DS(0x2u);
  55. /* Wait until it is done */
  56. while (SPC0->SC & SPC_SC_BUSY_MASK)
  57. ;
  58. if (0u == (SCG0->LDOCSR & SCG_LDOCSR_LDOEN_MASK)) {
  59. SCG0->TRIM_LOCK = 0x5a5a0001U;
  60. SCG0->LDOCSR |= SCG_LDOCSR_LDOEN_MASK;
  61. /* wait LDO ready */
  62. while (0U == (SCG0->LDOCSR & SCG_LDOCSR_VOUT_OK_MASK))
  63. ;
  64. }
  65. SYSCON->AHBCLKCTRLSET[2] |= SYSCON_AHBCLKCTRL2_USB_HS_MASK | SYSCON_AHBCLKCTRL2_USB_HS_PHY_MASK;
  66. SCG0->SOSCCFG &= ~(SCG_SOSCCFG_RANGE_MASK | SCG_SOSCCFG_EREFS_MASK);
  67. /* xtal = 20 ~ 30MHz */
  68. SCG0->SOSCCFG = (1U << SCG_SOSCCFG_RANGE_SHIFT) | (1U << SCG_SOSCCFG_EREFS_SHIFT);
  69. SCG0->SOSCCSR |= SCG_SOSCCSR_SOSCEN_MASK;
  70. while (1) {
  71. if (SCG0->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK) {
  72. break;
  73. }
  74. }
  75. SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK | SYSCON_CLOCK_CTRL_CLKIN_ENA_FM_USBH_LPT_MASK;
  76. CLOCK_EnableClock(kCLOCK_UsbHs);
  77. CLOCK_EnableClock(kCLOCK_UsbHsPhy);
  78. CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000U);
  79. CLOCK_EnableUsbhsClock();
  80. USB_EhciPhyInit(kUSB_ControllerEhci0, BOARD_XTAL0_CLK_HZ, &phyConfig);
  81. #endif
  82. #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U)
  83. CLOCK_AttachClk(kCLK_48M_to_USB0);
  84. CLOCK_EnableClock(kCLOCK_Usb0Ram);
  85. CLOCK_EnableClock(kCLOCK_Usb0Fs);
  86. CLOCK_EnableUsbfsClock();
  87. #endif
  88. }
  89. static void usb_host_mode_init(CHIPIDEA_TypeDef *ptr)
  90. {
  91. /* Set mode to host, must be set immediately after reset */
  92. ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
  93. ptr->USBMODE |= USB_USBMODE_CM_SET(3);
  94. /* Set the endian */
  95. ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
  96. /* Set parallel interface signal */
  97. ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
  98. /* Set parallel transceiver width */
  99. ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
  100. /* Not use interrupt threshold. */
  101. ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
  102. }
  103. void usb_hc_low_level_init(struct usbh_bus *bus)
  104. {
  105. USB_ClockInit();
  106. /* Install isr, set priority, and enable IRQ. */
  107. NVIC_SetPriority((IRQn_Type)USB1_HS_IRQn, 3);
  108. EnableIRQ((IRQn_Type)USB1_HS_IRQn);
  109. }
  110. void usb_hc_low_level2_init(struct usbh_bus *bus)
  111. {
  112. usb_host_mode_init((CHIPIDEA_TypeDef *)(bus->hcd.reg_base));
  113. }
  114. void usb_hc_low_level_deinit(struct usbh_bus *bus)
  115. {
  116. DisableIRQ((IRQn_Type)USB1_HS_IRQn);
  117. }
  118. uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
  119. {
  120. (void)port;
  121. uint8_t speed;
  122. CHIPIDEA_TypeDef *ptr = (CHIPIDEA_TypeDef *)bus->hcd.reg_base;
  123. speed = USB_PORTSC1_PSPD_GET(ptr->PORTSC1);
  124. if (speed == 0x00) {
  125. return USB_SPEED_FULL;
  126. }
  127. if (speed == 0x01) {
  128. return USB_SPEED_LOW;
  129. }
  130. if (speed == 0x02) {
  131. USB_EhcihostPhyDisconnectDetectCmd(kUSB_ControllerEhci0, 1);
  132. return USB_SPEED_HIGH;
  133. }
  134. return 0;
  135. }