summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/usb-drv-pp502x.c346
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c5
2 files changed, 198 insertions, 153 deletions
diff --git a/firmware/target/arm/usb-drv-pp502x.c b/firmware/target/arm/usb-drv-pp502x.c
index 413d905293..2d51ce55e9 100644
--- a/firmware/target/arm/usb-drv-pp502x.c
+++ b/firmware/target/arm/usb-drv-pp502x.c
@@ -30,6 +30,10 @@
30 30
31#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000)) 31#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
32#define REG_HWGENERAL (*(volatile unsigned int *)(USB_BASE+0x004)) 32#define REG_HWGENERAL (*(volatile unsigned int *)(USB_BASE+0x004))
33#define REG_HWHOST (*(volatile unsigned int *)(USB_BASE+0x008))
34#define REG_HWDEVICE (*(volatile unsigned int *)(USB_BASE+0x00c))
35#define REG_TXBUF (*(volatile unsigned int *)(USB_BASE+0x010))
36#define REG_RXBUF (*(volatile unsigned int *)(USB_BASE+0x014))
33#define REG_CAPLENGTH (*(volatile unsigned char*)(USB_BASE+0x100)) 37#define REG_CAPLENGTH (*(volatile unsigned char*)(USB_BASE+0x100))
34#define REG_DCIVERSION (*(volatile unsigned int *)(USB_BASE+0x120)) 38#define REG_DCIVERSION (*(volatile unsigned int *)(USB_BASE+0x120))
35#define REG_DCCPARAMS (*(volatile unsigned int *)(USB_BASE+0x124)) 39#define REG_DCCPARAMS (*(volatile unsigned int *)(USB_BASE+0x124))
@@ -278,6 +282,10 @@
278 DTD_STATUS_DATA_BUFF_ERR | \ 282 DTD_STATUS_DATA_BUFF_ERR | \
279 DTD_STATUS_TRANSACTION_ERR) 283 DTD_STATUS_TRANSACTION_ERR)
280 284
285#define DTD_RESERVED_LENGTH_MASK 0x0001ffff
286#define DTD_RESERVED_IN_USE 0x80000000
287#define DTD_RESERVED_PIPE_MASK 0x0ff00000
288#define DTD_RESERVED_PIPE_OFFSET 20
281/*-------------------------------------------------------------------------*/ 289/*-------------------------------------------------------------------------*/
282 290
283/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ 291/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */
@@ -294,7 +302,7 @@ struct transfer_descriptor {
294 unsigned int reserved; 302 unsigned int reserved;
295} __attribute__ ((packed)); 303} __attribute__ ((packed));
296 304
297static struct transfer_descriptor _td_array[32] __attribute((aligned (32))); 305static struct transfer_descriptor _td_array[NUM_ENDPOINTS*2] __attribute((aligned (32)));
298static struct transfer_descriptor* td_array; 306static struct transfer_descriptor* td_array;
299 307
300/* manual: 32.13.1 Endpoint Queue Head (dQH) */ 308/* manual: 32.13.1 Endpoint Queue Head (dQH) */
@@ -304,30 +312,36 @@ struct queue_head {
304 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */ 312 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */
305 struct transfer_descriptor dtd; /* dTD overlay */ 313 struct transfer_descriptor dtd; /* dTD overlay */
306 unsigned int setup_buffer[2]; /* Setup data 8 bytes */ 314 unsigned int setup_buffer[2]; /* Setup data 8 bytes */
307 unsigned int reserved[4]; 315 unsigned int reserved; /* for software use, pointer to the first TD */
316 unsigned int status; /* for software use, status of chain in progress */
317 unsigned int length; /* for software use, transfered bytes of chain in progress */
318 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
308} __attribute__((packed)); 319} __attribute__((packed));
309 320
310static struct queue_head _qh_array[NUM_ENDPOINTS*2] __attribute((aligned (2048))); 321static struct queue_head _qh_array[NUM_ENDPOINTS*2] __attribute((aligned (2048)));
311static struct queue_head* qh_array; 322static struct queue_head* qh_array;
323static struct event_queue transfer_completion_queue[NUM_ENDPOINTS*2];
312 324
313 325
314static const unsigned int pipe2mask[NUM_ENDPOINTS*2] = { 326static const unsigned int pipe2mask[] = {
315 0x01, 0x010000, 327 0x01, 0x010000,
316 0x02, 0x020000, 328 0x02, 0x020000,
317 0x04, 0x040000, 329 0x04, 0x040000,
330 0x08, 0x080000,
331 0x10, 0x100000,
318}; 332};
319 333
320static struct transfer_descriptor* first_td;
321static struct transfer_descriptor* last_td;
322
323/*-------------------------------------------------------------------------*/ 334/*-------------------------------------------------------------------------*/
324static void transfer_completed(void); 335static void transfer_completed(void);
325static int prime_transfer(int endpoint, void* ptr, int len, bool send); 336static void control_received(void);
337static int prime_transfer(int endpoint, void* ptr,
338 int len, bool send, bool wait);
326static void prepare_td(struct transfer_descriptor* td, 339static void prepare_td(struct transfer_descriptor* td,
327 struct transfer_descriptor* previous_td, 340 struct transfer_descriptor* previous_td,
328 void *ptr, int len); 341 void *ptr, int len,int pipe);
329static void bus_reset(void); 342static void bus_reset(void);
330static void init_queue_heads(void); 343static void init_control_queue_heads(void);
344static void init_bulk_queue_heads(void);
331static void init_endpoints(void); 345static void init_endpoints(void);
332/*-------------------------------------------------------------------------*/ 346/*-------------------------------------------------------------------------*/
333 347
@@ -344,6 +358,7 @@ void usb_drv_init(void)
344 REG_USBCMD |= USBCMD_CTRL_RESET; 358 REG_USBCMD |= USBCMD_CTRL_RESET;
345 while (REG_USBCMD & USBCMD_CTRL_RESET); 359 while (REG_USBCMD & USBCMD_CTRL_RESET);
346 360
361
347 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; 362 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
348 363
349 /* Force device to full speed */ 364 /* Force device to full speed */
@@ -352,7 +367,7 @@ void usb_drv_init(void)
352 367
353 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array); 368 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array);
354 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array); 369 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array);
355 init_queue_heads(); 370 init_control_queue_heads();
356 memset(td_array, 0, sizeof _td_array); 371 memset(td_array, 0, sizeof _td_array);
357 372
358 REG_ENDPOINTLISTADDR = (unsigned int)qh_array; 373 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
@@ -372,6 +387,7 @@ void usb_drv_init(void)
372 /* go go go */ 387 /* go go go */
373 REG_USBCMD |= USBCMD_RUN; 388 REG_USBCMD |= USBCMD_RUN;
374 389
390
375 logf("usb_drv_init() finished"); 391 logf("usb_drv_init() finished");
376 logf("usb id %x", REG_ID); 392 logf("usb id %x", REG_ID);
377 logf("usb dciversion %x", REG_DCIVERSION); 393 logf("usb dciversion %x", REG_DCIVERSION);
@@ -407,15 +423,7 @@ void usb_drv_int(void)
407 423
408 /* a control packet? */ 424 /* a control packet? */
409 if (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0) { 425 if (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0) {
410 /* copy setup data from packet */ 426 control_received();
411 unsigned int tmp[2];
412 tmp[0] = qh_array[0].setup_buffer[0];
413 tmp[1] = qh_array[0].setup_buffer[1];
414
415 /* acknowledge packet recieved */
416 REG_ENDPTSETUPSTAT |= EPSETUP_STATUS_EP0;
417
418 usb_core_control_request((struct usb_ctrlrequest*)tmp);
419 } 427 }
420 428
421 if (REG_ENDPTCOMPLETE) 429 if (REG_ENDPTCOMPLETE)
@@ -441,29 +449,52 @@ void usb_drv_int(void)
441 } 449 }
442} 450}
443 451
444void usb_drv_stall(int endpoint, bool stall) 452bool usb_drv_stalled(int endpoint,bool in)
453{
454 if(in) {
455 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_TX_EP_STALL)!=0);
456 }
457 else {
458 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_RX_EP_STALL)!=0);
459 }
460
461}
462void usb_drv_stall(int endpoint, bool stall,bool in)
445{ 463{
446 logf("%sstall %d", stall?"":"un", endpoint); 464 logf("%sstall %d", stall?"":"un", endpoint);
447 465
448 if (stall) { 466 if(in) {
449 REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL; 467 if (stall) {
450 REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL; 468 REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL;
469 }
470 else {
471 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL;
472 }
451 } 473 }
452 else { 474 else {
453 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL; 475 if (stall) {
454 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL; 476 REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL;
477 }
478 else {
479 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL;
480 }
455 } 481 }
456} 482}
457 483
484int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
485{
486 return prime_transfer(endpoint, ptr, length, true, false);
487}
488
458int usb_drv_send(int endpoint, void* ptr, int length) 489int usb_drv_send(int endpoint, void* ptr, int length)
459{ 490{
460 return prime_transfer(endpoint, ptr, length, true); 491 return prime_transfer(endpoint, ptr, length, true, true);
461} 492}
462 493
463int usb_drv_recv(int endpoint, void* ptr, int length) 494int usb_drv_recv(int endpoint, void* ptr, int length)
464{ 495{
465 //logf("usbrecv(%x, %d)", ptr, length); 496 //logf("usbrecv(%x, %d)", ptr, length);
466 return prime_transfer(endpoint, ptr, length, false); 497 return prime_transfer(endpoint, ptr, length, false, false);
467} 498}
468 499
469void usb_drv_wait(int endpoint, bool send) 500void usb_drv_wait(int endpoint, bool send)
@@ -485,6 +516,7 @@ int usb_drv_port_speed(void)
485void usb_drv_set_address(int address) 516void usb_drv_set_address(int address)
486{ 517{
487 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS; 518 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS;
519 init_bulk_queue_heads();
488 init_endpoints(); 520 init_endpoints();
489} 521}
490 522
@@ -496,78 +528,43 @@ void usb_drv_reset_endpoint(int endpoint, bool send)
496 while (REG_ENDPTFLUSH & mask); 528 while (REG_ENDPTFLUSH & mask);
497} 529}
498 530
499int usb_drv_get_last_transfer_length(void)
500{
501 struct transfer_descriptor* current_td = first_td;
502 int length = 0;
503
504 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) {
505 if ((current_td->size_ioc_sts & 0xff) != 0)
506 return -1;
507
508 length += current_td->reserved -
509 ((current_td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS);
510 current_td = (struct transfer_descriptor*)current_td->next_td_ptr;
511 }
512 return length;
513}
514int usb_drv_get_last_transfer_status(void)
515{
516 struct transfer_descriptor* current_td = first_td;
517
518 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) {
519 if ((current_td->size_ioc_sts & 0xff) != 0)
520 return current_td->size_ioc_sts & 0xff;
521
522 current_td = (struct transfer_descriptor*)current_td->next_td_ptr;
523 }
524 return 0;
525}
526 531
527/*-------------------------------------------------------------------------*/ 532/*-------------------------------------------------------------------------*/
528 533
529/* manual: 32.14.5.2 */ 534/* manual: 32.14.5.2 */
530static int prime_transfer(int endpoint, void* ptr, int len, bool send) 535static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait)
531{ 536{
532 int pipe = endpoint * 2 + (send ? 1 : 0); 537 int pipe = endpoint * 2 + (send ? 1 : 0);
533 unsigned int mask = pipe2mask[pipe]; 538 unsigned int mask = pipe2mask[pipe];
534 last_td = 0;
535 struct queue_head* qh = &qh_array[pipe]; 539 struct queue_head* qh = &qh_array[pipe];
536 static long last_tick; 540 static long last_tick;
541 struct transfer_descriptor* new_td;
537 542
538/* 543/*
539 if (send && endpoint > EP_CONTROL) { 544 if (send && endpoint > EP_CONTROL) {
540 logf("usb: sent %d bytes", len); 545 logf("usb: sent %d bytes", len);
541 } 546 }
542*/ 547*/
548 qh->status = 0;
549 qh->length = 0;
550 qh->wait = wait;
543 551
544 if (len==0) {
545 struct transfer_descriptor* new_td = &td_array[0];
546 prepare_td(new_td, 0, ptr, 0);
547 552
548 last_td = new_td; 553 new_td=&td_array[pipe];
549 first_td = new_td; 554 prepare_td(new_td, 0, ptr, len,pipe);
550 } 555 //logf("starting ep %d %s",endpoint,send?"send":"receive");
551 else {
552 int td_idx = 0;
553 while (len > 0) {
554 int current_transfer_length = MIN(16384,len);
555 struct transfer_descriptor* new_td = &td_array[td_idx];
556 prepare_td(new_td, last_td, ptr, current_transfer_length);
557
558 last_td = new_td;
559 len -= current_transfer_length;
560 td_idx++;
561 ptr += current_transfer_length;
562 }
563 first_td = &td_array[0];
564 }
565 556
566 qh->dtd.next_td_ptr = (unsigned int)first_td; 557 qh->dtd.next_td_ptr = (unsigned int)new_td;
567 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); 558 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
568 559
569 REG_ENDPTPRIME |= mask; 560 REG_ENDPTPRIME |= mask;
570 561
562 if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) {
563 /* 32.14.3.2.2 */
564 logf("new setup arrived");
565 return -4;
566 }
567
571 last_tick = current_tick; 568 last_tick = current_tick;
572 while ((REG_ENDPTPRIME & mask)) { 569 while ((REG_ENDPTPRIME & mask)) {
573 if (REG_USBSTS & USBSTS_RESET) 570 if (REG_USBSTS & USBSTS_RESET)
@@ -583,38 +580,43 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send)
583 logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); 580 logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff );
584 return -3; 581 return -3;
585 } 582 }
583 if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) {
584 /* 32.14.3.2.2 */
585 logf("new setup arrived");
586 return -4;
587 }
586 588
587 if (send) { 589 if (wait) {
588 /* wait for transfer to finish */ 590 /* wait for transfer to finish */
589 struct transfer_descriptor* current_td = first_td; 591 struct queue_event ev;
590 592 queue_wait(&transfer_completion_queue[pipe], &ev);
591 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) { 593 if(qh->status!=0) {
592 while ((current_td->size_ioc_sts & 0xff) == DTD_STATUS_ACTIVE) { 594 return -5;
593 if (REG_ENDPTCOMPLETE & mask)
594 REG_ENDPTCOMPLETE |= mask;
595
596 /* let the host handle timeouts */
597 if (REG_USBSTS & USBSTS_RESET) {
598 logf("td interrupted by reset");
599 return -4;
600 }
601 }
602 if ((current_td->size_ioc_sts & 0xff) != 0) {
603 logf("td failed with error %X",(current_td->size_ioc_sts & 0xff));
604 return -6;
605 }
606 //logf("td finished : %X",current_td->size_ioc_sts & 0xff);
607 current_td=(struct transfer_descriptor*)current_td->next_td_ptr;
608 } 595 }
609 //logf("all tds done"); 596 //logf("all tds done");
610 } 597 }
611
612 return 0; 598 return 0;
613} 599}
614 600
601void usb_drv_cancel_all_transfers(void)
602{
603 int i;
604 REG_ENDPTFLUSH = ~0;
605 while (REG_ENDPTFLUSH);
606
607 memset(td_array, 0, sizeof _td_array);
608 for(i=0;i<NUM_ENDPOINTS*2;i++) {
609 if(qh_array[i].wait) {
610 qh_array[i].wait=0;
611 qh_array[i].status=DTD_STATUS_HALTED;
612 queue_post(&transfer_completion_queue[i],0, 0);
613 }
614 }
615}
616
615static void prepare_td(struct transfer_descriptor* td, 617static void prepare_td(struct transfer_descriptor* td,
616 struct transfer_descriptor* previous_td, 618 struct transfer_descriptor* previous_td,
617 void *ptr, int len) 619 void *ptr, int len,int pipe)
618{ 620{
619 //logf("adding a td : %d",len); 621 //logf("adding a td : %d",len);
620 memset(td, 0, sizeof(struct transfer_descriptor)); 622 memset(td, 0, sizeof(struct transfer_descriptor));
@@ -626,35 +628,72 @@ static void prepare_td(struct transfer_descriptor* td,
626 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000; 628 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
627 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000; 629 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
628 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000; 630 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
629 td->reserved = len; 631 td->reserved |= DTD_RESERVED_LENGTH_MASK & len;
632 td->reserved |= DTD_RESERVED_IN_USE;
633 td->reserved |= (pipe << DTD_RESERVED_PIPE_OFFSET);
630 634
631 if (previous_td != 0) { 635 if (previous_td != 0) {
632 previous_td->next_td_ptr=(unsigned int)td; 636 previous_td->next_td_ptr=(unsigned int)td;
633 previous_td->size_ioc_sts&=~DTD_IOC;// Only an interrupt on the last one
634 } 637 }
635} 638}
636 639
637static void transfer_completed(void) 640static void control_received(void)
638{ 641{
639 int i; 642 int i;
643 logf("control stuff");
644 /* copy setup data from packet */
645 static unsigned int tmp[2];
646 tmp[0] = qh_array[0].setup_buffer[0];
647 tmp[1] = qh_array[0].setup_buffer[1];
648
649 /* acknowledge packet recieved */
650 REG_ENDPTSETUPSTAT |= EPSETUP_STATUS_EP0;
651
652 /* Stop pending interrupt transfers */
653 for(i=0;i<2;i++) {
654 if(qh_array[i].wait) {
655 qh_array[i].wait=0;
656 qh_array[i].status=DTD_STATUS_HALTED;
657 queue_post(&transfer_completion_queue[i],0, 0);
658 }
659 }
660
661 usb_core_control_request((struct usb_ctrlrequest*)tmp);
662}
663
664static void transfer_completed(void)
665{
666 int ep;
640 unsigned int mask = REG_ENDPTCOMPLETE; 667 unsigned int mask = REG_ENDPTCOMPLETE;
641 REG_ENDPTCOMPLETE |= mask; 668 REG_ENDPTCOMPLETE |= mask;
642 669
643 //logf("usb comp %x", mask); 670 for (ep=0; ep<NUM_ENDPOINTS; ep++) {
644 671 int dir;
645 for (i=0; i<NUM_ENDPOINTS; i++) { 672 for (dir=0; dir<2; dir++) {
646 int x; 673 int pipe = ep * 2 + dir;
647 for (x=0; x<2; x++) { 674 if (mask & pipe2mask[pipe]) {
648 unsigned int status; 675 struct queue_head* qh = &qh_array[pipe];
649 int pipe = i * 2 + x; 676 struct transfer_descriptor *td = &td_array[pipe];
650 677
651 if (mask & pipe2mask[pipe]) 678 if(td->size_ioc_sts & DTD_STATUS_ACTIVE) {
652 usb_core_transfer_complete(i, x ? true : false); 679 /* TODO this shouldn't happen, but...*/
653 680 break;
654 status = usb_drv_get_last_transfer_status(); 681 }
655 if ((mask & pipe2mask[pipe]) && 682 if((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS != 0 && dir==0) {
656 status & DTD_ERROR_MASK) { 683 /* We got less data than we asked for. */
657 logf("pipe %d err %x", pipe, status & DTD_ERROR_MASK); 684 }
685 qh->length = (td->reserved & DTD_RESERVED_LENGTH_MASK) -
686 ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS);
687 if(td->size_ioc_sts & DTD_ERROR_MASK) {
688 logf("pipe %d err %x", pipe, td->size_ioc_sts & DTD_ERROR_MASK);
689 qh->status |= td->size_ioc_sts & DTD_ERROR_MASK;
690 /* TODO we need to handle this somehow. Flush the endpoint ? */
691 }
692 if(qh->wait) {
693 qh->wait=0;
694 queue_post(&transfer_completion_queue[pipe],0, 0);
695 }
696 usb_core_transfer_complete(ep, dir, qh->status, qh->length);
658 } 697 }
659 } 698 }
660 } 699 }
@@ -685,61 +724,66 @@ static void bus_reset(void)
685 logf("usb: short reset timeout"); 724 logf("usb: short reset timeout");
686 } 725 }
687 726
688 REG_ENDPTFLUSH = ~0; 727 usb_drv_cancel_all_transfers();
689 //while (REG_ENDPTFLUSH);
690 728
691 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { 729 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) {
692 logf("usb: slow reset!"); 730 logf("usb: slow reset!");
693 } 731 }
694
695 logf("PTS : %X",(REG_PORTSC1 & 0xC0000000)>>30);
696 logf("STS : %X",(REG_PORTSC1 & 0x20000000)>>29);
697 logf("PTW : %X",(REG_PORTSC1 & 0x10000000)>>28);
698 logf("PSPD : %X",(REG_PORTSC1 & 0x0C000000)>>26);
699 logf("PFSC : %X",(REG_PORTSC1 & 0x01000000)>>24);
700 logf("PTC : %X",(REG_PORTSC1 & 0x000F0000)>>16);
701 logf("PO : %X",(REG_PORTSC1 & 0x00002000)>>13);
702} 732}
703 733
704/* manual: 32.14.4.1 Queue Head Initialization */ 734/* manual: 32.14.4.1 Queue Head Initialization */
705static void init_queue_heads(void) 735static void init_control_queue_heads(void)
736{
737 int i;
738 memset(qh_array, 0, sizeof _qh_array);
739
740 /*** control ***/
741 qh_array[EP_CONTROL].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS | QH_IOS;
742 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE;
743 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS;
744 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
745
746 for(i=0;i<2;i++) {
747 queue_init(&transfer_completion_queue[i], false);
748 }
749}
750/* manual: 32.14.4.1 Queue Head Initialization */
751static void init_bulk_queue_heads(void)
706{ 752{
707 int tx_packetsize; 753 int tx_packetsize;
708 int rx_packetsize; 754 int rx_packetsize;
755 int i;
709 756
710 if (usb_drv_port_speed()) { 757 if (usb_drv_port_speed()) {
711 rx_packetsize = 512; 758 rx_packetsize = 512;
712 tx_packetsize = 512; 759 tx_packetsize = 512;
713 } 760 }
714 else { 761 else {
715 rx_packetsize = 16; 762 rx_packetsize = 64;
716 tx_packetsize = 16; 763 tx_packetsize = 64;
717 } 764 }
718 memset(qh_array, 0, sizeof _qh_array);
719
720 /*** control ***/
721 qh_array[EP_CONTROL].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS | QH_IOS;
722 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE;
723 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS;
724 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
725 765
726 /*** bulk ***/ 766 /*** bulk ***/
727 qh_array[EP_RX*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 767 for(i=1;i<NUM_ENDPOINTS;i++) {
728 qh_array[EP_RX*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 768 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
729 qh_array[EP_TX*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 769 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
730 qh_array[EP_TX*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 770 qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
771 qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
772 }
773 for(i=2;i<NUM_ENDPOINTS*2;i++) {
774 queue_init(&transfer_completion_queue[i], false);
775 }
731} 776}
732 777
733static void init_endpoints(void) 778static void init_endpoints(void)
734{ 779{
780 int i;
735 /* bulk */ 781 /* bulk */
736 REG_ENDPTCTRL(EP_RX) = 782 for(i=1;i<NUM_ENDPOINTS;i++) {
737 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | 783 REG_ENDPTCTRL(i) =
738 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) | 784 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
739 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT); 785 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
740 786 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) |
741 REG_ENDPTCTRL(EP_TX) = 787 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT);
742 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | 788 }
743 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) |
744 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT);
745} 789}
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index 46a5b9942f..4ac515ba1c 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -34,6 +34,7 @@ void usb_init_device(void)
34{ 34{
35 /* enable usb module */ 35 /* enable usb module */
36 outl(inl(0x7000002C) | 0x3000000, 0x7000002C); 36 outl(inl(0x7000002C) | 0x3000000, 0x7000002C);
37
37 DEV_EN |= DEV_USB0; 38 DEV_EN |= DEV_USB0;
38 DEV_EN |= DEV_USB1; 39 DEV_EN |= DEV_USB1;
39 40
@@ -46,6 +47,7 @@ void usb_init_device(void)
46#if CONFIG_CPU == PP5020 47#if CONFIG_CPU == PP5020
47 DEV_INIT2 |= INIT_USB; 48 DEV_INIT2 |= INIT_USB;
48#endif 49#endif
50
49 while ((inl(0x70000028) & 0x80) == 0); 51 while ((inl(0x70000028) & 0x80) == 0);
50 outl(inl(0x70000028) | 0x2, 0x70000028); 52 outl(inl(0x70000028) | 0x2, 0x70000028);
51 udelay(0x186A0); 53 udelay(0x186A0);
@@ -68,9 +70,8 @@ void usb_init_device(void)
68void usb_enable(bool on) 70void usb_enable(bool on)
69{ 71{
70 if (on) { 72 if (on) {
71#ifdef USE_ROCKBOX_USB
72 usb_core_init(); 73 usb_core_init();
73#else 74#if !defined(USE_ROCKBOX_USB)
74 /* until we have native mass-storage mode, we want to reboot on 75 /* until we have native mass-storage mode, we want to reboot on
75 usb host connect */ 76 usb host connect */
76#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB) 77#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)