diff options
-rw-r--r-- | firmware/export/jz4740.h | 20 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4740.c | 4 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | 261 |
3 files changed, 178 insertions, 107 deletions
diff --git a/firmware/export/jz4740.h b/firmware/export/jz4740.h index 5642dc8464..f029ad606e 100644 --- a/firmware/export/jz4740.h +++ b/firmware/export/jz4740.h | |||
@@ -2471,11 +2471,11 @@ | |||
2471 | #define USB_CSR0_SVDSETUPEND 0x80 | 2471 | #define USB_CSR0_SVDSETUPEND 0x80 |
2472 | 2472 | ||
2473 | /* Endpoint CSR register bits */ | 2473 | /* Endpoint CSR register bits */ |
2474 | #define USB_INCSRH_AUTOSET 0x8000 | 2474 | #define USB_INCSRH_AUTOSET 0x80 |
2475 | #define USB_INCSRH_ISO 0x4000 | 2475 | #define USB_INCSRH_ISO 0x40 |
2476 | #define USB_INCSRH_MODE 0x2000 | 2476 | #define USB_INCSRH_MODE 0x20 |
2477 | #define USB_INCSRH_DMAREQENAB 0x1000 | 2477 | #define USB_INCSRH_DMAREQENAB 0x10 |
2478 | #define USB_INCSRH_DMAREQMODE 0x0400 | 2478 | #define USB_INCSRH_DMAREQMODE 0x04 |
2479 | #define USB_INCSR_CDT 0x40 | 2479 | #define USB_INCSR_CDT 0x40 |
2480 | #define USB_INCSR_SENTSTALL 0x20 | 2480 | #define USB_INCSR_SENTSTALL 0x20 |
2481 | #define USB_INCSR_SENDSTALL 0x10 | 2481 | #define USB_INCSR_SENDSTALL 0x10 |
@@ -2483,11 +2483,11 @@ | |||
2483 | #define USB_INCSR_UNDERRUN 0x04 | 2483 | #define USB_INCSR_UNDERRUN 0x04 |
2484 | #define USB_INCSR_FFNOTEMPT 0x02 | 2484 | #define USB_INCSR_FFNOTEMPT 0x02 |
2485 | #define USB_INCSR_INPKTRDY 0x01 | 2485 | #define USB_INCSR_INPKTRDY 0x01 |
2486 | #define USB_OUTCSRH_AUTOCLR 0x8000 | 2486 | #define USB_OUTCSRH_AUTOCLR 0x80 |
2487 | #define USB_OUTCSRH_ISO 0x4000 | 2487 | #define USB_OUTCSRH_ISO 0x40 |
2488 | #define USB_OUTCSRH_DMAREQENAB 0x2000 | 2488 | #define USB_OUTCSRH_DMAREQENAB 0x20 |
2489 | #define USB_OUTCSRH_DNYT 0x1000 | 2489 | #define USB_OUTCSRH_DNYT 0x10 |
2490 | #define USB_OUTCSRH_DMAREQMODE 0x0800 | 2490 | #define USB_OUTCSRH_DMAREQMODE 0x08 |
2491 | #define USB_OUTCSR_CDT 0x80 | 2491 | #define USB_OUTCSR_CDT 0x80 |
2492 | #define USB_OUTCSR_SENTSTALL 0x40 | 2492 | #define USB_OUTCSR_SENTSTALL 0x40 |
2493 | #define USB_OUTCSR_SENDSTALL 0x20 | 2493 | #define USB_OUTCSR_SENDSTALL 0x20 |
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c index c029dd46bb..f78f3592e5 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4740.c | |||
@@ -238,7 +238,7 @@ static char* parse_exception(unsigned int cause) | |||
238 | 238 | ||
239 | void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc) | 239 | void exception_handler(void* stack_ptr, unsigned int cause, unsigned int epc) |
240 | { | 240 | { |
241 | panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), cause, epc, (unsigned int)stack_ptr); | 241 | panicf("Exception occurred: %s [0x%08x] at 0x%08x (stack at 0x%08x)", parse_exception(cause), read_c0_badvaddr(), epc, (unsigned int)stack_ptr); |
242 | } | 242 | } |
243 | 243 | ||
244 | void tlb_refill_handler(void) | 244 | void tlb_refill_handler(void) |
@@ -308,7 +308,7 @@ static void pll_init(void) | |||
308 | 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, | 308 | 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, |
309 | 9 | 309 | 9 |
310 | }; | 310 | }; |
311 | int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ | 311 | int div[5] = {0, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */ |
312 | int nf, pllout2; | 312 | int nf, pllout2; |
313 | 313 | ||
314 | cfcr = CPM_CPCCR_CLKOEN | | 314 | cfcr = CPM_CPCCR_CLKOEN | |
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c index 7bd0ba4ae5..2dd73c01a4 100644 --- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c | |||
@@ -127,21 +127,30 @@ static void writeFIFO(struct usb_endpoint *ep, unsigned int size) | |||
127 | { | 127 | { |
128 | logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); | 128 | logf("writeFIFO(EP%d, %d)", EP_NUMBER2(ep), size); |
129 | 129 | ||
130 | register unsigned int *d = (unsigned int *)EP_PTR(ep); | 130 | register unsigned int *d32 = (unsigned int *)EP_PTR(ep); |
131 | register unsigned char *c; | 131 | register unsigned char *d8 = (unsigned char *)EP_PTR(ep); |
132 | register unsigned int s; | 132 | register unsigned int s; |
133 | 133 | ||
134 | if(size > 0) | 134 | if(size > 0) |
135 | { | 135 | { |
136 | s = size >> 2; | 136 | if(UNLIKELY((unsigned int)d8 & 3)) |
137 | while (s--) | 137 | { |
138 | REG32(ep->fifo_addr) = *d++; | 138 | s = size; |
139 | 139 | while(s--) | |
140 | if( (s = size & 3) ) | 140 | REG8(ep->fifo_addr) = *d8++; |
141 | } | ||
142 | else | ||
141 | { | 143 | { |
142 | c = (unsigned char *)d; | 144 | s = size >> 2; |
143 | while (s--) | 145 | while (s--) |
144 | REG8(ep->fifo_addr) = *c++; | 146 | REG32(ep->fifo_addr) = *d32++; |
147 | |||
148 | if( (s = size & 3) ) | ||
149 | { | ||
150 | d8 = (unsigned char *)d32; | ||
151 | while (s--) | ||
152 | REG8(ep->fifo_addr) = *d8++; | ||
153 | } | ||
145 | } | 154 | } |
146 | } | 155 | } |
147 | } | 156 | } |
@@ -158,9 +167,9 @@ static void flushFIFO(struct usb_endpoint *ep) | |||
158 | case ep_bulk: | 167 | case ep_bulk: |
159 | case ep_interrupt: | 168 | case ep_interrupt: |
160 | if(EP_IS_IN(ep)) | 169 | if(EP_IS_IN(ep)) |
161 | REG_USB_REG_INCSR |= USB_INCSR_FF; | 170 | REG_USB_REG_INCSR |= (USB_INCSR_FF | USB_INCSR_CDT); |
162 | else | 171 | else |
163 | REG_USB_REG_OUTCSR |= USB_OUTCSR_FF; | 172 | REG_USB_REG_OUTCSR |= (USB_OUTCSR_FF | USB_OUTCSR_CDT); |
164 | break; | 173 | break; |
165 | } | 174 | } |
166 | } | 175 | } |
@@ -249,7 +258,7 @@ static void EP0_handler(void) | |||
249 | } | 258 | } |
250 | 259 | ||
251 | static void EPIN_handler(unsigned int endpoint) | 260 | static void EPIN_handler(unsigned int endpoint) |
252 | { | 261 | { |
253 | struct usb_endpoint* ep = &endpoints[endpoint*2+1]; | 262 | struct usb_endpoint* ep = &endpoints[endpoint*2+1]; |
254 | unsigned int length, csr; | 263 | unsigned int length, csr; |
255 | 264 | ||
@@ -266,14 +275,12 @@ static void EPIN_handler(unsigned int endpoint) | |||
266 | return; | 275 | return; |
267 | } | 276 | } |
268 | 277 | ||
269 | #if 0 | 278 | if(ep->use_dma) |
270 | if(ep->use_dma == true) | ||
271 | return; | 279 | return; |
272 | #endif | ||
273 | 280 | ||
274 | if(csr & USB_INCSR_FFNOTEMPT) | 281 | if(csr & USB_INCSR_FFNOTEMPT) |
275 | { | 282 | { |
276 | logf("FIFO is not empty!: 0x%x", csr); | 283 | logf("FIFO is not empty! 0x%x", csr); |
277 | return; | 284 | return; |
278 | } | 285 | } |
279 | 286 | ||
@@ -306,56 +313,113 @@ static void EPOUT_handler(unsigned int endpoint) | |||
306 | struct usb_endpoint* ep = &endpoints[endpoint*2]; | 313 | struct usb_endpoint* ep = &endpoints[endpoint*2]; |
307 | unsigned int size, csr; | 314 | unsigned int size, csr; |
308 | 315 | ||
309 | select_endpoint(endpoint); | ||
310 | csr = REG_USB_REG_OUTCSR; | ||
311 | logf("EPOUT_handler(%d): 0x%x", endpoint, csr); | ||
312 | |||
313 | if(!ep->busy) | 316 | if(!ep->busy) |
314 | return; | 317 | return; |
315 | |||
316 | if(csr & USB_OUTCSR_SENTSTALL) | ||
317 | { | ||
318 | logf("stall sent, flushing fifo.."); | ||
319 | flushFIFO(ep); | ||
320 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; | ||
321 | return; | ||
322 | } | ||
323 | 318 | ||
324 | if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ | 319 | select_endpoint(endpoint); |
320 | while((csr = REG_USB_REG_OUTCSR) & (USB_OUTCSR_SENTSTALL|USB_OUTCSR_OUTPKTRDY)) | ||
325 | { | 321 | { |
326 | size = REG_USB_REG_OUTCOUNT; | 322 | logf("EPOUT_handler(%d): 0x%x", endpoint, csr); |
323 | if(csr & USB_OUTCSR_SENTSTALL) | ||
324 | { | ||
325 | logf("stall sent, flushing fifo.."); | ||
326 | flushFIFO(ep); | ||
327 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_SENTSTALL; | ||
328 | return; | ||
329 | } | ||
327 | 330 | ||
328 | readFIFO(ep, size); | 331 | if(ep->use_dma) |
329 | ep->received += size; | 332 | return; |
333 | |||
334 | if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ | ||
335 | { | ||
336 | size = REG_USB_REG_OUTCOUNT; | ||
337 | |||
338 | readFIFO(ep, size); | ||
339 | ep->received += size; | ||
340 | |||
341 | /*if(csr & USB_OUTCSR_FFFULL) | ||
342 | csr &= ~USB_OUTCSR_FFFULL;*/ | ||
343 | |||
344 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | ||
345 | |||
346 | logf("received: %d max length: %d", ep->received, ep->length); | ||
347 | |||
348 | if(size < ep->fifo_size || ep->received >= ep->length) | ||
349 | { | ||
350 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); | ||
351 | if(ep->wait) | ||
352 | wakeup_signal(&ep_wkup[endpoint*2]); | ||
353 | logf("receive transfer_complete"); | ||
354 | ep->received = 0; | ||
355 | ep->length = 0; | ||
356 | ep->buf = NULL; | ||
357 | ep->busy = false; | ||
358 | return; | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | } | ||
330 | 363 | ||
331 | REG_USB_REG_OUTCSR = csr & ~USB_OUTCSR_OUTPKTRDY; | 364 | static void EPDMA_handler(int number) |
365 | { | ||
366 | int endpoint=-1; | ||
367 | unsigned int size=0; | ||
368 | if(number == USB_INTR_DMA_BULKIN) | ||
369 | endpoint = (REG_USB_REG_CNTL1 >> 4) & 0xF; | ||
370 | else if(number == USB_INTR_DMA_BULKOUT) | ||
371 | endpoint = (REG_USB_REG_CNTL2 >> 4) & 0xF; | ||
372 | |||
373 | struct usb_endpoint* ep = &endpoints[endpoint]; | ||
374 | logf("DMA_BULK%d %d", number, endpoint); | ||
375 | |||
376 | if(number == USB_INTR_DMA_BULKIN) | ||
377 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR1; | ||
378 | else if(number == USB_INTR_DMA_BULKOUT) | ||
379 | size = (unsigned int)ep->buf - REG_USB_REG_ADDR2; | ||
380 | |||
381 | if(number == USB_INTR_DMA_BULKOUT) | ||
382 | { | ||
383 | /* Disable DMA */ | ||
384 | REG_USB_REG_CNTL2 = 0; | ||
332 | 385 | ||
333 | logf("received: %d max length: %d", ep->received, ep->length); | 386 | __dcache_invalidate_all(); |
334 | 387 | ||
335 | if(size < ep->fifo_size || ep->received >= ep->length) | 388 | select_endpoint(endpoint); |
389 | /* Read out last packet manually */ | ||
390 | unsigned int lpack_size = REG_USB_REG_OUTCOUNT; | ||
391 | if(lpack_size > 0) | ||
336 | { | 392 | { |
337 | usb_core_transfer_complete(endpoint, USB_DIR_OUT, 0, ep->received); | 393 | ep->buf += ep->length - lpack_size; |
338 | if(ep->wait) | 394 | readFIFO(ep, lpack_size); |
339 | wakeup_signal(&ep_wkup[endpoint*2]); | 395 | REG_USB_REG_OUTCSR &= ~USB_OUTCSR_OUTPKTRDY; |
340 | logf("receive transfer_complete"); | ||
341 | ep->received = 0; | ||
342 | ep->length = 0; | ||
343 | ep->buf = NULL; | ||
344 | ep->busy = false; | ||
345 | } | 396 | } |
346 | } | 397 | } |
398 | else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size) | ||
399 | /* If the last packet is less than MAXP, set INPKTRDY manually */ | ||
400 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; | ||
401 | |||
402 | usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT, | ||
403 | 0, ep->length); | ||
404 | |||
405 | ep->busy = false; | ||
406 | ep->sent = 0; | ||
407 | ep->length = 0; | ||
408 | ep->buf = NULL; | ||
409 | if(ep->wait) | ||
410 | wakeup_signal(&ep_wkup[EP_NUMBER(ep)]); | ||
347 | } | 411 | } |
348 | 412 | ||
349 | static void setup_endpoint(struct usb_endpoint *ep) | 413 | static void setup_endpoint(struct usb_endpoint *ep) |
350 | { | 414 | { |
351 | int csr; | 415 | int csr, csrh; |
352 | ep->sent = 0; | ||
353 | ep->length = 0; | ||
354 | 416 | ||
355 | select_endpoint(EP_NUMBER2(ep)); | 417 | select_endpoint(EP_NUMBER2(ep)); |
356 | 418 | ||
357 | ep->busy = false; | 419 | ep->busy = false; |
358 | ep->wait = false; | 420 | ep->wait = false; |
421 | ep->sent = 0; | ||
422 | ep->length = 0; | ||
359 | 423 | ||
360 | if(ep->type == ep_bulk) | 424 | if(ep->type == ep_bulk) |
361 | { | 425 | { |
@@ -367,27 +431,31 @@ static void setup_endpoint(struct usb_endpoint *ep) | |||
367 | 431 | ||
368 | if(EP_IS_IN(ep)) | 432 | if(EP_IS_IN(ep)) |
369 | { | 433 | { |
370 | REG_USB_REG_INMAXP = ep->fifo_size; | 434 | csr = (USB_INCSR_FF | USB_INCSR_CDT); |
371 | csr = (USB_INCSR_FF | USB_INCSR_CDT | USB_INCSRH_MODE); | 435 | csrh = USB_INCSRH_MODE; |
372 | if(ep->use_dma) | 436 | if(ep->use_dma) |
373 | csr |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET); | 437 | csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE); |
374 | 438 | ||
375 | REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); | 439 | REG_USB_REG_INMAXP = ep->fifo_size; |
376 | REG_USB_REG_INCSR = csr; | 440 | REG_USB_REG_INCSR = csr; |
441 | REG_USB_REG_INCSRH = csrh; | ||
442 | REG_USB_REG_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); | ||
377 | } | 443 | } |
378 | else | 444 | else |
379 | { | 445 | { |
380 | REG_USB_REG_OUTMAXP = ep->fifo_size; | ||
381 | csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); | 446 | csr = (USB_OUTCSR_FF | USB_OUTCSR_CDT); |
447 | csrh = 0; | ||
382 | 448 | ||
383 | if(ep->type == ep_interrupt) | 449 | if(ep->type == ep_interrupt) |
384 | csr |= USB_OUTCSRH_DNYT; | 450 | csrh |= USB_OUTCSRH_DNYT; |
385 | 451 | ||
386 | if(ep->use_dma) | 452 | if(ep->use_dma) |
387 | csr |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); | 453 | csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE); |
388 | 454 | ||
389 | REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); | 455 | REG_USB_REG_OUTMAXP = ep->fifo_size; |
390 | REG_USB_REG_OUTCSR = csr; | 456 | REG_USB_REG_OUTCSR = csr; |
457 | REG_USB_REG_OUTCSRH = csrh; | ||
458 | REG_USB_REG_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); | ||
391 | } | 459 | } |
392 | } | 460 | } |
393 | 461 | ||
@@ -395,13 +463,13 @@ static void udc_reset(void) | |||
395 | { | 463 | { |
396 | /* From the datasheet: | 464 | /* From the datasheet: |
397 | 465 | ||
398 | When a reset condition is detected on the USB, the controller performs the following actions: | 466 | When a reset condition is detected on the USB, the controller performs the following actions: |
399 | * Sets FAddr to 0. | 467 | * Sets FAddr to 0. |
400 | * Sets Index to 0. | 468 | * Sets Index to 0. |
401 | * Flushes all endpoint FIFOs. | 469 | * Flushes all endpoint FIFOs. |
402 | * Clears all control/status registers. | 470 | * Clears all control/status registers. |
403 | * Enables all endpoint interrupts. | 471 | * Enables all endpoint interrupts. |
404 | * Generates a Reset interrupt. | 472 | * Generates a Reset interrupt. |
405 | */ | 473 | */ |
406 | 474 | ||
407 | logf("udc_reset()"); | 475 | logf("udc_reset()"); |
@@ -430,7 +498,8 @@ static void udc_reset(void) | |||
430 | select_endpoint(0); | 498 | select_endpoint(0); |
431 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); | 499 | REG_USB_REG_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND); |
432 | 500 | ||
433 | for(i=2; i<TOTAL_EP(); i++) /* Skip EP0 */ | 501 | /* Reset other endpoints */ |
502 | for(i=2; i<TOTAL_EP(); i++) | ||
434 | setup_endpoint(&endpoints[i]); | 503 | setup_endpoint(&endpoints[i]); |
435 | 504 | ||
436 | /* Enable interrupts */ | 505 | /* Enable interrupts */ |
@@ -451,6 +520,8 @@ void UDC(void) | |||
451 | 520 | ||
452 | if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)) | 521 | if(UNLIKELY(intrUSB == 0 && intrIn == 0 && intrOut == 0 && intrDMA == 0)) |
453 | return; | 522 | return; |
523 | |||
524 | logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA); | ||
454 | 525 | ||
455 | /* EPIN & EPOUT are all handled in DMA */ | 526 | /* EPIN & EPOUT are all handled in DMA */ |
456 | if(intrIn & USB_INTR_EP0) | 527 | if(intrIn & USB_INTR_EP0) |
@@ -473,30 +544,10 @@ void UDC(void) | |||
473 | { | 544 | { |
474 | logf("USB resume"); | 545 | logf("USB resume"); |
475 | } | 546 | } |
476 | #if 0 | ||
477 | if(intrDMA & USB_INTR_DMA_BULKIN) | 547 | if(intrDMA & USB_INTR_DMA_BULKIN) |
478 | { | 548 | EPDMA_handler(USB_INTR_DMA_BULKIN); |
479 | logf("DMA_BULKIN %d", ((REG_USB_REG_CNTL1 >> 4) & 0xF)); | ||
480 | unsigned int size = (unsigned int)endpoints[3].buf - REG_USB_REG_ADDR2; | ||
481 | if(size < endpoints[3].length) | ||
482 | { | ||
483 | select_endpoint(1); | ||
484 | writeFIFO(endpoints[3], endpoints[3].length - size); | ||
485 | REG_USB_REG_INCSR |= USB_INCSR_INPKTRDY; | ||
486 | } | ||
487 | |||
488 | usb_core_transfer_complete(1, USB_DIR_IN, 0, endpoints[3].length); | ||
489 | } | ||
490 | if(intrDMA & USB_INTR_DMA_BULKOUT) | 549 | if(intrDMA & USB_INTR_DMA_BULKOUT) |
491 | { | 550 | EPDMA_handler(USB_INTR_DMA_BULKOUT); |
492 | logf("DMA_BULKOUT %d", ((REG_USB_REG_CNTL2 >> 4) & 0xF)); | ||
493 | |||
494 | select_endpoint(1); | ||
495 | REG_USB_REG_OUTCSR &= ~(USB_OUTCSRH_DMAREQENAB | USB_OUTCSR_OUTPKTRDY); | ||
496 | |||
497 | usb_core_transfer_complete(1, USB_DIR_OUT, 0, 0); | ||
498 | } | ||
499 | #endif | ||
500 | } | 551 | } |
501 | 552 | ||
502 | bool usb_drv_stalled(int endpoint, bool in) | 553 | bool usb_drv_stalled(int endpoint, bool in) |
@@ -610,6 +661,10 @@ void usb_drv_init(void) | |||
610 | /* Enable the USB PHY */ | 661 | /* Enable the USB PHY */ |
611 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; | 662 | REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE; |
612 | 663 | ||
664 | /* Dis- and reconnect from USB */ | ||
665 | REG_USB_REG_POWER &= ~USB_POWER_SOFTCONN; | ||
666 | REG_USB_REG_POWER |= USB_POWER_SOFTCONN; | ||
667 | |||
613 | udc_reset(); | 668 | udc_reset(); |
614 | } | 669 | } |
615 | 670 | ||
@@ -660,8 +715,8 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | |||
660 | endpoints[1].length = length; | 715 | endpoints[1].length = length; |
661 | ep0state = USB_EP0_TX; | 716 | ep0state = USB_EP0_TX; |
662 | EP0_send(); | 717 | EP0_send(); |
663 | |||
664 | restore_irq(flags); | 718 | restore_irq(flags); |
719 | |||
665 | return 0; | 720 | return 0; |
666 | } | 721 | } |
667 | else | 722 | else |
@@ -671,15 +726,19 @@ int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) | |||
671 | endpoints[endpoint*2+1].sent = 0; | 726 | endpoints[endpoint*2+1].sent = 0; |
672 | endpoints[endpoint*2+1].length = length; | 727 | endpoints[endpoint*2+1].length = length; |
673 | endpoints[endpoint*2+1].busy = true; | 728 | endpoints[endpoint*2+1].busy = true; |
674 | #if 0 | 729 | if(endpoints[endpoint*2+1].use_dma) |
675 | select_endpoint(endpoint); | 730 | { |
731 | //dma_cache_wback_inv((unsigned long)ptr, length); | ||
732 | __dcache_writeback_all(); | ||
733 | REG_USB_REG_ADDR1 = (unsigned long)ptr & 0x7fffffff; | ||
734 | REG_USB_REG_COUNT1 = length; | ||
735 | REG_USB_REG_CNTL1 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | | ||
736 | USB_CNTL_DIR_IN | USB_CNTL_ENA | | ||
737 | USB_CNTL_EP(endpoint) | USB_CNTL_BURST_16); | ||
738 | } | ||
739 | else | ||
740 | EPIN_handler(endpoint); | ||
676 | 741 | ||
677 | REG_USB_REG_ADDR2 = ((unsigned long)ptr) & 0x7fffffff; | ||
678 | REG_USB_REG_COUNT2 = length; | ||
679 | REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | USB_CNTL_DIR_IN | USB_CNTL_ENA); | ||
680 | #else | ||
681 | EPIN_handler(endpoint); | ||
682 | #endif | ||
683 | restore_irq(flags); | 742 | restore_irq(flags); |
684 | return 0; | 743 | return 0; |
685 | } | 744 | } |
@@ -717,8 +776,20 @@ int usb_drv_recv(int endpoint, void* ptr, int length) | |||
717 | endpoints[endpoint*2].received = 0; | 776 | endpoints[endpoint*2].received = 0; |
718 | endpoints[endpoint*2].length = length; | 777 | endpoints[endpoint*2].length = length; |
719 | endpoints[endpoint*2].busy = true; | 778 | endpoints[endpoint*2].busy = true; |
720 | restore_irq(flags); | 779 | if(endpoints[endpoint*2].use_dma) |
780 | { | ||
781 | //dma_cache_wback_inv((unsigned long)ptr, length); | ||
782 | __dcache_writeback_all(); | ||
783 | REG_USB_REG_ADDR2 = (unsigned long)ptr & 0x7fffffff; | ||
784 | REG_USB_REG_COUNT2 = length; | ||
785 | REG_USB_REG_CNTL2 = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | | ||
786 | USB_CNTL_ENA | USB_CNTL_EP(endpoint) | | ||
787 | USB_CNTL_BURST_16); | ||
788 | } | ||
789 | else | ||
790 | EPOUT_handler(endpoint); | ||
721 | 791 | ||
792 | restore_irq(flags); | ||
722 | return 0; | 793 | return 0; |
723 | } | 794 | } |
724 | } | 795 | } |