diff options
Diffstat (limited to 'drivers/usb/musb/blackfin.c')
-rw-r--r-- | drivers/usb/musb/blackfin.c | 153 |
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 | ||
138 | static void musb_conn_timer_handler(unsigned long _musb) | 178 | static 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 | ||
228 | void musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 268 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) |
229 | { | 269 | { |
270 | return -EIO; | ||
230 | } | 271 | } |
231 | 272 | ||
232 | int __init musb_platform_init(struct musb *musb) | 273 | int __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(); |