summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2016-04-26 07:49:07 (GMT)
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-04-28 07:47:29 (GMT)
commit676e3497448177bdb1934cbc4402f921730a5864 (patch)
tree608781fab70cfcb53fb9ac8fe13ad80afe1f82cc /drivers/usb/dwc3
parenta6ef3e02542a33fb705e6977221deb0292b27398 (diff)
downloadlinux-676e3497448177bdb1934cbc4402f921730a5864.tar.xz
usb: dwc3: gadget: update DCFG.NumP to max burst size
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>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r--drivers/usb/dwc3/core.h3
-rw-r--r--drivers/usb/dwc3/gadget.c14
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 87df6dd..c5f576a 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -271,6 +271,9 @@
#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 */
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 43efb62..4b681b0 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -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)