diff options
Diffstat (limited to 'firmware/target/arm/usb-s3c6400x.c')
-rw-r--r-- | firmware/target/arm/usb-s3c6400x.c | 57 |
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 | ||
533 | static volatile bool inflight = false; | ||
534 | static volatile bool plugged = false; | ||
535 | |||
534 | static void reset_endpoints(int reinit) | 536 | static 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 | ||
572 | int usb_drv_request_endpoint(int type, int dir) | 575 | int 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 | ||
726 | static void ep_transfer(int ep, void *ptr, int length, bool out) | 730 | static 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 | ||
743 | int usb_drv_send(int endpoint, void *ptr, int length) | 762 | int 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 | ||
781 | void usb_drv_exit(void) | 801 | void 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 */ |