diff options
author | David Brownell <david-b@pacbell.net> | 2005-04-28 16:52:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:50 -0400 |
commit | 65111084c63d7674dc37833e8eb59cfdaa4d0bda (patch) | |
tree | c2251a7b78f5adbfd30c4d30e15633020ea95c75 | |
parent | 907cba35f7f24587f0eff60073e1f4e1e01c976d (diff) |
[PATCH] USB: more omap_udc updates (dma and omap1710)
More omap_udc updates:
* OMAP 1710 updates
- new UDC bit for clearing endpoint toggle, affecting CLEAR_HALT
- new OTG bits affecting wakeup
* Fix the bug Vladimir noted, that IN-DMA transfer code path kicks in
for under 1024 bytes (not "up to 1024 bytes")
* Handle transceiver setup more intelligently
- use transceiver whenever one's available; this can be handy
for GPIO based, loopback, or transceiverless configs
- cleanup correctly after the "unrecognized HMC" case
* DMA performance tweaks
- allow burst/pack for memory access
- use 16 bit DMA access most of the time on TIPB
* Add workarounds for some DMA errata (not observed "in the wild"):
- DMA CSAC/CDAC reads returning zero
- RX/TX DMA config registers bit 12 always reads as zero (TI patch)
* More "sparse" warnings removed, notably "changing" the SETUP packet
to return data in USB byteorder (an API change, null effect on OMAP
except for these warnings).
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/omap_udc.c | 153 | ||||
-rw-r--r-- | drivers/usb/gadget/omap_udc.h | 4 | ||||
-rw-r--r-- | include/asm-arm/arch-omap/usb.h | 9 |
3 files changed, 125 insertions, 41 deletions
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 4ec91a68f96c..a2b812af6e66 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -166,7 +166,7 @@ static int omap_ep_enable(struct usb_ep *_ep, | |||
166 | maxp = le16_to_cpu (desc->wMaxPacketSize); | 166 | maxp = le16_to_cpu (desc->wMaxPacketSize); |
167 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK | 167 | if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK |
168 | && maxp != ep->maxpacket) | 168 | && maxp != ep->maxpacket) |
169 | || desc->wMaxPacketSize > ep->maxpacket | 169 | || le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket |
170 | || !desc->wMaxPacketSize) { | 170 | || !desc->wMaxPacketSize) { |
171 | DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); | 171 | DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name); |
172 | return -ERANGE; | 172 | return -ERANGE; |
@@ -213,7 +213,7 @@ static int omap_ep_enable(struct usb_ep *_ep, | |||
213 | ep->has_dma = 0; | 213 | ep->has_dma = 0; |
214 | ep->lch = -1; | 214 | ep->lch = -1; |
215 | use_ep(ep, UDC_EP_SEL); | 215 | use_ep(ep, UDC_EP_SEL); |
216 | UDC_CTRL_REG = UDC_RESET_EP; | 216 | UDC_CTRL_REG = udc->clr_halt; |
217 | ep->ackwait = 0; | 217 | ep->ackwait = 0; |
218 | deselect_ep(); | 218 | deselect_ep(); |
219 | 219 | ||
@@ -537,6 +537,32 @@ static int read_fifo(struct omap_ep *ep, struct omap_req *req) | |||
537 | 537 | ||
538 | /*-------------------------------------------------------------------------*/ | 538 | /*-------------------------------------------------------------------------*/ |
539 | 539 | ||
540 | static inline dma_addr_t dma_csac(unsigned lch) | ||
541 | { | ||
542 | dma_addr_t csac; | ||
543 | |||
544 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is | ||
545 | * read before the DMA controller finished disabling the channel. | ||
546 | */ | ||
547 | csac = omap_readw(OMAP_DMA_CSAC(lch)); | ||
548 | if (csac == 0) | ||
549 | csac = omap_readw(OMAP_DMA_CSAC(lch)); | ||
550 | return csac; | ||
551 | } | ||
552 | |||
553 | static inline dma_addr_t dma_cdac(unsigned lch) | ||
554 | { | ||
555 | dma_addr_t cdac; | ||
556 | |||
557 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is | ||
558 | * read before the DMA controller finished disabling the channel. | ||
559 | */ | ||
560 | cdac = omap_readw(OMAP_DMA_CDAC(lch)); | ||
561 | if (cdac == 0) | ||
562 | cdac = omap_readw(OMAP_DMA_CDAC(lch)); | ||
563 | return cdac; | ||
564 | } | ||
565 | |||
540 | static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) | 566 | static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) |
541 | { | 567 | { |
542 | dma_addr_t end; | 568 | dma_addr_t end; |
@@ -547,7 +573,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) | |||
547 | if (cpu_is_omap15xx()) | 573 | if (cpu_is_omap15xx()) |
548 | return 0; | 574 | return 0; |
549 | 575 | ||
550 | end = omap_readw(OMAP_DMA_CSAC(ep->lch)); | 576 | end = dma_csac(ep->lch); |
551 | if (end == ep->dma_counter) | 577 | if (end == ep->dma_counter) |
552 | return 0; | 578 | return 0; |
553 | 579 | ||
@@ -558,14 +584,14 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) | |||
558 | } | 584 | } |
559 | 585 | ||
560 | #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ | 586 | #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ |
561 | ? OMAP_DMA_CSAC(x) /* really: CPC */ \ | 587 | ? omap_readw(OMAP_DMA_CSAC(x)) /* really: CPC */ \ |
562 | : OMAP_DMA_CDAC(x)) | 588 | : dma_cdac(x)) |
563 | 589 | ||
564 | static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) | 590 | static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) |
565 | { | 591 | { |
566 | dma_addr_t end; | 592 | dma_addr_t end; |
567 | 593 | ||
568 | end = omap_readw(DMA_DEST_LAST(ep->lch)); | 594 | end = DMA_DEST_LAST(ep->lch); |
569 | if (end == ep->dma_counter) | 595 | if (end == ep->dma_counter) |
570 | return 0; | 596 | return 0; |
571 | 597 | ||
@@ -592,7 +618,7 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) | |||
592 | : OMAP_DMA_SYNC_ELEMENT; | 618 | : OMAP_DMA_SYNC_ELEMENT; |
593 | 619 | ||
594 | /* measure length in either bytes or packets */ | 620 | /* measure length in either bytes or packets */ |
595 | if ((cpu_is_omap16xx() && length <= (UDC_TXN_TSC + 1)) | 621 | if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC) |
596 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { | 622 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { |
597 | txdma_ctrl = UDC_TXN_EOT | length; | 623 | txdma_ctrl = UDC_TXN_EOT | length; |
598 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 624 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, |
@@ -601,15 +627,15 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) | |||
601 | length = min(length / ep->maxpacket, | 627 | length = min(length / ep->maxpacket, |
602 | (unsigned) UDC_TXN_TSC + 1); | 628 | (unsigned) UDC_TXN_TSC + 1); |
603 | txdma_ctrl = length; | 629 | txdma_ctrl = length; |
604 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 630 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
605 | ep->ep.maxpacket, length, sync_mode); | 631 | ep->ep.maxpacket >> 1, length, sync_mode); |
606 | length *= ep->maxpacket; | 632 | length *= ep->maxpacket; |
607 | } | 633 | } |
608 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 634 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
609 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); | 635 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); |
610 | 636 | ||
611 | omap_start_dma(ep->lch); | 637 | omap_start_dma(ep->lch); |
612 | ep->dma_counter = omap_readw(OMAP_DMA_CSAC(ep->lch)); | 638 | ep->dma_counter = dma_csac(ep->lch); |
613 | UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); | 639 | UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel); |
614 | UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; | 640 | UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl; |
615 | req->dma_bytes = length; | 641 | req->dma_bytes = length; |
@@ -649,12 +675,12 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) | |||
649 | packets = (req->req.length - req->req.actual) / ep->ep.maxpacket; | 675 | packets = (req->req.length - req->req.actual) / ep->ep.maxpacket; |
650 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); | 676 | packets = min(packets, (unsigned)UDC_RXN_TC + 1); |
651 | req->dma_bytes = packets * ep->ep.maxpacket; | 677 | req->dma_bytes = packets * ep->ep.maxpacket; |
652 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 678 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
653 | ep->ep.maxpacket, packets, | 679 | ep->ep.maxpacket >> 1, packets, |
654 | OMAP_DMA_SYNC_ELEMENT); | 680 | OMAP_DMA_SYNC_ELEMENT); |
655 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 681 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
656 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); | 682 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); |
657 | ep->dma_counter = omap_readw(DMA_DEST_LAST(ep->lch)); | 683 | ep->dma_counter = DMA_DEST_LAST(ep->lch); |
658 | 684 | ||
659 | UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); | 685 | UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); |
660 | UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); | 686 | UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel); |
@@ -762,7 +788,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
762 | reg = UDC_TXDMA_CFG_REG; | 788 | reg = UDC_TXDMA_CFG_REG; |
763 | else | 789 | else |
764 | reg = UDC_RXDMA_CFG_REG; | 790 | reg = UDC_RXDMA_CFG_REG; |
765 | reg |= 1 << 12; /* "pulse" activated */ | 791 | reg |= UDC_DMA_REQ; /* "pulse" activated */ |
766 | 792 | ||
767 | ep->dma_channel = 0; | 793 | ep->dma_channel = 0; |
768 | ep->lch = -1; | 794 | ep->lch = -1; |
@@ -786,6 +812,11 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
786 | ep->ep.name, dma_error, ep, &ep->lch); | 812 | ep->ep.name, dma_error, ep, &ep->lch); |
787 | if (status == 0) { | 813 | if (status == 0) { |
788 | UDC_TXDMA_CFG_REG = reg; | 814 | UDC_TXDMA_CFG_REG = reg; |
815 | /* EMIFF */ | ||
816 | omap_set_dma_src_burst_mode(ep->lch, | ||
817 | OMAP_DMA_DATA_BURST_4); | ||
818 | omap_set_dma_src_data_pack(ep->lch, 1); | ||
819 | /* TIPB */ | ||
789 | omap_set_dma_dest_params(ep->lch, | 820 | omap_set_dma_dest_params(ep->lch, |
790 | OMAP_DMA_PORT_TIPB, | 821 | OMAP_DMA_PORT_TIPB, |
791 | OMAP_DMA_AMODE_CONSTANT, | 822 | OMAP_DMA_AMODE_CONSTANT, |
@@ -796,10 +827,15 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
796 | ep->ep.name, dma_error, ep, &ep->lch); | 827 | ep->ep.name, dma_error, ep, &ep->lch); |
797 | if (status == 0) { | 828 | if (status == 0) { |
798 | UDC_RXDMA_CFG_REG = reg; | 829 | UDC_RXDMA_CFG_REG = reg; |
830 | /* TIPB */ | ||
799 | omap_set_dma_src_params(ep->lch, | 831 | omap_set_dma_src_params(ep->lch, |
800 | OMAP_DMA_PORT_TIPB, | 832 | OMAP_DMA_PORT_TIPB, |
801 | OMAP_DMA_AMODE_CONSTANT, | 833 | OMAP_DMA_AMODE_CONSTANT, |
802 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG)); | 834 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG)); |
835 | /* EMIFF */ | ||
836 | omap_set_dma_dest_burst_mode(ep->lch, | ||
837 | OMAP_DMA_DATA_BURST_4); | ||
838 | omap_set_dma_dest_data_pack(ep->lch, 1); | ||
803 | } | 839 | } |
804 | } | 840 | } |
805 | if (status) | 841 | if (status) |
@@ -864,9 +900,13 @@ static void dma_channel_release(struct omap_ep *ep) | |||
864 | (ep->bEndpointAddress & USB_DIR_IN) ? 't' : 'r', | 900 | (ep->bEndpointAddress & USB_DIR_IN) ? 't' : 'r', |
865 | ep->dma_channel - 1, req); | 901 | ep->dma_channel - 1, req); |
866 | 902 | ||
903 | /* NOTE: re-setting RX_REQ/TX_REQ because of a chip bug (before | ||
904 | * OMAP 1710 ES2.0) where reading the DMA_CFG can clear them. | ||
905 | */ | ||
906 | |||
867 | /* wait till current packet DMA finishes, and fifo empties */ | 907 | /* wait till current packet DMA finishes, and fifo empties */ |
868 | if (ep->bEndpointAddress & USB_DIR_IN) { | 908 | if (ep->bEndpointAddress & USB_DIR_IN) { |
869 | UDC_TXDMA_CFG_REG &= ~mask; | 909 | UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; |
870 | 910 | ||
871 | if (req) { | 911 | if (req) { |
872 | finish_in_dma(ep, req, -ECONNRESET); | 912 | finish_in_dma(ep, req, -ECONNRESET); |
@@ -879,7 +919,7 @@ static void dma_channel_release(struct omap_ep *ep) | |||
879 | while (UDC_TXDMA_CFG_REG & mask) | 919 | while (UDC_TXDMA_CFG_REG & mask) |
880 | udelay(10); | 920 | udelay(10); |
881 | } else { | 921 | } else { |
882 | UDC_RXDMA_CFG_REG &= ~mask; | 922 | UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ; |
883 | 923 | ||
884 | /* dma empties the fifo */ | 924 | /* dma empties the fifo */ |
885 | while (UDC_RXDMA_CFG_REG & mask) | 925 | while (UDC_RXDMA_CFG_REG & mask) |
@@ -1140,7 +1180,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) | |||
1140 | dma_channel_claim(ep, channel); | 1180 | dma_channel_claim(ep, channel); |
1141 | } else { | 1181 | } else { |
1142 | use_ep(ep, 0); | 1182 | use_ep(ep, 0); |
1143 | UDC_CTRL_REG = UDC_RESET_EP; | 1183 | UDC_CTRL_REG = ep->udc->clr_halt; |
1144 | ep->ackwait = 0; | 1184 | ep->ackwait = 0; |
1145 | if (!(ep->bEndpointAddress & USB_DIR_IN)) { | 1185 | if (!(ep->bEndpointAddress & USB_DIR_IN)) { |
1146 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1186 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
@@ -1514,6 +1554,10 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1514 | UDC_EP_NUM_REG = 0; | 1554 | UDC_EP_NUM_REG = 0; |
1515 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); | 1555 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); |
1516 | 1556 | ||
1557 | #define w_value le16_to_cpup (&u.r.wValue) | ||
1558 | #define w_index le16_to_cpup (&u.r.wIndex) | ||
1559 | #define w_length le16_to_cpup (&u.r.wLength) | ||
1560 | |||
1517 | /* Delegate almost all control requests to the gadget driver, | 1561 | /* Delegate almost all control requests to the gadget driver, |
1518 | * except for a handful of ch9 status/feature requests that | 1562 | * except for a handful of ch9 status/feature requests that |
1519 | * hardware doesn't autodecode _and_ the gadget API hides. | 1563 | * hardware doesn't autodecode _and_ the gadget API hides. |
@@ -1528,11 +1572,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1528 | /* udc needs to know when ep != 0 is valid */ | 1572 | /* udc needs to know when ep != 0 is valid */ |
1529 | if (u.r.bRequestType != USB_RECIP_DEVICE) | 1573 | if (u.r.bRequestType != USB_RECIP_DEVICE) |
1530 | goto delegate; | 1574 | goto delegate; |
1531 | if (u.r.wLength != 0) | 1575 | if (w_length != 0) |
1532 | goto do_stall; | 1576 | goto do_stall; |
1533 | udc->ep0_set_config = 1; | 1577 | udc->ep0_set_config = 1; |
1534 | udc->ep0_reset_config = (u.r.wValue == 0); | 1578 | udc->ep0_reset_config = (w_value == 0); |
1535 | VDBG("set config %d\n", u.r.wValue); | 1579 | VDBG("set config %d\n", w_value); |
1536 | 1580 | ||
1537 | /* update udc NOW since gadget driver may start | 1581 | /* update udc NOW since gadget driver may start |
1538 | * queueing requests immediately; clear config | 1582 | * queueing requests immediately; clear config |
@@ -1548,18 +1592,18 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1548 | /* clear endpoint halt */ | 1592 | /* clear endpoint halt */ |
1549 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | 1593 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) |
1550 | goto delegate; | 1594 | goto delegate; |
1551 | if (u.r.wValue != USB_ENDPOINT_HALT | 1595 | if (w_value != USB_ENDPOINT_HALT |
1552 | || u.r.wLength != 0) | 1596 | || w_length != 0) |
1553 | goto do_stall; | 1597 | goto do_stall; |
1554 | ep = &udc->ep[u.r.wIndex & 0xf]; | 1598 | ep = &udc->ep[w_index & 0xf]; |
1555 | if (ep != ep0) { | 1599 | if (ep != ep0) { |
1556 | if (u.r.wIndex & USB_DIR_IN) | 1600 | if (w_index & USB_DIR_IN) |
1557 | ep += 16; | 1601 | ep += 16; |
1558 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC | 1602 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC |
1559 | || !ep->desc) | 1603 | || !ep->desc) |
1560 | goto do_stall; | 1604 | goto do_stall; |
1561 | use_ep(ep, 0); | 1605 | use_ep(ep, 0); |
1562 | UDC_CTRL_REG = UDC_RESET_EP; | 1606 | UDC_CTRL_REG = udc->clr_halt; |
1563 | ep->ackwait = 0; | 1607 | ep->ackwait = 0; |
1564 | if (!(ep->bEndpointAddress & USB_DIR_IN)) { | 1608 | if (!(ep->bEndpointAddress & USB_DIR_IN)) { |
1565 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1609 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
@@ -1577,11 +1621,11 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1577 | /* set endpoint halt */ | 1621 | /* set endpoint halt */ |
1578 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) | 1622 | if (u.r.bRequestType != USB_RECIP_ENDPOINT) |
1579 | goto delegate; | 1623 | goto delegate; |
1580 | if (u.r.wValue != USB_ENDPOINT_HALT | 1624 | if (w_value != USB_ENDPOINT_HALT |
1581 | || u.r.wLength != 0) | 1625 | || w_length != 0) |
1582 | goto do_stall; | 1626 | goto do_stall; |
1583 | ep = &udc->ep[u.r.wIndex & 0xf]; | 1627 | ep = &udc->ep[w_index & 0xf]; |
1584 | if (u.r.wIndex & USB_DIR_IN) | 1628 | if (w_index & USB_DIR_IN) |
1585 | ep += 16; | 1629 | ep += 16; |
1586 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC | 1630 | if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC |
1587 | || ep == ep0 || !ep->desc) | 1631 | || ep == ep0 || !ep->desc) |
@@ -1619,13 +1663,13 @@ ep0out_status_stage: | |||
1619 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1663 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1620 | UDC_EP_NUM_REG = UDC_EP_DIR; | 1664 | UDC_EP_NUM_REG = UDC_EP_DIR; |
1621 | status = 0; | 1665 | status = 0; |
1622 | VDBG("GET_STATUS, interface %d\n", u.r.wIndex); | 1666 | VDBG("GET_STATUS, interface %d\n", w_index); |
1623 | /* next, status stage */ | 1667 | /* next, status stage */ |
1624 | break; | 1668 | break; |
1625 | default: | 1669 | default: |
1626 | delegate: | 1670 | delegate: |
1627 | /* activate the ep0out fifo right away */ | 1671 | /* activate the ep0out fifo right away */ |
1628 | if (!udc->ep0_in && u.r.wLength) { | 1672 | if (!udc->ep0_in && w_length) { |
1629 | UDC_EP_NUM_REG = 0; | 1673 | UDC_EP_NUM_REG = 0; |
1630 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1674 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1631 | } | 1675 | } |
@@ -1636,7 +1680,11 @@ delegate: | |||
1636 | */ | 1680 | */ |
1637 | VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n", | 1681 | VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n", |
1638 | u.r.bRequestType, u.r.bRequest, | 1682 | u.r.bRequestType, u.r.bRequest, |
1639 | u.r.wValue, u.r.wIndex, u.r.wLength); | 1683 | w_value, w_index, w_length); |
1684 | |||
1685 | #undef w_value | ||
1686 | #undef w_index | ||
1687 | #undef w_length | ||
1640 | 1688 | ||
1641 | /* The gadget driver may return an error here, | 1689 | /* The gadget driver may return an error here, |
1642 | * causing an immediate protocol stall. | 1690 | * causing an immediate protocol stall. |
@@ -2181,14 +2229,14 @@ static int proc_otg_show(struct seq_file *s) | |||
2181 | 2229 | ||
2182 | tmp = OTG_REV_REG; | 2230 | tmp = OTG_REV_REG; |
2183 | trans = USB_TRANSCEIVER_CTRL_REG; | 2231 | trans = USB_TRANSCEIVER_CTRL_REG; |
2184 | seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %03x\n", | 2232 | seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %05x\n", |
2185 | tmp >> 4, tmp & 0xf, trans); | 2233 | tmp >> 4, tmp & 0xf, trans); |
2186 | tmp = OTG_SYSCON_1_REG; | 2234 | tmp = OTG_SYSCON_1_REG; |
2187 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," | 2235 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," |
2188 | FOURBITS "\n", tmp, | 2236 | FOURBITS "\n", tmp, |
2189 | trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R), | 2237 | trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R), |
2190 | trx_mode(USB1_TRX_MODE(tmp), trans & CONF_USB1_UNI_R), | 2238 | trx_mode(USB1_TRX_MODE(tmp), trans & CONF_USB1_UNI_R), |
2191 | (USB0_TRX_MODE(tmp) == 0) | 2239 | (USB0_TRX_MODE(tmp) == 0 && !cpu_is_omap1710()) |
2192 | ? "internal" | 2240 | ? "internal" |
2193 | : trx_mode(USB0_TRX_MODE(tmp), 1), | 2241 | : trx_mode(USB0_TRX_MODE(tmp), 1), |
2194 | (tmp & OTG_IDLE_EN) ? " !otg" : "", | 2242 | (tmp & OTG_IDLE_EN) ? " !otg" : "", |
@@ -2418,6 +2466,10 @@ static inline void remove_proc_file(void) {} | |||
2418 | /* Before this controller can enumerate, we need to pick an endpoint | 2466 | /* Before this controller can enumerate, we need to pick an endpoint |
2419 | * configuration, or "fifo_mode" That involves allocating 2KB of packet | 2467 | * configuration, or "fifo_mode" That involves allocating 2KB of packet |
2420 | * buffer space among the endpoints we'll be operating. | 2468 | * buffer space among the endpoints we'll be operating. |
2469 | * | ||
2470 | * NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when | ||
2471 | * UDC_SYSCON_1_REG.CFG_LOCK is set can now work. We won't use that | ||
2472 | * capability yet though. | ||
2421 | */ | 2473 | */ |
2422 | static unsigned __init | 2474 | static unsigned __init |
2423 | omap_ep_setup(char *name, u8 addr, u8 type, | 2475 | omap_ep_setup(char *name, u8 addr, u8 type, |
@@ -2690,6 +2742,19 @@ static int __init omap_udc_probe(struct device *dev) | |||
2690 | FUNC_MUX_CTRL_0_REG = tmp; | 2742 | FUNC_MUX_CTRL_0_REG = tmp; |
2691 | } | 2743 | } |
2692 | } else { | 2744 | } else { |
2745 | /* The transceiver may package some GPIO logic or handle | ||
2746 | * loopback and/or transceiverless setup; if we find one, | ||
2747 | * use it. Except for OTG, we don't _need_ to talk to one; | ||
2748 | * but not having one probably means no VBUS detection. | ||
2749 | */ | ||
2750 | xceiv = otg_get_transceiver(); | ||
2751 | if (xceiv) | ||
2752 | type = xceiv->label; | ||
2753 | else if (config->otg) { | ||
2754 | DBG("OTG requires external transceiver!\n"); | ||
2755 | goto cleanup0; | ||
2756 | } | ||
2757 | |||
2693 | hmc = HMC_1610; | 2758 | hmc = HMC_1610; |
2694 | switch (hmc) { | 2759 | switch (hmc) { |
2695 | case 0: /* POWERUP DEFAULT == 0 */ | 2760 | case 0: /* POWERUP DEFAULT == 0 */ |
@@ -2706,25 +2771,27 @@ static int __init omap_udc_probe(struct device *dev) | |||
2706 | case 16: | 2771 | case 16: |
2707 | case 19: | 2772 | case 19: |
2708 | case 25: | 2773 | case 25: |
2709 | xceiv = otg_get_transceiver(); | ||
2710 | if (!xceiv) { | 2774 | if (!xceiv) { |
2711 | DBG("external transceiver not registered!\n"); | 2775 | DBG("external transceiver not registered!\n"); |
2712 | if (config->otg) | ||
2713 | goto cleanup0; | ||
2714 | type = "unknown"; | 2776 | type = "unknown"; |
2715 | } else | 2777 | } |
2716 | type = xceiv->label; | ||
2717 | break; | 2778 | break; |
2718 | case 21: /* internal loopback */ | 2779 | case 21: /* internal loopback */ |
2719 | type = "loopback"; | 2780 | type = "loopback"; |
2720 | break; | 2781 | break; |
2721 | case 14: /* transceiverless */ | 2782 | case 14: /* transceiverless */ |
2783 | if (cpu_is_omap1710()) | ||
2784 | goto bad_on_1710; | ||
2785 | /* FALL THROUGH */ | ||
2786 | case 13: | ||
2787 | case 15: | ||
2722 | type = "no"; | 2788 | type = "no"; |
2723 | break; | 2789 | break; |
2724 | 2790 | ||
2725 | default: | 2791 | default: |
2792 | bad_on_1710: | ||
2726 | ERR("unrecognized UDC HMC mode %d\n", hmc); | 2793 | ERR("unrecognized UDC HMC mode %d\n", hmc); |
2727 | return -ENODEV; | 2794 | goto cleanup0; |
2728 | } | 2795 | } |
2729 | } | 2796 | } |
2730 | INFO("hmc mode %d, %s transceiver\n", hmc, type); | 2797 | INFO("hmc mode %d, %s transceiver\n", hmc, type); |
@@ -2741,6 +2808,12 @@ static int __init omap_udc_probe(struct device *dev) | |||
2741 | udc->gadget.is_otg = (config->otg != 0); | 2808 | udc->gadget.is_otg = (config->otg != 0); |
2742 | #endif | 2809 | #endif |
2743 | 2810 | ||
2811 | /* starting with omap1710 es2.0, clear toggle is a separate bit */ | ||
2812 | if (UDC_REV_REG >= 0x61) | ||
2813 | udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE; | ||
2814 | else | ||
2815 | udc->clr_halt = UDC_RESET_EP; | ||
2816 | |||
2744 | /* USB general purpose IRQ: ep0, state changes, dma, etc */ | 2817 | /* USB general purpose IRQ: ep0, state changes, dma, etc */ |
2745 | status = request_irq(odev->resource[1].start, omap_udc_irq, | 2818 | status = request_irq(odev->resource[1].start, omap_udc_irq, |
2746 | SA_SAMPLE_RANDOM, driver_name, udc); | 2819 | SA_SAMPLE_RANDOM, driver_name, udc); |
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h index c9e68541622c..652ee4627344 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/omap_udc.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */ | 20 | #define UDC_CTRL_REG UDC_REG(0x0C) /* Endpoint control */ |
21 | # define UDC_CLR_HALT (1 << 7) | 21 | # define UDC_CLR_HALT (1 << 7) |
22 | # define UDC_SET_HALT (1 << 6) | 22 | # define UDC_SET_HALT (1 << 6) |
23 | # define UDC_CLRDATA_TOGGLE (1 << 3) | ||
23 | # define UDC_SET_FIFO_EN (1 << 2) | 24 | # define UDC_SET_FIFO_EN (1 << 2) |
24 | # define UDC_CLR_EP (1 << 1) | 25 | # define UDC_CLR_EP (1 << 1) |
25 | # define UDC_RESET_EP (1 << 0) | 26 | # define UDC_RESET_EP (1 << 0) |
@@ -99,6 +100,7 @@ | |||
99 | 100 | ||
100 | /* DMA configuration registers: up to three channels in each direction. */ | 101 | /* DMA configuration registers: up to three channels in each direction. */ |
101 | #define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */ | 102 | #define UDC_RXDMA_CFG_REG UDC_REG(0x40) /* 3 eps for RX DMA */ |
103 | # define UDC_DMA_REQ (1 << 12) | ||
102 | #define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */ | 104 | #define UDC_TXDMA_CFG_REG UDC_REG(0x44) /* 3 eps for TX DMA */ |
103 | #define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */ | 105 | #define UDC_DATA_DMA_REG UDC_REG(0x48) /* rx/tx fifo addr */ |
104 | 106 | ||
@@ -162,6 +164,7 @@ struct omap_udc { | |||
162 | spinlock_t lock; | 164 | spinlock_t lock; |
163 | struct omap_ep ep[32]; | 165 | struct omap_ep ep[32]; |
164 | u16 devstat; | 166 | u16 devstat; |
167 | u16 clr_halt; | ||
165 | struct otg_transceiver *transceiver; | 168 | struct otg_transceiver *transceiver; |
166 | struct list_head iso; | 169 | struct list_head iso; |
167 | unsigned softconnect:1; | 170 | unsigned softconnect:1; |
@@ -171,7 +174,6 @@ struct omap_udc { | |||
171 | unsigned ep0_set_config:1; | 174 | unsigned ep0_set_config:1; |
172 | unsigned ep0_reset_config:1; | 175 | unsigned ep0_reset_config:1; |
173 | unsigned ep0_setup:1; | 176 | unsigned ep0_setup:1; |
174 | |||
175 | struct completion *done; | 177 | struct completion *done; |
176 | }; | 178 | }; |
177 | 179 | ||
diff --git a/include/asm-arm/arch-omap/usb.h b/include/asm-arm/arch-omap/usb.h index 1438c6cef0ca..054fb9a8e0c6 100644 --- a/include/asm-arm/arch-omap/usb.h +++ b/include/asm-arm/arch-omap/usb.h | |||
@@ -47,6 +47,15 @@ | |||
47 | # define HMC_TLLATTACH (1 << 6) | 47 | # define HMC_TLLATTACH (1 << 6) |
48 | # define OTG_HMC(w) (((w)>>0)&0x3f) | 48 | # define OTG_HMC(w) (((w)>>0)&0x3f) |
49 | #define OTG_CTRL_REG OTG_REG32(0x0c) | 49 | #define OTG_CTRL_REG OTG_REG32(0x0c) |
50 | # define OTG_USB2_EN (1 << 29) | ||
51 | # define OTG_USB2_DP (1 << 28) | ||
52 | # define OTG_USB2_DM (1 << 27) | ||
53 | # define OTG_USB1_EN (1 << 26) | ||
54 | # define OTG_USB1_DP (1 << 25) | ||
55 | # define OTG_USB1_DM (1 << 24) | ||
56 | # define OTG_USB0_EN (1 << 23) | ||
57 | # define OTG_USB0_DP (1 << 22) | ||
58 | # define OTG_USB0_DM (1 << 21) | ||
50 | # define OTG_ASESSVLD (1 << 20) | 59 | # define OTG_ASESSVLD (1 << 20) |
51 | # define OTG_BSESSEND (1 << 19) | 60 | # define OTG_BSESSEND (1 << 19) |
52 | # define OTG_BSESSVLD (1 << 18) | 61 | # define OTG_BSESSVLD (1 << 18) |