]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
usb: xhci: add quirks flag to support MediaTek xHCI 0.96
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Tue, 8 Sep 2020 16:59:57 +0000 (18:59 +0200)
committerMarek Vasut <marex@denx.de>
Thu, 1 Oct 2020 17:43:05 +0000 (19:43 +0200)
There some vendor quirks for MTK xHCI 0.96 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 reserved
   DWs of slot context and endpoint context.
2. 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: Frank Wunderlich <frank-w@public-files.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
drivers/usb/host/xhci-mtk.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
include/usb/xhci.h

index 8ff71854fcdfe0fafe934de6065168f474e39c54..f3f181dae0101645b54a4d61648faa4ef8e2769e 100644 (file)
@@ -258,6 +258,7 @@ static int xhci_mtk_probe(struct udevice *dev)
        if (ret)
                goto ssusb_init_err;
 
+       mtk->ctrl.quirks = XHCI_MTK_HOST;
        hcor = (struct xhci_hcor *)((uintptr_t)mtk->hcd +
                        HC_LENGTH(xhci_readl(&mtk->hcd->cr_capbase)));
 
index 603e0e5b765e8c305f6aef598a56ff4cea3b3aff..3f915ae115e7fc2412302b350fcacaf7434d027d 100644 (file)
@@ -332,7 +332,8 @@ static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
 {
        u32 total_packet_count;
 
-       if (ctrl->hci_version < 0x100)
+       /* MTK xHCI 0.96 contains some features from 1.0 */
+       if (ctrl->hci_version < 0x100 && !(ctrl->quirks & XHCI_MTK_HOST))
                return ((td_total_len - transferred) >> 10);
 
        /* One TRB with a zero-length data packet. */
@@ -340,6 +341,10 @@ static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
            trb_buff_len == td_total_len)
                return 0;
 
+       /* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */
+       if ((ctrl->quirks & XHCI_MTK_HOST) && (ctrl->hci_version < 0x100))
+               trb_buff_len = 0;
+
        total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
 
        /* Queueing functions don't count the current TRB into transferred */
@@ -823,7 +828,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
                field |= 0x1;
 
        /* xHCI 1.0 6.4.1.2.1: Transfer Type field */
-       if (ctrl->hci_version >= 0x100) {
+       if (ctrl->hci_version >= 0x100 || ctrl->quirks & XHCI_MTK_HOST) {
                if (length > 0) {
                        if (req->requesttype & USB_DIR_IN)
                                field |= (TRB_DATA_IN << TRB_TX_TYPE_SHIFT);
index 4be14112435a6b5c007024167bea8e8992397757..51edeb22c1429b6c6eec4eca5d028dd3555266ac 100644 (file)
@@ -650,7 +650,7 @@ static int xhci_set_configuration(struct usb_device *udev)
                 * are put into reserved DWs in Slot and Endpoint Contexts
                 * for synchronous endpoints.
                 */
-               if (IS_ENABLED(CONFIG_USB_XHCI_MTK)) {
+               if (ctrl->quirks & XHCI_MTK_HOST) {
                        ep_ctx[ep_index]->reserved[0] =
                                cpu_to_le32(EP_BPKTS(1) | EP_BBM(1));
                }
index 15926eb9f4dae0c97f135cdc105208556ad1598e..3de46cd95e7810a117645798f03b5d3134d299b6 100644 (file)
@@ -1230,6 +1230,8 @@ struct xhci_ctrl {
        struct xhci_virt_device *devs[MAX_HC_SLOTS];
        int rootdev;
        u16 hci_version;
+       u32 quirks;
+#define XHCI_MTK_HOST          BIT(0)
 };
 
 unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);