Skip to content

Commit 01ecc17

Browse files
Mark Chenholtmann
authored andcommitted
Bluetooth: mt7921s: fix btmtksdio_[drv|fw]_pmctrl()
According to the firmware behavior (even the oldest one in linux-firmware) If the firmware is downloaded, MT7921S must rely on the additional mailbox mechanism that resides in firmware to check if the device is the right state for btmtksdio_mcu_[drv|fw]_pmctrl(). Otherwise, we still apply the old way for that. That is a necessary patch before we enable runtime pm for mt7921s as default. Fixes: c603bf1 ("Bluetooth: btmtksdio: add MT7921s Bluetooth support") Co-developed-by: Sean Wang <[email protected]> Signed-off-by: Sean Wang <[email protected]> Signed-off-by: Mark Chen <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 752aea5 commit 01ecc17

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

drivers/bluetooth/btmtksdio.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,25 @@ static bool enable_autosuspend;
3838
struct btmtksdio_data {
3939
const char *fwname;
4040
u16 chipid;
41+
bool lp_mbox_supported;
4142
};
4243

4344
static const struct btmtksdio_data mt7663_data = {
4445
.fwname = FIRMWARE_MT7663,
4546
.chipid = 0x7663,
47+
.lp_mbox_supported = false,
4648
};
4749

4850
static const struct btmtksdio_data mt7668_data = {
4951
.fwname = FIRMWARE_MT7668,
5052
.chipid = 0x7668,
53+
.lp_mbox_supported = false,
5154
};
5255

5356
static const struct btmtksdio_data mt7921_data = {
5457
.fwname = FIRMWARE_MT7961,
5558
.chipid = 0x7921,
59+
.lp_mbox_supported = true,
5660
};
5761

5862
static const struct sdio_device_id btmtksdio_table[] = {
@@ -90,8 +94,12 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
9094
#define FW_MAILBOX_INT BIT(15)
9195
#define RX_PKT_LEN GENMASK(31, 16)
9296

97+
#define MTK_REG_CSICR 0xc0
98+
#define CSICR_CLR_MBOX_ACK BIT(0)
9399
#define MTK_REG_PH2DSM0R 0xc4
94100
#define PH2DSM0R_DRIVER_OWN BIT(0)
101+
#define MTK_REG_PD2HRM0R 0xdc
102+
#define PD2HRM0R_DRV_OWN BIT(0)
95103

96104
#define MTK_REG_CTDR 0x18
97105

@@ -104,6 +112,7 @@ MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
104112
#define BTMTKSDIO_TX_WAIT_VND_EVT 1
105113
#define BTMTKSDIO_HW_TX_READY 2
106114
#define BTMTKSDIO_FUNC_ENABLED 3
115+
#define BTMTKSDIO_PATCH_ENABLED 4
107116

108117
struct mtkbtsdio_hdr {
109118
__le16 len;
@@ -282,13 +291,31 @@ static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
282291
return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
283292
}
284293

294+
static u32 btmtksdio_drv_own_query_79xx(struct btmtksdio_dev *bdev)
295+
{
296+
return sdio_readl(bdev->func, MTK_REG_PD2HRM0R, NULL);
297+
}
298+
285299
static int btmtksdio_fw_pmctrl(struct btmtksdio_dev *bdev)
286300
{
287301
u32 status;
288302
int err;
289303

290304
sdio_claim_host(bdev->func);
291305

306+
if (bdev->data->lp_mbox_supported &&
307+
test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state)) {
308+
sdio_writel(bdev->func, CSICR_CLR_MBOX_ACK, MTK_REG_CSICR,
309+
&err);
310+
err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
311+
status, !(status & PD2HRM0R_DRV_OWN),
312+
2000, 1000000);
313+
if (err < 0) {
314+
bt_dev_err(bdev->hdev, "mailbox ACK not cleared");
315+
goto out;
316+
}
317+
}
318+
292319
/* Return ownership to the device */
293320
sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
294321
if (err < 0)
@@ -321,6 +348,12 @@ static int btmtksdio_drv_pmctrl(struct btmtksdio_dev *bdev)
321348
err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
322349
status & C_COM_DRV_OWN, 2000, 1000000);
323350

351+
if (!err && bdev->data->lp_mbox_supported &&
352+
test_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state))
353+
err = readx_poll_timeout(btmtksdio_drv_own_query_79xx, bdev,
354+
status, status & PD2HRM0R_DRV_OWN,
355+
2000, 1000000);
356+
324357
out:
325358
sdio_release_host(bdev->func);
326359

@@ -728,6 +761,7 @@ static int btmtksdio_func_query(struct hci_dev *hdev)
728761

729762
static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
730763
{
764+
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
731765
struct btmtk_hci_wmt_params wmt_params;
732766
struct btmtk_tci_sleep tci_sleep;
733767
struct sk_buff *skb;
@@ -788,6 +822,8 @@ static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
788822
return err;
789823
}
790824

825+
set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
826+
791827
ignore_func_on:
792828
/* Apply the low power environment setup */
793829
tci_sleep.mode = 0x5;
@@ -810,6 +846,7 @@ static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
810846

811847
static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
812848
{
849+
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
813850
struct btmtk_hci_wmt_params wmt_params;
814851
u8 param = 0x1;
815852
int err;
@@ -835,6 +872,7 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
835872

836873
hci_set_msft_opcode(hdev, 0xFD30);
837874
hci_set_aosp_capable(hdev);
875+
set_bit(BTMTKSDIO_PATCH_ENABLED, &bdev->tx_state);
838876

839877
return err;
840878
}

0 commit comments

Comments
 (0)