Hi, Thinh Nguyen wrote: > 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 <thinhn@xxxxxxxxxxxx> > --- > Changes in v2 - > None > > drivers/usb/dwc3/core.h | 4 ++++ > drivers/usb/dwc3/gadget.c | 52 +++++++++++++++++++++++++++++++++++++---------- > 2 files changed, 45 insertions(+), 11 deletions(-) > > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h > index 6a6baadcb697..0f019db5e125 100644 > --- a/drivers/usb/dwc3/core.h > +++ b/drivers/usb/dwc3/core.h > @@ -309,6 +309,10 @@ > #define DWC3_GTXFIFOSIZ_TXFDEP(n) ((n) & 0xffff) > #define DWC3_GTXFIFOSIZ_TXFSTADDR(n) ((n) & 0xffff0000) > > +/* Global RX Fifo Size Register */ > +#define DWC31_GRXFIFOSIZ_RXFDEP(n) ((n) & 0x7fff) /* DWC_usb31 only */ > +#define DWC3_GRXFIFOSIZ_RXFDEP(n) ((n) & 0xffff) > + > /* Global Event Size Registers */ > #define DWC3_GEVNTSIZ_INTMASK BIT(31) > #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index 5da266173146..3b3e6a655c6a 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -2207,7 +2207,6 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) > { > struct dwc3 *dwc = dep->dwc; > int mdwidth; > - int kbytes; > int size; > > mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); > @@ -2223,17 +2222,17 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) > /* FIFO Depth is in MDWDITH bytes. Multiply */ > size *= mdwidth; > > - kbytes = size / 1024; > - if (kbytes == 0) > - kbytes = 1; > - > /* > - * FIFO sizes account an extra MDWIDTH * (kbytes + 1) bytes for > - * internal overhead. We don't really know how these are used, > - * but documentation say it exists. > + * To meet performance requirement, a minimum TxFIFO size of 3x > + * MaxPacketSize is recommended for endpoints that support burst and a > + * minimum TxFIFO size of 2x MaxPacketSize for endpoints that don't > + * support burst. Use those numbers and we can calculate the max packet > + * limit as below. > */ > - size -= mdwidth * (kbytes + 1); > - size /= kbytes; > + if (dwc->maximum_speed >= USB_SPEED_SUPER) > + size /= 3; > + else > + size /= 2; > > usb_ep_set_maxpacket_limit(&dep->endpoint, size); > > @@ -2251,8 +2250,39 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) > static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) > { > struct dwc3 *dwc = dep->dwc; > + int mdwidth; > + int size; > + > + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); > + > + /* MDWIDTH is represented in bits, convert to bytes */ > + mdwidth /= 8; > > - usb_ep_set_maxpacket_limit(&dep->endpoint, 1024); > + /* All OUT endpoints share a single RxFIFO space */ > + size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0)); > + if (dwc3_is_usb31(dwc)) > + size = DWC31_GRXFIFOSIZ_RXFDEP(size); > + else > + size = DWC3_GRXFIFOSIZ_RXFDEP(size); > + > + /* FIFO depth is in MDWDITH bytes */ > + size *= mdwidth; > + > + /* > + * To meet performance requirement, a minimum recommended RxFIFO size > + * is defined as follow: > + * RxFIFO size >= (3 x MaxPacketSize) + > + * (3 x 8 bytes setup packets size) + (16 bytes clock crossing margin) > + * > + * Then calculate the max packet limit as below. > + */ > + size -= (3 * 8) + 16; > + if (size < 0) > + size = 0; > + else > + size /= 3; > + > + usb_ep_set_maxpacket_limit(&dep->endpoint, size); > dep->endpoint.max_streams = 15; > dep->endpoint.ops = &dwc3_gadget_ep_ops; > list_add_tail(&dep->endpoint.ep_list, Please let me know if these patches are not clear or that they are lost somewhere. I'll try my best to clarify if anything's not clear. Thanks, Thinh