blackfin_usb.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Blackfin MUSB HCD (Host Controller Driver) for u-boot
  3. *
  4. * Copyright (c) 2008-2009 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <usb.h>
  10. #include <asm/blackfin.h>
  11. #include <asm/clock.h>
  12. #include <asm/mach-common/bits/usb.h>
  13. #include "musb_core.h"
  14. #ifndef CONFIG_USB_BLACKFIN_CLKIN
  15. #define CONFIG_USB_BLACKFIN_CLKIN 24
  16. #endif
  17. /* MUSB platform configuration */
  18. struct musb_config musb_cfg = {
  19. .regs = (struct musb_regs *)USB_FADDR,
  20. .timeout = 0x3FFFFFF,
  21. .musb_speed = 0,
  22. };
  23. /*
  24. * This function read or write data to endpoint fifo
  25. * Blackfin use DMA polling method to avoid buffer alignment issues
  26. *
  27. * ep - Endpoint number
  28. * length - Number of bytes to write to FIFO
  29. * fifo_data - Pointer to data buffer to be read/write
  30. * is_write - Flag for read or write
  31. */
  32. void rw_fifo(u8 ep, u32 length, void *fifo_data, int is_write)
  33. {
  34. struct bfin_musb_dma_regs *regs;
  35. u32 val = (u32)fifo_data;
  36. blackfin_dcache_flush_invalidate_range(fifo_data, fifo_data + length);
  37. regs = (void *)USB_DMA_INTERRUPT;
  38. regs += ep;
  39. /* Setup DMA address register */
  40. bfin_write16(&regs->addr_low, val);
  41. SSYNC();
  42. bfin_write16(&regs->addr_high, val >> 16);
  43. SSYNC();
  44. /* Setup DMA count register */
  45. bfin_write16(&regs->count_low, length);
  46. bfin_write16(&regs->count_high, 0);
  47. SSYNC();
  48. /* Enable the DMA */
  49. val = (ep << 4) | DMA_ENA | INT_ENA;
  50. if (is_write)
  51. val |= DIRECTION;
  52. bfin_write16(&regs->control, val);
  53. SSYNC();
  54. /* Wait for compelete */
  55. while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << ep)))
  56. continue;
  57. /* acknowledge dma interrupt */
  58. bfin_write_USB_DMA_INTERRUPT(1 << ep);
  59. SSYNC();
  60. /* Reset DMA */
  61. bfin_write16(&regs->control, 0);
  62. SSYNC();
  63. }
  64. void write_fifo(u8 ep, u32 length, void *fifo_data)
  65. {
  66. rw_fifo(ep, length, fifo_data, 1);
  67. }
  68. void read_fifo(u8 ep, u32 length, void *fifo_data)
  69. {
  70. rw_fifo(ep, length, fifo_data, 0);
  71. }
  72. /*
  73. * CPU and board-specific MUSB initializations. Aliased function
  74. * signals caller to move on.
  75. */
  76. static void __def_musb_init(void)
  77. {
  78. }
  79. void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
  80. static void bfin_anomaly_init(void)
  81. {
  82. u32 revid;
  83. if (!ANOMALY_05000346 && !ANOMALY_05000347)
  84. return;
  85. revid = bfin_revid();
  86. #ifdef __ADSPBF54x__
  87. if (revid > 0)
  88. return;
  89. #endif
  90. #ifdef __ADSPBF52x__
  91. if (ANOMALY_BF526 && revid > 0)
  92. return;
  93. if (ANOMALY_BF527 && revid > 1)
  94. return;
  95. #endif
  96. if (ANOMALY_05000346) {
  97. bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
  98. SSYNC();
  99. }
  100. if (ANOMALY_05000347) {
  101. bfin_write_USB_APHY_CNTRL(0x0);
  102. SSYNC();
  103. }
  104. }
  105. int musb_platform_init(void)
  106. {
  107. /* board specific initialization */
  108. board_musb_init();
  109. bfin_anomaly_init();
  110. /* Configure PLL oscillator register */
  111. bfin_write_USB_PLLOSC_CTRL(0x3080 |
  112. ((480 / CONFIG_USB_BLACKFIN_CLKIN) << 1));
  113. SSYNC();
  114. bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
  115. SSYNC();
  116. bfin_write_USB_EP_NI0_RXMAXP(64);
  117. SSYNC();
  118. bfin_write_USB_EP_NI0_TXMAXP(64);
  119. SSYNC();
  120. /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
  121. bfin_write_USB_GLOBINTR(0x7);
  122. SSYNC();
  123. bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
  124. EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
  125. EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
  126. EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
  127. EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
  128. SSYNC();
  129. return 0;
  130. }
  131. /*
  132. * This function performs Blackfin platform specific deinitialization for usb.
  133. */
  134. void musb_platform_deinit(void)
  135. {
  136. }