Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> writes: > 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. They're now in my testing/fixes. Thanks -- balbi
Attachment:
signature.asc
Description: PGP signature