usb_glue_aic.c 4.3 KB

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