summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@haltian.com>2016-08-12 17:29:35 +0300
committerFelipe Balbi <felipe.balbi@linux.intel.com>2016-08-25 12:13:10 +0300
commit17f6ed62b0dbe58ca9f527d87612de04ed2cce8b (patch)
tree6a4e7354d1e312250390eeb689a0b30be3af64b4 /drivers/usb/gadget
parent1de2ebfb8cd522ad7d0deae94ae47592f975e017 (diff)
downloadlinux-17f6ed62b0dbe58ca9f527d87612de04ed2cce8b.tar.xz
usb: gadget: net2280: match interrupt endpoints to PIO endpoints and DMA to bulk
With composite gadget (ACM + NCM), USB3380 to host TCP transfer speed dropped to 150 Mbit/s compared to 900 Mbit/s with NCM gadget. Problem seems to be that net2280/USB3380 has only four DMA channels and those DMA channels are allocated to first HW endpoints. Endpoint match function was mapping endpoint names directly, so NCM did not get DMA for bulk endpoints. This patch changed match_ep to prefer DMA enabled hw endpoints for bulk usb endpoints and PIO for interrupt usb endpoints. Signed-off-by: Jussi Kivilinna <jussi.kivilinna@haltian.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/udc/net2280.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c
index cd876bff5106..a28eb87078ae 100644
--- a/drivers/usb/gadget/udc/net2280.c
+++ b/drivers/usb/gadget/udc/net2280.c
@@ -1573,6 +1573,44 @@ static struct usb_ep *net2280_match_ep(struct usb_gadget *_gadget,
return ep;
}
+ /* USB3380: Only first four endpoints have DMA channels. Allocate
+ * slower interrupt endpoints from PIO hw endpoints, to allow bulk/isoc
+ * endpoints use DMA hw endpoints.
+ */
+ if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT &&
+ usb_endpoint_dir_in(desc)) {
+ ep = gadget_find_ep_by_name(_gadget, "ep2in");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ ep = gadget_find_ep_by_name(_gadget, "ep4in");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ } else if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_INT &&
+ !usb_endpoint_dir_in(desc)) {
+ ep = gadget_find_ep_by_name(_gadget, "ep1out");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ ep = gadget_find_ep_by_name(_gadget, "ep3out");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ } else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK &&
+ usb_endpoint_dir_in(desc)) {
+ ep = gadget_find_ep_by_name(_gadget, "ep1in");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ ep = gadget_find_ep_by_name(_gadget, "ep3in");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ } else if (usb_endpoint_type(desc) != USB_ENDPOINT_XFER_BULK &&
+ !usb_endpoint_dir_in(desc)) {
+ ep = gadget_find_ep_by_name(_gadget, "ep2out");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ ep = gadget_find_ep_by_name(_gadget, "ep4out");
+ if (ep && usb_gadget_ep_match_desc(_gadget, ep, desc, ep_comp))
+ return ep;
+ }
+
/* USB3380: use same address for usb and hardware endpoints */
snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc),
usb_endpoint_dir_in(desc) ? "in" : "out");