linux-mediatek.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices
@ 2021-02-02 10:26 mark-yw.chen
  2021-02-02 10:26 ` [PATCH v4 1/2] Bluetooth: btusb: Fine-tune mt7663 mechanism mark-yw.chen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: mark-yw.chen @ 2021-02-02 10:26 UTC (permalink / raw)
  To: marcel, johan.hedberg, Sean.Wang
  Cc: robin.chiu, mark-yw.chen, linux-kernel, linux-bluetooth,
	linux-mediatek, Eric.liang

From: "mark-yw.chen" <mark-yw.chen@mediatek.com>

v4:
1. add read chip info. from MediaTek bluetooth devices.
2. support download firmware for MT7921U.

mark-yw.chen (2):
  Bluetooth: btusb: Fine-tune mt7663 mechanism.
  Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB
    devices

 drivers/bluetooth/btusb.c | 211 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 206 insertions(+), 5 deletions(-)

-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v4 1/2] Bluetooth: btusb: Fine-tune mt7663 mechanism.
  2021-02-02 10:26 [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices mark-yw.chen
@ 2021-02-02 10:26 ` mark-yw.chen
  2021-02-02 10:26 ` [PATCH v4 2/2] Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB devices mark-yw.chen
  2021-02-02 16:22 ` [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices Marcel Holtmann
  2 siblings, 0 replies; 4+ messages in thread
From: mark-yw.chen @ 2021-02-02 10:26 UTC (permalink / raw)
  To: marcel, johan.hedberg, Sean.Wang
  Cc: robin.chiu, Mark Chen, linux-kernel, linux-bluetooth,
	linux-mediatek, Eric.liang

From: "mark-yw.chen" <mark-yw.chen@mediatek.com>

Fine-tune read register for mt7663/mt7921.
For mediatek chip spcific wmt protocol, we add more delay to send EP0
In-Token.

Signed-off-by: Mark Chen <Mark-YW.Chen@mediatek.com>
---
 drivers/bluetooth/btusb.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 03b83aa91277..2ba8dd6d3d2d 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -3138,6 +3138,7 @@ enum {
 enum {
 	BTMTK_WMT_INVALID,
 	BTMTK_WMT_PATCH_UNDONE,
+	BTMTK_WMT_PATCH_PROGRESS,
 	BTMTK_WMT_PATCH_DONE,
 	BTMTK_WMT_ON_UNDONE,
 	BTMTK_WMT_ON_DONE,
@@ -3153,7 +3154,7 @@ struct btmtk_wmt_hdr {
 
 struct btmtk_hci_wmt_cmd {
 	struct btmtk_wmt_hdr hdr;
-	u8 data[256];
+	u8 data[1000];
 } __packed;
 
 struct btmtk_hci_wmt_evt {
@@ -3252,7 +3253,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
 	 * to generate the event. Otherwise, the WMT event cannot return from
 	 * the device successfully.
 	 */
-	udelay(100);
+	udelay(500);
 
 	usb_anchor_urb(urb, &data->ctrl_anchor);
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -3555,9 +3556,9 @@ static int btusb_mtk_reg_read(struct btusb_data *data, u32 reg, u32 *val)
 	return err;
 }
 
-static int btusb_mtk_id_get(struct btusb_data *data, u32 *id)
+static int btusb_mtk_id_get(struct btusb_data *data, u32 reg, u32 *id)
 {
-	return btusb_mtk_reg_read(data, 0x80000008, id);
+	return btusb_mtk_reg_read(data, reg, id);
 }
 
 static int btusb_mtk_setup(struct hci_dev *hdev)
@@ -3575,7 +3576,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 
 	calltime = ktime_get();
 
-	err = btusb_mtk_id_get(data, &dev_id);
+	err = btusb_mtk_id_get(data, 0x80000008, &dev_id);
 	if (err < 0) {
 		bt_dev_err(hdev, "Failed to get device id (%d)", err);
 		return err;
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v4 2/2] Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB devices
  2021-02-02 10:26 [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices mark-yw.chen
  2021-02-02 10:26 ` [PATCH v4 1/2] Bluetooth: btusb: Fine-tune mt7663 mechanism mark-yw.chen
@ 2021-02-02 10:26 ` mark-yw.chen
  2021-02-02 16:22 ` [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices Marcel Holtmann
  2 siblings, 0 replies; 4+ messages in thread
From: mark-yw.chen @ 2021-02-02 10:26 UTC (permalink / raw)
  To: marcel, johan.hedberg, Sean.Wang
  Cc: robin.chiu, Mark Chen, linux-kernel, linux-bluetooth,
	linux-mediatek, Eric.liang

From: "mark-yw.chen" <mark-yw.chen@mediatek.com>

There is mt7921 firmware download mechanism

1. Read Chip id from MT7921.

2. Download firmware by endpoint 0, it's the same mechanism with
mt7663/mt7668.
   (it's medaitek specific header format for downloading firmware.)

3. Enabling Bluetooth function.

The information in /sys/kernel/debug/usb/devices about the MT7921U
Bluetooth device is listed as the below.

  T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 40 Spd=480  MxCh= 0
  D:  Ver= 2.10 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
  P:  Vendor=0e8d ProdID=7961 Rev= 1.00
  S:  Manufacturer=MediaTek Inc.
  S:  Product=Wireless_Device
  S:  SerialNumber=000000000
  C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=100mA
  A:  FirstIf#= 0 IfCount= 3 Cls=e0(wlcon) Sub=01 Prot=01
  I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=125us
  E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
  E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
  I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
  I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
  I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
  I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
  I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
  I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
  I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
  E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
  E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
  I:* If#= 2 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
  E:  Ad=8a(I) Atr=03(Int.) MxPS=  64 Ivl=125us
  E:  Ad=0a(O) Atr=03(Int.) MxPS=  64 Ivl=125us
  I:  If#= 2 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none)
  E:  Ad=8a(I) Atr=03(Int.) MxPS= 512 Ivl=125us
  E:  Ad=0a(O) Atr=03(Int.) MxPS= 512 Ivl=125us

Signed-off-by: Mark Chen <Mark-YW.Chen@mediatek.com>
---
 drivers/bluetooth/btusb.c | 200 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2ba8dd6d3d2d..4d51ecd19bd3 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -3127,6 +3127,12 @@ static int btusb_shutdown_intel_new(struct hci_dev *hdev)
 #define FIRMWARE_MT7668		"mediatek/mt7668pr2h.bin"
 
 #define HCI_WMT_MAX_EVENT_SIZE		64
+/* It is for mt79xx download rom patch*/
+#define MTK_FW_ROM_PATCH_HEADER_SIZE	32
+#define MTK_FW_ROM_PATCH_GD_SIZE	64
+#define MTK_FW_ROM_PATCH_SEC_MAP_SIZE	64
+#define MTK_SEC_MAP_COMMON_SIZE	12
+#define MTK_SEC_MAP_NEED_SEND_SIZE	52
 
 enum {
 	BTMTK_WMT_PATCH_DWNLD = 0x1,
@@ -3183,6 +3189,40 @@ struct btmtk_hci_wmt_params {
 	u32 *status;
 };
 
+struct btmtk_patch_header {
+	u8 datetime[16];
+	u8 platform[4];
+	__le16 hwver;
+	__le16 swver;
+	__le32 magicnum;
+} __packed;
+
+struct btmtk_global_desc {
+	__le32 patch_ver;
+	__le32 sub_sys;
+	__le32 feature_opt;
+	__le32 section_num;
+} __packed;
+
+struct btmtk_section_map {
+	__le32 sectype;
+	__le32 secoffset;
+	__le32 secsize;
+	union {
+		__le32 u4SecSpec[13];
+		struct {
+			__le32 dlAddr;
+			__le32 dlsize;
+			__le32 seckeyidx;
+			__le32 alignlen;
+			__le32 sectype;
+			__le32 dlmodecrctype;
+			__le32 crc;
+			__le32 reserved[6];
+		} bin_info_spec;
+	};
+} __packed;
+
 static void btusb_mtk_wmt_recv(struct urb *urb)
 {
 	struct hci_dev *hdev = urb->context;
@@ -3406,6 +3446,14 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
 		else
 			status = BTMTK_WMT_ON_UNDONE;
 		break;
+	case BTMTK_WMT_PATCH_DWNLD:
+		if (wmt_evt->whdr.flag == 2)
+			status = BTMTK_WMT_PATCH_DONE;
+		else if (wmt_evt->whdr.flag == 1)
+			status = BTMTK_WMT_PATCH_PROGRESS;
+		else
+			status = BTMTK_WMT_PATCH_UNDONE;
+		break;
 	}
 
 	if (wmt_params->status)
@@ -3418,6 +3466,122 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
 	return err;
 }
 
+static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname)
+{
+	struct btmtk_hci_wmt_params wmt_params;
+	struct btmtk_patch_header *patchhdr = NULL;
+	struct btmtk_global_desc *globaldesc = NULL;
+	struct btmtk_section_map *sectionmap;
+	const struct firmware *fw;
+	const u8 *fw_ptr;
+	const u8 *fw_bin_ptr;
+	size_t fw_size;
+	int err, dlen, i, status;
+	u8 flag, first_block, retry;
+	u32 section_num, dl_size, section_offset;
+	u8 cmd[64];
+
+	err = request_firmware(&fw, fwname, &hdev->dev);
+	if (err < 0) {
+		bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
+		return err;
+	}
+
+	fw_ptr = fw->data;
+	fw_bin_ptr = fw_ptr;
+	fw_size = fw->size;
+	patchhdr = (struct btmtk_patch_header *)fw_ptr;
+	globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
+	section_num = globaldesc->section_num;
+
+	for (i = 0; i < section_num; i++) {
+		first_block = 1;
+		fw_ptr = fw_bin_ptr;
+		sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
+			      MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
+
+		section_offset = sectionmap->secoffset;
+		dl_size = sectionmap->bin_info_spec.dlsize;
+
+		if (dl_size > 0) {
+			retry = 20;
+			while (retry > 0) {
+				cmd[0] = 0; /* 0 means legacy dl mode. */
+				memcpy(cmd + 1,
+				       fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
+				       MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
+				       MTK_SEC_MAP_COMMON_SIZE,
+				       MTK_SEC_MAP_NEED_SEND_SIZE + 1);
+
+				wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
+				wmt_params.status = &status;
+				wmt_params.flag = 0;
+				wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
+				wmt_params.data = &cmd;
+
+				err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
+				if (err < 0) {
+					bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
+						   err);
+					goto err_release_fw;
+				}
+
+				if (status == BTMTK_WMT_PATCH_UNDONE) {
+					break;
+				} else if (status == BTMTK_WMT_PATCH_PROGRESS) {
+					msleep(100);
+					retry--;
+				} else if (status == BTMTK_WMT_PATCH_DONE) {
+					goto next_section;
+				} else {
+					bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
+						   status);
+					goto err_release_fw;
+				}
+			}
+
+			fw_ptr += section_offset;
+			wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
+			wmt_params.status = NULL;
+
+			while (dl_size > 0) {
+				dlen = min_t(int, 250, dl_size);
+				if (first_block == 1) {
+					flag = 1;
+					first_block = 0;
+				} else if (dl_size - dlen <= 0) {
+					flag = 3;
+				} else {
+					flag = 2;
+				}
+
+				wmt_params.flag = flag;
+				wmt_params.dlen = dlen;
+				wmt_params.data = fw_ptr;
+
+				err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
+				if (err < 0) {
+					bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
+						   err);
+					goto err_release_fw;
+				}
+
+				dl_size -= dlen;
+				fw_ptr += dlen;
+			}
+		}
+next_section:
+		continue;
+	}
+	/* Wait a few moments for firmware activation done */
+	usleep_range(100000, 120000);
+
+err_release_fw:
+	release_firmware(fw);
+
+	return err;
+}
+
 static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
 {
 	struct btmtk_hci_wmt_params wmt_params;
@@ -3572,6 +3736,8 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 	const char *fwname;
 	int err, status;
 	u32 dev_id;
+	char fw_bin_name[64];
+	u32 fw_version;
 	u8 param;
 
 	calltime = ktime_get();
@@ -3582,6 +3748,19 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 		return err;
 	}
 
+	if (!dev_id) {
+		err = btusb_mtk_id_get(data, 0x70010200, &dev_id);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to get device id (%d)", err);
+			return err;
+		}
+		err = btusb_mtk_id_get(data, 0x80021004, &fw_version);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to get fw version (%d)", err);
+			return err;
+		}
+	}
+
 	switch (dev_id) {
 	case 0x7663:
 		fwname = FIRMWARE_MT7663;
@@ -3589,6 +3768,26 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 	case 0x7668:
 		fwname = FIRMWARE_MT7668;
 		break;
+	case 0x7961:
+		snprintf(fw_bin_name, sizeof(fw_bin_name),
+			"mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
+			 dev_id & 0xffff, (fw_version & 0xff) + 1);
+		err = btusb_mtk_setup_firmware_79xx(hdev, fw_bin_name);
+
+		/* Enable Bluetooth protocol */
+		param = 1;
+		wmt_params.op = BTMTK_WMT_FUNC_CTRL;
+		wmt_params.flag = 0;
+		wmt_params.dlen = sizeof(param);
+		wmt_params.data = &param;
+		wmt_params.status = NULL;
+
+		err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
+		if (err < 0) {
+			bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
+			return err;
+		}
+		goto done;
 	default:
 		bt_dev_err(hdev, "Unsupported support hardware variant (%08x)",
 			   dev_id);
@@ -3666,6 +3865,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
 	}
 	kfree_skb(skb);
 
+done:
 	rettime = ktime_get();
 	delta = ktime_sub(rettime, calltime);
 	duration = (unsigned long long)ktime_to_ns(delta) >> 10;
-- 
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices
  2021-02-02 10:26 [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices mark-yw.chen
  2021-02-02 10:26 ` [PATCH v4 1/2] Bluetooth: btusb: Fine-tune mt7663 mechanism mark-yw.chen
  2021-02-02 10:26 ` [PATCH v4 2/2] Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB devices mark-yw.chen
@ 2021-02-02 16:22 ` Marcel Holtmann
  2 siblings, 0 replies; 4+ messages in thread
From: Marcel Holtmann @ 2021-02-02 16:22 UTC (permalink / raw)
  To: Mark-YW.Chen
  Cc: Johan Hedberg, Eric.liang, Sean.Wang, LKML,
	Bluetooth Kernel Mailing List, linux-mediatek, robin.chiu

Hi Mark,

> v4:
> 1. add read chip info. from MediaTek bluetooth devices.
> 2. support download firmware for MT7921U.
> 
> mark-yw.chen (2):
>  Bluetooth: btusb: Fine-tune mt7663 mechanism.
>  Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB
>    devices
> 
> drivers/bluetooth/btusb.c | 211 +++++++++++++++++++++++++++++++++++++-
> 1 file changed, 206 insertions(+), 5 deletions(-)

both patches have been applied to bluetooth-next tree.

Regards

Marcel


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-02-02 16:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-02 10:26 [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices mark-yw.chen
2021-02-02 10:26 ` [PATCH v4 1/2] Bluetooth: btusb: Fine-tune mt7663 mechanism mark-yw.chen
2021-02-02 10:26 ` [PATCH v4 2/2] Bluetooth: btusb: Add protocol support for MediaTek MT7921U USB devices mark-yw.chen
2021-02-02 16:22 ` [PATCH v4 0/2] Bluetooth: btusb: Add protocol for MediaTek bluetooth devices Marcel Holtmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).