summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/export/jz4760b.h12
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h1
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4760.c383
-rw-r--r--utils/hwstub/stub/jz4760b/jz4760b.h5
4 files changed, 262 insertions, 139 deletions
diff --git a/firmware/export/jz4760b.h b/firmware/export/jz4760b.h
index e61689105c..589f67800a 100644
--- a/firmware/export/jz4760b.h
+++ b/firmware/export/jz4760b.h
@@ -6992,8 +6992,12 @@ do { \
6992#define USB_OUTCSRH (USB_BASE + 0x17) /* EP1-15 OUT CSR MSB 8-bit */ 6992#define USB_OUTCSRH (USB_BASE + 0x17) /* EP1-15 OUT CSR MSB 8-bit */
6993#define USB_OUTCOUNT (USB_BASE + 0x18) /* EP1-15 OUT FIFO count 16-bit */ 6993#define USB_OUTCOUNT (USB_BASE + 0x18) /* EP1-15 OUT FIFO count 16-bit */
6994 6994
6995#define USB_CONFIGDATA (USB_BASE + 0x1f) /* Fixed config */
6996
6995#define USB_FIFO_EP(n) (USB_BASE + (n)*4 + 0x20) 6997#define USB_FIFO_EP(n) (USB_BASE + (n)*4 + 0x20)
6996 6998
6999#define USB_HWVERS (USB_BASE + 0x6c)
7000
6997#define USB_EPINFO (USB_BASE + 0x78) /* Endpoint information */ 7001#define USB_EPINFO (USB_BASE + 0x78) /* Endpoint information */
6998#define USB_RAMINFO (USB_BASE + 0x79) /* RAM information */ 7002#define USB_RAMINFO (USB_BASE + 0x79) /* RAM information */
6999 7003
@@ -7034,6 +7038,7 @@ do { \
7034#define USB_INCSRH_DMAREQENAB 0x10 7038#define USB_INCSRH_DMAREQENAB 0x10
7035#define USB_INCSRH_FRCDATATOG 0x08 7039#define USB_INCSRH_FRCDATATOG 0x08
7036#define USB_INCSRH_DMAREQMODE 0x04 7040#define USB_INCSRH_DMAREQMODE 0x04
7041#define USB_INCSR_INCOMPTX 0x80
7037#define USB_INCSR_CDT 0x40 7042#define USB_INCSR_CDT 0x40
7038#define USB_INCSR_SENTSTALL 0x20 7043#define USB_INCSR_SENTSTALL 0x20
7039#define USB_INCSR_SENDSTALL 0x10 7044#define USB_INCSR_SENDSTALL 0x10
@@ -7077,6 +7082,10 @@ do { \
7077#define USB_CNTL_BURST_8 (2 << 9) 7082#define USB_CNTL_BURST_8 (2 << 9)
7078#define USB_CNTL_BURST_16 (3 << 9) 7083#define USB_CNTL_BURST_16 (3 << 9)
7079 7084
7085/* USB HW revision */
7086#define USB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f)
7087#define USB_HWVERS_MINOR(x) (x & 0x3ff)
7088
7080/* DMA interrupt bits */ 7089/* DMA interrupt bits */
7081#define USB_INTR_DMA_BULKIN 1 7090#define USB_INTR_DMA_BULKIN 1
7082#define USB_INTR_DMA_BULKOUT 2 7091#define USB_INTR_DMA_BULKOUT 2
@@ -7104,6 +7113,7 @@ do { \
7104#define REG_USB_OUTCSRH REG8(USB_OUTCSRH) 7113#define REG_USB_OUTCSRH REG8(USB_OUTCSRH)
7105#define REG_USB_OUTCOUNT REG16(USB_OUTCOUNT) 7114#define REG_USB_OUTCOUNT REG16(USB_OUTCOUNT)
7106 7115
7116#define REG_USB_CONFIGDATA REG8(USB_CONFIGDATA)
7107#define REG_USB_FIFO_EP(n) REG32(USB_FIFO_EP(n)) 7117#define REG_USB_FIFO_EP(n) REG32(USB_FIFO_EP(n))
7108 7118
7109#define REG_USB_INTR REG8(USB_INTR) 7119#define REG_USB_INTR REG8(USB_INTR)
@@ -7111,6 +7121,8 @@ do { \
7111#define REG_USB_ADDR(n) REG32(USB_ADDR(n)) 7121#define REG_USB_ADDR(n) REG32(USB_ADDR(n))
7112#define REG_USB_COUNT(n) REG32(USB_COUNT(n)) 7122#define REG_USB_COUNT(n) REG32(USB_COUNT(n))
7113 7123
7124#define REG_USB_HWVERS REG16(USB_HWVERS)
7125
7114#define REG_USB_EPINFO REG8(USB_EPINFO) 7126#define REG_USB_EPINFO REG8(USB_EPINFO)
7115#define REG_USB_RAMINFO REG8(USB_RAMINFO) 7127#define REG_USB_RAMINFO REG8(USB_RAMINFO)
7116 7128
diff --git a/firmware/target/mips/ingenic_jz47xx/system-target.h b/firmware/target/mips/ingenic_jz47xx/system-target.h
index 30c1668bf7..9dc1a5c8c8 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-target.h
+++ b/firmware/target/mips/ingenic_jz47xx/system-target.h
@@ -83,6 +83,7 @@ static inline void restore_interrupt(int status)
83#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000) 83#define UNCACHED_ADDRESS(addr) ((unsigned int)(addr) | 0xA0000000)
84#define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x)) 84#define UNCACHED_ADDR(x) UNCACHED_ADDRESS((x))
85#define PHYSADDR(x) ((x) & 0x1fffffff) 85#define PHYSADDR(x) ((x) & 0x1fffffff)
86#define VIRTADDR(x) ((x) | 0xA0000000)
86 87
87void system_enable_irq(unsigned int irq); 88void system_enable_irq(unsigned int irq);
88void udelay(unsigned int usec); 89void udelay(unsigned int usec);
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
index 275fd3fd2b..8562d9253c 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
@@ -7,7 +7,8 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2016 by Roman Stolyarov 10 * Copyright (C) 2016 Roman Stolyarov
11 * Copyright (C) 2020 Solomon Peachy
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
@@ -20,7 +21,7 @@
20 ****************************************************************************/ 21 ****************************************************************************/
21 22
22#include "config.h" 23#include "config.h"
23/*#define LOGF_ENABLE*/ 24//#define LOGF_ENABLE
24#include "logf.h" 25#include "logf.h"
25#include "system.h" 26#include "system.h"
26#include "usb_ch9.h" 27#include "usb_ch9.h"
@@ -29,6 +30,8 @@
29#include "cpu.h" 30#include "cpu.h"
30#include "thread.h" 31#include "thread.h"
31 32
33#define USE_USB_DMA
34
32#define PIN_USB_DET (32*4+19) 35#define PIN_USB_DET (32*4+19)
33#define IRQ_USB_DET GPIO_IRQ(PIN_USB_DET) 36#define IRQ_USB_DET GPIO_IRQ(PIN_USB_DET)
34#define GPIO_USB_DET GPIO147 37#define GPIO_USB_DET GPIO147
@@ -43,6 +46,13 @@
43#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint)) 46#define TOTAL_EP() (sizeof(endpoints)/sizeof(struct usb_endpoint))
44#define EP_IS_IN(ep) (EP_NUMBER((ep))%2) 47#define EP_IS_IN(ep) (EP_NUMBER((ep))%2)
45 48
49#define TXCSR_WZC_BITS (USB_INCSR_SENTSTALL | USB_INCSR_UNDERRUN | USB_INCSR_FFNOTEMPT | USB_INCSR_INCOMPTX)
50
51/* NOTE: IN/OUT is from the HOST perspective. We're a peripheral, so:
52 IN = DEV->HOST, (ie we send)
53 OUT = HOST->DEV, (ie we recv)
54*/
55
46enum ep_type 56enum ep_type
47{ 57{
48 ep_control, 58 ep_control,
@@ -53,6 +63,16 @@ enum ep_type
53 63
54struct usb_endpoint 64struct usb_endpoint
55{ 65{
66 const enum ep_type type;
67 const long fifo_addr;
68 unsigned short fifo_size;
69 bool allocated;
70 int use_dma; /* -1 = no, 0 = mode_0, 1 = mode_1 */
71
72 struct semaphore complete;
73
74 uint8_t config;
75
56 volatile void *buf; 76 volatile void *buf;
57 volatile size_t length; 77 volatile size_t length;
58 union 78 union
@@ -60,24 +80,14 @@ struct usb_endpoint
60 volatile size_t sent; 80 volatile size_t sent;
61 volatile size_t received; 81 volatile size_t received;
62 }; 82 };
83 volatile int rc;
63 volatile bool busy; 84 volatile bool busy;
64
65 const enum ep_type type;
66 const bool use_dma;
67
68 const long fifo_addr;
69 unsigned short fifo_size;
70
71 volatile bool wait; 85 volatile bool wait;
72 struct semaphore complete;
73
74 volatile int rc;
75 bool allocated;
76}; 86};
77 87
78#define EP_INIT(_type, _fifo_addr, _fifo_size, _buf, _use_dma) \ 88#define EP_INIT(_type, _fifo_addr, _fifo_size, _buf) \
79 { .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \ 89 { .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \
80 .buf = (_buf), .use_dma = (_use_dma), \ 90 .buf = (_buf), .use_dma = -1, \
81 .length = 0, .busy = false, .wait = false, .allocated = false } 91 .length = 0, .busy = false, .wait = false, .allocated = false }
82 92
83static union 93static union
@@ -91,12 +101,12 @@ static volatile bool ep0_data_requested = false;
91 101
92static struct usb_endpoint endpoints[] = 102static struct usb_endpoint endpoints[] =
93{ 103{
94 EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL, false), 104 EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL),
95 EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx.buf, false), 105 EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx.buf),
96 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 106 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL),
97 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 107 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL),
98 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false), 108 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL),
99 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false), 109 EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL),
100}; 110};
101 111
102static inline void select_endpoint(int ep) 112static inline void select_endpoint(int ep)
@@ -329,7 +339,8 @@ static void EP0_handler(void)
329 EP0_send(); 339 EP0_send();
330} 340}
331 341
332static void EPIN_handler(unsigned int endpoint) 342/* Does new work */
343static void EPIN_send(unsigned int endpoint)
333{ 344{
334 struct usb_endpoint* ep = &endpoints[endpoint*2]; 345 struct usb_endpoint* ep = &endpoints[endpoint*2];
335 unsigned int length, csr; 346 unsigned int length, csr;
@@ -338,45 +349,153 @@ static void EPIN_handler(unsigned int endpoint)
338 csr = REG_USB_INCSR; 349 csr = REG_USB_INCSR;
339 logf("%s(%d): 0x%x", __func__, endpoint, csr); 350 logf("%s(%d): 0x%x", __func__, endpoint, csr);
340 351
341 if(!ep->busy) 352 if (!ep->busy) {
342 {
343 logf("Entered EPIN handler without work!"); 353 logf("Entered EPIN handler without work!");
344 return; 354 return;
345 } 355 }
346 356
347 if(csr & USB_INCSR_SENTSTALL) 357 if (csr & USB_INCSR_INPKTRDY) {
348 { 358 logf("PKTRDY %d", endpoint);
349 REG_USB_INCSR = csr & ~USB_INCSR_SENTSTALL;
350 return; 359 return;
351 } 360 }
352 361
353 if(ep->use_dma) 362 if (csr & USB_INCSR_SENTSTALL) {
363 logf("SENDSTALL %d", endpoint);
364 REG_USB_INCSR = csr & ~USB_INCSR_SENTSTALL;
354 return; 365 return;
366 }
355 367
356 if(csr & USB_INCSR_FFNOTEMPT) 368 if (csr & USB_INCSR_FFNOTEMPT) {
357 {
358 logf("FIFO is not empty! 0x%x", csr); 369 logf("FIFO is not empty! 0x%x", csr);
359 return; 370 return;
360 } 371 }
361 372
373#ifdef USE_USB_DMA
374 if(ep->use_dma >= 0) {
375 logf("DMA busy(%x %x %x)", REG_USB_ADDR(USB_INTR_DMA_BULKIN), REG_USB_COUNT(USB_INTR_DMA_BULKIN),REG_USB_CNTL(USB_INTR_DMA_BULKIN));
376
377 return;
378 }
379#endif
380
362 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length); 381 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length);
363 382
383#ifdef USE_USB_DMA
384 /* Can we use DMA? */
385 if (ep->type == ep_bulk && ep->length && (!(((unsigned long)ep->buf + ep->sent) % 4)) && !button_hold()) {
386 if (ep->length >= ep->fifo_size)
387 ep->use_dma = 1;
388 else
389 ep->use_dma = 0;
390 } else {
391 ep->use_dma = -1;
392 }
393
394 if (ep->use_dma >= 0) {
395 commit_discard_dcache_range((void*)ep->buf + ep->sent, ep->length - ep->sent);
396 /* Set up DMA */
397 uint16_t dmacr = USB_CNTL_BURST_16 | USB_CNTL_EP(EP_NUMBER2(ep)) | USB_CNTL_ENA | USB_CNTL_INTR_EN | USB_CNTL_DIR_IN ;
398 if (ep->use_dma > 0)
399 dmacr |= USB_CNTL_MODE_1;
400
401 REG_USB_ADDR(USB_INTR_DMA_BULKIN) = PHYSADDR((unsigned long)ep->buf + ep->sent);
402 REG_USB_COUNT(USB_INTR_DMA_BULKIN) = ep->length - ep->sent;
403 REG_USB_CNTL(USB_INTR_DMA_BULKIN) = dmacr;
404
405 uint16_t csr = REG_USB_INCSR;
406 if (ep->use_dma == 0) {
407 csr &= ~((USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQENAB) << 8);
408 REG_USB_INCSR = csr | TXCSR_WZC_BITS;
409 csr &= ~((USB_INCSRH_DMAREQMODE) << 8);
410 csr |= ((USB_INCSRH_DMAREQENAB | USB_INCSRH_MODE) << 8);
411 } else {
412 csr |= ((USB_INCSRH_DMAREQENAB | USB_INCSRH_MODE | USB_INCSRH_DMAREQMODE) << 8);
413 csr |= ((USB_INCSRH_AUTOSET) << 8);
414 }
415 csr &= ~USB_INCSR_UNDERRUN;
416
417 logf("DMA setup(%d: %x %x %x %x - %d)", EP_NUMBER2(ep), (unsigned int)PHYSADDR((unsigned long)ep->buf), ep->length, dmacr, csr, ep->use_dma);
418
419 REG_USB_INCSR = csr;
420
421 return;
422 }
423#endif
424
425 /* Non-DMA code */
364 if(ep->sent == 0) 426 if(ep->sent == 0)
365 length = MIN(ep->length, ep->fifo_size); 427 length = MIN(ep->length, ep->fifo_size);
366 else 428 else
367 length = MIN(EP_BUF_LEFT(ep), ep->fifo_size); 429 length = MIN(EP_BUF_LEFT(ep), ep->fifo_size);
368 430
369 writeFIFO(ep, length); 431 writeFIFO(ep, length);
370 REG_USB_INCSR = csr | USB_INCSR_INPKTRDY;
371 ep->sent += length; 432 ep->sent += length;
433 csr &= ~USB_INCSR_UNDERRUN;
434 csr |= USB_INCSR_INPKTRDY;
435 logf("Non-DMA TX %x", csr);
436 REG_USB_INCSR = csr;
437}
372 438
373 if(ep->sent >= ep->length) 439static void EPIN_complete(unsigned int endpoint)
374 { 440{
441 struct usb_endpoint* ep = &endpoints[endpoint*2];
442 uint16_t csr;
443
444 select_endpoint(endpoint);
445 csr = REG_USB_INCSR;
446 logf("%s(%d): 0x%x", __func__, endpoint, csr);
447
448 if (csr & USB_INCSR_SENTSTALL) {
449 logf("SENDSTALL %d\n", endpoint);
450 REG_USB_INCSR = csr & ~USB_INCSR_SENTSTALL; // XXX TXCSR_P_WZC_BITS
451 return;
452 }
453
454 if (csr & USB_INCSR_UNDERRUN) {
455 csr |= TXCSR_WZC_BITS;
456 csr &= ~(USB_INCSR_UNDERRUN | USB_INCSR_INPKTRDY);
457 REG_USB_INCSR = csr;
458 logf("underrun! %x", csr);
459 }
460
461 if (!ep->busy) {
462 logf("Entered EPIN_complete without work!");
463 return;
464 }
465
466 if (ep->use_dma >= 0) {
467 logf("DMA status (%x %x %x)", REG_USB_ADDR(USB_INTR_DMA_BULKIN), REG_USB_COUNT(USB_INTR_DMA_BULKIN),REG_USB_CNTL(USB_INTR_DMA_BULKIN));
468 return;
469 }
470
471 /* If we get here, the operation is completed, and we need to clean up */
472
473 /* Make sure DMA engine is idle */
474 if (csr & (USB_INCSRH_DMAREQENAB << 8)) {
475 csr |= TXCSR_WZC_BITS;
476 csr &= ~(USB_INCSR_UNDERRUN | USB_INCSR_INPKTRDY |
477 ((USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET) << 8));
478 REG_USB_INCSR = csr;
479 csr = REG_USB_INCSR;
480 logf("DMA cleanup %x", csr);
481 }
482
483 // XXX send a zero-length packet if necessary.
484 // if tx complete, and ep->length > 0 and ep->length % fifo == 0,
485 // REG_USB_INCSR = MODE | PKTRDY;
486 // Not needed for mass storage as it counts packets but
487 // if we ever enable other protocls...
488
489 logf("EP%d: %d -> %d", endpoint, ep->sent, ep->length);
490
491 if(ep->sent >= ep->length) {
375 if (!ep->wait) 492 if (!ep->wait)
376 usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); 493 usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent);
377 ep->rc = 0; 494 ep->rc = 0;
378 ep_transfer_completed(ep); 495 ep_transfer_completed(ep);
379 logf("sent complete"); 496 logf("send complete");
497 } else {
498 EPIN_send(endpoint);
380 } 499 }
381} 500}
382 501
@@ -403,9 +522,6 @@ static void EPOUT_handler(unsigned int endpoint)
403 return; 522 return;
404 } 523 }
405 524
406 if(ep->use_dma)
407 return;
408
409 if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */ 525 if(csr & USB_OUTCSR_OUTPKTRDY) /* There is a packet in the fifo */
410 { 526 {
411 size = REG_USB_OUTCOUNT; 527 size = REG_USB_OUTCOUNT;
@@ -430,59 +546,55 @@ static void EPOUT_handler(unsigned int endpoint)
430 } 546 }
431} 547}
432 548
549#ifdef USE_USB_DMA
433static void EPDMA_handler(int number) 550static void EPDMA_handler(int number)
434{ 551{
435 int endpoint = -1; 552 int endpoint = -1;
436 unsigned int size = 0; 553 int size = 0;
437 struct usb_endpoint* ep = NULL; 554 struct usb_endpoint* ep = NULL;
438 555
439 if(number == USB_INTR_DMA_BULKIN) 556 endpoint = (REG_USB_CNTL(number) >> 4) & 0xF;
440 { 557 ep = &endpoints[endpoint*2];
441 endpoint = (REG_USB_CNTL(0) >> 4) & 0xF; 558 if (!(REG_USB_CNTL(number) & USB_CNTL_DIR_IN))
442 ep = &endpoints[endpoint*2]; 559 ep++; /* RX endpoint is +1 in the array */
443 size = (unsigned int)ep->buf - REG_USB_ADDR(0); 560 size = VIRTADDR(REG_USB_ADDR(number)) - ((unsigned int)ep->buf + ep->sent);
444 } 561
445 else if(number == USB_INTR_DMA_BULKOUT) 562 if (number == USB_INTR_DMA_BULKIN) {
446 { 563 if ((ep->use_dma == 0) || (size % ep->fifo_size)) {
447 endpoint = (REG_USB_CNTL(1) >> 4) & 0xF; 564 /* DMA is completed, but the final (short) packet needs to
448 ep = &endpoints[endpoint*2+1]; 565 be manually initiated! */
449 size = (unsigned int)ep->buf - REG_USB_ADDR(1); 566 uint16_t incsr;
450 } 567 select_endpoint(endpoint);
451 568 incsr = REG_USB_INCSR;
452 logf("DMA_BULK%d %d", number, endpoint); 569
453 570 if (ep->use_dma == 1) {
454 if(number == USB_INTR_DMA_BULKOUT) 571 /* Switch to Mode 0 DMA */
455 { 572 incsr &= ~((USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQENAB) << 8);
456 /* Disable DMA */ 573 REG_USB_INCSR = incsr;
457 REG_USB_CNTL(1) = 0; 574 incsr &= ~((USB_INCSRH_DMAREQMODE) << 8);
458 575 incsr |= ((USB_INCSRH_DMAREQENAB) << 8);
459 commit_discard_dcache(); // XXX range? 576 }
460 577 incsr |= USB_INCSR_INPKTRDY;
461 select_endpoint(endpoint); 578 logf("DMA dangling %x", incsr);
462 /* Read out last packet manually */ 579 REG_USB_INCSR = incsr;
463 unsigned int lpack_size = REG_USB_OUTCOUNT;
464 if(lpack_size > 0)
465 {
466 ep->buf += ep->length - lpack_size;
467 readFIFO(ep, lpack_size);
468 REG_USB_OUTCSR &= ~USB_OUTCSR_OUTPKTRDY;
469 } 580 }
470 } 581 logf("DMA TX%d %d @%d/%d", number, size, ep->sent, ep->length);
471 else if(number == USB_INTR_DMA_BULKIN && size % ep->fifo_size) 582 ep->sent += size;
472 { 583 ep->use_dma = -1; /* DMA is complete, mark channel as idle */
473 /* If the last packet is less than MAXP, set INPKTRDY manually */ 584
474 REG_USB_INCSR |= USB_INCSR_INPKTRDY; 585 EPIN_complete(endpoint);
475 } 586 } else if (number == USB_INTR_DMA_BULKOUT) {
476 587 /* RX DMA completed */
477 if (ep) 588 logf("DMA RX%d %d @%d/%d", number, size, ep->received, ep->length);
478 { 589 ep->received += size;
479 int dir = EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT; 590 ep->use_dma = -1;
480 if ((dir == USB_DIR_OUT) || !ep->wait) 591
481 usb_core_transfer_complete(endpoint, dir, 0, ep->length); 592 EPOUT_handler(endpoint);
482 ep->rc = 0; 593 } else if (ep) {
483 ep_transfer_completed(ep); 594 ep->use_dma = -1;
484 } 595 }
485} 596}
597#endif
486 598
487static void setup_endpoint(struct usb_endpoint *ep) 599static void setup_endpoint(struct usb_endpoint *ep)
488{ 600{
@@ -510,14 +622,13 @@ static void setup_endpoint(struct usb_endpoint *ep)
510 if(ep->type != ep_control) 622 if(ep->type != ep_control)
511 ep->fifo_size = usb_drv_port_speed() ? 512 : 64; 623 ep->fifo_size = usb_drv_port_speed() ? 512 : 64;
512 624
625 ep->config = REG_USB_CONFIGDATA;
626
513 if(EP_IS_IN(ep)) 627 if(EP_IS_IN(ep))
514 { 628 {
515 csr = (USB_INCSR_FF | USB_INCSR_CDT); 629 csr = (USB_INCSR_FF | USB_INCSR_CDT);
516 csrh = USB_INCSRH_MODE; 630 csrh = USB_INCSRH_MODE;
517 631
518 if(ep->use_dma)
519 csrh |= (USB_INCSRH_DMAREQENAB | USB_INCSRH_AUTOSET | USB_INCSRH_DMAREQMODE);
520
521 if(ep->type == ep_interrupt) 632 if(ep->type == ep_interrupt)
522 csrh |= USB_INCSRH_FRCDATATOG; 633 csrh |= USB_INCSRH_FRCDATATOG;
523 634
@@ -525,6 +636,8 @@ static void setup_endpoint(struct usb_endpoint *ep)
525 REG_USB_INCSR = csr; 636 REG_USB_INCSR = csr;
526 REG_USB_INCSRH = csrh; 637 REG_USB_INCSRH = csrh;
527 638
639 logf("IN %d (%x %x %x)", endpoint, ep->fifo_size, csr, csrh);
640
528 if (ep->allocated) 641 if (ep->allocated)
529 REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); 642 REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep));
530 } 643 }
@@ -536,13 +649,12 @@ static void setup_endpoint(struct usb_endpoint *ep)
536 if(ep->type == ep_interrupt) 649 if(ep->type == ep_interrupt)
537 csrh |= USB_OUTCSRH_DNYT; 650 csrh |= USB_OUTCSRH_DNYT;
538 651
539 if(ep->use_dma)
540 csrh |= (USB_OUTCSRH_DMAREQENAB | USB_OUTCSRH_AUTOCLR | USB_OUTCSRH_DMAREQMODE);
541
542 REG_USB_OUTMAXP = ep->fifo_size; 652 REG_USB_OUTMAXP = ep->fifo_size;
543 REG_USB_OUTCSR = csr; 653 REG_USB_OUTCSR = csr;
544 REG_USB_OUTCSRH = csrh; 654 REG_USB_OUTCSRH = csrh;
545 655
656 logf("OUT %d (%x %x %x)", endpoint, ep->fifo_size, csr, csrh);
657
546 if (ep->allocated) 658 if (ep->allocated)
547 REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); 659 REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep));
548 } 660 }
@@ -574,8 +686,8 @@ static void udc_reset(void)
574 REG_USB_INTRUSBE = 0; 686 REG_USB_INTRUSBE = 0;
575 687
576 /* Disable DMA */ 688 /* Disable DMA */
577 REG_USB_CNTL(0) = 0; 689 REG_USB_CNTL(USB_INTR_DMA_BULKIN) = 0;
578 REG_USB_CNTL(1) = 0; 690 REG_USB_CNTL(USB_INTR_DMA_BULKOUT) = 0;
579 691
580 /* High speed, softconnect */ 692 /* High speed, softconnect */
581 REG_USB_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB); 693 REG_USB_POWER = (USB_POWER_SOFTCONN | USB_POWER_HSENAB);
@@ -584,6 +696,9 @@ static void udc_reset(void)
584 select_endpoint(0); 696 select_endpoint(0);
585 REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO); 697 REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO);
586 698
699 endpoints[0].config = REG_USB_CONFIGDATA;
700 endpoints[1].config = REG_USB_CONFIGDATA;
701
587 if (endpoints[0].busy) 702 if (endpoints[0].busy)
588 { 703 {
589 if (endpoints[0].wait) 704 if (endpoints[0].wait)
@@ -627,17 +742,19 @@ void OTG(void)
627 unsigned char intrUSB = REG_USB_INTRUSB; 742 unsigned char intrUSB = REG_USB_INTRUSB;
628 unsigned short intrIn = REG_USB_INTRIN; 743 unsigned short intrIn = REG_USB_INTRIN;
629 unsigned short intrOut = REG_USB_INTROUT; 744 unsigned short intrOut = REG_USB_INTROUT;
745#ifdef USE_USB_DMA
630 unsigned char intrDMA = REG_USB_INTR; 746 unsigned char intrDMA = REG_USB_INTR;
747#endif
631 748
632 logf("%x %x %x %x", intrUSB, intrIn, intrOut, intrDMA); 749 logf("IRQ %x %x %x %x", intrUSB, intrIn, intrOut, intrDMA);
633 750
634 /* EPIN & EPOUT are all handled in DMA */ 751 /* EPIN & EPOUT are all handled in DMA */
635 if(intrIn & USB_INTR_EP(0)) 752 if(intrIn & USB_INTR_EP(0))
636 EP0_handler(); 753 EP0_handler();
637 if(intrIn & USB_INTR_EP(1)) 754 if(intrIn & USB_INTR_EP(1))
638 EPIN_handler(1); 755 EPIN_complete(1);
639 if(intrIn & USB_INTR_EP(2)) 756 if(intrIn & USB_INTR_EP(2))
640 EPIN_handler(2); 757 EPIN_complete(2);
641 if(intrOut & USB_INTR_EP(1)) 758 if(intrOut & USB_INTR_EP(1))
642 EPOUT_handler(1); 759 EPOUT_handler(1);
643 if(intrOut & USB_INTR_EP(2)) 760 if(intrOut & USB_INTR_EP(2))
@@ -648,10 +765,12 @@ void OTG(void)
648 logf("USB suspend"); 765 logf("USB suspend");
649 if(intrUSB & USB_INTR_RESUME) 766 if(intrUSB & USB_INTR_RESUME)
650 logf("USB resume"); 767 logf("USB resume");
651 if(intrDMA & USB_INTR_DMA_BULKIN) 768#ifdef USE_USB_DMA
769 if(intrDMA & (1<<USB_INTR_DMA_BULKIN))
652 EPDMA_handler(USB_INTR_DMA_BULKIN); 770 EPDMA_handler(USB_INTR_DMA_BULKIN);
653 if(intrDMA & USB_INTR_DMA_BULKOUT) 771 if(intrDMA & (1<<USB_INTR_DMA_BULKOUT))
654 EPDMA_handler(USB_INTR_DMA_BULKOUT); 772 EPDMA_handler(USB_INTR_DMA_BULKOUT);
773#endif
655} 774}
656 775
657bool usb_drv_stalled(int endpoint, bool in) 776bool usb_drv_stalled(int endpoint, bool in)
@@ -790,6 +909,10 @@ void usb_drv_exit(void)
790{ 909{
791 logf("%s()", __func__); 910 logf("%s()", __func__);
792 911
912 select_endpoint(1);
913
914 logf("DMA X (%x %x %x %x)", REG_USB_ADDR(USB_INTR_DMA_BULKIN), REG_USB_COUNT(USB_INTR_DMA_BULKIN),REG_USB_CNTL(USB_INTR_DMA_BULKIN), REG_USB_INCSR);
915
793 REG_USB_FADDR = 0; 916 REG_USB_FADDR = 0;
794 REG_USB_INDEX = 0; 917 REG_USB_INDEX = 0;
795 918
@@ -798,9 +921,11 @@ void usb_drv_exit(void)
798 REG_USB_INTROUTE = 0; 921 REG_USB_INTROUTE = 0;
799 REG_USB_INTRUSBE = 0; 922 REG_USB_INTRUSBE = 0;
800 923
924#ifdef USE_USB_DMA
801 /* Disable DMA */ 925 /* Disable DMA */
802 REG_USB_CNTL(0) = 0; 926 REG_USB_CNTL(USB_INTR_DMA_BULKIN) = 0;
803 REG_USB_CNTL(1) = 0; 927 REG_USB_CNTL(USB_INTR_DMA_BULKOUT) = 0;
928#endif
804 929
805 /* Disconnect from USB */ 930 /* Disconnect from USB */
806 REG_USB_POWER &= ~USB_POWER_SOFTCONN; 931 REG_USB_POWER &= ~USB_POWER_SOFTCONN;
@@ -817,10 +942,8 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
817{ 942{
818 int flags = disable_irq_save(); 943 int flags = disable_irq_save();
819 944
820 if(ep->type == ep_control) 945 if (ep->type == ep_control) {
821 { 946 if ((ptr == NULL && length == 0) || !ep0_data_requested) {
822 if ((ptr == NULL && length == 0) || !ep0_data_requested)
823 {
824 restore_irq(flags); 947 restore_irq(flags);
825 return; 948 return;
826 } 949 }
@@ -831,36 +954,22 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
831 ep->sent = 0; 954 ep->sent = 0;
832 ep->length = length; 955 ep->length = length;
833 ep->busy = true; 956 ep->busy = true;
834 if(blocking) 957 if(blocking) {
835 {
836 ep->rc = -1; 958 ep->rc = -1;
837 ep->wait = true; 959 ep->wait = true;
960 } else {
961 ep->rc = 0;
838 } 962 }
839 else ep->rc = 0;
840 963
841 if(ep->type == ep_control) 964 if (ep->type == ep_control) {
842 {
843 EP0_send(); 965 EP0_send();
844 } 966 } else {
845 else 967 EPIN_send(EP_NUMBER2(ep));
846 {
847 if(ep->use_dma)
848 {
849 commit_discard_dcache_range(ptr, length);
850 REG_USB_ADDR(0) = PHYSADDR((unsigned long)ptr);
851 REG_USB_COUNT(0) = length;
852 REG_USB_CNTL(0) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 |
853 USB_CNTL_DIR_IN | USB_CNTL_ENA |
854 USB_CNTL_EP(EP_NUMBER2(ep)) | USB_CNTL_BURST_16);
855 }
856 else
857 EPIN_handler(EP_NUMBER2(ep));
858 } 968 }
859 969
860 restore_irq(flags); 970 restore_irq(flags);
861 971
862 if(blocking) 972 if(blocking) {
863 {
864 semaphore_wait(&ep->complete, HZ); 973 semaphore_wait(&ep->complete, HZ);
865 ep->wait = false; 974 ep->wait = false;
866 } 975 }
@@ -918,23 +1027,12 @@ int usb_drv_recv(int endpoint, void* ptr, int length)
918 ep->received = 0; 1027 ep->received = 0;
919 ep->length = length; 1028 ep->length = length;
920 ep->busy = true; 1029 ep->busy = true;
921 if(ep->use_dma) 1030
922 { 1031 if (endpoint == EP_CONTROL) {
923 discard_dcache_range(ptr, length); 1032 ep0_data_supplied = false;
924 REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr); 1033 EP0_handler();
925 REG_USB_COUNT(1) = length; 1034 } else {
926 REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 1035 EPOUT_handler(endpoint);
927 USB_CNTL_ENA | USB_CNTL_EP(endpoint) |
928 USB_CNTL_BURST_16);
929 }
930 else
931 {
932 if (endpoint == EP_CONTROL)
933 {
934 ep0_data_supplied = false;
935 EP0_handler();
936 }
937 else EPOUT_handler(endpoint);
938 } 1036 }
939 1037
940 restore_irq(flags); 1038 restore_irq(flags);
@@ -976,6 +1074,12 @@ void usb_drv_cancel_all_transfers(void)
976 1074
977 unsigned int i, flags = disable_irq_save(); 1075 unsigned int i, flags = disable_irq_save();
978 1076
1077#ifdef USE_USB_DMA
1078 /* Disable DMA */
1079 REG_USB_CNTL(USB_INTR_DMA_BULKIN) = 0;
1080 REG_USB_CNTL(USB_INTR_DMA_BULKOUT) = 0;
1081#endif
1082
979 for(i=0; i<TOTAL_EP(); i++) 1083 for(i=0; i<TOTAL_EP(); i++)
980 { 1084 {
981 if (endpoints[i].busy) 1085 if (endpoints[i].busy)
@@ -996,6 +1100,7 @@ void usb_drv_cancel_all_transfers(void)
996 select_endpoint(i/2); 1100 select_endpoint(i/2);
997 flushFIFO(&endpoints[i]); 1101 flushFIFO(&endpoints[i]);
998 } 1102 }
1103
999 restore_irq(flags); 1104 restore_irq(flags);
1000} 1105}
1001 1106
diff --git a/utils/hwstub/stub/jz4760b/jz4760b.h b/utils/hwstub/stub/jz4760b/jz4760b.h
index 97ef74a56c..d07a039f70 100644
--- a/utils/hwstub/stub/jz4760b/jz4760b.h
+++ b/utils/hwstub/stub/jz4760b/jz4760b.h
@@ -6966,6 +6966,8 @@ do { \
6966 6966
6967#define USB_FIFO_EP(n) (USB_BASE + (n)*4 + 0x20) 6967#define USB_FIFO_EP(n) (USB_BASE + (n)*4 + 0x20)
6968 6968
6969#define USB_HWVERS (USB_BASE + 0x6c)
6970
6969#define USB_EPINFO (USB_BASE + 0x78) /* Endpoint information */ 6971#define USB_EPINFO (USB_BASE + 0x78) /* Endpoint information */
6970#define USB_RAMINFO (USB_BASE + 0x79) /* RAM information */ 6972#define USB_RAMINFO (USB_BASE + 0x79) /* RAM information */
6971 6973
@@ -7006,6 +7008,7 @@ do { \
7006#define USB_INCSRH_DMAREQENAB 0x10 7008#define USB_INCSRH_DMAREQENAB 0x10
7007#define USB_INCSRH_FRCDATATOG 0x08 7009#define USB_INCSRH_FRCDATATOG 0x08
7008#define USB_INCSRH_DMAREQMODE 0x04 7010#define USB_INCSRH_DMAREQMODE 0x04
7011#define USB_INCSR_INCOMPTX 0x80
7009#define USB_INCSR_CDT 0x40 7012#define USB_INCSR_CDT 0x40
7010#define USB_INCSR_SENTSTALL 0x20 7013#define USB_INCSR_SENTSTALL 0x20
7011#define USB_INCSR_SENDSTALL 0x10 7014#define USB_INCSR_SENDSTALL 0x10
@@ -7083,6 +7086,8 @@ do { \
7083#define REG_USB_ADDR(n) REG32(USB_ADDR(n)) 7086#define REG_USB_ADDR(n) REG32(USB_ADDR(n))
7084#define REG_USB_COUNT(n) REG32(USB_COUNT(n)) 7087#define REG_USB_COUNT(n) REG32(USB_COUNT(n))
7085 7088
7089#define REG_USB_HWVERS REG16(USB_HWVERS)
7090
7086#define REG_USB_EPINFO REG8(USB_EPINFO) 7091#define REG_USB_EPINFO REG8(USB_EPINFO)
7087#define REG_USB_RAMINFO REG8(USB_RAMINFO) 7092#define REG_USB_RAMINFO REG8(USB_RAMINFO)
7088 7093