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 <johny...@synopsys.com>
> Signed-off-by: Felipe Balbi <felipe.ba...@linux.intel.com>
> ---
>  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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to