From patchwork Tue Dec 22 09:34:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunfeng Yun X-Patchwork-Id: 11986163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 633DCC43331 for ; Tue, 22 Dec 2020 09:36:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3232C23332 for ; Tue, 22 Dec 2020 09:36:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726187AbgLVJf6 (ORCPT ); Tue, 22 Dec 2020 04:35:58 -0500 Received: from mailgw02.mediatek.com ([1.203.163.81]:64058 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725882AbgLVJf5 (ORCPT ); Tue, 22 Dec 2020 04:35:57 -0500 X-UUID: df371734ab3c44b999c85cbc534ca34f-20201222 X-UUID: df371734ab3c44b999c85cbc534ca34f-20201222 Received: from mtkcas34.mediatek.inc [(172.27.4.253)] by mailgw02.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1067787219; Tue, 22 Dec 2020 17:34:54 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by MTKMBS31N2.mediatek.inc (172.27.4.87) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Dec 2020 17:34:52 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Dec 2020 17:34:50 +0800 From: Chunfeng Yun To: Ikjoon Jang CC: Chunfeng Yun , Tianping Fang , Zhanyong Wang , , , , Zhanyong Wang , Yaqii Wu Subject: [RFC PATCH v3 1/5] usb: xhci-mtk: improve bandwidth scheduling with multi-TT Date: Tue, 22 Dec 2020 17:34:38 +0800 Message-ID: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty MIME-Version: 1.0 X-TM-SNTS-SMTP: 9F5E60664AA303661E69680B986883877310DF91EE64BD122A745F1CB41CA4E52000:8 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: Zhanyong Wang After inserted the usb type-c 3.5mm dongle with headset, dmesg showed: usb 1-1.1: new full-speed USB device number 5 using xhci-mtk usb 1-1.1: New USB device found, idVendor=05ac, idProduct=110a, bcdDevice=26.11 usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-1.1: Product: USB-C to 3.5mm Headphone Jack Adapter usb 1-1.1: Manufacturer: Apple, Inc. usb 1-1.1: SerialNumber: DWH915501TFJKLTAM xhci-mtk 11200000.xhci: Not enough bandwidth! usb 1-1.1: can't set config #2, error -28 improve low-speed/full-speed INT/ISOC bandwidth scheduling with USB muli-TT. Signed-off-by: Yaqii Wu Signed-off-by: Chunfeng Yun --- v2~v3: no changes --- drivers/usb/host/xhci-mtk-sch.c | 91 ++++++++++++++++++++++++++++----- drivers/usb/host/xhci-mtk.h | 8 ++- 2 files changed, 84 insertions(+), 15 deletions(-) mode change 100644 => 100755 drivers/usb/host/xhci-mtk-sch.c diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c old mode 100644 new mode 100755 index 45c54d56ecbd..94292b9bbc63 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -383,7 +383,9 @@ static int check_sch_tt(struct usb_device *udev, u32 fs_budget_start; u32 start_ss, last_ss; u32 start_cs, last_cs; - int i; + u32 num_esit, base; + int i, j; + u32 tmp; start_ss = offset % 8; fs_budget_start = (start_ss + 1) % 8; @@ -398,10 +400,13 @@ static int check_sch_tt(struct usb_device *udev, 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)) + for (i = 0; i < sch_ep->cs_count; i++) { + if (test_bit(offset + i, tt->ss_bit_map)) return -ERANGE; + if (test_bit(offset + i, tt->cs_bit_map)) + return -ERANGE; + } } else { u32 cs_count = DIV_ROUND_UP(sch_ep->maxpkt, FS_PAYLOAD_MAX); @@ -428,8 +433,10 @@ static int check_sch_tt(struct usb_device *udev, 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)) + if (test_bit(offset, tt->ss_bit_map)) + return -ERANGE; + for (i = 0; i < cs_count; i++) { + if (test_bit(offset + 2 + i, tt->cs_bit_map)) return -ERANGE; } @@ -445,11 +452,22 @@ static int check_sch_tt(struct usb_device *udev, sch_ep->num_budget_microframes = sch_ep->esit; } + 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++) { + tmp = tt->fs_bus_bw[base + j] + + sch_ep->bw_cost_per_microframe; + if (tmp > FS_PAYLOAD_MAX) + return -ERANGE; + } + } + return 0; } static void update_sch_tt(struct usb_device *udev, - struct mu3h_sch_ep_info *sch_ep) + struct mu3h_sch_ep_info *sch_ep, bool used) { struct mu3h_sch_tt *tt = sch_ep->sch_tt; u32 base, num_esit; @@ -458,11 +476,52 @@ static void update_sch_tt(struct usb_device *udev, 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); + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + if (used) + set_bit(base + j, tt->split_bit_map); + else + clear_bit(base + j, tt->split_bit_map); + } + + if (sch_ep->ep_type == ISOC_OUT_EP) { + for (j = 0; j < sch_ep->num_budget_microframes; j++) { + if (used) { + set_bit(base + j, tt->ss_bit_map); + set_bit(base + j, tt->cs_bit_map); + tt->fs_bus_bw[base + j] += + sch_ep->bw_cost_per_microframe; + } else { + clear_bit(base + j, tt->ss_bit_map); + clear_bit(base + j, tt->cs_bit_map); + tt->fs_bus_bw[base + j] -= + sch_ep->bw_cost_per_microframe; + } + } + } else { + if (used) + set_bit(base, tt->ss_bit_map); + else + clear_bit(base, tt->ss_bit_map); + + for (j = 0; j < sch_ep->cs_count; j++) { + if (used) { + set_bit(base + 2 + j, tt->cs_bit_map); + + tt->fs_bus_bw[base + 2 + j] += + sch_ep->bw_cost_per_microframe; + } else { + clear_bit(base + 2 + j, tt->cs_bit_map); + tt->fs_bus_bw[base + 2 + j] -= + sch_ep->bw_cost_per_microframe; + } + } + } } - list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); + if (used) + list_add_tail(&sch_ep->tt_endpoint, &tt->ep_list); + else + list_del(&sch_ep->tt_endpoint); } static int check_sch_bw(struct usb_device *udev, @@ -470,6 +529,7 @@ static int check_sch_bw(struct usb_device *udev, { u32 offset; u32 esit; + u32 boundary; u32 min_bw; u32 min_index; u32 worst_bw; @@ -487,10 +547,13 @@ static int check_sch_bw(struct usb_device *udev, */ min_bw = ~0; min_index = 0; + boundary = esit; 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)) { + if (sch_ep->ep_type != ISOC_OUT_EP) + boundary = esit + 1; ret = check_sch_tt(udev, sch_ep, offset); if (ret) continue; @@ -498,7 +561,7 @@ static int check_sch_bw(struct usb_device *udev, tt_offset_ok = true; } - if ((offset + sch_ep->num_budget_microframes) > sch_ep->esit) + if ((offset + sch_ep->num_budget_microframes) > boundary) break; worst_bw = get_max_bw(sch_bw, sch_ep, offset); @@ -532,7 +595,7 @@ static int check_sch_bw(struct usb_device *udev, if (!tt_offset_ok) return -ERANGE; - update_sch_tt(udev, sch_ep); + update_sch_tt(udev, sch_ep, 1); } /* update bus bandwidth info */ @@ -696,12 +759,12 @@ 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, 0); - list_del(&sch_ep->endpoint); if (is_fs_or_ls(udev->speed)) { - list_del(&sch_ep->tt_endpoint); + update_sch_tt(udev, sch_ep, 0); drop_tt(udev); } + 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 a93cfe817904..323b281933b9 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -21,12 +21,18 @@ /** * @split_bit_map: used to avoid split microframes overlay + * @ss_bit_map: used to avoid start split microframes overlay + * @cs_bit_map: used to avoid complete split microframes overlay + * @fs_bus_bw: array to keep track of bandwidth already used at full speed * @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); + DECLARE_BITMAP(ss_bit_map, XHCI_MTK_MAX_ESIT); + DECLARE_BITMAP(cs_bit_map, XHCI_MTK_MAX_ESIT + 1); + u32 fs_bus_bw[XHCI_MTK_MAX_ESIT]; struct list_head ep_list; struct usb_tt *usb_tt; int tt_port; @@ -42,7 +48,7 @@ struct mu3h_sch_tt { * two bandwidth domains, one for IN eps and another for OUT eps. */ struct mu3h_sch_bw_info { - u32 bus_bw[XHCI_MTK_MAX_ESIT]; + u32 bus_bw[XHCI_MTK_MAX_ESIT + 1]; struct list_head bw_ep_list; }; From patchwork Tue Dec 22 09:34:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunfeng Yun X-Patchwork-Id: 11986161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1D6C1C4332E for ; Tue, 22 Dec 2020 09:36:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DF07023381 for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726055AbgLVJfu (ORCPT ); Tue, 22 Dec 2020 04:35:50 -0500 Received: from Mailgw01.mediatek.com ([1.203.163.78]:6954 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725895AbgLVJfq (ORCPT ); Tue, 22 Dec 2020 04:35:46 -0500 X-UUID: ffee714fcebf433f9e96065ed3bd8e9f-20201222 X-UUID: ffee714fcebf433f9e96065ed3bd8e9f-20201222 Received: from mtkcas35.mediatek.inc [(172.27.4.253)] by mailgw01.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 266398425; Tue, 22 Dec 2020 17:34:54 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by MTKMBS31N1.mediatek.inc (172.27.4.69) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Dec 2020 17:34:53 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Dec 2020 17:34:51 +0800 From: Chunfeng Yun To: Ikjoon Jang CC: Chunfeng Yun , Tianping Fang , Zhanyong Wang , , , , Zhanyong Wang Subject: [RFC PATCH v3 2/5] usb: xhci-mtk: add mt8192 wakeup Date: Tue, 22 Dec 2020 17:34:39 +0800 Message-ID: <1608629682-8535-2-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> References: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 4E19E506E984517EAF04F3A002C9AD4C689C86BC3D595BD82BBCC7BDB91C627F2000:8 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: Zhanyong Wang need to add wakeup solution as V3 since not support presently. Signed-off-by: Zhanyong Wang Signed-off-by: Chunfeng Yun --- v2~v3: no changes --- drivers/usb/host/xhci-mtk.c | 9 +++++++++ 1 file changed, 9 insertions(+) mode change 100644 => 100755 drivers/usb/host/xhci-mtk.c diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c old mode 100644 new mode 100755 index 8f321f39ab96..565ce4c16206 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -68,9 +68,13 @@ #define SSC_IP_SLEEP_EN BIT(4) #define SSC_SPM_INT_EN BIT(1) +/* mt8192 etc */ +#define SSC_IP_SLEEP_EN_V3 BIT(6) + enum ssusb_uwk_vers { SSUSB_UWK_V1 = 1, SSUSB_UWK_V2, + SSUSB_UWK_V3, }; static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) @@ -305,6 +309,11 @@ static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable) msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN; val = enable ? msk : 0; break; + case SSUSB_UWK_V3: + reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL; + msk = SSC_IP_SLEEP_EN_V3 | SSC_SPM_INT_EN; + val = enable ? msk : 0; + break; default: return; } From patchwork Tue Dec 22 09:34:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunfeng Yun X-Patchwork-Id: 11986159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1AD1C43381 for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C9132310D for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726082AbgLVJfu (ORCPT ); Tue, 22 Dec 2020 04:35:50 -0500 Received: from Mailgw01.mediatek.com ([1.203.163.78]:47521 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725897AbgLVJfp (ORCPT ); Tue, 22 Dec 2020 04:35:45 -0500 X-UUID: e0875460767e42219c5c57c658387b34-20201222 X-UUID: e0875460767e42219c5c57c658387b34-20201222 Received: from mtkcas32.mediatek.inc [(172.27.4.253)] by mailgw01.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 163910702; Tue, 22 Dec 2020 17:34:57 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by MTKMBS31DR.mediatek.inc (172.27.6.102) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Dec 2020 17:34:53 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Dec 2020 17:34:52 +0800 From: Chunfeng Yun To: Ikjoon Jang CC: Chunfeng Yun , Tianping Fang , Zhanyong Wang , , , Subject: [RFC PATCH v3 3/5] usb: xhci-mtk: fix random remote wakeup Date: Tue, 22 Dec 2020 17:34:40 +0800 Message-ID: <1608629682-8535-3-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> References: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: DB305DF1703578D7A07C42CC68D02DC8FE8162C6711BAE8B5815CD4297C816F72000:8 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Wakeup_signal will toggle status according to ssusb_ip_sleep signal after debounc time, add a delay time to avoid spurious wakeup event. Signed-off-by: Chunfeng Yun --- v3: new patch --- drivers/usb/host/xhci-mtk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 565ce4c16206..34bd3de090b1 100755 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -172,7 +172,10 @@ static int xhci_mtk_host_disable(struct xhci_hcd_mtk *mtk) if (ret) { dev_err(mtk->dev, "ip sleep failed!!!\n"); return ret; + } else { + usleep_range(200, 250); } + return 0; } From patchwork Tue Dec 22 09:34:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunfeng Yun X-Patchwork-Id: 11986157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 82693C433E6 for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4486D2310D for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725989AbgLVJfq (ORCPT ); Tue, 22 Dec 2020 04:35:46 -0500 Received: from mailgw02.mediatek.com ([210.61.82.184]:39305 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725852AbgLVJfp (ORCPT ); Tue, 22 Dec 2020 04:35:45 -0500 X-UUID: 3e1382f37dbe45d3a19ad2dd57127b50-20201222 X-UUID: 3e1382f37dbe45d3a19ad2dd57127b50-20201222 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw02.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 249683364; Tue, 22 Dec 2020 17:34:59 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Dec 2020 17:34:55 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Dec 2020 17:34:55 +0800 From: Chunfeng Yun To: Ikjoon Jang CC: Chunfeng Yun , Tianping Fang , Zhanyong Wang , , , , CK Hu , Zhanyong Wang Subject: [RFC PATCH v3 4/5] usb: xhci-mtk: add support runtime pm Date: Tue, 22 Dec 2020 17:34:41 +0800 Message-ID: <1608629682-8535-4-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> References: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: CK Hu add support runtime pm feature Signed-off-by: Zhanyong Wang Signed-off-by: Chunfeng Yun --- v3: 1. fix some issues 2. remove attribute files v2: fix error caused by request irq suggested by CK --- drivers/usb/host/xhci-mtk.c | 285 +++++++++++++++++++++++++++++++++++- drivers/usb/host/xhci-mtk.h | 14 ++ 2 files changed, 294 insertions(+), 5 deletions(-) mode change 100755 => 100644 drivers/usb/host/xhci-mtk.c diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c old mode 100755 new mode 100644 index 34bd3de090b1..c07d54acbcb7 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,72 @@ enum ssusb_uwk_vers { SSUSB_UWK_V3, }; +int xhci_mtk_runtime_ready; + +static int xhci_mtk_runtime_resume(struct device *dev); + +static void xhci_mtk_seal_work(struct work_struct *work) +{ + struct xhci_hcd_mtk *mtk = + container_of(work, struct xhci_hcd_mtk, seal.work); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + xhci_dbg(xhci, "spm unseals xHCI controller %i\n", mtk->seal_status); + if (mtk->seal_status == SEAL_SUSPENDED) { + mtk->seal_status = SEAL_RESUMING; + pm_runtime_mark_last_busy(mtk->dev); + pm_runtime_put_sync_autosuspend(mtk->dev); + } else { + /* + * FIXME: Sometimes seal_status will keep it on SEAL_RESUMING staus not to expect + * since pm_runtime_put_sync_autosuspend doesn't invoke runtime_resume of callback. + * and to survey why not to invoke runtime_resume callback named + * xhci_mtk_runtime_resume in time in short feature, Herely provide one solution + * that make sure seal_status to match h/w state machine,and MTK xHCI clocks + * on as soon as unseal event received. + */ + if (mtk->seal_status == SEAL_RESUMING) + xhci_mtk_runtime_resume(mtk->dev); + else + xhci_warn(xhci, + "Ignore seal wakeup source disordered in xHCI controller\n"); + } +} + +static irqreturn_t xhci_mtk_seal_irq(int irq, void *data) +{ + struct xhci_hcd_mtk *mtk = data; + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + xhci_dbg(xhci, "seal irq ISR invoked\n"); + + schedule_delayed_work(&mtk->seal, 0); + + return IRQ_HANDLED; +} + +static void xhci_mtk_seal_wakeup_enable(struct xhci_hcd_mtk *mtk, bool enable) +{ + struct irq_desc *desc; + struct device *dev = mtk->dev; + + if (mtk && mtk->seal_irq) { + desc = irq_to_desc(mtk->seal_irq); + if (enable) { + desc->irq_data.chip->irq_ack(&desc->irq_data); + enable_irq(mtk->seal_irq); + dev_dbg(dev, "%s: enable_irq %i\n", + __func__, mtk->seal_irq); + } else { + disable_irq(mtk->seal_irq); + dev_dbg(dev, "%s: disable_irq %i\n", + __func__, mtk->seal_irq); + } + } +} + static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) { struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; @@ -347,7 +414,6 @@ static int usb_wakeup_of_property_parse(struct xhci_hcd_mtk *mtk, mtk->uwk_reg_base, mtk->uwk_vers); return PTR_ERR_OR_ZERO(mtk->uwk); - } static void usb_wakeup_set(struct xhci_hcd_mtk *mtk, bool enable) @@ -482,9 +548,11 @@ static int xhci_mtk_probe(struct platform_device *pdev) return ret; } + pm_runtime_set_active(dev); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_autosuspend_delay(dev, + CONFIG_USB_AUTOSUSPEND_DELAY * 1000); pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - device_enable_async_suspend(dev); ret = xhci_mtk_ldos_enable(mtk); if (ret) @@ -499,6 +567,14 @@ static int xhci_mtk_probe(struct platform_device *pdev) ret = irq; goto disable_clk; } + dev_dbg(dev, "irq %i\n", irq); + + mtk->seal_irq = platform_get_irq_optional(pdev, 1); + if (mtk->seal_irq < 0) { + ret = mtk->seal_irq; + goto disable_clk; + } + dev_dbg(dev, "seal_irq %i\n", mtk->seal_irq); hcd = usb_create_hcd(driver, dev, dev_name(dev)); if (!hcd) { @@ -565,6 +641,27 @@ static int xhci_mtk_probe(struct platform_device *pdev) if (ret) goto dealloc_usb2_hcd; + INIT_DELAYED_WORK(&mtk->seal, xhci_mtk_seal_work); + snprintf(mtk->seal_descr, sizeof(mtk->seal_descr), "seal%s:usb%d", + hcd->driver->description, hcd->self.busnum); + ret = devm_request_irq(dev, mtk->seal_irq, &xhci_mtk_seal_irq, + IRQF_TRIGGER_FALLING, mtk->seal_descr, mtk); + if (ret != 0) { + dev_err(dev, "seal request interrupt %d failed\n", + mtk->seal_irq); + goto dealloc_usb2_hcd; + } + xhci_mtk_seal_wakeup_enable(mtk, false); + + device_enable_async_suspend(dev); + xhci_mtk_runtime_ready = 1; + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + dev_dbg(dev, "%s: xhci_mtk_runtime_ready %i", + __func__, xhci_mtk_runtime_ready); + return 0; dealloc_usb2_hcd: @@ -587,7 +684,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) xhci_mtk_ldos_disable(mtk); disable_pm: - pm_runtime_put_sync(dev); + pm_runtime_put_sync_autosuspend(dev); pm_runtime_disable(dev); return ret; } @@ -602,6 +699,7 @@ static int xhci_mtk_remove(struct platform_device *dev) pm_runtime_put_noidle(&dev->dev); pm_runtime_disable(&dev->dev); + xhci_mtk_runtime_ready = 0; usb_remove_hcd(shared_hcd); xhci->shared_hcd = NULL; device_init_wakeup(&dev->dev, false); @@ -638,6 +736,7 @@ static int __maybe_unused xhci_mtk_suspend(struct device *dev) xhci_mtk_host_disable(mtk); xhci_mtk_clks_disable(mtk); usb_wakeup_set(mtk, true); + return 0; } @@ -659,10 +758,185 @@ static int __maybe_unused xhci_mtk_resume(struct device *dev) return 0; } +static int __maybe_unused xhci_mtk_bus_status(struct device *dev) +{ + struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd; + struct xhci_hcd *xhci; + struct xhci_hub *usb2_rhub; + struct xhci_hub *usb3_rhub; + struct xhci_bus_state *bus_state; + struct xhci_port *port; + u32 usb2_suspended_ports = -1; + u32 usb3_suspended_ports = -1; + u16 status; + int num_ports; + int ret = 0; + int i; + + if (!mtk->hcd) + return -ESHUTDOWN; + + hcd = mtk->hcd; + xhci = hcd_to_xhci(hcd); + if ((xhci->xhc_state & XHCI_STATE_REMOVING) || + (xhci->xhc_state & XHCI_STATE_HALTED)) { + return -ESHUTDOWN; + } + + usb2_rhub = &xhci->usb2_rhub; + if (usb2_rhub) { + bus_state = &usb2_rhub->bus_state; + num_ports = usb2_rhub->num_ports; + usb2_suspended_ports = bus_state->suspended_ports; + usb2_suspended_ports ^= (BIT(num_ports) - 1); + usb2_suspended_ports &= (BIT(num_ports) - 1); + for (i = 0; i < num_ports; i++) { + if (usb2_suspended_ports & (1UL << i)) { + port = usb2_rhub->ports[i]; + status = readl(port->addr); + + xhci_dbg(xhci, + "USB20: portsc[%i]: 0x%04X\n", + i, status); + + if (!(status & PORT_CONNECT)) + usb2_suspended_ports &= ~(1UL << i); + } + } + + if (usb2_suspended_ports) { + ret = -EBUSY; + goto ebusy; + } + } + + usb3_rhub = &xhci->usb3_rhub; + if (usb3_rhub) { + bus_state = &usb3_rhub->bus_state; + num_ports = usb3_rhub->num_ports; + usb3_suspended_ports = bus_state->suspended_ports; + usb3_suspended_ports ^= (BIT(num_ports) - 1); + usb3_suspended_ports &= (BIT(num_ports) - 1); + for (i = 0; i < num_ports; i++) { + if (usb3_suspended_ports & BIT(i)) { + port = usb3_rhub->ports[i]; + status = readl(port->addr); + + xhci_dbg(xhci, "USB3: portsc[%i]: 0x%04X\n", + i, status); + + if (!(status & PORT_CONNECT)) + usb3_suspended_ports &= ~BIT(i); + } + } + + if (usb3_suspended_ports) { + ret = -EBUSY; + goto ebusy; + } + } + +ebusy: + xhci_dbg(xhci, "%s: USB2: 0x%08X, USB3: 0x%08X ret: %i\n", + __func__, usb2_suspended_ports, + usb3_suspended_ports, ret); + + return ret; +} + +static int __maybe_unused xhci_mtk_runtime_suspend(struct device *dev) +{ + bool wakeup = device_may_wakeup(dev); + struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd; + struct xhci_hcd *xhci; + int ret = 0; + + if (!mtk->hcd) + return -ESHUTDOWN; + + hcd = mtk->hcd; + xhci = hcd_to_xhci(hcd); + if ((xhci->xhc_state & XHCI_STATE_REMOVING) || + (xhci->xhc_state & XHCI_STATE_HALTED)) { + return -ESHUTDOWN; + } + + mtk->seal_status = SEAL_BUSY; + ret = xhci_mtk_bus_status(dev); + if (wakeup && !ret) { + mtk->seal_status = SEAL_SUSPENDING; + xhci_mtk_suspend(dev); + xhci_mtk_seal_wakeup_enable(mtk, true); + mtk->seal_status = SEAL_SUSPENDED; + xhci_dbg(xhci, "%s: seals xHCI controller\n", __func__); + } + + xhci_dbg(xhci, "%s: seals wakeup = %i, ret = %i!\n", + __func__, wakeup, ret); + + return ret; +} + +static int __maybe_unused xhci_mtk_runtime_resume(struct device *dev) +{ + bool wakeup = device_may_wakeup(dev); + struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd; + struct xhci_hcd *xhci; + + if (!mtk->hcd) + return -ESHUTDOWN; + + hcd = mtk->hcd; + xhci = hcd_to_xhci(hcd); + if ((xhci->xhc_state & XHCI_STATE_REMOVING) || + (xhci->xhc_state & XHCI_STATE_HALTED)) { + return -ESHUTDOWN; + } + + /* + * list cases by one extra interrupt named seal to process!!! + * Who to process these module reinitilization after SPM wakeup + * case 1: usb remote wakeup, therefore xHCI need reinitilizate also. + * case 2: other-wakeup-source wakeup, therefore, xHCI need reinit + * case 3: usb client driver can invoke it in runtime mechanism + * case 4: user active + */ + if (wakeup) { + xhci_mtk_seal_wakeup_enable(mtk, false); + xhci_mtk_resume(dev); + xhci_dbg(xhci, "%s: unseals xHCI controller\n", __func__); + } + mtk->seal_status = SEAL_RESUMED; + + xhci_dbg(xhci, "%s: unseals wakeup = %i\n", __func__, wakeup); + + return 0; +} + +static int __maybe_unused xhci_mtk_runtime_idle(struct device *dev) +{ + int ret = 0; + + dev_dbg(dev, "%s: xhci_mtk_runtime_ready %i", + __func__, xhci_mtk_runtime_ready); + + if (!xhci_mtk_runtime_ready) + ret = -EAGAIN; + + return ret; +} + static const struct dev_pm_ops xhci_mtk_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume) + SET_RUNTIME_PM_OPS(xhci_mtk_runtime_suspend, + xhci_mtk_runtime_resume, + xhci_mtk_runtime_idle) }; -#define DEV_PM_OPS IS_ENABLED(CONFIG_PM) ? &xhci_mtk_pm_ops : NULL + +#define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_mtk_pm_ops : NULL) #ifdef CONFIG_OF static const struct of_device_id mtk_xhci_of_match[] = { @@ -686,6 +960,7 @@ MODULE_ALIAS("platform:xhci-mtk"); static int __init xhci_mtk_init(void) { + xhci_mtk_runtime_ready = 0; xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides); return platform_driver_register(&mtk_xhci_driver); } diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h index 323b281933b9..103d83ce6a3e 100644 --- a/drivers/usb/host/xhci-mtk.h +++ b/drivers/usb/host/xhci-mtk.h @@ -133,6 +133,14 @@ struct mu3c_ippc_regs { __le32 reserved3[33]; /* 0x80 ~ 0xff */ }; +enum xhci_mtk_seal { + SEAL_BUSY = 0, + SEAL_SUSPENDING, + SEAL_SUSPENDED, + SEAL_RESUMING, + SEAL_RESUMED +}; + struct xhci_hcd_mtk { struct device *dev; struct usb_hcd *hcd; @@ -158,6 +166,12 @@ struct xhci_hcd_mtk { struct regmap *uwk; u32 uwk_reg_base; u32 uwk_vers; + + /* usb eint wakeup source */ + int seal_irq; + enum xhci_mtk_seal seal_status; + struct delayed_work seal; + char seal_descr[32]; /* "seal" + driver + bus # */ }; static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) From patchwork Tue Dec 22 09:34:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chunfeng Yun X-Patchwork-Id: 11986155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B947C433E0 for ; Tue, 22 Dec 2020 09:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CDFE523103 for ; Tue, 22 Dec 2020 09:36:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725913AbgLVJfp (ORCPT ); Tue, 22 Dec 2020 04:35:45 -0500 Received: from mailgw02.mediatek.com ([1.203.163.81]:3991 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1725895AbgLVJfo (ORCPT ); Tue, 22 Dec 2020 04:35:44 -0500 X-UUID: 1f47d6a946494a5996f43e801bdcac1f-20201222 X-UUID: 1f47d6a946494a5996f43e801bdcac1f-20201222 Received: from mtkcas35.mediatek.inc [(172.27.4.253)] by mailgw02.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 253076222; Tue, 22 Dec 2020 17:34:59 +0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by MTKMBS31N2.mediatek.inc (172.27.4.87) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 22 Dec 2020 17:34:57 +0800 Received: from localhost.localdomain (10.17.3.153) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Tue, 22 Dec 2020 17:34:55 +0800 From: Chunfeng Yun To: Ikjoon Jang CC: Chunfeng Yun , Tianping Fang , Zhanyong Wang , , , , Zhanyong Wang Subject: [RFC PATCH v3 5/5] arm64: dts: mt8192: add SSUSB related nodes Date: Tue, 22 Dec 2020 17:34:42 +0800 Message-ID: <1608629682-8535-5-git-send-email-chunfeng.yun@mediatek.com> X-Mailer: git-send-email 1.8.1.1.dirty In-Reply-To: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> References: <1608629682-8535-1-git-send-email-chunfeng.yun@mediatek.com> MIME-Version: 1.0 X-TM-SNTS-SMTP: 13DABBDEFD78ED4A7DB3C280B058F72B960972A49665467DDC424A771ACA78A32000:8 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org From: Zhanyong Wang Add SSUSB related nodes for mt8192 Signed-off-by: Zhanyong Wang Signed-off-by: Chunfeng Yun --- v3: rename node as 'usb' instead of xhci v2: include phy.h file Depends on: https://patchwork.kernel.org/patch/11713559/ [v4,1/3] arm64: dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile --- arch/arm64/boot/dts/mediatek/mt8192.dtsi | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi index 69d45c7b31f1..82d9f6eee404 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include / { compatible = "mediatek,mt8192"; @@ -416,6 +417,54 @@ status = "disabled"; }; + xhci: usb@11200000 { + compatible = "mediatek,mt8192-xhci", + "mediatek,mtk-xhci"; + reg = <0 0x11200000 0 0x1000>, + <0 0x11203e00 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts-extended = <&gic GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH 0>, + <&pio 211 IRQ_TYPE_LEVEL_LOW>; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>; + assigned-clocks = <&topckgen CLK_TOP_USB_TOP_SEL>, + <&topckgen CLK_TOP_SSUSB_XHCI_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>, + <&topckgen CLK_TOP_UNIVPLL_D5_D4>; + clocks = <&infracfg CLK_INFRA_SSUSB>, + <&infracfg CLK_INFRA_SSUSB_XHCI>, + <&apmixedsys CLK_APMIXED_USBPLL>; + clock-names = "sys_ck", "xhci_ck", "ref_ck"; + mediatek,syscon-wakeup = <&pericfg 0x420 3>; + #address-cells = <2>; + #size-cells = <2>; + }; + + u3phy0: usb-phy@11e40000 { + compatible = "mediatek,mt8192-tphy", + "mediatek,generic-tphy-v2"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "okay"; + + u2port0: usb-phy@11e40000 { + reg = <0 0x11e40000 0 0x700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@11e40700 { + reg = <0 0x11e40700 0 0x900>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + audsys: syscon@11210000 { compatible = "mediatek,mt8192-audsys", "syscon"; reg = <0 0x11210000 0 0x1000>;