On 5/18/2016 1:35 AM, Felipe Balbi wrote: > Instead of using burst size to configure NUMP, we > should be using RxFIFO Size instead. DWC3 is smart > enough to know that it shouldn't burst in case burst > size is 0. > > Reported-by: John Youn <johnyoun@xxxxxxxxxxxx> > Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> > --- > drivers/usb/dwc3/core.h | 12 +++++++++++ > drivers/usb/dwc3/gadget.c | 53 +++++++++++++++++++++++++++++++++++++---------- > 2 files changed, 54 insertions(+), 11 deletions(-) > > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h > index 9366351ac136..761dc34885be 100644 > --- a/drivers/usb/dwc3/core.h > +++ b/drivers/usb/dwc3/core.h > @@ -231,6 +231,14 @@ > #define DWC3_GEVNTSIZ_INTMASK (1 << 31) > #define DWC3_GEVNTSIZ_SIZE(n) ((n) & 0xffff) > > +/* Global HWPARAMS0 Register */ > +#define DWC3_GHWPARAMS0_USB3_MODE(n) ((n) & 0x3) > +#define DWC3_GHWPARAMS0_MBUS_TYPE(n) (((n) >> 3) & 0x7) > +#define DWC3_GHWPARAMS0_SBUS_TYPE(n) (((n) >> 6) & 0x3) > +#define DWC3_GHWPARAMS0_MDWIDTH(n) (((n) >> 8) & 0xff) > +#define DWC3_GHWPARAMS0_SDWIDTH(n) (((n) >> 16) & 0xff) > +#define DWC3_GHWPARAMS0_AWIDTH(n) (((n) >> 24) & 0xff) > + > /* Global HWPARAMS1 Register */ > #define DWC3_GHWPARAMS1_EN_PWROPT(n) (((n) & (3 << 24)) >> 24) > #define DWC3_GHWPARAMS1_EN_PWROPT_NO 0 > @@ -260,6 +268,10 @@ > /* Global HWPARAMS6 Register */ > #define DWC3_GHWPARAMS6_EN_FPGA (1 << 7) > > +/* Global HWPARAMS7 Register */ > +#define DWC3_GHWPARAMS7_RAM1_DEPTH(n) ((n) & 0xffff) > +#define DWC3_GHWPARAMS7_RAM2_DEPTH(n) (((n) >> 16) & 0xffff) > + > /* Global Frame Length Adjustment Register */ > #define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) > #define DWC3_GFLADJ_30MHZ_MASK 0x3f > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index adf743bca36f..4a3ed4cbe39b 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -463,17 +463,6 @@ static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep, > /* Burst size is only needed in SuperSpeed mode */ > if (dwc->gadget.speed >= USB_SPEED_SUPER) { > u32 burst = dep->endpoint.maxburst; > - u32 nump; > - u32 reg; > - > - /* update NumP */ > - reg = dwc3_readl(dwc->regs, DWC3_DCFG); > - nump = DWC3_DCFG_NUMP(reg); > - nump = max(nump, burst); > - reg &= ~DWC3_DCFG_NUMP_MASK; > - reg |= nump << DWC3_DCFG_NUMP_SHIFT; > - dwc3_writel(dwc->regs, DWC3_DCFG, reg); > - > params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst - 1); > } > > @@ -1589,6 +1578,46 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc) > static irqreturn_t dwc3_interrupt(int irq, void *_dwc); > static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc); > > +/** > + * dwc3_gadget_setup_nump - Calculate and initialize NUMP field of DCFG > + * dwc: pointer to our context structure > + * > + * The following looks like complex but it's actually very simple. In order to > + * calculate the number of packets we can burst at once on OUT transfers, we're > + * gonna use RxFIFO size. > + * > + * To calculate RxFIFO size we need two numbers: > + * MDWIDTH = size, in bits, of the internal memory bus > + * RAM2_DEPTH = depth, in MDWIDTH, of internal RAM2 (where RxFIFO sits) > + * > + * Given these two numbers, the formula is simple: > + * > + * RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16; > + * > + * 24 bytes is for 3x SETUP packets > + * 16 bytes is a clock domain crossing tolerance > + * > + * Given RxFIFO Size, NUMP = RxFIFOSize / 1024; > + */ > +static void dwc3_gadget_setup_nump(struct dwc3 *dwc) > +{ > + u32 ram2_depth; > + u32 mdwidth; > + u32 nump; > + u32 reg; > + > + ram2_depth = DWC3_GHWPARAMS7_RAM2_DEPTH(dwc->hwparams.hwparams7); > + mdwidth = DWC3_GHWPARAMS0_MDWIDTH(dwc->hwparams.hwparams0); > + > + nump = ((ram2_depth * mdwidth / 8) - 24 - 16) / 1024; This value should be capped to 16. John -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html