usb_glue_bouffalo.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "bflb_core.h"
  7. #include "bflb_l1c.h"
  8. #include "usbh_core.h"
  9. #include "hardware/usb_v2_reg.h"
  10. #ifndef CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
  11. #error "usb host must enable CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE"
  12. #endif
  13. #define BLFB_USB_BASE ((uint32_t)0x20072000)
  14. #define BFLB_PDS_BASE ((uint32_t)0x2000e000)
  15. #define PDS_USB_CTL_OFFSET (0x500) /* usb_ctl */
  16. #define PDS_USB_PHY_CTRL_OFFSET (0x504) /* usb_phy_ctrl */
  17. /* 0x500 : usb_ctl */
  18. #define PDS_REG_USB_SW_RST_N (1 << 0U)
  19. #define PDS_REG_USB_EXT_SUSP_N (1 << 1U)
  20. #define PDS_REG_USB_WAKEUP (1 << 2U)
  21. #define PDS_REG_USB_L1_WAKEUP (1 << 3U)
  22. #define PDS_REG_USB_DRVBUS_POL (1 << 4U)
  23. #define PDS_REG_USB_IDDIG (1 << 5U)
  24. /* 0x504 : usb_phy_ctrl */
  25. #define PDS_REG_USB_PHY_PONRST (1 << 0U)
  26. #define PDS_REG_USB_PHY_OSCOUTEN (1 << 1U)
  27. #define PDS_REG_USB_PHY_XTLSEL_SHIFT (2U)
  28. #define PDS_REG_USB_PHY_XTLSEL_MASK (0x3 << PDS_REG_USB_PHY_XTLSEL_SHIFT)
  29. #define PDS_REG_USB_PHY_OUTCLKSEL (1 << 4U)
  30. #define PDS_REG_USB_PHY_PLLALIV (1 << 5U)
  31. #define PDS_REG_PU_USB20_PSW (1 << 6U)
  32. #define USB_SOF_TIMER_MASK_AFTER_RESET_HS (0x44C)
  33. #define USB_SOF_TIMER_MASK_AFTER_RESET_FS (0x2710)
  34. extern void USBH_IRQHandler(uint8_t busid);
  35. void USBH_IRQ(int irq, void *arg) {
  36. USBH_IRQHandler(0);
  37. }
  38. static void bflb_usb_phy_init(void)
  39. {
  40. uint32_t regval;
  41. /* USB_PHY_CTRL[3:2] reg_usb_phy_xtlsel=0 */
  42. /* 2000e504 = 0x40; #100; USB_PHY_CTRL[6] reg_pu_usb20_psw=1 (VCC33A) */
  43. /* 2000e504 = 0x41; #500; USB_PHY_CTRL[0] reg_usb_phy_ponrst=1 */
  44. /* 2000e500 = 0x20; #100; USB_CTL[0] reg_usb_sw_rst_n=0 */
  45. /* 2000e500 = 0x22; #500; USB_CTL[1] reg_usb_ext_susp_n=1 */
  46. /* 2000e500 = 0x23; #100; USB_CTL[0] reg_usb_sw_rst_n=1 */
  47. /* #1.2ms; wait UCLK */
  48. /* wait(soc616_b0.usb_uclk); */
  49. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  50. regval &= ~PDS_REG_USB_PHY_XTLSEL_MASK;
  51. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  52. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  53. regval |= PDS_REG_PU_USB20_PSW;
  54. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  55. regval = getreg32(BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  56. regval |= PDS_REG_USB_PHY_PONRST;
  57. putreg32(regval, BFLB_PDS_BASE + PDS_USB_PHY_CTRL_OFFSET);
  58. /* greater than 5T */
  59. bflb_mtimer_delay_us(1);
  60. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  61. regval &= ~PDS_REG_USB_SW_RST_N;
  62. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  63. /* greater than 5T */
  64. bflb_mtimer_delay_us(1);
  65. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  66. regval |= PDS_REG_USB_EXT_SUSP_N;
  67. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  68. /* wait UCLK 1.2ms */
  69. bflb_mtimer_delay_ms(3);
  70. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  71. regval |= PDS_REG_USB_SW_RST_N;
  72. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  73. bflb_mtimer_delay_ms(2);
  74. }
  75. void usb_hc_low_level_init(struct usbh_bus *bus)
  76. {
  77. uint32_t regval;
  78. bflb_usb_phy_init();
  79. bflb_irq_attach(37, USBH_IRQ, NULL);
  80. bflb_irq_enable(37);
  81. /* enable device-A for host */
  82. regval = getreg32(BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  83. regval &= ~PDS_REG_USB_IDDIG;
  84. putreg32(regval, BFLB_PDS_BASE + PDS_USB_CTL_OFFSET);
  85. regval = getreg32(BLFB_USB_BASE + USB_OTG_CSR_OFFSET);
  86. regval |= USB_A_BUS_DROP_HOV;
  87. regval &= ~USB_A_BUS_REQ_HOV;
  88. putreg32(regval, BLFB_USB_BASE + USB_OTG_CSR_OFFSET);
  89. bflb_mtimer_delay_ms(10);
  90. /* enable vbus and bus control */
  91. regval = getreg32(BLFB_USB_BASE + USB_OTG_CSR_OFFSET);
  92. regval &= ~USB_A_BUS_DROP_HOV;
  93. regval |= USB_A_BUS_REQ_HOV;
  94. putreg32(regval, BLFB_USB_BASE + USB_OTG_CSR_OFFSET);
  95. regval = getreg32(BLFB_USB_BASE + USB_GLB_INT_OFFSET);
  96. regval |= USB_MDEV_INT;
  97. regval |= USB_MOTG_INT;
  98. regval &= ~USB_MHC_INT;
  99. putreg32(regval, BLFB_USB_BASE + USB_GLB_INT_OFFSET);
  100. }
  101. uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
  102. {
  103. uint8_t speed = 3;
  104. speed = (getreg32(BLFB_USB_BASE + USB_OTG_CSR_OFFSET) & USB_SPD_TYP_HOV_POV_MASK) >> USB_SPD_TYP_HOV_POV_SHIFT;
  105. if (speed == 0) {
  106. return USB_SPEED_FULL;
  107. } else if (speed == 1) {
  108. return USB_SPEED_LOW;
  109. } else if (speed == 2) {
  110. return USB_SPEED_HIGH;
  111. }
  112. return USB_SPEED_HIGH;
  113. }
  114. #ifdef CONFIG_USB_DCACHE_ENABLE
  115. void usb_dcache_clean(uintptr_t addr, size_t size)
  116. {
  117. bflb_l1c_dcache_clean_range((void *)addr, size);
  118. }
  119. void usb_dcache_invalidate(uintptr_t addr, size_t size)
  120. {
  121. bflb_l1c_dcache_invalidate_range((void *)addr, size);
  122. }
  123. void usb_dcache_flush(uintptr_t addr, size_t size)
  124. {
  125. bflb_l1c_dcache_clean_invalidate_range((void *)addr, size);
  126. }
  127. #endif