From patchwork Sat Jan 29 06:02:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Wang X-Patchwork-Id: 12729391 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0CD6BC433F5 for ; Sat, 29 Jan 2022 06:12:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=QlQmNaRJt1spw7xsRgAaolCBJ0SkgOkh/f/CE5EY1l0=; b=zYangqQ9drlrnp umIIcF8Z1y10I9rAUVR/cxS5d6+KV/yhj9uMPjlmFpzlSA1V5UfPgGm3tzwRnWL9NWborAy100gSE uBzkFmLJ0TZ/dQYYH8sm8pa/H+CaLcMVuhImjNljMleuQGx0ssJv/s6rC7PuEdgtKSUIYlSd9PqZp qqZl6e5DZocxXga2pcLAmt5KK38Qr6VypxaV4FynaYgjDxjQJehTdduaocM5paBN3M1XPwGuGd+vc VpNlC1VDY2M8y2PrIrrQBRn55SchDyz3yFPm6wHSPNqyRy9qy1DBbuL/bCMj5n8dsARiitYnrg6MD 7CxT4YXFbDsLM7BeqlKA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDgyD-0047LQ-NQ; Sat, 29 Jan 2022 06:12:21 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDgyA-0047Km-Cq for linux-mediatek@lists.infradead.org; Sat, 29 Jan 2022 06:12:20 +0000 X-UUID: ab168cbf3e4b4053baff4891911f1365-20220128 X-UUID: ab168cbf3e4b4053baff4891911f1365-20220128 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1432344614; Fri, 28 Jan 2022 23:12:13 -0700 Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 28 Jan 2022 22:02:11 -0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 29 Jan 2022 14:02:10 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 29 Jan 2022 14:02:10 +0800 From: To: , CC: , , , , , , , , , , , , , , , , , , , , , , , , , , , Chih-Ying Chiang , Mark Chen Subject: [PATCH 1/2] Bluetooth: mt7921s: support bluetooth reset mechanism Date: Sat, 29 Jan 2022 14:02:07 +0800 Message-ID: <52ae30c33f2994efcdff180764801141d59e6e0c.1643435854.git.objelf@gmail.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220128_221218_499278_2EECD473 X-CRM114-Status: GOOD ( 19.42 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Chih-Ying Chiang Implement .cmd_timeout to reset the MT7921s device via a dedicated GPIO pin when the firmware hang or the command has no response. Co-developed-by: Mark Chen Signed-off-by: Mark Chen Co-developed-by: Sean Wang Signed-off-by: Sean Wang Signed-off-by: Chih-Ying Chiang --- drivers/bluetooth/btmtk.h | 6 ++ drivers/bluetooth/btmtksdio.c | 113 +++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index fb76d9765ce0..8960a5f89d48 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -10,9 +10,15 @@ #define BTMTK_WMT_REG_WRITE 0x1 #define BTMTK_WMT_REG_READ 0x2 +#define MT7921_BTSYS_RST 0x70002610 +#define MT7921_BTSYS_RST_WITH_GPIO BIT(7) + #define MT7921_PINMUX_0 0x70005050 #define MT7921_PINMUX_1 0x70005054 +#define MT7921_DLSTATUS 0x7c053c10 +#define BT_DL_STATE BIT(1) + enum { BTMTK_WMT_PATCH_DWNLD = 0x1, BTMTK_WMT_TEST = 0x2, diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 8be763ab3bf4..8e200e80d2f6 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -12,10 +12,12 @@ #include #include +#include #include #include #include #include +#include #include #include @@ -83,6 +85,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table); #define MTK_REG_CHCR 0xc #define C_INT_CLR_CTRL BIT(1) +#define BT_RST_DONE BIT(8) /* CHISR have the same bits field definition with CHIER */ #define MTK_REG_CHISR 0x10 @@ -114,6 +117,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table); #define BTMTKSDIO_HW_TX_READY 2 #define BTMTKSDIO_FUNC_ENABLED 3 #define BTMTKSDIO_PATCH_ENABLED 4 +#define BTMTKSDIO_HW_RESET_ACTIVE 5 struct mtkbtsdio_hdr { __le16 len; @@ -133,6 +137,8 @@ struct btmtksdio_dev { struct sk_buff *evt_skb; const struct btmtksdio_data *data; + + struct gpio_desc *reset; }; static int mtk_hci_wmt_sync(struct hci_dev *hdev, @@ -297,6 +303,11 @@ static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev) return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL); } +static u32 btmtksdio_chcr_query(struct btmtksdio_dev *bdev) +{ + return sdio_readl(bdev->func, MTK_REG_CHCR, NULL); +} + static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev) { u32 status; @@ -967,6 +978,28 @@ static int btmtksdio_sco_setting(struct hci_dev *hdev) return btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); } +static int btmtksdio_reset_setting(struct hci_dev *hdev) +{ + int err; + u32 val; + + err = btmtksdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val); + if (err < 0) + return err; + + val |= 0x20; /* set the pin (bit field 11:8) work as GPIO mode */ + err = btmtksdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0); + if (err < 0) + return err; + + err = btmtksdio_mtk_reg_read(hdev, MT7921_BTSYS_RST, &val); + if (err < 0) + return err; + + val |= MT7921_BTSYS_RST_WITH_GPIO; + return btmtksdio_mtk_reg_write(hdev, MT7921_BTSYS_RST, val, ~0); +} + static int btmtksdio_setup(struct hci_dev *hdev) { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); @@ -974,13 +1007,32 @@ static int btmtksdio_setup(struct hci_dev *hdev) unsigned long long duration; char fwname[64]; int err, dev_id; - u32 fw_version = 0; + u32 fw_version = 0, val; calltime = ktime_get(); set_bit(BTMTKSDIO_HW_TX_READY, &bdev->tx_state); switch (bdev->data->chipid) { case 0x7921: + if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) { + err = btmtksdio_mtk_reg_read(hdev, MT7921_DLSTATUS, + &val); + if (err < 0) + return err; + + val &= ~BT_DL_STATE; + err = btmtksdio_mtk_reg_write(hdev, MT7921_DLSTATUS, + val, ~0); + if (err < 0) + return err; + + btmtksdio_fw_pmctrl(bdev); + msleep(20); + btmtksdio_drv_pmctrl(bdev); + + clear_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state); + } + err = btmtksdio_mtk_reg_read(hdev, 0x70010200, &dev_id); if (err < 0) { bt_dev_err(hdev, "Failed to get device id (%d)", err); @@ -1015,6 +1067,16 @@ static int btmtksdio_setup(struct hci_dev *hdev) return err; } + /* Enable GPIO reset mechanism */ + if (bdev->reset) { + err = btmtksdio_reset_setting(hdev); + if (err < 0) { + bt_dev_err(hdev, "Failed to enable Reset setting (%d)", err); + devm_gpiod_put(bdev->dev, bdev->reset); + bdev->reset = NULL; + } + } + break; case 0x7663: case 0x7668: @@ -1111,6 +1173,47 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +static void btmtksdio_cmd_timeout(struct hci_dev *hdev) +{ + struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); + u32 status; + int err; + + if (!bdev->reset || bdev->data->chipid != 0x7921) + return; + + pm_runtime_get_sync(bdev->dev); + + if (test_and_set_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) + return; + + sdio_claim_host(bdev->func); + + sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL); + skb_queue_purge(&bdev->txq); + cancel_work_sync(&bdev->txrx_work); + + gpiod_set_value_cansleep(bdev->reset, 1); + msleep(100); + gpiod_set_value_cansleep(bdev->reset, 0); + + err = readx_poll_timeout(btmtksdio_chcr_query, bdev, status, + status & BT_RST_DONE, 100000, 2000000); + if (err < 0) { + bt_dev_err(hdev, "Failed to reset (%d)", err); + goto err; + } + + clear_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state); +err: + sdio_release_host(bdev->func); + + pm_runtime_put_noidle(bdev->dev); + pm_runtime_disable(bdev->dev); + + hci_reset_dev(hdev); +} + static bool btmtksdio_sdio_wakeup(struct hci_dev *hdev) { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); @@ -1172,6 +1275,7 @@ static int btmtksdio_probe(struct sdio_func *func, hdev->open = btmtksdio_open; hdev->close = btmtksdio_close; + hdev->cmd_timeout = btmtksdio_cmd_timeout; hdev->flush = btmtksdio_flush; hdev->setup = btmtksdio_setup; hdev->shutdown = btmtksdio_shutdown; @@ -1216,6 +1320,13 @@ static int btmtksdio_probe(struct sdio_func *func, if (err) bt_dev_err(hdev, "failed to initialize device wakeup"); + bdev->dev->of_node = of_find_compatible_node(NULL, NULL, + "mediatek,mt7921s-bluetooth"); + bdev->reset = devm_gpiod_get_optional(bdev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(bdev->reset)) + err = PTR_ERR(bdev->reset); + return err; } From patchwork Sat Jan 29 06:02:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Wang X-Patchwork-Id: 12729392 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A00B1C433EF for ; Sat, 29 Jan 2022 06:12:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=vj6GsSh93k+AweyZVvcr8nqUQiIo4aOUOpXuK4bv1Hw=; b=VZ2aNEaXAqnJMS ScDQYhEpaY9swG+qxAbvc8k2LXGZgTFJjVfCVdghV9YcrzsnvWDjr8DOynFoSYSwVv1PQbMbpDVFt qqbEdPwRhL+V+iUghHYomvy1kUNkG7DMff9VGh4QypwnaJBhLiamv0Ebi8ALc1yo0BQCT0RFDRxBj HD7FZeWmpPDIiiNB+tsPmhgHo4ZQS+FHf1/zW7LcfahVLsZU0rhFR0HgAhdQ2SoulQCRts7Xqd3oC 7BK6popJ2ITozyGOXuOq839DDEXFF/tcknC2jgEWeC9rUDdhV7ET8ZbMpSp8BSofnEW6QBshEGqu0 pJyqecb1nU7CiXYg6zVg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDgyN-0047Nc-Ml; Sat, 29 Jan 2022 06:12:31 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDgyK-0047Lv-Cw for linux-mediatek@lists.infradead.org; Sat, 29 Jan 2022 06:12:29 +0000 X-UUID: 8803825b080b4020ad1560a28fd3f1b5-20220128 X-UUID: 8803825b080b4020ad1560a28fd3f1b5-20220128 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1229551839; Fri, 28 Jan 2022 23:12:21 -0700 Received: from mtkexhb01.mediatek.inc (172.21.101.102) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 28 Jan 2022 22:02:19 -0800 Received: from mtkcas11.mediatek.inc (172.21.101.40) by mtkexhb01.mediatek.inc (172.21.101.102) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Sat, 29 Jan 2022 14:02:12 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas11.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Sat, 29 Jan 2022 14:02:12 +0800 From: To: , CC: , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: [PATCH 2/2] Bluetooth: mediatek: fix the conflict between mtk and msft vendor event Date: Sat, 29 Jan 2022 14:02:08 +0800 Message-ID: <2eed797ac2605bd068a025486fc0c09c2687e50c.1643435854.git.objelf@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <52ae30c33f2994efcdff180764801141d59e6e0c.1643435854.git.objelf@gmail.com> References: <52ae30c33f2994efcdff180764801141d59e6e0c.1643435854.git.objelf@gmail.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220128_221228_472057_78C9ADDF X-CRM114-Status: GOOD ( 18.11 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Sean Wang There is a conflict between MediaTek wmt event and msft vendor extension logic in the core layer since 145373cb1b1f ("Bluetooth: Add framework for Microsoft vendor extension") was introduced because we changed the type of mediatek wmt event to the type of msft vendor event in the driver. But the purpose we reported mediatek event to the core layer is for the diagnostic purpose with that we are able to see the full packet trace via monitoring socket with btmon. Thus, it is harmless we keep the original type of mediatek vendor event here to avoid breaking the msft extension function especially they can be supported by Mediatek chipset like MT7921 , MT7922 devices and future devices. Signed-off-by: Sean Wang --- drivers/bluetooth/btmtk.h | 1 + drivers/bluetooth/btmtksdio.c | 9 +-------- drivers/bluetooth/btusb.c | 5 ----- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index 8960a5f89d48..013850fd2055 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -5,6 +5,7 @@ #define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin" #define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin" +#define HCI_EV_WMT 0xe4 #define HCI_WMT_MAX_EVENT_SIZE 64 #define BTMTK_WMT_REG_WRITE 0x1 diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 8e200e80d2f6..cbb09e1b823d 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -381,13 +381,6 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) struct hci_event_hdr *hdr = (void *)skb->data; int err; - /* Fix up the vendor event id with 0xff for vendor specific instead - * of 0xe4 so that event send via monitoring socket can be parsed - * properly. - */ - if (hdr->evt == 0xe4) - hdr->evt = HCI_EV_VENDOR; - /* When someone waits for the WMT event, the skb is being cloned * and being processed the events from there then. */ @@ -403,7 +396,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) if (err < 0) goto err_free_skb; - if (hdr->evt == HCI_EV_VENDOR) { + if (hdr->evt == HCI_EV_WMT) { if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) { /* Barrier to sync with other CPUs */ diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index aefa0ee293f3..55ebab019d29 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2271,11 +2271,6 @@ static void btusb_mtk_wmt_recv(struct urb *urb) skb_put_data(skb, urb->transfer_buffer, urb->actual_length); hdr = (void *)skb->data; - /* Fix up the vendor event id with 0xff for vendor specific - * instead of 0xe4 so that event send via monitoring socket can - * be parsed properly. - */ - hdr->evt = 0xff; /* When someone waits for the WMT event, the skb is being cloned * and being processed the events from there then.