diff options
Diffstat (limited to 'firmware/target/arm/usb-s3c6400x.c')
-rw-r--r-- | firmware/target/arm/usb-s3c6400x.c | 118 |
1 files changed, 50 insertions, 68 deletions
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c index ef9fc0d51c..c93922f9d6 100644 --- a/firmware/target/arm/usb-s3c6400x.c +++ b/firmware/target/arm/usb-s3c6400x.c | |||
@@ -79,62 +79,51 @@ static void reset_endpoints(int reinit) | |||
79 | semaphore_release(&endpoints[i].complete); | 79 | semaphore_release(&endpoints[i].complete); |
80 | } | 80 | } |
81 | 81 | ||
82 | DIEPCTL(0) = DEPCTL_usbactep | (1 << DEPCTL_nextep_bitp); | 82 | DEPCTL(0, false) = DEPCTL_usbactep | (1 << DEPCTL_nextep_bitp); |
83 | DOEPCTL(0) = DEPCTL_usbactep; | 83 | DEPCTL(0, true) = DEPCTL_usbactep; |
84 | DOEPTSIZ(0) = (1 << DEPTSIZ_pkcnt_bitp) | (1 << DEPTSIZ0_supcnt_bitp) | 64; | 84 | DEPTSIZ(0, true) = (1 << DEPTSIZ_pkcnt_bitp) | (1 << DEPTSIZ0_supcnt_bitp) | 64; |
85 | 85 | ||
86 | DOEPDMA(0) = &ctrlreq; | 86 | DEPDMA(0, true) = &ctrlreq; |
87 | DOEPCTL(0) |= DEPCTL_epena | DEPCTL_cnak; | 87 | DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak; |
88 | if (reinit) | 88 | if (reinit) |
89 | { | 89 | { |
90 | /* The size is getting set to zero, because we don't know | 90 | /* The size is getting set to zero, because we don't know |
91 | whether we are Full Speed or High Speed at this stage */ | 91 | whether we are Full Speed or High Speed at this stage */ |
92 | DIEPCTL(1) = DEPCTL_setd0pid | (3 << DEPCTL_nextep_bitp); | 92 | DEPCTL(1, false) = DEPCTL_setd0pid | (3 << DEPCTL_nextep_bitp); |
93 | DOEPCTL(2) = DEPCTL_setd0pid; | 93 | DEPCTL(2, true) = DEPCTL_setd0pid; |
94 | DIEPCTL(3) = DEPCTL_setd0pid | (0 << DEPCTL_nextep_bitp); | 94 | DEPCTL(3, false) = DEPCTL_setd0pid | (0 << DEPCTL_nextep_bitp); |
95 | DOEPCTL(4) = DEPCTL_setd0pid; | 95 | DEPCTL(4, true) = DEPCTL_setd0pid; |
96 | } | 96 | } |
97 | else | 97 | else |
98 | { | 98 | { |
99 | DIEPCTL(1) = (DIEPCTL(1) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; | 99 | DEPCTL(1, false) = (DEPCTL(1, false) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; |
100 | DOEPCTL(2) = (DOEPCTL(2) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; | 100 | DEPCTL(2, true) = (DEPCTL(2, true) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; |
101 | DIEPCTL(3) = (DIEPCTL(3) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; | 101 | DEPCTL(3, false) = (DEPCTL(3, false) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; |
102 | DOEPCTL(4) = (DOEPCTL(4) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; | 102 | DEPCTL(4, true) = (DEPCTL(4, true) & ~DEPCTL_usbactep) | DEPCTL_setd0pid; |
103 | } | 103 | } |
104 | DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */ | 104 | DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */ |
105 | } | 105 | } |
106 | 106 | ||
107 | int usb_drv_request_endpoint(int type, int dir) | 107 | int usb_drv_request_endpoint(int type, int dir) |
108 | { | 108 | { |
109 | size_t ep; | 109 | for(size_t ep = (dir == USB_DIR_IN) ? 1 : 2; ep < USB_NUM_ENDPOINTS; ep += 2) |
110 | int ret = -1; | ||
111 | |||
112 | if (dir == USB_DIR_IN) ep = 1; | ||
113 | else ep = 2; | ||
114 | |||
115 | while (ep < USB_NUM_ENDPOINTS) | ||
116 | { | ||
117 | if (!endpoints[ep].active) | 110 | if (!endpoints[ep].active) |
118 | { | 111 | { |
119 | endpoints[ep].active = true; | 112 | endpoints[ep].active = true; |
120 | ret = ep | dir; | 113 | DEPCTL(ep, !dir) = (DEPCTL(ep, !dir) & ~(DEPCTL_eptype_bits << DEPCTL_eptype_bitp)) | |
121 | uint32_t newbits = (type << DEPCTL_eptype_bitp) | DEPCTL_epena; | 114 | (type << DEPCTL_eptype_bitp) | DEPCTL_epena; |
122 | uint32_t mask = DEPCTL_eptype_bits << DEPCTL_eptype_bitp; | 115 | return ep | dir; |
123 | if (dir) DIEPCTL(ep) = (DIEPCTL(ep) & ~mask) | newbits; | ||
124 | else DOEPCTL(ep) = (DOEPCTL(ep) & ~mask) | newbits; | ||
125 | break; | ||
126 | } | 116 | } |
127 | ep += 2; | ||
128 | } | ||
129 | 117 | ||
130 | return ret; | 118 | return -1; |
131 | } | 119 | } |
132 | 120 | ||
133 | void usb_drv_release_endpoint(int ep) | 121 | void usb_drv_release_endpoint(int ep) |
134 | { | 122 | { |
135 | ep = ep & 0x7f; | 123 | ep = ep & 0x7f; |
136 | 124 | ||
137 | if (ep < 1 || ep > USB_NUM_ENDPOINTS) return; | 125 | if (ep < 1 || ep > USB_NUM_ENDPOINTS) |
126 | return; | ||
138 | 127 | ||
139 | endpoints[ep].active = false; | 128 | endpoints[ep].active = false; |
140 | } | 129 | } |
@@ -191,20 +180,20 @@ void INT_USB_FUNC(void) | |||
191 | { | 180 | { |
192 | /* Set up the maximum packet sizes accordingly */ | 181 | /* Set up the maximum packet sizes accordingly */ |
193 | uint32_t maxpacket = (usb_drv_port_speed() ? 512 : 64) << DEPCTL_mps_bitp; | 182 | uint32_t maxpacket = (usb_drv_port_speed() ? 512 : 64) << DEPCTL_mps_bitp; |
194 | DIEPCTL(1) = (DIEPCTL(1) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; | 183 | DEPCTL(1, false) = (DEPCTL(1, false) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; |
195 | DOEPCTL(2) = (DOEPCTL(2) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; | 184 | DEPCTL(2, true) = (DEPCTL(2, true) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; |
196 | DIEPCTL(3) = (DIEPCTL(3) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; | 185 | DEPCTL(3, false) = (DEPCTL(3, false) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; |
197 | DOEPCTL(4) = (DOEPCTL(4) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; | 186 | DEPCTL(4, true) = (DEPCTL(4, true) & ~(DEPCTL_mps_bits << DEPCTL_mps_bitp)) | maxpacket; |
198 | } | 187 | } |
199 | 188 | ||
200 | if (ints & GINTMSK_inepintr) | 189 | if (ints & GINTMSK_inepintr) |
201 | for (i = 0; i < 4; i += i + 1) // 0, 1, 3 | 190 | for (i = 0; i < 4; i += i + 1) // 0, 1, 3 |
202 | if ((epints = DIEPINT(i))) | 191 | if ((epints = DEPINT(i, false))) |
203 | { | 192 | { |
204 | if (epints & DIEPINT_xfercompl) | 193 | if (epints & DIEPINT_xfercompl) |
205 | { | 194 | { |
206 | invalidate_dcache(); | 195 | invalidate_dcache(); |
207 | int bytes = endpoints[i].size - (DIEPTSIZ(i) & 0x3FFFF); | 196 | int bytes = endpoints[i].size - (DEPTSIZ(i, false) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp)); |
208 | if (endpoints[i].busy) | 197 | if (endpoints[i].busy) |
209 | { | 198 | { |
210 | endpoints[i].busy = false; | 199 | endpoints[i].busy = false; |
@@ -226,17 +215,17 @@ void INT_USB_FUNC(void) | |||
226 | semaphore_release(&endpoints[i].complete); | 215 | semaphore_release(&endpoints[i].complete); |
227 | } | 216 | } |
228 | } | 217 | } |
229 | DIEPINT(i) = epints; | 218 | DEPINT(i, false) = epints; |
230 | } | 219 | } |
231 | 220 | ||
232 | if (ints & GINTMSK_outepintr) | 221 | if (ints & GINTMSK_outepintr) |
233 | for (i = 0; i < USB_NUM_ENDPOINTS; i += 2) | 222 | for (i = 0; i < USB_NUM_ENDPOINTS; i += 2) |
234 | if ((epints = DOEPINT(i))) | 223 | if ((epints = DEPINT(i, true))) |
235 | { | 224 | { |
236 | if (epints & DIEPINT_xfercompl) | 225 | if (epints & DIEPINT_xfercompl) |
237 | { | 226 | { |
238 | invalidate_dcache(); | 227 | invalidate_dcache(); |
239 | int bytes = endpoints[i].size - (DOEPTSIZ(i) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp)); | 228 | int bytes = endpoints[i].size - (DEPTSIZ(i, true) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp)); |
240 | if (endpoints[i].busy) | 229 | if (endpoints[i].busy) |
241 | { | 230 | { |
242 | endpoints[i].busy = false; | 231 | endpoints[i].busy = false; |
@@ -267,11 +256,11 @@ void INT_USB_FUNC(void) | |||
267 | /* Make sure EP0 OUT is set up to accept the next request */ | 256 | /* Make sure EP0 OUT is set up to accept the next request */ |
268 | if (i == 0) | 257 | if (i == 0) |
269 | { | 258 | { |
270 | DOEPTSIZ(0) = (1 << DEPTSIZ0_supcnt_bitp) | (1 << DEPTSIZ0_pkcnt_bitp) | 64; | 259 | DEPTSIZ(0, true) = (1 << DEPTSIZ0_supcnt_bitp) | (1 << DEPTSIZ0_pkcnt_bitp) | 64; |
271 | DOEPDMA(0) = &ctrlreq; | 260 | DEPDMA(0, true) = &ctrlreq; |
272 | DOEPCTL(0) |= DEPCTL_epena | DEPCTL_cnak; | 261 | DEPCTL(0, true) |= DEPCTL_epena | DEPCTL_cnak; |
273 | } | 262 | } |
274 | DOEPINT(i) = epints; | 263 | DEPINT(i, true) = epints; |
275 | } | 264 | } |
276 | 265 | ||
277 | GINTSTS = ints; | 266 | GINTSTS = ints; |
@@ -290,43 +279,43 @@ static void ep_send(int ep, const void *ptr, int length) | |||
290 | { | 279 | { |
291 | endpoints[ep].busy = true; | 280 | endpoints[ep].busy = true; |
292 | endpoints[ep].size = length; | 281 | endpoints[ep].size = length; |
293 | DIEPCTL(ep) |= DEPCTL_usbactep; | 282 | DEPCTL(ep, false) |= DEPCTL_usbactep; |
294 | int blocksize = usb_drv_port_speed() ? 512 : 64; | 283 | int blocksize = usb_drv_port_speed() ? 512 : 64; |
295 | int packets = (length + blocksize - 1) / blocksize; | 284 | int packets = (length + blocksize - 1) / blocksize; |
296 | if (!length) | 285 | if (!length) |
297 | { | 286 | { |
298 | DIEPTSIZ(ep) = 1 << DEPTSIZ0_pkcnt_bitp; /* one empty packet */ | 287 | DEPTSIZ(ep, false) = 1 << DEPTSIZ0_pkcnt_bitp; /* one empty packet */ |
299 | DIEPDMA(ep) = NULL; | 288 | DEPDMA(ep, false) = NULL; |
300 | } | 289 | } |
301 | else | 290 | else |
302 | { | 291 | { |
303 | DIEPTSIZ(ep) = length | (packets << DEPTSIZ0_pkcnt_bitp); | 292 | DEPTSIZ(ep, false) = length | (packets << DEPTSIZ0_pkcnt_bitp); |
304 | DIEPDMA(ep) = ptr; | 293 | DEPDMA(ep, false) = ptr; |
305 | } | 294 | } |
306 | clean_dcache(); | 295 | clean_dcache(); |
307 | DIEPCTL(ep) |= DEPCTL_epena | DEPCTL_cnak; | 296 | DEPCTL(ep, false) |= DEPCTL_epena | DEPCTL_cnak; |
308 | } | 297 | } |
309 | 298 | ||
310 | static void ep_recv(int ep, void *ptr, int length) | 299 | static void ep_recv(int ep, void *ptr, int length) |
311 | { | 300 | { |
312 | endpoints[ep].busy = true; | 301 | endpoints[ep].busy = true; |
313 | endpoints[ep].size = length; | 302 | endpoints[ep].size = length; |
314 | DOEPCTL(ep) &= ~DEPCTL_naksts; | 303 | DEPCTL(ep, true) &= ~DEPCTL_naksts; |
315 | DOEPCTL(ep) |= DEPCTL_usbactep; | 304 | DEPCTL(ep, true) |= DEPCTL_usbactep; |
316 | int blocksize = usb_drv_port_speed() ? 512 : 64; | 305 | int blocksize = usb_drv_port_speed() ? 512 : 64; |
317 | int packets = (length + blocksize - 1) / blocksize; | 306 | int packets = (length + blocksize - 1) / blocksize; |
318 | if (!length) | 307 | if (!length) |
319 | { | 308 | { |
320 | DOEPTSIZ(ep) = 1 << DEPTSIZ0_pkcnt_bitp; /* one empty packet */ | 309 | DEPTSIZ(ep, true) = 1 << DEPTSIZ0_pkcnt_bitp; /* one empty packet */ |
321 | DOEPDMA(ep) = NULL; | 310 | DEPDMA(ep, true) = NULL; |
322 | } | 311 | } |
323 | else | 312 | else |
324 | { | 313 | { |
325 | DOEPTSIZ(ep) = length | (packets << DEPTSIZ0_pkcnt_bitp); | 314 | DEPTSIZ(ep, true) = length | (packets << DEPTSIZ0_pkcnt_bitp); |
326 | DOEPDMA(ep) = ptr; | 315 | DEPDMA(ep, true) = ptr; |
327 | } | 316 | } |
328 | clean_dcache(); | 317 | clean_dcache(); |
329 | DOEPCTL(ep) |= DEPCTL_epena | DEPCTL_cnak; | 318 | DEPCTL(ep, true) |= DEPCTL_epena | DEPCTL_cnak; |
330 | } | 319 | } |
331 | 320 | ||
332 | int usb_drv_send(int endpoint, void *ptr, int length) | 321 | int usb_drv_send(int endpoint, void *ptr, int length) |
@@ -365,22 +354,15 @@ void usb_drv_set_test_mode(int mode) | |||
365 | 354 | ||
366 | bool usb_drv_stalled(int endpoint, bool in) | 355 | bool usb_drv_stalled(int endpoint, bool in) |
367 | { | 356 | { |
368 | if (in) return DIEPCTL(endpoint) & DEPCTL_naksts; | 357 | return DEPCTL(endpoint, !in) & DEPCTL_naksts; |
369 | else return DOEPCTL(endpoint) & DEPCTL_naksts; | ||
370 | } | 358 | } |
371 | 359 | ||
372 | void usb_drv_stall(int endpoint, bool stall, bool in) | 360 | void usb_drv_stall(int endpoint, bool stall, bool in) |
373 | { | 361 | { |
374 | if (in) | 362 | if (stall) |
375 | { | 363 | DEPCTL(endpoint, !in) |= DEPCTL_naksts; |
376 | if (stall) DIEPCTL(endpoint) |= DEPCTL_naksts; | ||
377 | else DIEPCTL(endpoint) &= ~DEPCTL_naksts; | ||
378 | } | ||
379 | else | 364 | else |
380 | { | 365 | DEPCTL(endpoint, !in) &= ~DEPCTL_naksts; |
381 | if (stall) DOEPCTL(endpoint) |= DEPCTL_naksts; | ||
382 | else DOEPCTL(endpoint) &= ~DEPCTL_naksts; | ||
383 | } | ||
384 | } | 366 | } |
385 | 367 | ||
386 | void usb_drv_init(void) | 368 | void usb_drv_init(void) |