diff options
author | Felipe Balbi <felipe.balbi@linux.intel.com> | 2017-01-23 19:01:59 +0300 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2017-01-25 13:49:00 +0300 |
commit | 28781789051ef65ced5dbc40734bfacb5e1e8ea4 (patch) | |
tree | 8fef6c9a46ee8c698135e3c7ea826558400e54ad | |
parent | 3c6aea7344c363f298bfb9952e2906b9574f59dc (diff) | |
download | linux-28781789051ef65ced5dbc40734bfacb5e1e8ea4.tar.xz |
usb: dwc3: gadget: read IN ep FIFO size from HW
Instead of assuming all IN endpoints support 1024
bytes, let's read the actual value from HW and pass
that to gadget API.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0a664d8eba3f..4db97ecae885 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1967,6 +1967,44 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, dep->endpoint.ops = &dwc3_gadget_ep0_ops; if (!epnum) dwc->gadget.ep0 = &dep->endpoint; + } else if (direction) { + int mdwidth; + int size; + int ret; + int num; + + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); + /* MDWIDTH is represented in bits, we need it in bytes */ + mdwidth /= 8; + + size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(i)); + size = DWC3_GTXFIFOSIZ_TXFDEF(size); + + /* FIFO Depth is in MDWDITH bytes. Multiply */ + size *= mdwidth; + + num = size / 1024; + if (num == 0) + num = 1; + + /* + * FIFO sizes account an extra MDWIDTH * (num + 1) bytes for + * internal overhead. We don't really know how these are used, + * but documentation say it exists. + */ + size -= mdwidth * (num + 1); + size /= num; + + 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, + &dwc->gadget.ep_list); + + ret = dwc3_alloc_trb_pool(dep); + if (ret) + return ret; } else { int ret; |