aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/blackfin.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/blackfin.c')
-rw-r--r--drivers/usb/musb/blackfin.c134
1 files changed, 91 insertions, 43 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 */
53void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) 93void 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