usb_glue_aic.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright (c) 2022, Artinchip Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <aic_core.h>
  7. #include <aic_hal.h>
  8. #include <hal_syscfg.h>
  9. #include "usbh_core.h"
  10. #include "usb_ehci_priv.h"
  11. extern void USBH_IRQHandler(uint8_t busid);
  12. static void aic_ehci_isr(int vector, void *arg)
  13. {
  14. struct usbh_bus *bus = (struct usbh_bus *)arg;
  15. extern void USBH_IRQHandler(uint8_t busid);
  16. USBH_IRQHandler(bus->hcd.hcd_id);
  17. }
  18. static void aic_ohci_isr(int vector, void *arg)
  19. {
  20. struct usbh_bus *bus = (struct usbh_bus *)arg;
  21. extern void OHCI_IRQHandler(uint8_t busid);
  22. OHCI_IRQHandler(bus->hcd.hcd_id);
  23. }
  24. typedef struct aic_ehci_config {
  25. uint32_t base_addr;
  26. uint32_t clk_id;
  27. uint32_t rst_id;
  28. uint32_t phy_clk_id;
  29. uint32_t phy_rst_id;
  30. uint32_t irq_num;
  31. }aic_ehci_config_t;
  32. aic_ehci_config_t config[] = {
  33. #ifdef AIC_USING_USB0_HOST
  34. {
  35. USB_HOST0_BASE,
  36. CLK_USBH0,
  37. RESET_USBH0,
  38. CLK_USB_PHY0,
  39. RESET_USBPHY0,
  40. USB_HOST0_EHCI_IRQn
  41. },
  42. #else
  43. {
  44. 0xFFFFFFFF,
  45. 0xFFFFFFFF,
  46. 0xFFFFFFFF,
  47. 0xFFFFFFFF,
  48. 0xFFFFFFFF,
  49. 0xFFFFFFFF
  50. },
  51. #endif
  52. #ifdef AIC_USING_USB1_HOST
  53. {
  54. USB_HOST1_BASE,
  55. CLK_USBH1,
  56. RESET_USBH1,
  57. CLK_USB_PHY1,
  58. RESET_USBPHY1,
  59. USB_HOST1_EHCI_IRQn
  60. }
  61. #endif
  62. };
  63. void usb_hc_low_level_init(struct usbh_bus *bus)
  64. {
  65. uint32_t val;
  66. int i = 0;
  67. for (i=0; i<sizeof(config)/sizeof(aic_ehci_config_t); i++) {
  68. if (bus->hcd.reg_base == config[i].base_addr)
  69. break;
  70. }
  71. if (i == sizeof(config)/sizeof(aic_ehci_config_t))
  72. return;
  73. /* set usb0 phy switch: Host/Device */
  74. if (i == 0)
  75. syscfg_usb_phy0_sw_host(1);
  76. /* enable clock */
  77. hal_clk_enable(config[i].phy_clk_id);
  78. hal_clk_enable(config[i].clk_id);
  79. aicos_udelay(300);
  80. hal_reset_assert(config[i].phy_rst_id);
  81. hal_reset_assert(config[i].rst_id);
  82. aicos_udelay(300);
  83. hal_reset_deassert(config[i].phy_rst_id);
  84. hal_reset_deassert(config[i].rst_id);
  85. aicos_udelay(300);
  86. /* set phy type: UTMI/ULPI */
  87. val = readl((volatile void *)(unsigned long)(config[i].base_addr+0x800));
  88. #ifdef FPGA_BOARD_ARTINCHIP
  89. /* fpga phy type = ULPI */
  90. writel((val & ~0x1U), (volatile void *)(unsigned long)(config[i].base_addr+0x800));
  91. #else
  92. /* board phy type = UTMI */
  93. writel((val | 0x1), (volatile void *)(unsigned long)(config[i].base_addr+0x800));
  94. #endif
  95. /* Set AHB2STBUS_INSREG01
  96. Set EHCI packet buffer IN/OUT threshold (in DWORDs)
  97. Must increase the OUT threshold to avoid underrun. (FIFO size - 4)
  98. */
  99. writel((32 | (127 << 16)), (volatile void *)(unsigned long)(config[i].base_addr+0x94));
  100. /* register interrupt callback */
  101. aicos_request_irq(config[i].irq_num, (irq_handler_t)aic_ehci_isr,
  102. 0, "usb_host_ehci", bus);
  103. aicos_request_irq(config[i].irq_num + 1, (irq_handler_t)aic_ohci_isr,
  104. 0, "usb_host_ohci", bus);
  105. aicos_irq_enable(config[i].irq_num);
  106. }
  107. uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
  108. {
  109. /* Defined by individual manufacturers */
  110. uint32_t regval;
  111. regval = EHCI_HCOR->portsc[port-1];
  112. if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
  113. return USB_SPEED_LOW;
  114. if (regval & EHCI_PORTSC_PE)
  115. return USB_SPEED_HIGH;
  116. else
  117. return USB_SPEED_FULL;
  118. }
  119. void usb_ehci_dcache_clean(uintptr_t addr, uint32_t len)
  120. {
  121. aicos_dcache_clean_range((size_t *)addr, len);
  122. }
  123. void usb_ehci_dcache_invalidate(uintptr_t addr, uint32_t len)
  124. {
  125. aicos_dcache_invalid_range((size_t *)addr, len);
  126. }
  127. void usb_ehci_dcache_clean_invalidate(uintptr_t addr, uint32_t len)
  128. {
  129. aicos_dcache_clean_invalid_range((size_t *)addr, len);
  130. }
  131. int usbh_init(void)
  132. {
  133. #if defined(AIC_USING_USB0_HOST) || defined(AIC_USING_USB1_HOST)
  134. int bus_id = 0;
  135. #endif
  136. #ifdef AIC_USING_USB0_HOST
  137. usbh_initialize(bus_id, USB_HOST0_BASE);
  138. bus_id++;
  139. #endif
  140. #ifdef AIC_USING_USB1_HOST
  141. usbh_initialize(bus_id, USB_HOST1_BASE);
  142. bus_id++;
  143. #endif
  144. return 0;
  145. }
  146. #if defined(KERNEL_RTTHREAD)
  147. #include <rtthread.h>
  148. #include <rtdevice.h>
  149. INIT_ENV_EXPORT(usbh_init);
  150. #if defined (RT_USING_FINSH)
  151. #include <finsh.h>
  152. MSH_CMD_EXPORT_ALIAS(lsusb, lsusb, list usb device);
  153. #endif
  154. #endif