From patchwork Thu Sep 20 16:13:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607995 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B3E1B15A6 for ; Thu, 20 Sep 2018 16:11:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A26962DEF0 for ; Thu, 20 Sep 2018 16:11:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A03DF2E075; Thu, 20 Sep 2018 16:11:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 315292E05F for ; Thu, 20 Sep 2018 16:11:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732165AbeITVzW (ORCPT ); Thu, 20 Sep 2018 17:55:22 -0400 Received: from mga05.intel.com ([192.55.52.43]:60307 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730484AbeITVyr (ORCPT ); Thu, 20 Sep 2018 17:54:47 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827487" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:35 -0700 From: Mathias Nyman To: Cc: , Chunfeng Yun , Mathias Nyman Subject: [PATCH v2 01/10] usb: xhci-mtk: use maximum ESIT payload of endpiont context Date: Thu, 20 Sep 2018 19:13:31 +0300 Message-Id: <1537460020-1009-2-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chunfeng Yun 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 Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mtk-sch.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index fa33d6e..46fe0a2 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -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; From patchwork Thu Sep 20 16:13:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607993 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4B8DF15A6 for ; Thu, 20 Sep 2018 16:11:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B4D22E057 for ; Thu, 20 Sep 2018 16:11:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 385292DEB1; Thu, 20 Sep 2018 16:11:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C54B92DF0A for ; Thu, 20 Sep 2018 16:11:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730920AbeITVyt (ORCPT ); Thu, 20 Sep 2018 17:54:49 -0400 Received: from mga05.intel.com ([192.55.52.43]:60307 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730915AbeITVyt (ORCPT ); Thu, 20 Sep 2018 17:54:49 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827501" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:37 -0700 From: Mathias Nyman To: Cc: , Chunfeng Yun , Mathias Nyman Subject: [PATCH v2 02/10] usb: xhci-mtk: fix ISOC error when interval is zero Date: Thu, 20 Sep 2018 19:13:32 +0300 Message-Id: <1537460020-1009-3-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chunfeng Yun If the interval equal zero, needn't round up to power of two for the number of packets in each ESIT, so fix it. Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mtk-sch.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 46fe0a2..057f453 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -126,7 +126,9 @@ static void setup_sch_info(struct usb_device *udev, } if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { - if (esit_pkts <= sch_ep->esit) + if (sch_ep->esit == 1) + sch_ep->pkts = esit_pkts; + else if (esit_pkts <= sch_ep->esit) sch_ep->pkts = 1; else sch_ep->pkts = roundup_pow_of_two(esit_pkts) From patchwork Thu Sep 20 16:13:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607977 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 905AA112B for ; Thu, 20 Sep 2018 16:10:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 47A632E03D for ; Thu, 20 Sep 2018 16:10:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 45FAD2DF9D; Thu, 20 Sep 2018 16:10:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB8202DF9D for ; Thu, 20 Sep 2018 16:10:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731019AbeITVyv (ORCPT ); Thu, 20 Sep 2018 17:54:51 -0400 Received: from mga05.intel.com ([192.55.52.43]:60307 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726128AbeITVyv (ORCPT ); Thu, 20 Sep 2018 17:54:51 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827511" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:38 -0700 From: Mathias Nyman To: Cc: , Chunfeng Yun , Mathias Nyman Subject: [PATCH v2 03/10] usb: xhci-mtk: improve bandwidth scheduling Date: Thu, 20 Sep 2018 19:13:33 +0300 Message-Id: <1537460020-1009-4-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chunfeng Yun Mainly improve SuperSpeed ISOC bandwidth in last microframe, and LowSpeed/FullSpeed IN INT/ISOC bandwidth in split and idle microframes by introduing a bandwidth budget table; Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mtk-sch.c | 162 +++++++++++++++++++++++++--------------- drivers/usb/host/xhci-mtk.h | 2 + 2 files changed, 104 insertions(+), 60 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 057f453..7efd890 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -18,6 +18,11 @@ #define HS_BW_BOUNDARY 6144 /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ #define FS_PAYLOAD_MAX 188 +/* + * max number of microframes for split transfer, + * for fs isoc in : 1 ss + 1 idle + 7 cs + */ +#define TT_MICROFRAMES_MAX 9 /* mtk scheduler bitmasks */ #define EP_BPKTS(p) ((p) & 0x3f) @@ -64,20 +69,57 @@ static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, return bw_index; } +static u32 get_esit(struct xhci_ep_ctx *ep_ctx) +{ + u32 esit; + + esit = 1 << CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); + if (esit > XHCI_MTK_MAX_ESIT) + esit = XHCI_MTK_MAX_ESIT; + + return esit; +} + +static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, + struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) +{ + struct mu3h_sch_ep_info *sch_ep; + u32 len_bw_budget_table; + size_t mem_size; + + if (is_fs_or_ls(udev->speed)) + len_bw_budget_table = TT_MICROFRAMES_MAX; + else if ((udev->speed == USB_SPEED_SUPER) + && usb_endpoint_xfer_isoc(&ep->desc)) + len_bw_budget_table = get_esit(ep_ctx); + else + len_bw_budget_table = 1; + + mem_size = sizeof(struct mu3h_sch_ep_info) + + len_bw_budget_table * sizeof(u32); + sch_ep = kzalloc(mem_size, GFP_KERNEL); + if (!sch_ep) + return ERR_PTR(-ENOMEM); + + sch_ep->ep = ep; + + return sch_ep; +} + static void setup_sch_info(struct usb_device *udev, struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) { u32 ep_type; - u32 ep_interval; - u32 max_packet_size; + u32 maxpkt; u32 max_burst; u32 mult; u32 esit_pkts; u32 max_esit_payload; + u32 *bwb_table = sch_ep->bw_budget_table; + int i; 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)); + maxpkt = 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 = @@ -85,9 +127,10 @@ static void setup_sch_info(struct usb_device *udev, 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->esit = get_esit(ep_ctx); sch_ep->offset = 0; sch_ep->burst_mode = 0; + sch_ep->repeat = 0; if (udev->speed == USB_SPEED_HIGH) { sch_ep->cs_count = 0; @@ -98,7 +141,6 @@ static void setup_sch_info(struct usb_device *udev, * in a interval */ sch_ep->num_budget_microframes = 1; - sch_ep->repeat = 0; /* * xHCI spec section6.2.3.4 @@ -106,26 +148,30 @@ static void setup_sch_info(struct usb_device *udev, * opportunities per microframe */ sch_ep->pkts = max_burst + 1; - sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; + sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; + bwb_table[0] = sch_ep->bw_cost_per_microframe; } else if (udev->speed == USB_SPEED_SUPER) { /* usb3_r1 spec section4.4.7 & 4.4.8 */ sch_ep->cs_count = 0; + sch_ep->burst_mode = 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); + esit_pkts = DIV_ROUND_UP(max_esit_payload, maxpkt); 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; - sch_ep->repeat = 0; + bwb_table[0] = maxpkt * sch_ep->pkts; } if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { + u32 remainder; + if (sch_ep->esit == 1) sch_ep->pkts = esit_pkts; else if (esit_pkts <= sch_ep->esit) @@ -137,43 +183,37 @@ static void setup_sch_info(struct usb_device *udev, sch_ep->num_budget_microframes = DIV_ROUND_UP(esit_pkts, sch_ep->pkts); - if (sch_ep->num_budget_microframes > 1) - sch_ep->repeat = 1; - else - sch_ep->repeat = 0; + sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); + sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; + + remainder = sch_ep->bw_cost_per_microframe; + remainder *= sch_ep->num_budget_microframes; + remainder -= (maxpkt * esit_pkts); + for (i = 0; i < sch_ep->num_budget_microframes - 1; i++) + bwb_table[i] = sch_ep->bw_cost_per_microframe; + + /* last one <= bw_cost_per_microframe */ + bwb_table[i] = remainder; } - sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; } else if (is_fs_or_ls(udev->speed)) { - - /* - * usb_20 spec section11.18.4 - * assume worst cases - */ - sch_ep->repeat = 0; sch_ep->pkts = 1; /* at most one packet for each microframe */ - if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { - sch_ep->cs_count = 3; /* at most need 3 CS*/ - /* one for SS and one for budgeted transaction */ - sch_ep->num_budget_microframes = sch_ep->cs_count + 2; - sch_ep->bw_cost_per_microframe = max_packet_size; - } - if (ep_type == ISOC_OUT_EP) { + sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); + sch_ep->num_budget_microframes = sch_ep->cs_count + 2; + sch_ep->bw_cost_per_microframe = + (maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX; - /* - * the best case FS budget assumes that 188 FS bytes - * occur in each microframe - */ - sch_ep->num_budget_microframes = DIV_ROUND_UP( - max_packet_size, FS_PAYLOAD_MAX); - sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; - sch_ep->cs_count = sch_ep->num_budget_microframes; - } - if (ep_type == ISOC_IN_EP) { - /* at most need additional two CS. */ - sch_ep->cs_count = DIV_ROUND_UP( - max_packet_size, FS_PAYLOAD_MAX) + 2; - sch_ep->num_budget_microframes = sch_ep->cs_count + 2; - sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; + /* init budget table */ + if (ep_type == ISOC_OUT_EP) { + for (i = 0; i < sch_ep->num_budget_microframes; i++) + bwb_table[i] = sch_ep->bw_cost_per_microframe; + } else if (ep_type == INT_OUT_EP) { + /* only first one consumes bandwidth, others as zero */ + bwb_table[0] = sch_ep->bw_cost_per_microframe; + } else { /* INT_IN_EP or ISOC_IN_EP */ + bwb_table[0] = 0; /* start split */ + bwb_table[1] = 0; /* idle */ + for (i = 2; i < sch_ep->num_budget_microframes; i++) + bwb_table[i] = sch_ep->bw_cost_per_microframe; } } } @@ -184,6 +224,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, { u32 num_esit; u32 max_bw = 0; + u32 bw; int i; int j; @@ -192,15 +233,17 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, u32 base = offset + i * sch_ep->esit; for (j = 0; j < sch_ep->num_budget_microframes; j++) { - if (sch_bw->bus_bw[base + j] > max_bw) - max_bw = sch_bw->bus_bw[base + j]; + bw = sch_bw->bus_bw[base + j] + + sch_ep->bw_budget_table[j]; + if (bw > max_bw) + max_bw = bw; } } return max_bw; } static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, - struct mu3h_sch_ep_info *sch_ep, int bw_cost) + struct mu3h_sch_ep_info *sch_ep, bool used) { u32 num_esit; u32 base; @@ -210,8 +253,14 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; for (i = 0; i < num_esit; i++) { base = sch_ep->offset + i * sch_ep->esit; - for (j = 0; j < sch_ep->num_budget_microframes; j++) - sch_bw->bus_bw[base + j] += bw_cost; + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + if (used) + sch_bw->bus_bw[base + j] += + sch_ep->bw_budget_table[j]; + else + sch_bw->bus_bw[base + j] -= + sch_ep->bw_budget_table[j]; + } } } @@ -220,17 +269,12 @@ static int check_sch_bw(struct usb_device *udev, { u32 offset; u32 esit; - u32 num_budget_microframes; u32 min_bw; u32 min_index; u32 worst_bw; u32 bw_boundary; - if (sch_ep->esit > XHCI_MTK_MAX_ESIT) - sch_ep->esit = XHCI_MTK_MAX_ESIT; - esit = sch_ep->esit; - num_budget_microframes = sch_ep->num_budget_microframes; /* * Search through all possible schedule microframes. @@ -239,7 +283,7 @@ static int check_sch_bw(struct usb_device *udev, min_bw = ~0; min_index = 0; for (offset = 0; offset < esit; offset++) { - if ((offset + num_budget_microframes) > sch_ep->esit) + if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit) break; /* @@ -263,11 +307,11 @@ static int check_sch_bw(struct usb_device *udev, ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; /* check bandwidth */ - if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary) + if (min_bw > bw_boundary) return -ERANGE; /* update bus bandwidth info */ - update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe); + update_bus_bw(sch_bw, sch_ep, 1); return 0; } @@ -362,8 +406,8 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, bw_index = get_bw_index(xhci, udev, ep); sch_bw = &sch_array[bw_index]; - sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO); - if (!sch_ep) + sch_ep = create_sch_ep(udev, ep, ep_ctx); + if (IS_ERR_OR_NULL(sch_ep)) return -ENOMEM; setup_sch_info(udev, ep_ctx, sch_ep); @@ -376,7 +420,6 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, } list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); - sch_ep->ep = ep; ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); @@ -421,8 +464,7 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { if (sch_ep->ep == ep) { - update_bus_bw(sch_bw, sch_ep, - -sch_ep->bw_cost_per_microframe); + update_bus_bw(sch_bw, sch_ep, 0); list_del(&sch_ep->endpoint); kfree(sch_ep); break; diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index cc59d80..f8864fc 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -57,6 +57,7 @@ struct mu3h_sch_bw_info { * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets * according to @pkts and @repeat. normal mode is used by * default + * @bw_budget_table: table to record bandwidth budget per microframe */ struct mu3h_sch_ep_info { u32 esit; @@ -73,6 +74,7 @@ struct mu3h_sch_ep_info { u32 pkts; u32 cs_count; u32 burst_mode; + u32 bw_budget_table[0]; }; #define MU3C_U3_PORT_MAX 4 From patchwork Thu Sep 20 16:13:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607981 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB1FC17EE for ; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A730E2E001 for ; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4A502DF3C; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 950462E04F for ; Thu, 20 Sep 2018 16:10:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731163AbeITVyx (ORCPT ); Thu, 20 Sep 2018 17:54:53 -0400 Received: from mga05.intel.com ([192.55.52.43]:60307 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731009AbeITVyx (ORCPT ); Thu, 20 Sep 2018 17:54:53 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827525" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:40 -0700 From: Mathias Nyman To: Cc: , Chunfeng Yun , Mathias Nyman Subject: [PATCH v2 04/10] usb: xhci-mtk: supports bandwidth scheduling with multi-TT Date: Thu, 20 Sep 2018 19:13:34 +0300 Message-Id: <1537460020-1009-5-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chunfeng Yun Supports LowSpeed and FullSpeed INT/ISOC bandwidth scheduling with USB multi-TT Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mtk-sch.c | 247 ++++++++++++++++++++++++++++++++++++++-- drivers/usb/host/xhci-mtk.h | 21 ++++ 2 files changed, 258 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 7efd890..36050a1 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -80,10 +80,98 @@ static u32 get_esit(struct xhci_ep_ctx *ep_ctx) return esit; } +static struct mu3h_sch_tt *find_tt(struct usb_device *udev) +{ + struct usb_tt *utt = udev->tt; + struct mu3h_sch_tt *tt, **tt_index, **ptt; + unsigned int port; + bool allocated_index = false; + + if (!utt) + return NULL; /* Not below a TT */ + + /* + * Find/create our data structure. + * For hubs with a single TT, we get it directly. + * For hubs with multiple TTs, there's an extra level of pointers. + */ + tt_index = NULL; + if (utt->multi) { + tt_index = utt->hcpriv; + if (!tt_index) { /* Create the index array */ + tt_index = kcalloc(utt->hub->maxchild, + sizeof(*tt_index), GFP_KERNEL); + if (!tt_index) + return ERR_PTR(-ENOMEM); + utt->hcpriv = tt_index; + allocated_index = true; + } + port = udev->ttport - 1; + ptt = &tt_index[port]; + } else { + port = 0; + ptt = (struct mu3h_sch_tt **) &utt->hcpriv; + } + + tt = *ptt; + if (!tt) { /* Create the mu3h_sch_tt */ + tt = kzalloc(sizeof(*tt), GFP_KERNEL); + if (!tt) { + if (allocated_index) { + utt->hcpriv = NULL; + kfree(tt_index); + } + return ERR_PTR(-ENOMEM); + } + INIT_LIST_HEAD(&tt->ep_list); + tt->usb_tt = utt; + tt->tt_port = port; + *ptt = tt; + } + + return tt; +} + +/* Release the TT above udev, if it's not in use */ +static void drop_tt(struct usb_device *udev) +{ + struct usb_tt *utt = udev->tt; + struct mu3h_sch_tt *tt, **tt_index, **ptt; + int i, cnt; + + if (!utt || !utt->hcpriv) + return; /* Not below a TT, or never allocated */ + + cnt = 0; + if (utt->multi) { + tt_index = utt->hcpriv; + ptt = &tt_index[udev->ttport - 1]; + /* How many entries are left in tt_index? */ + for (i = 0; i < utt->hub->maxchild; ++i) + cnt += !!tt_index[i]; + } else { + tt_index = NULL; + ptt = (struct mu3h_sch_tt **)&utt->hcpriv; + } + + tt = *ptt; + if (!tt || !list_empty(&tt->ep_list)) + return; /* never allocated , or still in use*/ + + *ptt = NULL; + kfree(tt); + + if (cnt == 1) { + utt->hcpriv = NULL; + kfree(tt_index); + } +} + static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) { struct mu3h_sch_ep_info *sch_ep; + struct mu3h_sch_tt *tt = NULL; u32 len_bw_budget_table; size_t mem_size; @@ -101,6 +189,15 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, if (!sch_ep) return ERR_PTR(-ENOMEM); + if (is_fs_or_ls(udev->speed)) { + tt = find_tt(udev); + if (IS_ERR(tt)) { + kfree(sch_ep); + return ERR_PTR(-ENOMEM); + } + } + + sch_ep->sch_tt = tt; sch_ep->ep = ep; return sch_ep; @@ -128,6 +225,8 @@ static void setup_sch_info(struct usb_device *udev, CTX_TO_MAX_ESIT_PAYLOAD(le32_to_cpu(ep_ctx->tx_info)); sch_ep->esit = get_esit(ep_ctx); + sch_ep->ep_type = ep_type; + sch_ep->maxpkt = maxpkt; sch_ep->offset = 0; sch_ep->burst_mode = 0; sch_ep->repeat = 0; @@ -197,8 +296,13 @@ static void setup_sch_info(struct usb_device *udev, } } else if (is_fs_or_ls(udev->speed)) { sch_ep->pkts = 1; /* at most one packet for each microframe */ + + /* + * num_budget_microframes and cs_count will be updated when + * check TT for INT_OUT_EP, ISOC/INT_IN_EP type + */ sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); - sch_ep->num_budget_microframes = sch_ep->cs_count + 2; + sch_ep->num_budget_microframes = sch_ep->cs_count; sch_ep->bw_cost_per_microframe = (maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX; @@ -212,7 +316,13 @@ static void setup_sch_info(struct usb_device *udev, } else { /* INT_IN_EP or ISOC_IN_EP */ bwb_table[0] = 0; /* start split */ bwb_table[1] = 0; /* idle */ - for (i = 2; i < sch_ep->num_budget_microframes; i++) + /* + * due to cs_count will be updated according to cs + * position, assign all remainder budget array + * elements as @bw_cost_per_microframe, but only first + * @num_budget_microframes elements will be used later + */ + for (i = 2; i < TT_MICROFRAMES_MAX; i++) bwb_table[i] = sch_ep->bw_cost_per_microframe; } } @@ -264,6 +374,96 @@ static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, } } +static int check_sch_tt(struct usb_device *udev, + struct mu3h_sch_ep_info *sch_ep, u32 offset) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u32 extra_cs_count; + u32 fs_budget_start; + u32 start_ss, last_ss; + u32 start_cs, last_cs; + int i; + + start_ss = offset % 8; + fs_budget_start = (start_ss + 1) % 8; + + if (sch_ep->ep_type == ISOC_OUT_EP) { + last_ss = start_ss + sch_ep->cs_count - 1; + + /* + * usb_20 spec section11.18: + * must never schedule Start-Split in Y6 + */ + if (!(start_ss == 7 || last_ss < 6)) + return -ERANGE; + + for (i = 0; i < sch_ep->cs_count; i++) + if (test_bit(offset + i, tt->split_bit_map)) + return -ERANGE; + + } else { + u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); + + /* + * usb_20 spec section11.18: + * must never schedule Start-Split in Y6 + */ + if (start_ss == 6) + return -ERANGE; + + /* one uframe for ss + one uframe for idle */ + start_cs = (start_ss + 2) % 8; + last_cs = start_cs + cs_count - 1; + + if (last_cs > 7) + return -ERANGE; + + if (sch_ep->ep_type == ISOC_IN_EP) + extra_cs_count = (last_cs == 7) ? 1 : 2; + else /* ep_type : INTR IN / INTR OUT */ + extra_cs_count = (fs_budget_start == 6) ? 1 : 2; + + cs_count += extra_cs_count; + if (cs_count > 7) + cs_count = 7; /* HW limit */ + + for (i = 0; i < cs_count + 2; i++) { + if (test_bit(offset + i, tt->split_bit_map)) + return -ERANGE; + } + + sch_ep->cs_count = cs_count; + /* one for ss, the other for idle */ + sch_ep->num_budget_microframes = cs_count + 2; + + /* + * if interval=1, maxp >752, num_budge_micoframe is larger + * than sch_ep->esit, will overstep boundary + */ + if (sch_ep->num_budget_microframes > sch_ep->esit) + sch_ep->num_budget_microframes = sch_ep->esit; + } + + return 0; +} + +static void update_sch_tt(struct usb_device *udev, + struct mu3h_sch_ep_info *sch_ep) +{ + struct mu3h_sch_tt *tt = sch_ep->sch_tt; + u32 base, num_esit; + int i, j; + + num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; + for (i = 0; i < num_esit; i++) { + base = sch_ep->offset + i * sch_ep->esit; + for (j = 0; j < sch_ep->num_budget_microframes; j++) + set_bit(base + j, tt->split_bit_map); + } + + list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); +} + static int check_sch_bw(struct usb_device *udev, struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) { @@ -273,6 +473,10 @@ static int check_sch_bw(struct usb_device *udev, u32 min_index; u32 worst_bw; u32 bw_boundary; + u32 min_num_budget; + u32 min_cs_count; + bool tt_offset_ok = false; + int ret; esit = sch_ep->esit; @@ -282,26 +486,30 @@ static int check_sch_bw(struct usb_device *udev, */ min_bw = ~0; min_index = 0; + min_cs_count = sch_ep->cs_count; + min_num_budget = sch_ep->num_budget_microframes; for (offset = 0; offset < esit; offset++) { + if (is_fs_or_ls(udev->speed)) { + ret = check_sch_tt(udev, sch_ep, offset); + if (ret) + continue; + else + tt_offset_ok = true; + } + if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit) break; - /* - * usb_20 spec section11.18: - * must never schedule Start-Split in Y6 - */ - if (is_fs_or_ls(udev->speed) && (offset % 8 == 6)) - continue; - worst_bw = get_max_bw(sch_bw, sch_ep, offset); if (min_bw > worst_bw) { min_bw = worst_bw; min_index = offset; + min_cs_count = sch_ep->cs_count; + min_num_budget = sch_ep->num_budget_microframes; } if (min_bw == 0) break; } - sch_ep->offset = min_index; bw_boundary = (udev->speed == USB_SPEED_SUPER) ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; @@ -310,6 +518,18 @@ static int check_sch_bw(struct usb_device *udev, if (min_bw > bw_boundary) return -ERANGE; + sch_ep->offset = min_index; + sch_ep->cs_count = min_cs_count; + sch_ep->num_budget_microframes = min_num_budget; + + if (is_fs_or_ls(udev->speed)) { + /* all offset for tt is not ok*/ + if (!tt_offset_ok) + return -ERANGE; + + update_sch_tt(udev, sch_ep); + } + /* update bus bandwidth info */ update_bus_bw(sch_bw, sch_ep, 1); @@ -415,6 +635,9 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ret = check_sch_bw(udev, sch_bw, sch_ep); if (ret) { xhci_err(xhci, "Not enough bandwidth!\n"); + if (is_fs_or_ls(udev->speed)) + drop_tt(udev); + kfree(sch_ep); return -ENOSPC; } @@ -466,6 +689,10 @@ void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, if (sch_ep->ep == ep) { update_bus_bw(sch_bw, sch_ep, 0); list_del(&sch_ep->endpoint); + if (is_fs_or_ls(udev->speed)) { + list_del(&sch_ep->tt_endpoint); + drop_tt(udev); + } kfree(sch_ep); break; } diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index f8864fc..8be8c5f 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -20,6 +20,19 @@ #define XHCI_MTK_MAX_ESIT 64 /** + * @split_bit_map: used to avoid split microframes overlay + * @ep_list: Endpoints using this TT + * @usb_tt: usb TT related + * @tt_port: TT port number + */ +struct mu3h_sch_tt { + DECLARE_BITMAP(split_bit_map, XHCI_MTK_MAX_ESIT); + struct list_head ep_list; + struct usb_tt *usb_tt; + int tt_port; +}; + +/** * struct mu3h_sch_bw_info: schedule information for bandwidth domain * * @bus_bw: array to keep track of bandwidth already used at each uframes @@ -41,6 +54,10 @@ struct mu3h_sch_bw_info { * (@repeat==1) scheduled within the interval * @bw_cost_per_microframe: bandwidth cost per microframe * @endpoint: linked into bandwidth domain which it belongs to + * @tt_endpoint: linked into mu3h_sch_tt's list which it belongs to + * @sch_tt: mu3h_sch_tt linked into + * @ep_type: endpoint type + * @maxpkt: max packet size of endpoint * @ep: address of usb_host_endpoint struct * @offset: which uframe of the interval that transfer should be * scheduled first time within the interval @@ -64,6 +81,10 @@ struct mu3h_sch_ep_info { u32 num_budget_microframes; u32 bw_cost_per_microframe; struct list_head endpoint; + struct list_head tt_endpoint; + struct mu3h_sch_tt *sch_tt; + u32 ep_type; + u32 maxpkt; void *ep; /* * mtk xHCI scheduling information put into reserved DWs From patchwork Thu Sep 20 16:13:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607979 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80813161F for ; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E02D2DFCA for ; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6B65F2DF95; Thu, 20 Sep 2018 16:10:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF0F52DF48 for ; Thu, 20 Sep 2018 16:10:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731376AbeITVyz (ORCPT ); Thu, 20 Sep 2018 17:54:55 -0400 Received: from mga05.intel.com ([192.55.52.43]:60307 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731009AbeITVyy (ORCPT ); Thu, 20 Sep 2018 17:54:54 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827544" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:42 -0700 From: Mathias Nyman To: Cc: , Chunfeng Yun , Mathias Nyman Subject: [PATCH v2 05/10] usb: xhci-mtk: supports SSP without external USB3 gen2 hub Date: Thu, 20 Sep 2018 19:13:35 +0300 Message-Id: <1537460020-1009-6-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chunfeng Yun Supports SSP scheduling only for SSP device directly connected to root hub but not through external USB3 gen2 hub which need use a new scheduling way. Signed-off-by: Chunfeng Yun Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mtk-sch.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 36050a1..fea5555 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -13,6 +13,7 @@ #include "xhci.h" #include "xhci-mtk.h" +#define SSP_BW_BOUNDARY 130000 #define SS_BW_BOUNDARY 51000 /* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */ #define HS_BW_BOUNDARY 6144 @@ -25,7 +26,7 @@ #define TT_MICROFRAMES_MAX 9 /* mtk scheduler bitmasks */ -#define EP_BPKTS(p) ((p) & 0x3f) +#define EP_BPKTS(p) ((p) & 0x7f) #define EP_BCSCOUNT(p) (((p) & 0x7) << 8) #define EP_BBM(p) ((p) << 11) #define EP_BOFFSET(p) ((p) & 0x3fff) @@ -56,7 +57,7 @@ static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, virt_dev = xhci->devs[udev->slot_id]; - if (udev->speed == USB_SPEED_SUPER) { + if (udev->speed >= USB_SPEED_SUPER) { if (usb_endpoint_dir_out(&ep->desc)) bw_index = (virt_dev->real_port - 1) * 2; else @@ -177,7 +178,7 @@ static struct mu3h_sch_ep_info *create_sch_ep(struct usb_device *udev, if (is_fs_or_ls(udev->speed)) len_bw_budget_table = TT_MICROFRAMES_MAX; - else if ((udev->speed == USB_SPEED_SUPER) + else if ((udev->speed >= USB_SPEED_SUPER) && usb_endpoint_xfer_isoc(&ep->desc)) len_bw_budget_table = get_esit(ep_ctx); else @@ -249,7 +250,7 @@ static void setup_sch_info(struct usb_device *udev, sch_ep->pkts = max_burst + 1; sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; bwb_table[0] = sch_ep->bw_cost_per_microframe; - } else if (udev->speed == USB_SPEED_SUPER) { + } else if (udev->speed >= USB_SPEED_SUPER) { /* usb3_r1 spec section4.4.7 & 4.4.8 */ sch_ep->cs_count = 0; sch_ep->burst_mode = 1; @@ -511,8 +512,12 @@ static int check_sch_bw(struct usb_device *udev, break; } - bw_boundary = (udev->speed == USB_SPEED_SUPER) - ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; + if (udev->speed == USB_SPEED_SUPER_PLUS) + bw_boundary = SSP_BW_BOUNDARY; + else if (udev->speed == USB_SPEED_SUPER) + bw_boundary = SS_BW_BOUNDARY; + else + bw_boundary = HS_BW_BOUNDARY; /* check bandwidth */ if (min_bw > bw_boundary) From patchwork Thu Sep 20 16:13:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607989 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 803AF6CB for ; Thu, 20 Sep 2018 16:11:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 942042E09D for ; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 918BB2E09E; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 36A112E096 for ; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732158AbeITVzM (ORCPT ); Thu, 20 Sep 2018 17:55:12 -0400 Received: from mga01.intel.com ([192.55.52.88]:60871 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731996AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827560" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:43 -0700 From: Mathias Nyman To: Cc: , Peter Chen , Mathias Nyman Subject: [PATCH v2 06/10] usb: host: xhci-plat: add platform TPL support Date: Thu, 20 Sep 2018 19:13:36 +0300 Message-Id: <1537460020-1009-7-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Peter Chen The TPL support is used to identify targeted devices during EH2.0 and EH3.0 certification test, the user can add "tpl-support" at dts to enable this feature. Signed-off-by: Peter Chen Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-plat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 94e9392..32b5574 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "xhci.h" #include "xhci-plat.h" @@ -305,6 +306,8 @@ static int xhci_plat_probe(struct platform_device *pdev) hcd->skip_phy_initialization = 1; } + hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); + xhci->shared_hcd->tpl_support = hcd->tpl_support; ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_usb_phy; From patchwork Thu Sep 20 16:13:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607983 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C04E6CB for ; Thu, 20 Sep 2018 16:11:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B558E2DF84 for ; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B33422E07C; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EF1C2E079 for ; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732095AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 Received: from mga01.intel.com ([192.55.52.88]:60871 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727476AbeITVzJ (ORCPT ); Thu, 20 Sep 2018 17:55:09 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827590" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:45 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH v2 07/10] xhci: Use soft retry to recover faster from transaction errors Date: Thu, 20 Sep 2018 19:13:37 +0300 Message-Id: <1537460020-1009-8-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use soft retry to recover from a USB Transaction Errors that are caused by temporary error conditions. The USB device is not aware that the xHC has halted the endpoint, and will be waiting for another retry A Soft Retry perform additional retries and recover from an error which has caused the xHC to halt an endpoint. Soft retry has some limitations: Soft Retry attempts shall not be performed on Isoch endpoints Soft Retry attempts shall not be performed if the device is behind a TT in a HS Hub Software shall limit the number of unsuccessful Soft Retry attempts to prevent an infinite loop. For more details on Soft retry see xhci specs 4.6.8.1 Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 19 +++++++++++++++++++ drivers/usb/host/xhci.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f0a99aa..c41341e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1155,6 +1155,10 @@ static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, /* Clear our internal halted state */ xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_HALTED; } + + /* if this was a soft reset, then restart */ + if ((le32_to_cpu(trb->generic.field[3])) & TRB_TSP) + ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id, @@ -2132,10 +2136,16 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, union xhci_trb *ep_trb, struct xhci_transfer_event *event, struct xhci_virt_ep *ep, int *status) { + struct xhci_slot_ctx *slot_ctx; struct xhci_ring *ep_ring; u32 trb_comp_code; u32 remaining, requested, ep_trb_len; + unsigned int slot_id; + int ep_index; + slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); + slot_ctx = xhci_get_slot_ctx(xhci, xhci->devs[slot_id]->out_ctx); + ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); @@ -2144,6 +2154,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, switch (trb_comp_code) { case COMP_SUCCESS: + ep_ring->err_count = 0; /* handle success with untransferred data as short packet */ if (ep_trb != td->last_trb || remaining) { xhci_warn(xhci, "WARN Successful completion on short TX\n"); @@ -2167,6 +2178,14 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, ep_trb_len = 0; remaining = 0; break; + case COMP_USB_TRANSACTION_ERROR: + if ((ep_ring->err_count++ > MAX_SOFT_RETRY) || + le32_to_cpu(slot_ctx->tt_info) & TT_SLOT) + break; + *status = 0; + xhci_cleanup_halted_endpoint(xhci, slot_id, ep_index, + ep_ring->stream_id, td, EP_SOFT_RESET); + return 0; default: /* do nothing */ break; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 6230a57..b635785 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1496,6 +1496,7 @@ static inline const char *xhci_trb_type_string(u8 type) /* How much data is left before the 64KB boundary? */ #define TRB_BUFF_LEN_UP_TO_BOUNDARY(addr) (TRB_MAX_BUFF_SIZE - \ (addr & (TRB_MAX_BUFF_SIZE - 1))) +#define MAX_SOFT_RETRY 3 struct xhci_segment { union xhci_trb *trbs; @@ -1583,6 +1584,7 @@ struct xhci_ring { * if we own the TRB (if we are the consumer). See section 4.9.1. */ u32 cycle_state; + unsigned int err_count; unsigned int stream_id; unsigned int num_segs; unsigned int num_trbs_free; From patchwork Thu Sep 20 16:13:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607987 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC7AC6CB for ; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 31A4D2DEB1 for ; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 259632E02D; Thu, 20 Sep 2018 16:11:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 88BBF2E057 for ; Thu, 20 Sep 2018 16:11:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732037AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 Received: from mga01.intel.com ([192.55.52.88]:60871 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731992AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827603" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:47 -0700 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH v2 08/10] xhci-pci: allow host runtime PM as default for Intel Alpine and Titan Ridge Date: Thu, 20 Sep 2018 19:13:38 +0300 Message-Id: <1537460020-1009-9-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The xhci controller on Alpine and Titan Ridge keeps the whole thunderbolt awake if the host controller is not allowed tp sleep. This is the case even if no USB devices are connected to the host. Because of this bigger impact, allow runtime pm as default for these xhci controllers in the driver. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-pci.c | 24 ++++++++++++++++++++++++ drivers/usb/host/xhci.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 6372edf..9433e70 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -41,6 +41,13 @@ #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8 #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 +#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI 0x15b5 +#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI 0x15b6 +#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_XHCI 0x15db +#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_XHCI 0x15d4 +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_XHCI 0x15e9 +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI 0x15ec +#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI 0x15f0 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba @@ -189,6 +196,16 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) xhci->quirks |= XHCI_MISSING_CAS; + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + (pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI)) + xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_EJ168) { xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -332,6 +349,9 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ pm_runtime_put_noidle(&dev->dev); + if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) + pm_runtime_allow(&dev->dev); + return 0; put_usb3_hcd: @@ -349,6 +369,10 @@ static void xhci_pci_remove(struct pci_dev *dev) xhci = hcd_to_xhci(pci_get_drvdata(dev)); xhci->xhc_state |= XHCI_STATE_REMOVING; + + if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) + pm_runtime_forbid(&dev->dev); + if (xhci->shared_hcd) { usb_remove_hcd(xhci->shared_hcd); usb_put_hcd(xhci->shared_hcd); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index b635785..bf0b369 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1848,6 +1848,7 @@ struct xhci_hcd { #define XHCI_SUSPEND_DELAY BIT_ULL(30) #define XHCI_INTEL_USB_ROLE_SW BIT_ULL(31) #define XHCI_ZERO_64B_REGS BIT_ULL(32) +#define XHCI_DEFAULT_PM_RUNTIME_ALLOW BIT_ULL(33) unsigned int num_active_eps; unsigned int limit_active_eps; From patchwork Thu Sep 20 16:13:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607991 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E15115A6 for ; Thu, 20 Sep 2018 16:11:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 747432E04D for ; Thu, 20 Sep 2018 16:11:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 73B382E089; Thu, 20 Sep 2018 16:11:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFB762DF48 for ; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732112AbeITVzL (ORCPT ); Thu, 20 Sep 2018 17:55:11 -0400 Received: from mga01.intel.com ([192.55.52.88]:60871 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731992AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827614" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:48 -0700 From: Mathias Nyman To: Cc: , Thierry Reding , Mathias Nyman Subject: [PATCH v2 09/10] usb: xhci: tegra: Firmware header is little endian Date: Thu, 20 Sep 2018 19:13:39 +0300 Message-Id: <1537460020-1009-10-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding The XUSB firmware header is in little endian byte order, so make the fields __le32 and __le16 instead of u32 and u16 to avoid warnings from sparse when the fields are used with the endian-aware __le32_to_cpu() and __le16_to_cpu() accessors, respectively. Signed-off-by: Thierry Reding Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-tegra.c | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 4b463e5..4ee510a 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -107,35 +107,35 @@ #define IMEM_BLOCK_SIZE 256 struct tegra_xusb_fw_header { - u32 boot_loadaddr_in_imem; - u32 boot_codedfi_offset; - u32 boot_codetag; - u32 boot_codesize; - u32 phys_memaddr; - u16 reqphys_memsize; - u16 alloc_phys_memsize; - u32 rodata_img_offset; - u32 rodata_section_start; - u32 rodata_section_end; - u32 main_fnaddr; - u32 fwimg_cksum; - u32 fwimg_created_time; - u32 imem_resident_start; - u32 imem_resident_end; - u32 idirect_start; - u32 idirect_end; - u32 l2_imem_start; - u32 l2_imem_end; - u32 version_id; + __le32 boot_loadaddr_in_imem; + __le32 boot_codedfi_offset; + __le32 boot_codetag; + __le32 boot_codesize; + __le32 phys_memaddr; + __le16 reqphys_memsize; + __le16 alloc_phys_memsize; + __le32 rodata_img_offset; + __le32 rodata_section_start; + __le32 rodata_section_end; + __le32 main_fnaddr; + __le32 fwimg_cksum; + __le32 fwimg_created_time; + __le32 imem_resident_start; + __le32 imem_resident_end; + __le32 idirect_start; + __le32 idirect_end; + __le32 l2_imem_start; + __le32 l2_imem_end; + __le32 version_id; u8 init_ddirect; u8 reserved[3]; - u32 phys_addr_log_buffer; - u32 total_log_entries; - u32 dequeue_ptr; - u32 dummy_var[2]; - u32 fwimg_len; + __le32 phys_addr_log_buffer; + __le32 total_log_entries; + __le32 dequeue_ptr; + __le32 dummy_var[2]; + __le32 fwimg_len; u8 magic[8]; - u32 ss_low_power_entry_timeout; + __le32 ss_low_power_entry_timeout; u8 num_hsic_port; u8 padding[139]; /* Pad to 256 bytes */ }; From patchwork Thu Sep 20 16:13:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 10607985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5F51F161F for ; Thu, 20 Sep 2018 16:11:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D8FE32E004 for ; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D73922DF48; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 66C7D2E083 for ; Thu, 20 Sep 2018 16:11:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732080AbeITVzK (ORCPT ); Thu, 20 Sep 2018 17:55:10 -0400 Received: from mga11.intel.com ([192.55.52.93]:47558 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731009AbeITVzJ (ORCPT ); Thu, 20 Sep 2018 17:55:09 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Sep 2018 09:10:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,399,1531810800"; d="scan'208";a="91827671" Received: from mattu-haswell.fi.intel.com ([10.237.72.164]) by fmsmga001.fm.intel.com with ESMTP; 20 Sep 2018 09:10:50 -0700 From: Mathias Nyman To: Cc: , Anshuman Gupta , Mathias Nyman Subject: [PATCH v2 10/10] xhci: Avoid USB autosuspend when resuming USB2 ports. Date: Thu, 20 Sep 2018 19:13:40 +0300 Message-Id: <1537460020-1009-11-git-send-email-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> References: <1537460020-1009-1-git-send-email-mathias.nyman@linux.intel.com> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Anshuman Gupta When USB bus host controller root hub resumes from autosuspend, it immediately tries to enter auto-suspend, but there can be a scenario when root hub is resuming its usb2 ports, in that particular case USB host controller auto suspend fails since it is busy to resuming its usb2 ports. This makes multiple failed cycles of auto-suspend until all usb2 ports of host controller root hub do not resume. This patch uses USB core framework usb_hcd_start_port_resume, usb_hcd_end_port_resume API's in order to autoresume/autosuspend root hub properly. Signed-off-by: Anshuman Gupta Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-hub.c | 5 +++++ drivers/usb/host/xhci-ring.c | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 7e2a531..12eea73 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -900,6 +900,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, set_bit(wIndex, &bus_state->resuming_ports); bus_state->resume_done[wIndex] = timeout; mod_timer(&hcd->rh_timer, timeout); + usb_hcd_start_port_resume(&hcd->self, wIndex); } /* Has resume been signalled for USB_RESUME_TIME yet? */ } else if (time_after_eq(jiffies, @@ -940,6 +941,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, clear_bit(wIndex, &bus_state->rexit_ports); } + usb_hcd_end_port_resume(&hcd->self, wIndex); bus_state->port_c_suspend |= 1 << wIndex; bus_state->suspended_ports &= ~(1 << wIndex); } else { @@ -962,6 +964,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, (raw_port_status & PORT_PLS_MASK) != XDEV_RESUME) { bus_state->resume_done[wIndex] = 0; clear_bit(wIndex, &bus_state->resuming_ports); + usb_hcd_end_port_resume(&hcd->self, wIndex); } @@ -1337,6 +1340,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; set_bit(wIndex, &bus_state->resuming_ports); + usb_hcd_start_port_resume(&hcd->self, wIndex); xhci_set_link_state(xhci, ports[wIndex], XDEV_RESUME); spin_unlock_irqrestore(&xhci->lock, flags); @@ -1345,6 +1349,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, xhci_set_link_state(xhci, ports[wIndex], XDEV_U0); clear_bit(wIndex, &bus_state->resuming_ports); + usb_hcd_end_port_resume(&hcd->self, wIndex); } bus_state->port_c_suspend |= 1 << wIndex; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c41341e..a8d92c9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1606,6 +1606,7 @@ static void handle_port_status(struct xhci_hcd *xhci, set_bit(HCD_FLAG_POLL_RH, &hcd->flags); mod_timer(&hcd->rh_timer, bus_state->resume_done[hcd_portnum]); + usb_hcd_start_port_resume(&hcd->self, hcd_portnum); bogus_port_status = true; } }