summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch187
1 files changed, 187 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch
new file mode 100644
index 0000000000..3038dd171d
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/musb/0023-musb-add-high-bandwidth-ISO-support.patch
@@ -0,0 +1,187 @@
1From 2e049a88b729ae2fdc0ecdabad1857810bd62737 Mon Sep 17 00:00:00 2001
2From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
3Date: Fri, 3 Apr 2009 16:16:17 -0700
4Subject: [PATCH] musb: add high bandwidth ISO support
5
6Tested on OMAP3 host side with Creative (Live! Cam Optia) USB camera
7which uses high bandwidth isochronous IN endpoints. FIFO mode 4 is
8updated to provide the needed 4K endpoint buffer without breaking
9the g_nokia composite gadget configuration. (This is the only
10gadget driver known to use enough endpoints to notice the change.)
11
12Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
13Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
14---
15 drivers/usb/musb/musb_core.c | 19 ++++++++---------
16 drivers/usb/musb/musb_core.h | 3 ++
17 drivers/usb/musb/musb_host.c | 47 +++++++++++++++++++++++++++++++----------
18 drivers/usb/musb/musb_host.h | 1 +
19 4 files changed, 48 insertions(+), 22 deletions(-)
20
21diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
22index a1de43b..d953305 100644
23--- a/drivers/usb/musb/musb_core.c
24+++ b/drivers/usb/musb/musb_core.c
25@@ -1068,14 +1068,13 @@ static struct fifo_cfg __initdata mode_4_cfg[] = {
26 { .hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 512, },
27 { .hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 512, },
28 { .hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 512, },
29-{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 512, },
30-{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 512, },
31-{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 512, },
32-{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 512, },
33-{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 512, },
34-{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 512, },
35-{ .hw_ep_num = 13, .style = FIFO_TX, .maxpacket = 512, },
36-{ .hw_ep_num = 13, .style = FIFO_RX, .maxpacket = 512, },
37+{ .hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 256, },
38+{ .hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 64, },
39+{ .hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 256, },
40+{ .hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 64, },
41+{ .hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 256, },
42+{ .hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 64, },
43+{ .hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 4096, },
44 { .hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024, },
45 { .hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024, },
46 };
47@@ -1335,11 +1334,11 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
48 }
49 if (reg & MUSB_CONFIGDATA_HBRXE) {
50 strcat(aInfo, ", HB-ISO Rx");
51- strcat(aInfo, " (X)"); /* no driver support */
52+ musb->hb_iso_rx = true;
53 }
54 if (reg & MUSB_CONFIGDATA_HBTXE) {
55 strcat(aInfo, ", HB-ISO Tx");
56- strcat(aInfo, " (X)"); /* no driver support */
57+ musb->hb_iso_tx = true;
58 }
59 if (reg & MUSB_CONFIGDATA_SOFTCONE)
60 strcat(aInfo, ", SoftConn");
61diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
62index f56a56c..0ac4faf 100644
63--- a/drivers/usb/musb/musb_core.h
64+++ b/drivers/usb/musb/musb_core.h
65@@ -387,6 +387,9 @@ struct musb {
66 unsigned is_multipoint:1;
67 unsigned ignore_disconnect:1; /* during bus resets */
68
69+ unsigned hb_iso_rx:1; /* high bandwidth iso rx? */
70+ unsigned hb_iso_tx:1; /* high bandwidth iso tx? */
71+
72 #ifdef C_MP_TX
73 unsigned bulk_split:1;
74 #define can_bulk_split(musb,type) \
75diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
76index 71e835e..ece5122 100644
77--- a/drivers/usb/musb/musb_host.c
78+++ b/drivers/usb/musb/musb_host.c
79@@ -602,7 +602,8 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
80 musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg);
81 musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
82 /* NOTE: bulk combining rewrites high bits of maxpacket */
83- musb_writew(ep->regs, MUSB_RXMAXP, qh->maxpacket);
84+ musb_writew(ep->regs, MUSB_RXMAXP,
85+ qh->maxpacket | ((qh->hb_mult - 1) << 11));
86
87 ep->rx_reinit = 0;
88 }
89@@ -624,9 +625,10 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
90 csr = musb_readw(epio, MUSB_TXCSR);
91 if (length > pkt_size) {
92 mode = 1;
93- csr |= MUSB_TXCSR_AUTOSET
94- | MUSB_TXCSR_DMAMODE
95- | MUSB_TXCSR_DMAENAB;
96+ csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB;
97+ /* autoset shouldn't be set in high bandwidth */
98+ if (qh->hb_mult == 1)
99+ csr |= MUSB_TXCSR_AUTOSET;
100 } else {
101 mode = 0;
102 csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE);
103@@ -1432,6 +1434,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
104 /* packet error reported later */
105 iso_err = true;
106 }
107+ } else if (rx_csr & MUSB_RXCSR_INCOMPRX) {
108+ DBG(3, "end %d high bandwidth incomplete ISO packet RX\n",
109+ epnum);
110+ status = -EPROTO;
111 }
112
113 /* faults abort the transfer */
114@@ -1639,7 +1645,11 @@ void musb_host_rx(struct musb *musb, u8 epnum)
115 val &= ~MUSB_RXCSR_H_AUTOREQ;
116 else
117 val |= MUSB_RXCSR_H_AUTOREQ;
118- val |= MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB;
119+ val |= MUSB_RXCSR_DMAENAB;
120+
121+ /* autoclear shouldn't be set in high bandwidth */
122+ if (qh->hb_mult == 1)
123+ val |= MUSB_RXCSR_AUTOCLEAR;
124
125 musb_writew(epio, MUSB_RXCSR,
126 MUSB_RXCSR_H_WZC_BITS | val);
127@@ -1725,9 +1735,10 @@ static int musb_schedule(
128 continue;
129
130 if (is_in)
131- diff = hw_ep->max_packet_sz_rx - qh->maxpacket;
132+ diff = hw_ep->max_packet_sz_rx;
133 else
134- diff = hw_ep->max_packet_sz_tx - qh->maxpacket;
135+ diff = hw_ep->max_packet_sz_tx;
136+ diff -= (qh->maxpacket * qh->hb_mult);
137
138 if (diff >= 0 && best_diff > diff) {
139 best_diff = diff;
140@@ -1830,15 +1841,27 @@ static int musb_urb_enqueue(
141 qh->is_ready = 1;
142
143 qh->maxpacket = le16_to_cpu(epd->wMaxPacketSize);
144+ qh->type = usb_endpoint_type(epd);
145
146- /* no high bandwidth support yet */
147- if (qh->maxpacket & ~0x7ff) {
148- ret = -EMSGSIZE;
149- goto done;
150+ /* Bits 11 & 12 of wMaxPacketSize encode high bandwidth multiplier.
151+ * Some musb cores don't support high bandwidth ISO transfers; and
152+ * we don't (yet!) support high bandwidth interrupt transfers.
153+ */
154+ qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03);
155+ if (qh->hb_mult > 1) {
156+ int ok = (qh->type == USB_ENDPOINT_XFER_ISOC);
157+
158+ if (ok)
159+ ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx)
160+ || (usb_pipeout(urb->pipe) && musb->hb_iso_tx);
161+ if (!ok) {
162+ ret = -EMSGSIZE;
163+ goto done;
164+ }
165+ qh->maxpacket &= 0x7ff;
166 }
167
168 qh->epnum = usb_endpoint_num(epd);
169- qh->type = usb_endpoint_type(epd);
170
171 /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */
172 qh->addr_reg = (u8) usb_pipedevice(urb->pipe);
173diff --git a/drivers/usb/musb/musb_host.h b/drivers/usb/musb/musb_host.h
174index 0b7fbcd..14b0077 100644
175--- a/drivers/usb/musb/musb_host.h
176+++ b/drivers/usb/musb/musb_host.h
177@@ -67,6 +67,7 @@ struct musb_qh {
178 u8 is_ready; /* safe to modify hw_ep */
179 u8 type; /* XFERTYPE_* */
180 u8 epnum;
181+ u8 hb_mult; /* high bandwidth pkts per uf */
182 u16 maxpacket;
183 u16 frame; /* for periodic schedule */
184 unsigned iso_idx; /* in urb->iso_frame_desc[] */
185--
1861.6.0.4
187