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.c153
1 files changed, 95 insertions, 58 deletions
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index fcec87ea709e..ec8d324237f6 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -11,7 +11,6 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/slab.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/list.h> 15#include <linux/list.h>
17#include <linux/gpio.h> 16#include <linux/gpio.h>
@@ -29,6 +28,7 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
29{ 28{
30 void __iomem *fifo = hw_ep->fifo; 29 void __iomem *fifo = hw_ep->fifo;
31 void __iomem *epio = hw_ep->regs; 30 void __iomem *epio = hw_ep->regs;
31 u8 epnum = hw_ep->epnum;
32 32
33 prefetch((u8 *)src); 33 prefetch((u8 *)src);
34 34
@@ -39,14 +39,51 @@ void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src)
39 39
40 dump_fifo_data(src, len); 40 dump_fifo_data(src, len);
41 41
42 if (unlikely((unsigned long)src & 0x01)) 42 if (!ANOMALY_05000380 && epnum != 0) {
43 outsw_8((unsigned long)fifo, src, 43 u16 dma_reg;
44 len & 0x01 ? (len >> 1) + 1 : len >> 1); 44
45 else 45 flush_dcache_range((unsigned long)src,
46 outsw((unsigned long)fifo, src, 46 (unsigned long)(src + len));
47 len & 0x01 ? (len >> 1) + 1 : len >> 1); 47
48} 48 /* Setup DMA address register */
49 dma_reg = (u32)src;
50 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
51 SSYNC();
52
53 dma_reg = (u32)src >> 16;
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();
49 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, (len + 1) >> 1);
83 else
84 outsw((unsigned long)fifo, src, (len + 1) >> 1);
85 }
86}
50/* 87/*
51 * Unload an endpoint's FIFO 88 * Unload an endpoint's FIFO
52 */ 89 */
@@ -54,53 +91,62 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
54{ 91{
55 void __iomem *fifo = hw_ep->fifo; 92 void __iomem *fifo = hw_ep->fifo;
56 u8 epnum = hw_ep->epnum; 93 u8 epnum = hw_ep->epnum;
57 u16 dma_reg = 0;
58 94
59 DBG(4, "%cX ep%d fifo %p count %d buf %p\n", 95 if (ANOMALY_05000467 && epnum != 0) {
60 'R', hw_ep->epnum, fifo, len, dst); 96 u16 dma_reg;
61 97
62#ifdef CONFIG_BF52x 98 invalidate_dcache_range((unsigned long)dst,
63 invalidate_dcache_range((unsigned int)dst, 99 (unsigned long)(dst + len));
64 (unsigned int)(dst + len));
65 100
66 /* Setup DMA address register */ 101 /* Setup DMA address register */
67 dma_reg = (u16) ((u32) dst & 0xFFFF); 102 dma_reg = (u32)dst;
68 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg); 103 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_LOW), dma_reg);
69 SSYNC(); 104 SSYNC();
70 105
71 dma_reg = (u16) (((u32) dst >> 16) & 0xFFFF); 106 dma_reg = (u32)dst >> 16;
72 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg); 107 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_ADDR_HIGH), dma_reg);
73 SSYNC(); 108 SSYNC();
74 109
75 /* Setup DMA count register */ 110 /* Setup DMA count register */
76 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len); 111 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_LOW), len);
77 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0); 112 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_COUNT_HIGH), 0);
78 SSYNC(); 113 SSYNC();
79 114
80 /* Enable the DMA */ 115 /* Enable the DMA */
81 dma_reg = (epnum << 4) | DMA_ENA | INT_ENA; 116 dma_reg = (epnum << 4) | DMA_ENA | INT_ENA;
82 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg); 117 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), dma_reg);
83 SSYNC(); 118 SSYNC();
84 119
85 /* Wait for compelete */ 120 /* Wait for compelete */
86 while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum))) 121 while (!(bfin_read_USB_DMA_INTERRUPT() & (1 << epnum)))
87 cpu_relax(); 122 cpu_relax();
88 123
89 /* acknowledge dma interrupt */ 124 /* acknowledge dma interrupt */
90 bfin_write_USB_DMA_INTERRUPT(1 << epnum); 125 bfin_write_USB_DMA_INTERRUPT(1 << epnum);
91 SSYNC(); 126 SSYNC();
92 127
93 /* Reset DMA */ 128 /* Reset DMA */
94 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0); 129 bfin_write16(USB_DMA_REG(epnum, USB_DMAx_CTRL), 0);
95 SSYNC(); 130 SSYNC();
96#else 131 } else {
97 if (unlikely((unsigned long)dst & 0x01)) 132 SSYNC();
98 insw_8((unsigned long)fifo, dst, 133 /* Read the last byte of packet with odd size from address fifo + 4
99 len & 0x01 ? (len >> 1) + 1 : len >> 1); 134 * to trigger 1 byte access to EP0 FIFO.
100 else 135 */
101 insw((unsigned long)fifo, dst, 136 if (len == 1)
102 len & 0x01 ? (len >> 1) + 1 : len >> 1); 137 *dst = (u8)inw((unsigned long)fifo + 4);
103#endif 138 else {
139 if (unlikely((unsigned long)dst & 0x01))
140 insw_8((unsigned long)fifo, dst, len >> 1);
141 else
142 insw((unsigned long)fifo, dst, len >> 1);
143
144 if (len & 0x01)
145 *(dst + len - 1) = (u8)inw((unsigned long)fifo + 4);
146 }
147 }
148 DBG(4, "%cX ep%d fifo %p count %d buf %p\n",
149 'R', hw_ep->epnum, fifo, len, dst);
104 150
105 dump_fifo_data(dst, len); 151 dump_fifo_data(dst, len);
106} 152}
@@ -126,13 +172,7 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
126 172
127 spin_unlock_irqrestore(&musb->lock, flags); 173 spin_unlock_irqrestore(&musb->lock, flags);
128 174
129 /* REVISIT we sometimes get spurious IRQs on g_ep0 175 return retval;
130 * not clear why... fall in BF54x too.
131 */
132 if (retval != IRQ_HANDLED)
133 DBG(5, "spurious?\n");
134
135 return IRQ_HANDLED;
136} 176}
137 177
138static void musb_conn_timer_handler(unsigned long _musb) 178static void musb_conn_timer_handler(unsigned long _musb)
@@ -225,8 +265,9 @@ int musb_platform_get_vbus_status(struct musb *musb)
225 return 0; 265 return 0;
226} 266}
227 267
228void musb_platform_set_mode(struct musb *musb, u8 musb_mode) 268int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
229{ 269{
270 return -EIO;
230} 271}
231 272
232int __init musb_platform_init(struct musb *musb) 273int __init musb_platform_init(struct musb *musb)
@@ -261,10 +302,6 @@ int __init musb_platform_init(struct musb *musb)
261 SSYNC(); 302 SSYNC();
262 } 303 }
263 304
264 /* TODO
265 * Set SIC-IVG register
266 */
267
268 /* Configure PLL oscillator register */ 305 /* Configure PLL oscillator register */
269 bfin_write_USB_PLLOSC_CTRL(0x30a8); 306 bfin_write_USB_PLLOSC_CTRL(0x30a8);
270 SSYNC(); 307 SSYNC();