summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/usb-s3c6400x.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c
index 2b221b1963..71bd127dab 100644
--- a/firmware/target/arm/usb-s3c6400x.c
+++ b/firmware/target/arm/usb-s3c6400x.c
@@ -481,16 +481,13 @@ static void ep_transfer(int ep, void *ptr, int len, bool out)
481 481
482 if (out) 482 if (out)
483 DEPCTL(ep, out) &= ~DEPCTL_stall; 483 DEPCTL(ep, out) &= ~DEPCTL_stall;
484 DEPCTL(ep, out) |= DEPCTL_usbactep;
485 484
486 int mps = usb_drv_port_speed() ? 512 : 64; 485 int mps = usb_drv_port_speed() ? 512 : 64;
487 int nb_packets = (len + mps - 1) / mps; 486 int nb_packets = (len + mps - 1) / mps;
488 if (nb_packets == 0) 487 if (nb_packets == 0)
489 nb_packets = 1; 488 nb_packets = 1;
490 489
491 DEPDMA(ep, out) = len 490 DEPDMA(ep, out) = len ? (void*)AS3525_PHYSICAL_ADDR(ptr) : NULL;
492 ? (void*)AS3525_PHYSICAL_ADDR(ptr)
493 : (void*)0x10000000;
494 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len; 491 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
495 if(out) 492 if(out)
496 discard_dcache_range(ptr, len); 493 discard_dcache_range(ptr, len);
@@ -499,6 +496,8 @@ static void ep_transfer(int ep, void *ptr, int len, bool out)
499 496
500 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out)); 497 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));
501 498
499// if (!out) while (((GNPTXSTS & 0xffff) << 2) < MIN(mps, length));
500
502 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak; 501 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;
503 502
504 restore_irq(oldlevel); 503 restore_irq(oldlevel);
@@ -531,6 +530,9 @@ static union
531 unsigned char payload[64]; 530 unsigned char payload[64];
532} ctrlreq USB_DEVBSS_ATTR; 531} ctrlreq USB_DEVBSS_ATTR;
533 532
533static volatile bool inflight = false;
534static volatile bool plugged = false;
535
534static void reset_endpoints(int reinit) 536static void reset_endpoints(int reinit)
535{ 537{
536 unsigned int i; 538 unsigned int i;
@@ -567,6 +569,7 @@ static void reset_endpoints(int reinit)
567 DEPCTL(4, true) = DEPCTL(4, true) | DEPCTL_usbactep | DEPCTL_setd0pid; 569 DEPCTL(4, true) = DEPCTL(4, true) | DEPCTL_usbactep | DEPCTL_setd0pid;
568 } 570 }
569 DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */ 571 DAINTMSK = 0xFFFFFFFF; /* Enable interrupts on all EPs */
572 inflight = false;
570} 573}
571 574
572int usb_drv_request_endpoint(int type, int dir) 575int usb_drv_request_endpoint(int type, int dir)
@@ -613,8 +616,8 @@ static void usb_reset(void)
613 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */ 616 while (GRSTCTL & GRSTCTL_csftrst); /* Wait for OTG to ack reset */
614 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */ 617 while (!(GRSTCTL & GRSTCTL_ahbidle)); /* Wait for OTG AHB master idle */
615 618
616 GRXFSIZ = 512; 619 GRXFSIZ = 1024;
617 GNPTXFSIZ = MAKE_FIFOSIZE_DATA(512); 620 GNPTXFSIZ = (256 << 16) | 1024;
618 621
619 GAHBCFG = SYNOPSYSOTG_AHBCFG; 622 GAHBCFG = SYNOPSYSOTG_AHBCFG;
620 GUSBCFG = (1 << 12) | (1 << 10) | GUSBCFG_phy_if; /* OTG: 16bit PHY and some reserved bits */ 623 GUSBCFG = (1 << 12) | (1 << 10) | GUSBCFG_phy_if; /* OTG: 16bit PHY and some reserved bits */
@@ -641,6 +644,7 @@ static void handle_ep_int(bool out)
641 644
642 if (epints & DEPINT_xfercompl) 645 if (epints & DEPINT_xfercompl)
643 { 646 {
647 if (!out) inflight = false;
644 commit_discard_dcache(); 648 commit_discard_dcache();
645 int bytes = endpoints[ep].size - (DEPTSIZ(ep, out) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp)); 649 int bytes = endpoints[ep].size - (DEPTSIZ(ep, out) & (DEPTSIZ_xfersize_bits < DEPTSIZ_xfersize_bitp));
646 if (endpoints[ep].busy) 650 if (endpoints[ep].busy)
@@ -723,21 +727,36 @@ void INT_USB_FUNC(void)
723 GINTSTS = ints; 727 GINTSTS = ints;
724} 728}
725 729
726static void ep_transfer(int ep, void *ptr, int length, bool out) 730static void ep_transfer(int ep, void *ptr, int len, bool out)
727{ 731{
732 while (!out && inflight && plugged);
733 if (!plugged) return;
734
735 /* disable interrupts to avoid any race */
736 int oldlevel = disable_irq_save();
737 if (!out) inflight = true;
728 endpoints[ep].busy = true; 738 endpoints[ep].busy = true;
729 endpoints[ep].size = length; 739 endpoints[ep].size = len;
730 if (out) 740
731 DEPCTL(ep, out) &= ~DEPCTL_stall; 741 if (out) DEPCTL(ep, out) &= ~DEPCTL_stall;
732 int blocksize = usb_drv_port_speed() ? 512 : 64; 742
733 int packets = (length + blocksize - 1) / blocksize; 743
734 if (packets == 0) 744 int mps = usb_drv_port_speed() ? 512 : 64;
735 packets = 1; 745 int nb_packets = (len + mps - 1) / mps;
736 746 if (nb_packets == 0)
737 DEPTSIZ(ep, out) = length | (packets << DEPTSIZ0_pkcnt_bitp); 747 nb_packets = 1;
738 DEPDMA(ep, out) = length ? ptr : NULL; 748
739 commit_dcache(); 749 DEPDMA(ep, out) = len ? ptr : NULL;
750 DEPTSIZ(ep, out) = (nb_packets << DEPTSIZ_pkcnt_bitp) | len;
751
752 if(out) discard_dcache_range(ptr, len);
753 else commit_dcache_range(ptr, len);
754
755 logf("pkt=%d dma=%lx", nb_packets, DEPDMA(ep, out));
756
740 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak; 757 DEPCTL(ep, out) |= DEPCTL_epena | DEPCTL_cnak;
758
759 restore_irq(oldlevel);
741} 760}
742 761
743int usb_drv_send(int endpoint, void *ptr, int length) 762int usb_drv_send(int endpoint, void *ptr, int length)
@@ -775,11 +794,13 @@ void usb_drv_init(void)
775 PCGCCTL = 0; 794 PCGCCTL = 0;
776 795
777 /* reset the beast */ 796 /* reset the beast */
797 plugged = true;
778 usb_reset(); 798 usb_reset();
779} 799}
780 800
781void usb_drv_exit(void) 801void usb_drv_exit(void)
782{ 802{
803 plugged = false;
783 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon; 804 DCTL = DCTL_pwronprgdone | DCTL_sftdiscon;
784 805
785 OPHYPWR = 0xF; /* PHY: Power down */ 806 OPHYPWR = 0xF; /* PHY: Power down */