Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

jz4760: Lots of stability fixes to the USB driver.

It actually works for transferring data now!

Igor Poretsky gets full credit for this patch.

Change-Id: I247c70fdf45e590b4699b9b8668bbdab7bc3ef03

+293 -84
+1
docs/CREDITS
··· 666 666 Alexander Yurenin 667 667 Roman Stolyarov 668 668 Solomon Peachy 669 + Igor Poretsky 669 670 670 671 The libmad team 671 672 The wavpack team
+292 -84
firmware/target/mips/ingenic_jz47xx/usb-jz4760.c
··· 53 53 54 54 struct usb_endpoint 55 55 { 56 - void *buf; 57 - size_t length; 56 + volatile void *buf; 57 + volatile size_t length; 58 58 union 59 59 { 60 - size_t sent; 61 - size_t received; 60 + volatile size_t sent; 61 + volatile size_t received; 62 62 }; 63 - bool busy; 63 + volatile bool busy; 64 64 65 65 const enum ep_type type; 66 66 const bool use_dma; ··· 68 68 const long fifo_addr; 69 69 unsigned short fifo_size; 70 70 71 - bool wait; 71 + volatile bool wait; 72 72 struct semaphore complete; 73 + 74 + volatile int rc; 75 + bool allocated; 73 76 }; 74 77 75 78 #define EP_INIT(_type, _fifo_addr, _fifo_size, _buf, _use_dma) \ 76 79 { .type = (_type), .fifo_addr = (_fifo_addr), .fifo_size = (_fifo_size), \ 77 - .buf = (_buf), .use_dma = (_use_dma), .length = 0, .busy = false, .wait = false } 80 + .buf = (_buf), .use_dma = (_use_dma), \ 81 + .length = 0, .busy = false, .wait = false, .allocated = false } 82 + 83 + static union 84 + { 85 + int buf[64 / sizeof(int)]; 86 + struct usb_ctrlrequest request; 87 + } ep0_rx; 88 + 89 + static volatile bool ep0_data_supplied = false; 90 + static volatile bool ep0_data_requested = false; 78 91 79 - static unsigned char ep0_rx_buf[64]; 80 92 static struct usb_endpoint endpoints[] = 81 93 { 82 94 EP_INIT(ep_control, USB_FIFO_EP(0), 64, NULL, false), 83 - EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx_buf, false), 95 + EP_INIT(ep_control, USB_FIFO_EP(0), 64, &ep0_rx.buf, false), 84 96 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 85 97 EP_INIT(ep_bulk, USB_FIFO_EP(1), 512, NULL, false), 86 - EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false), 87 - EP_INIT(ep_interrupt, USB_FIFO_EP(2), 64, NULL, false), 98 + EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false), 99 + EP_INIT(ep_interrupt, USB_FIFO_EP(2), 512, NULL, false), 88 100 }; 89 101 90 102 static inline void select_endpoint(int ep) ··· 133 145 logf("%s(EP%d, %d)", __func__, EP_NUMBER2(ep), size); 134 146 135 147 register unsigned int *d32 = (unsigned int *)EP_PTR(ep); 148 + register unsigned char *d8 = (unsigned char *)d32; 136 149 register size_t s = size >> 2; 150 + register unsigned int x; 137 151 138 152 if(size > 0) 139 153 { 140 - while (s--) 141 - REG32(ep->fifo_addr) = *d32++; 154 + if( ((unsigned int)d8 & 3) == 0 ) 155 + { 156 + while (s--) 157 + REG32(ep->fifo_addr) = *d32++; 158 + d8 = (unsigned char *)d32; 159 + } 160 + else 161 + { 162 + while (s--) 163 + { 164 + x = (unsigned int)(*d8++) & 0xff; 165 + x |= ((unsigned int)(*d8++) & 0xff) << 8; 166 + x |= ((unsigned int)(*d8++) & 0xff) << 16; 167 + x |= ((unsigned int)(*d8++) & 0xff) << 24; 168 + REG32(ep->fifo_addr) = x; 169 + } 170 + } 142 171 143 172 if( (s = size & 3) ) 144 173 { 145 - register unsigned char *d8 = (unsigned char *)d32; 146 174 while (s--) 147 175 REG8(ep->fifo_addr) = *d8++; 148 176 } ··· 183 211 { 184 212 struct usb_endpoint* ep = &endpoints[0]; 185 213 unsigned int length; 186 - unsigned char csr0; 214 + unsigned short csr0; 187 215 188 216 select_endpoint(0); 189 217 csr0 = REG_USB_CSR0; 190 218 191 219 if(ep->sent == 0) 220 + { 192 221 length = MIN(ep->length, ep->fifo_size); 222 + REG_USB_CSR0 = (csr0 | USB_CSR0_FLUSHFIFO); 223 + } 193 224 else 194 225 length = MIN(EP_BUF_LEFT(ep), ep->fifo_size); 195 226 ··· 199 230 if(ep->sent >= ep->length) 200 231 { 201 232 REG_USB_CSR0 = (csr0 | USB_CSR0_INPKTRDY | USB_CSR0_DATAEND); /* Set data end! */ 202 - usb_core_transfer_complete(0, USB_DIR_IN, 0, ep->sent); 233 + if (!ep->wait) 234 + usb_core_transfer_complete(0, USB_DIR_IN, 0, ep->sent); 235 + ep->rc = 0; 203 236 ep_transfer_completed(ep); 204 237 } 205 238 else ··· 208 241 209 242 static void EP0_handler(void) 210 243 { 211 - logf("%s()", __func__); 212 - 213 - unsigned char csr0; 244 + unsigned short csr0; 214 245 struct usb_endpoint *ep_send = &endpoints[0]; 215 246 struct usb_endpoint *ep_recv = &endpoints[1]; 216 247 217 248 /* Read CSR0 */ 218 249 select_endpoint(0); 219 250 csr0 = REG_USB_CSR0; 251 + 252 + logf("%s(): 0x%x", __func__, csr0); 220 253 221 254 /* Check for SentStall: 222 255 This bit is set when a STALL handshake is transmitted. The CPU should clear this bit. ··· 234 267 */ 235 268 if(csr0 & USB_CSR0_SETUPEND) 236 269 { 237 - REG_USB_CSR0 = csr0 | USB_CSR0_SVDSETUPEND; 238 - return; 270 + csr0 |= USB_CSR0_SVDSETUPEND; 271 + REG_USB_CSR0 = csr0; 272 + ep0_data_supplied = false; 273 + ep0_data_requested = false; 274 + if (ep_send->busy) 275 + { 276 + if (!ep_send->wait) 277 + usb_core_transfer_complete(0, USB_DIR_IN, -1, 0); 278 + ep_transfer_completed(ep_send); 279 + } 280 + if (ep_recv->busy) 281 + { 282 + usb_core_transfer_complete(0, USB_DIR_OUT, -1, 0); 283 + ep_transfer_completed(ep_recv); 284 + } 239 285 } 240 286 241 287 /* Call relevant routines for endpoint 0 state */ 242 - if(ep_send->busy) 243 - EP0_send(); 244 - else if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ 288 + if(csr0 & USB_CSR0_OUTPKTRDY) /* There is a packet in the fifo */ 245 289 { 246 - readFIFO(ep_recv, REG_USB_COUNT0); 247 - REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ 248 - usb_core_control_request((struct usb_ctrlrequest*)ep_recv->buf); 290 + if (ep_send->busy) 291 + { 292 + if (!ep_send->wait) 293 + usb_core_transfer_complete(0, USB_DIR_IN, -1, 0); 294 + ep_transfer_completed(ep_send); 295 + } 296 + if (ep_recv->busy && ep_recv->buf && ep_recv->length) 297 + { 298 + unsigned int size = REG_USB_COUNT0; 299 + readFIFO(ep_recv, size); 300 + ep_recv->received += size; 301 + if (size < ep_recv->fifo_size || ep_recv->received >= ep_recv->length) 302 + { 303 + REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY | USB_CSR0_DATAEND; /* Set data end! */ 304 + usb_core_transfer_complete(0, USB_DIR_OUT, 0, ep_recv->received); 305 + ep_transfer_completed(ep_recv); 306 + } 307 + else REG_USB_CSR0 = csr0 | USB_CSR0_SVDOUTPKTRDY; /* clear OUTPKTRDY bit */ 308 + } 309 + else if (!ep0_data_supplied) 310 + { 311 + ep_recv->buf = ep0_rx.buf; 312 + readFIFO(ep_recv, REG_USB_COUNT0); 313 + csr0 |= USB_CSR0_SVDOUTPKTRDY; 314 + if (!ep0_rx.request.wLength) 315 + { 316 + csr0 |= USB_CSR0_DATAEND; /* Set data end! */ 317 + ep0_data_requested = false; 318 + ep0_data_supplied = false; 319 + } 320 + else if (ep0_rx.request.bRequestType & USB_DIR_IN) 321 + ep0_data_requested = true; 322 + else ep0_data_supplied = true; 323 + REG_USB_CSR0 = csr0; 324 + usb_core_control_request(&ep0_rx.request); 325 + ep_transfer_completed(ep_recv); 326 + } 249 327 } 328 + else if (ep_send->busy) 329 + EP0_send(); 250 330 } 251 331 252 332 static void EPIN_handler(unsigned int endpoint) ··· 292 372 293 373 if(ep->sent >= ep->length) 294 374 { 295 - usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); 375 + if (!ep->wait) 376 + usb_core_transfer_complete(endpoint, USB_DIR_IN, 0, ep->sent); 377 + ep->rc = 0; 296 378 ep_transfer_completed(ep); 297 379 logf("sent complete"); 298 380 } ··· 352 434 { 353 435 int endpoint = -1; 354 436 unsigned int size = 0; 437 + struct usb_endpoint* ep = NULL; 355 438 356 439 if(number == USB_INTR_DMA_BULKIN) 440 + { 357 441 endpoint = (REG_USB_CNTL(0) >> 4) & 0xF; 442 + ep = &endpoints[endpoint*2]; 443 + size = (unsigned int)ep->buf - REG_USB_ADDR(0); 444 + } 358 445 else if(number == USB_INTR_DMA_BULKOUT) 446 + { 359 447 endpoint = (REG_USB_CNTL(1) >> 4) & 0xF; 448 + ep = &endpoints[endpoint*2+1]; 449 + size = (unsigned int)ep->buf - REG_USB_ADDR(1); 450 + } 360 451 361 - struct usb_endpoint* ep = &endpoints[endpoint]; 362 452 logf("DMA_BULK%d %d", number, endpoint); 363 - 364 - if(number == USB_INTR_DMA_BULKIN) 365 - size = (unsigned int)ep->buf - REG_USB_ADDR(0); 366 - else if(number == USB_INTR_DMA_BULKOUT) 367 - size = (unsigned int)ep->buf - REG_USB_ADDR(1); 368 453 369 454 if(number == USB_INTR_DMA_BULKOUT) 370 455 { ··· 389 474 REG_USB_INCSR |= USB_INCSR_INPKTRDY; 390 475 } 391 476 392 - usb_core_transfer_complete(endpoint, EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT, 393 - 0, ep->length); 394 - ep_transfer_completed(ep); 477 + if (ep) 478 + { 479 + int dir = EP_IS_IN(ep) ? USB_DIR_IN : USB_DIR_OUT; 480 + if ((dir == USB_DIR_OUT) || !ep->wait) 481 + usb_core_transfer_complete(endpoint, dir, 0, ep->length); 482 + ep->rc = 0; 483 + ep_transfer_completed(ep); 484 + } 395 485 } 396 486 397 487 static void setup_endpoint(struct usb_endpoint *ep) 398 488 { 399 - int csr, csrh; 489 + int endpoint = EP_NUMBER2(ep); 490 + unsigned char csr, csrh; 400 491 401 - select_endpoint(EP_NUMBER2(ep)); 492 + select_endpoint(endpoint); 493 + 494 + if (ep->busy) 495 + { 496 + if(EP_IS_IN(ep)) 497 + { 498 + if (ep->wait) 499 + semaphore_release(&ep->complete); 500 + else usb_core_transfer_complete(endpoint, USB_DIR_IN, -1, 0); 501 + } 502 + else usb_core_transfer_complete(endpoint, USB_DIR_OUT, -1, 0); 503 + } 402 504 403 505 ep->busy = false; 404 506 ep->wait = false; 405 507 ep->sent = 0; 406 508 ep->length = 0; 407 509 408 - if(ep->type == ep_bulk) 409 - { 410 - if(REG_USB_POWER & USB_POWER_HSMODE) 411 - ep->fifo_size = 512; 412 - else 413 - ep->fifo_size = 64; 414 - } 510 + if(ep->type != ep_control) 511 + ep->fifo_size = usb_drv_port_speed() ? 512 : 64; 415 512 416 513 if(EP_IS_IN(ep)) 417 514 { ··· 427 524 REG_USB_INMAXP = ep->fifo_size; 428 525 REG_USB_INCSR = csr; 429 526 REG_USB_INCSRH = csrh; 430 - REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); 527 + 528 + if (ep->allocated) 529 + REG_USB_INTRINE |= USB_INTR_EP(EP_NUMBER2(ep)); 431 530 } 432 531 else 433 532 { ··· 443 542 REG_USB_OUTMAXP = ep->fifo_size; 444 543 REG_USB_OUTCSR = csr; 445 544 REG_USB_OUTCSRH = csrh; 446 - REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); 545 + 546 + if (ep->allocated) 547 + REG_USB_INTROUTE |= USB_INTR_EP(EP_NUMBER2(ep)); 447 548 } 448 549 } 449 550 ··· 483 584 select_endpoint(0); 484 585 REG_USB_CSR0 = (USB_CSR0_SVDOUTPKTRDY | USB_CSR0_SVDSETUPEND | USB_CSR0_FLUSHFIFO); 485 586 587 + if (endpoints[0].busy) 588 + { 589 + if (endpoints[0].wait) 590 + semaphore_release(&endpoints[0].complete); 591 + else usb_core_transfer_complete(0, USB_DIR_IN, -1, 0); 592 + } 593 + 594 + endpoints[0].busy = false; 595 + endpoints[0].wait = false; 596 + endpoints[0].sent = 0; 597 + endpoints[0].length = 0; 598 + endpoints[0].allocated = true; 599 + 600 + if (endpoints[1].busy) 601 + usb_core_transfer_complete(0, USB_DIR_OUT, -1, 0); 602 + 603 + endpoints[1].busy = false; 604 + endpoints[1].wait = false; 605 + endpoints[1].received = 0; 606 + endpoints[1].length = 0; 607 + endpoints[1].allocated = true; 608 + 486 609 /* Reset other endpoints */ 487 610 for(i=2; i<TOTAL_EP(); i++) 488 611 setup_endpoint(&endpoints[i]); 612 + 613 + ep0_data_supplied = false; 614 + ep0_data_requested = false; 489 615 490 616 /* Enable interrupts */ 491 617 REG_USB_INTRINE |= USB_INTR_EP(0); ··· 498 624 void OTG(void) 499 625 { 500 626 /* Read interrupt registers */ 501 - unsigned char intrUSB = REG_USB_INTRUSB & 0x07; /* Mask SOF */ 627 + unsigned char intrUSB = REG_USB_INTRUSB; 502 628 unsigned short intrIn = REG_USB_INTRIN; 503 629 unsigned short intrOut = REG_USB_INTROUT; 504 630 unsigned char intrDMA = REG_USB_INTR; ··· 689 815 690 816 static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length, bool blocking) 691 817 { 692 - if(ep->type == ep_control && ptr == NULL && length == 0) 693 - return; /* ACK request, handled in the ISR */ 694 - 695 818 int flags = disable_irq_save(); 696 819 820 + if(ep->type == ep_control) 821 + { 822 + if ((ptr == NULL && length == 0) || !ep0_data_requested) 823 + { 824 + restore_irq(flags); 825 + return; 826 + } 827 + ep0_data_requested = false; 828 + } 829 + 697 830 ep->buf = ptr; 698 831 ep->sent = 0; 699 832 ep->length = length; 700 833 ep->busy = true; 701 834 if(blocking) 835 + { 836 + ep->rc = -1; 702 837 ep->wait = true; 838 + } 839 + else ep->rc = 0; 703 840 704 841 if(ep->type == ep_control) 705 842 { ··· 725 862 726 863 if(blocking) 727 864 { 728 - semaphore_wait(&ep->complete, TIMEOUT_BLOCK); 865 + semaphore_wait(&ep->complete, HZ); 729 866 ep->wait = false; 730 867 } 731 868 } 732 869 733 870 int usb_drv_send_nonblocking(int endpoint, void* ptr, int length) 734 871 { 872 + struct usb_endpoint *ep = &endpoints[(endpoint & 0x7F)*2]; 873 + 735 874 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 736 875 737 - usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, false); 876 + if (ep->allocated) 877 + { 878 + usb_drv_send_internal(ep, ptr, length, false); 879 + return 0; 880 + } 738 881 739 - return 0; 882 + return -1; 740 883 } 741 884 742 885 int usb_drv_send(int endpoint, void* ptr, int length) 743 886 { 887 + struct usb_endpoint *ep = &endpoints[(endpoint & 0x7F)*2]; 888 + 744 889 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 745 890 746 - usb_drv_send_internal(&endpoints[(endpoint & 0x7F)*2], ptr, length, true); 891 + if (ep->allocated) 892 + { 893 + usb_drv_send_internal(ep, ptr, length, true); 894 + return ep->rc; 895 + } 747 896 748 - return 0; 897 + return -1; 749 898 } 750 899 751 900 int usb_drv_recv(int endpoint, void* ptr, int length) ··· 756 905 757 906 logf("%s(%d, 0x%x, %d)", __func__, endpoint, (int)ptr, length); 758 907 759 - if(endpoint == EP_CONTROL) 760 - return 0; /* all EP0 OUT transactions are handled within the ISR */ 908 + if (ptr == NULL || length == 0) 909 + return 0; 910 + 911 + ep = &endpoints[endpoint*2+1]; 912 + 913 + if (!ep->allocated) 914 + return -1; 915 + 916 + flags = disable_irq_save(); 917 + 918 + ep->buf = ptr; 919 + ep->received = 0; 920 + ep->length = length; 921 + ep->busy = true; 922 + if(ep->use_dma) 923 + { 924 + //dma_cache_wback_inv((unsigned long)ptr, length); 925 + __dcache_writeback_all(); 926 + REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr); 927 + REG_USB_COUNT(1) = length; 928 + REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 929 + USB_CNTL_ENA | USB_CNTL_EP(endpoint) | 930 + USB_CNTL_BURST_16); 931 + } 761 932 else 762 933 { 763 - flags = disable_irq_save(); 764 - ep = &endpoints[endpoint*2+1]; 765 - 766 - ep->buf = ptr; 767 - ep->received = 0; 768 - ep->length = length; 769 - ep->busy = true; 770 - if(ep->use_dma) 934 + if (endpoint == EP_CONTROL) 771 935 { 772 - //dma_cache_wback_inv((unsigned long)ptr, length); 773 - __dcache_writeback_all(); 774 - REG_USB_ADDR(1) = PHYSADDR((unsigned long)ptr); 775 - REG_USB_COUNT(1) = length; 776 - REG_USB_CNTL(1) = (USB_CNTL_INTR_EN | USB_CNTL_MODE_1 | 777 - USB_CNTL_ENA | USB_CNTL_EP(endpoint) | 778 - USB_CNTL_BURST_16); 936 + ep0_data_supplied = false; 937 + EP0_handler(); 779 938 } 780 - else 781 - EPOUT_handler(endpoint); 782 - 783 - restore_irq(flags); 784 - return 0; 939 + else EPOUT_handler(endpoint); 785 940 } 941 + 942 + restore_irq(flags); 943 + return 0; 786 944 } 787 945 788 946 void usb_drv_set_test_mode(int mode) ··· 818 976 { 819 977 logf("%s()", __func__); 820 978 821 - unsigned int i, flags; 822 - flags = disable_irq_save(); 979 + unsigned int i, flags = disable_irq_save(); 823 980 824 981 for(i=0; i<TOTAL_EP(); i++) 825 982 { 983 + if (endpoints[i].busy) 984 + { 985 + if (i & 1) 986 + usb_core_transfer_complete(i >> 1, USB_DIR_OUT, -1, 0); 987 + else if (endpoints[i].wait) 988 + semaphore_release(&endpoints[i].complete); 989 + else usb_core_transfer_complete(i >> 1, USB_DIR_IN, -1, 0); 990 + } 991 + 826 992 if(i != 1) /* ep0 out needs special handling */ 827 993 endpoints[i].buf = NULL; 828 994 ··· 834 1000 } 835 1001 restore_irq(flags); 836 1002 } 837 - 838 1003 839 1004 void usb_drv_release_endpoint(int ep) 840 1005 { 841 - (void)ep; 1006 + int n = ep & 0x7f; 1007 + 842 1008 logf("%s(%d, %s)", __func__, (ep & 0x7F), (ep >> 7) ? "IN" : "OUT"); 1009 + 1010 + if (n) 1011 + { 1012 + int dir = ep & USB_ENDPOINT_DIR_MASK; 1013 + 1014 + if(dir == USB_DIR_IN) 1015 + { 1016 + REG_USB_INTRINE &= ~USB_INTR_EP(n); 1017 + endpoints[n << 1].allocated = false; 1018 + } 1019 + else 1020 + { 1021 + REG_USB_INTROUTE &= ~USB_INTR_EP(n); 1022 + endpoints[(n << 1) + 1].allocated = false; 1023 + } 1024 + } 843 1025 } 844 1026 845 1027 int usb_drv_request_endpoint(int type, int dir) ··· 854 1036 { 855 1037 case USB_ENDPOINT_XFER_BULK: 856 1038 if(dir == USB_DIR_IN) 1039 + { 1040 + if (endpoints[2].allocated) 1041 + break; 1042 + endpoints[2].allocated = true; 1043 + REG_USB_INTRINE |= USB_INTR_EP(1); 857 1044 return (1 | USB_DIR_IN); 1045 + } 858 1046 else 1047 + { 1048 + if (endpoints[3].allocated) 1049 + break; 1050 + endpoints[3].allocated = true; 1051 + REG_USB_INTROUTE |= USB_INTR_EP(1); 859 1052 return (1 | USB_DIR_OUT); 1053 + } 860 1054 861 1055 case USB_ENDPOINT_XFER_INT: 862 1056 if(dir == USB_DIR_IN) 1057 + { 1058 + if (endpoints[4].allocated) 1059 + break; 1060 + endpoints[4].allocated = true; 1061 + REG_USB_INTRINE |= USB_INTR_EP(2); 863 1062 return (2 | USB_DIR_IN); 1063 + } 864 1064 else 1065 + { 1066 + if (endpoints[5].allocated) 1067 + break; 1068 + endpoints[5].allocated = true; 1069 + REG_USB_INTROUTE |= USB_INTR_EP(2); 865 1070 return (2 | USB_DIR_OUT); 1071 + } 866 1072 867 1073 default: 868 - return -1; 1074 + break; 869 1075 } 1076 + 1077 + return -1; 870 1078 }