usb: dwc3: gadget: update DCFG.NumP to max burst size
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Tue, 26 Apr 2016 07:49:07 +0000 (10:49 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Thu, 28 Apr 2016 07:47:29 +0000 (10:47 +0300)
NumP field of DCFG register is used on NumP field of
ACK TP header and it tells the host how many packets
an endpoint can receive before waiting for
synchronization.

Documentation says it should be set to anything
<=bMaxBurst. Interestingly, however, this setting is
not per-endpoint how it should be (different
endpoints could have different burst sizes), but
things seem to work okay right now.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index 87df6dd20d23b8e6572e0b6009b5a751b65639bb..c5f576aa190307f182351fb651ada03c24fda0b0 100644 (file)
 #define DWC3_DCFG_LOWSPEED     (2 << 0)
 #define DWC3_DCFG_FULLSPEED1   (3 << 0)
 
+#define DWC3_DCFG_NUMP_SHIFT   17
+#define DWC3_DCFG_NUMP(n)      (((n) & 0x1f) >> DWC3_DCFG_NUMP_SHIFT)
+#define DWC3_DCFG_NUMP_MASK    (0x1f << DWC3_DCFG_NUMP_SHIFT)
 #define DWC3_DCFG_LPM_CAP      (1 << 22)
 
 /* Device Control Register */
index 43efb627d1cf179395213c841727751393648c54..4b681b0d420f3f55c5a3435865659d5f28623db9 100644 (file)
@@ -464,9 +464,19 @@ 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 - 1;
+               u32 burst = dep->endpoint.maxburst;
+               u32 nump;
+               u32 reg;
 
-               params.param0 |= DWC3_DEPCFG_BURST_SIZE(burst);
+               /* 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);
        }
 
        if (ignore)