blackfin_usb.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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/mach-common/bits/usb.h>
  12. #include "musb_core.h"
  13. /* MUSB platform configuration */
  14. struct musb_config musb_cfg = {
  15. .regs = (struct musb_regs *)USB_FADDR,
  16. .timeout = 0x3FFFFFF,
  17. .musb_speed = 0,
  18. };
  19. /*
  20. * This function read or write data to endpoint fifo
  21. * Blackfin use DMA polling method to avoid buffer alignment issues
  22. *
  23. * ep - Endpoint number
  24. * length - Number of bytes to write to FIFO
  25. * fifo_data - Pointer to data buffer to be read/write
  26. * is_write - Flag for read or write
  27. */
  28. void rw_fifo(u8 ep, u32 length, void *fifo_data, int is_write)
  29. {
  30. struct bfin_musb_dma_regs *regs;
  31. u32 val = (u32)fifo_data;
  32. blackfin_dcache_flush_invalidate_range(fifo_data, fifo_data + length);
  33. regs = (void *)USB_DMA_INTERRUPT;
  34. regs += ep;
  35. /* Setup DMA address register */
  36. bfin_write16(&regs->addr_low, val);
  37. SSYNC();
  38. bfin_write16(&regs->addr_high, val >> 16);
  39. SSYNC();
  40. /* Setup DMA count register */
  41. bfin_write16(&regs->count_low, length);
  42. bfin_write16(&regs->count_high, 0);
  43. SSYNC();
  44. /* Enable the DMA */
  45. val = (ep << 4) | DMA_ENA | INT_ENA;
  46. if (is_write)
  47. val |= DIRECTION;
  48. bfin_write16(&regs->control, val);
  49. SSYNC();
  50. /* Wait for compelete */
  51. while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << ep)))
  52. continue;
  53. /* acknowledge dma interrupt */
  54. bfin_write_USB_DMA_INTERRUPT(1 << ep);
  55. SSYNC();
  56. /* Reset DMA */
  57. bfin_write16(&regs->control, 0);
  58. SSYNC();
  59. }
  60. void write_fifo(u8 ep, u32 length, void *fifo_data)
  61. {
  62. rw_fifo(ep, length, fifo_data, 1);
  63. }
  64. void read_fifo(u8 ep, u32 length, void *fifo_data)
  65. {
  66. rw_fifo(ep, length, fifo_data, 0);
  67. }
  68. /*
  69. * CPU and board-specific MUSB initializations. Aliased function
  70. * signals caller to move on.
  71. */
  72. static void __def_musb_init(void)
  73. {
  74. }
  75. void board_musb_init(void) __attribute__((weak, alias("__def_musb_init")));
  76. int musb_platform_init(void)
  77. {
  78. /* board specific initialization */
  79. board_musb_init();
  80. if (ANOMALY_05000346) {
  81. bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value);
  82. SSYNC();
  83. }
  84. if (ANOMALY_05000347) {
  85. bfin_write_USB_APHY_CNTRL(0x0);
  86. SSYNC();
  87. }
  88. /* Configure PLL oscillator register */
  89. bfin_write_USB_PLLOSC_CTRL(0x30a8);
  90. SSYNC();
  91. bfin_write_USB_SRP_CLKDIV((get_sclk()/1000) / 32 - 1);
  92. SSYNC();
  93. bfin_write_USB_EP_NI0_RXMAXP(64);
  94. SSYNC();
  95. bfin_write_USB_EP_NI0_TXMAXP(64);
  96. SSYNC();
  97. /* Route INTRUSB/INTR_RX/INTR_TX to USB_INT0*/
  98. bfin_write_USB_GLOBINTR(0x7);
  99. SSYNC();
  100. bfin_write_USB_GLOBAL_CTL(GLOBAL_ENA | EP1_TX_ENA | EP2_TX_ENA |
  101. EP3_TX_ENA | EP4_TX_ENA | EP5_TX_ENA |
  102. EP6_TX_ENA | EP7_TX_ENA | EP1_RX_ENA |
  103. EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA |
  104. EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA);
  105. SSYNC();
  106. return 0;
  107. }
  108. /*
  109. * This function performs Blackfin platform specific deinitialization for usb.
  110. */
  111. void musb_platform_deinit(void)
  112. {
  113. }