usb: xhci-mtk: use maximum ESIT payload of endpiont context
authorChunfeng Yun <chunfeng.yun@mediatek.com>
Thu, 20 Sep 2018 16:13:31 +0000 (19:13 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2018 13:04:45 +0000 (15:04 +0200)
Make use of maximum ESIT payload of endpoint context to calculate
the number of packets to send in each ESIT

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-mtk-sch.c

index fa33d6e5b1cbd8aaab17c4995088d1b544530530..46fe0a200ca7d03c62ec7a1187e5383782860ac7 100644 (file)
@@ -73,12 +73,17 @@ static void setup_sch_info(struct usb_device *udev,
        u32 max_burst;
        u32 mult;
        u32 esit_pkts;
+       u32 max_esit_payload;
 
        ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
        ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
        max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
        max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
        mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
+       max_esit_payload =
+               (CTX_TO_MAX_ESIT_PAYLOAD_HI(
+                       le32_to_cpu(ep_ctx->ep_info)) << 16) |
+                CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info));
 
        sch_ep->esit = 1 << ep_interval;
        sch_ep->offset = 0;
@@ -105,7 +110,15 @@ static void setup_sch_info(struct usb_device *udev,
        } else if (udev->speed == USB_SPEED_SUPER) {
                /* usb3_r1 spec section4.4.7 & 4.4.8 */
                sch_ep->cs_count = 0;
-               esit_pkts = (mult + 1) * (max_burst + 1);
+               /*
+                * some device's (d)wBytesPerInterval is set as 0,
+                * then max_esit_payload is 0, so evaluate esit_pkts from
+                * mult and burst
+                */
+               esit_pkts = DIV_ROUND_UP(max_esit_payload, max_packet_size);
+               if (esit_pkts == 0)
+                       esit_pkts = (mult + 1) * (max_burst + 1);
+
                if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
                        sch_ep->pkts = esit_pkts;
                        sch_ep->num_budget_microframes = 1;