summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorChunfeng Yun <chunfeng.yun@mediatek.com>2015-11-24 13:09:55 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-01 10:45:51 -0800
commit0cbd4b34cda9dfd36b6c26b692dee181e0100b67 (patch)
tree2e90f0a0e59b8289a3497293b81baead68c4c76f /drivers/usb/host/xhci-ring.c
parentc74732e3c5f02b09ad839238622a8bd4fad75f84 (diff)
downloadlinux-0cbd4b34cda9dfd36b6c26b692dee181e0100b67.tar.bz2
xhci: mediatek: support MTK xHCI host controller
There some vendor quirks for MTK xhci host controller: 1. It defines some extra SW scheduling parameters for HW to minimize the scheduling effort for synchronous and interrupt endpoints. The parameters are put into reseved DWs of slot context and endpoint context. 2. Its IMODI unit for Interrupter Moderation register is 8 times as much as that defined in xHCI spec. 3. Its TDS in Normal TRB defines a number of packets that remains to be transferred for a TD after processing all Max packets in all previous TRBs. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Tested-by: Daniel Thompson <daniel.thompson@linaro.org> Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6c5e8133cf87..8fab75863f1a 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -68,6 +68,7 @@
#include <linux/slab.h>
#include "xhci.h"
#include "xhci-trace.h"
+#include "xhci-mtk.h"
/*
* Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
@@ -3074,17 +3075,22 @@ static u32 xhci_td_remainder(struct xhci_hcd *xhci, int transferred,
{
u32 maxp, total_packet_count;
- if (xhci->hci_version < 0x100)
+ /* MTK xHCI is mostly 0.97 but contains some features from 1.0 */
+ if (xhci->hci_version < 0x100 && !(xhci->quirks & XHCI_MTK_HOST))
return ((td_total_len - transferred) >> 10);
- maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
- total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
-
/* One TRB with a zero-length data packet. */
if (num_trbs_left == 0 || (transferred == 0 && trb_buff_len == 0) ||
trb_buff_len == td_total_len)
return 0;
+ /* for MTK xHCI, TD size doesn't include this TRB */
+ if (xhci->quirks & XHCI_MTK_HOST)
+ trb_buff_len = 0;
+
+ maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+ total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
+
/* Queueing functions don't count the current TRB into transferred */
return (total_packet_count - ((transferred + trb_buff_len) / maxp));
}
@@ -3472,7 +3478,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
field |= 0x1;
/* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */
- if (xhci->hci_version >= 0x100) {
+ if ((xhci->hci_version >= 0x100) || (xhci->quirks & XHCI_MTK_HOST)) {
if (urb->transfer_buffer_length > 0) {
if (setup->bRequestType & USB_DIR_IN)
field |= TRB_TX_TYPE(TRB_DATA_IN);