Skip to content

Commit d94ea53

Browse files
Thinh Nguyenfelipebalbi
authored andcommitted
usb: dwc3: gadget: Properly set maxpacket limit
Currently the calculation of max packet size limit for IN endpoints is too restrictive. This prevents a matching of a capable hardware endpoint during configuration. Below is the minimum recommended HW configuration to support a particular endpoint setup from the databook: For OUT endpoints, the databook recommended the minimum RxFIFO size to be at least 3x MaxPacketSize + 3x setup packets size (8 bytes each) + clock crossing margin (16 bytes). For IN endpoints, the databook recommended the minimum TxFIFO size to be at least 3x MaxPacketSize for endpoints that support burst. If the endpoint doesn't support burst or when the device is operating in USB 2.0 mode, a minimum TxFIFO size of 2x MaxPacketSize is recommended. Base on these recommendations, we can calculate the MaxPacketSize limit of each endpoint. This patch revises the IN endpoint MaxPacketSize limit and also sets the MaxPacketSize limit for OUT endpoints. Reference: Databook 3.30a section 3.2.2 and 3.2.3 Signed-off-by: Thinh Nguyen <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 586f433 commit d94ea53

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

drivers/usb/dwc3/core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,10 @@
311311
#define DWC3_GTXFIFOSIZ_TXFDEP(n) ((n) & 0xffff)
312312
#define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000)
313313

314+
/* Global RX Fifo Size Register */
315+
#define DWC31_GRXFIFOSIZ_RXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */
316+
#define DWC3_GRXFIFOSIZ_RXFDEP(n) ((n) & 0xffff)
317+
314318
/* Global Event Size Registers */
315319
#define DWC3_GEVNTSIZ_INTMASK BIT(31)
316320
#define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff)

drivers/usb/dwc3/gadget.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,7 +2227,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
22272227
{
22282228
struct dwc3 *dwc = dep->dwc;
22292229
int mdwidth;
2230-
int kbytes;
22312230
int size;
22322231

22332232
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
@@ -2243,17 +2242,17 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
22432242
/* FIFO Depth is in MDWDITH bytes. Multiply */
22442243
size *= mdwidth;
22452244

2246-
kbytes = size / 1024;
2247-
if (kbytes == 0)
2248-
kbytes = 1;
2249-
22502245
/*
2251-
* FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for
2252-
* internal overhead. We don't really know how these are used,
2253-
* but documentation say it exists.
2246+
* To meet performance requirement, a minimum TxFIFO size of 3x
2247+
* MaxPacketSize is recommended for endpoints that support burst and a
2248+
* minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't
2249+
* support burst. Use those numbers and we can calculate the max packet
2250+
* limit as below.
22542251
*/
2255-
size -= mdwidth * (kbytes + 1);
2256-
size /= kbytes;
2252+
if (dwc->maximum_speed >= USB_SPEED_SUPER)
2253+
size /= 3;
2254+
else
2255+
size /= 2;
22572256

22582257
usb_ep_set_maxpacket_limit(&dep->endpoint, size);
22592258

@@ -2271,8 +2270,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
22712270
static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep)
22722271
{
22732272
struct dwc3 *dwc = dep->dwc;
2273+
int mdwidth;
2274+
int size;
2275+
2276+
mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
2277+
2278+
/* MDWIDTH is represented in bits, convert to bytes */
2279+
mdwidth /= 8;
22742280

2275-
usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
2281+
/* All OUT endpoints share a single RxFIFO space */
2282+
size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0));
2283+
if (dwc3_is_usb31(dwc))
2284+
size = DWC31_GRXFIFOSIZ_RXFDEP(size);
2285+
else
2286+
size = DWC3_GRXFIFOSIZ_RXFDEP(size);
2287+
2288+
/* FIFO depth is in MDWDITH bytes */
2289+
size *= mdwidth;
2290+
2291+
/*
2292+
* To meet performance requirement, a minimum recommended RxFIFO size
2293+
* is defined as follow:
2294+
* RxFIFO size >= (3 x MaxPacketSize) +
2295+
* (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin)
2296+
*
2297+
* Then calculate the max packet limit as below.
2298+
*/
2299+
size -= (3 * 8) + 16;
2300+
if (size < 0)
2301+
size = 0;
2302+
else
2303+
size /= 3;
2304+
2305+
usb_ep_set_maxpacket_limit(&dep->endpoint, size);
22762306
dep->endpoint.max_streams = 15;
22772307
dep->endpoint.ops = &dwc3_gadget_ep_ops;
22782308
list_add_tail(&dep->endpoint.ep_list,

0 commit comments

Comments
 (0)