diff options
| -rw-r--r-- | drivers/usb/musb/blackfin.c | 134 | ||||
| -rw-r--r-- | drivers/usb/musb/blackfin.h | 2 |
2 files changed, 91 insertions, 45 deletions
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index fe4934d9602c..ad26e6569665 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
| @@ -29,6 +29,8 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
| 29 | { | 29 | { |
| 30 | void __iomem *fifo = hw_ep->fifo; | 30 | void __iomem *fifo = hw_ep->fifo; |
| 31 | void __iomem *epio = hw_ep->regs; | 31 | void __iomem *epio = hw_ep->regs; |
| 32 | u8 epnum = hw_ep->epnum; | ||
| 33 | u16 dma_reg = 0; | ||
| 32 | 34 | ||
| 33 | prefetch((u8 *)src); | 35 | prefetch((u8 *)src); |
| 34 | 36 | ||
| @@ -39,67 +41,113 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) | |||
| 39 | 41 | ||
| 40 | dump_fifo_data(src, len); | 42 | dump_fifo_data(src, len); |
| 41 | 43 | ||
| 42 | if (unlikely((unsigned long)src & 0x01)) | 44 | if (!ANOMALY_05000380 && epnum != 0) { |
| 43 | outsw_8((unsigned long)fifo, src, | 45 | flush_dcache_range((unsigned int)src, |
| 44 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | 46 | (unsigned int)(src + len)); |
| 45 | else | 47 | |
| 46 | outsw((unsigned long)fifo, src, | 48 | /* Setup DMA address register */ |
| 47 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | 49 | dma_reg = (u16) ((u32) src & 0xFFFF); |
| 48 | } | 50 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
| 51 | SSYNC(); | ||
| 52 | |||
| 53 | dma_reg = (u16) (((u32) src >> 16) & 0xFFFF); | ||
| 54 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | ||
| 55 | SSYNC(); | ||
| 56 | |||
| 57 | /* Setup DMA count register */ | ||
| 58 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | ||
| 59 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | ||
| 60 | SSYNC(); | ||
| 61 | |||
| 62 | /* Enable the DMA */ | ||
| 63 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA | DIRECTION; | ||
| 64 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | ||
| 65 | SSYNC(); | ||
| 66 | |||
| 67 | /* Wait for compelete */ | ||
| 68 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | ||
| 69 | cpu_relax(); | ||
| 70 | |||
| 71 | /* acknowledge dma interrupt */ | ||
| 72 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | ||
| 73 | SSYNC(); | ||
| 74 | |||
| 75 | /* Reset DMA */ | ||
| 76 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
| 77 | SSYNC(); | ||
| 78 | } else { | ||
| 79 | SSYNC(); | ||
| 80 | |||
| 81 | if (unlikely((unsigned long)src & 0x01)) | ||
| 82 | outsw_8((unsigned long)fifo, src, | ||
| 83 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 84 | else | ||
| 85 | outsw((unsigned long)fifo, src, | ||
| 86 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 49 | 87 | ||
| 88 | } | ||
| 89 | } | ||
| 50 | /* | 90 | /* |
| 51 | * Unload an endpoint's FIFO | 91 | * Unload an endpoint's FIFO |
| 52 | */ | 92 | */ |
| 53 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | 93 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) |
| 54 | { | 94 | { |
| 55 | void __iomem *fifo = hw_ep->fifo; | 95 | void __iomem *fifo = hw_ep->fifo; |
| 56 | |||
| 57 | #ifdef CONFIG_BF52x | ||
| 58 | u8 epnum = hw_ep->epnum; | 96 | u8 epnum = hw_ep->epnum; |
| 59 | u16 dma_reg = 0; | 97 | u16 dma_reg = 0; |
| 60 | 98 | ||
| 61 | invalidate_dcache_range((unsigned int)dst, | 99 | if (ANOMALY_05000467 && epnum != 0) { |
| 62 | (unsigned int)(dst + len)); | ||
| 63 | 100 | ||
| 64 | /* Setup DMA address register */ | 101 | invalidate_dcache_range((unsigned int)dst, |
| 65 | dma_reg = (u16) ((u32) dst & 0xFFFF); | 102 | (unsigned int)(dst + len)); |
| 66 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); | ||
| 67 | SSYNC(); | ||
| 68 | 103 | ||
| 69 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); | 104 | /* Setup DMA address register */ |
| 70 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); | 105 | dma_reg = (u16) ((u32) dst & 0xFFFF); |
| 71 | SSYNC(); | 106 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); |
| 107 | SSYNC(); | ||
| 72 | 108 | ||
| 73 | /* Setup DMA count register */ | 109 | dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); |
| 74 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); | 110 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); |
| 75 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); | 111 | SSYNC(); |
| 76 | SSYNC(); | ||
| 77 | 112 | ||
| 78 | /* Enable the DMA */ | 113 | /* Setup DMA count register */ |
| 79 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; | 114 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); |
| 80 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); | 115 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); |
| 81 | SSYNC(); | 116 | SSYNC(); |
| 82 | 117 | ||
| 83 | /* Wait for compelete */ | 118 | /* Enable the DMA */ |
| 84 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) | 119 | dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; |
| 85 | cpu_relax(); | 120 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); |
| 121 | SSYNC(); | ||
| 86 | 122 | ||
| 87 | /* acknowledge dma interrupt */ | 123 | /* Wait for compelete */ |
| 88 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); | 124 | while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) |
| 89 | SSYNC(); | 125 | cpu_relax(); |
| 90 | 126 | ||
| 91 | /* Reset DMA */ | 127 | /* acknowledge dma interrupt */ |
| 92 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | 128 | bfin_write_USB_DMA_INTERRUPT(1 << epnum); |
| 93 | SSYNC(); | 129 | SSYNC(); |
| 94 | #else | ||
| 95 | if (unlikely((unsigned long)dst & 0x01)) | ||
| 96 | insw_8((unsigned long)fifo, dst, | ||
| 97 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 98 | else | ||
| 99 | insw((unsigned long)fifo, dst, | ||
| 100 | len & 0x01 ? (len >> 1) + 1 : len >> 1); | ||
| 101 | #endif | ||
| 102 | 130 | ||
| 131 | /* Reset DMA */ | ||
| 132 | bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); | ||
| 133 | SSYNC(); | ||
| 134 | } else { | ||
| 135 | SSYNC(); | ||
| 136 | /* Read the last byte of packet with odd size from address fifo + 4 | ||
| 137 | * to trigger 1 byte access to EP0 FIFO. | ||
| 138 | */ | ||
| 139 | if (len == 1) | ||
| 140 | *dst = (u8)inw((unsigned long)fifo + 4); | ||
| 141 | else { | ||
| 142 | if (unlikely((unsigned long)dst & 0x01)) | ||
| 143 | insw_8((unsigned long)fifo, dst, len >> 1); | ||
| 144 | else | ||
| 145 | insw((unsigned long)fifo, dst, len >> 1); | ||
| 146 | |||
| 147 | if (len & 0x01) | ||
| 148 | *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4); | ||
| 149 | } | ||
| 150 | } | ||
| 103 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", | 151 | DBG(4, "%cX ep%d fifo %p count %d buf %p\n", |
| 104 | 'R', hw_ep->epnum, fifo, len, dst); | 152 | 'R', hw_ep->epnum, fifo, len, dst); |
| 105 | 153 | ||
diff --git a/drivers/usb/musb/blackfin.h b/drivers/usb/musb/blackfin.h index 10b7d7584f4b..bd9352a2ef2a 100644 --- a/drivers/usb/musb/blackfin.h +++ b/drivers/usb/musb/blackfin.h | |||
| @@ -69,7 +69,6 @@ static void dump_fifo_data(u8 *buf, u16 len) | |||
| 69 | #define dump_fifo_data(buf, len) do {} while (0) | 69 | #define dump_fifo_data(buf, len) do {} while (0) |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #ifdef CONFIG_BF52x | ||
| 73 | 72 | ||
| 74 | #define USB_DMA_BASE USB_DMA_INTERRUPT | 73 | #define USB_DMA_BASE USB_DMA_INTERRUPT |
| 75 | #define USB_DMAx_CTRL 0x04 | 74 | #define USB_DMAx_CTRL 0x04 |
| @@ -79,7 +78,6 @@ static void dump_fifo_data(u8 *buf, u16 len) | |||
| 79 | #define USB_DMAx_COUNT_HIGH 0x14 | 78 | #define USB_DMAx_COUNT_HIGH 0x14 |
| 80 | 79 | ||
| 81 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) | 80 | #define USB_DMA_REG(ep, reg) (USB_DMA_BASE + 0x20 * ep + reg) |
| 82 | #endif | ||
| 83 | 81 | ||
| 84 | /* Almost 1 second */ | 82 | /* Almost 1 second */ |
| 85 | #define TIMER_DELAY (1 * HZ) | 83 | #define TIMER_DELAY (1 * HZ) |
