Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: btnxpuart: Add support for 4M baudrate

This adds support for 4000000 as secondary baudrate.

This value is selected from device tree property "max-speed"
which is then used to download FW chunks, and as operational baudrate after
HCI initialization is done.

Earlier, the secondary baudrate was fixed to 3000000 in driver, but now
with "max-speed" property, this secondary baudrate can be set to
4000000.

The secondary baudrate is set by the driver by sending a vendor command
(3F 09) to the firmware, with secondary baudrate parameter, in
nxp_post_init().

Any other value set for max-speed other than 3000000 or 4000000 will
default to 3000000, which is supported by all legacy and new NXP chipsets.

This feature is applicable for all new V3 bootloader chips and w8987 V1
bootloader chip.

This property does not apply for w8997 compatible device, since it
downloads a helper.bin FW file that sets secondary baudrate as 3000000
only.

The switch to 4000000 baudrate is validated using a Saleae Logic Analyzer
and imx8m-mini with AW693 M.2 module.

Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Neeraj Sanjay Kale and committed by
Luiz Augusto von Dentz
45b54f00 4112e29a

+27 -9
+27 -9
drivers/bluetooth/btnxpuart.c
··· 73 73 #define FW_AUTH_ENC 0xc0 74 74 75 75 #define HCI_NXP_PRI_BAUDRATE 115200 76 - #define HCI_NXP_SEC_BAUDRATE 3000000 76 + #define HCI_NXP_SEC_BAUDRATE_3M 3000000 77 + #define HCI_NXP_SEC_BAUDRATE_4M 4000000 77 78 78 79 #define MAX_FW_FILE_NAME_LEN 50 79 80 ··· 202 201 u32 new_baudrate; 203 202 u32 current_baudrate; 204 203 u32 fw_init_baudrate; 204 + u32 secondary_baudrate; 205 205 enum bootloader_param_change timeout_changed; 206 206 enum bootloader_param_change baudrate_changed; 207 207 bool helper_downloaded; ··· 804 802 nxpdev->fw_v3_offset_correction += req_len; 805 803 } else if (req_len == sizeof(uart_config)) { 806 804 uart_config.clkdiv.address = __cpu_to_le32(clkdivaddr); 807 - uart_config.clkdiv.value = __cpu_to_le32(0x00c00000); 805 + if (nxpdev->new_baudrate == HCI_NXP_SEC_BAUDRATE_4M) 806 + uart_config.clkdiv.value = __cpu_to_le32(0x01000000); 807 + else 808 + uart_config.clkdiv.value = __cpu_to_le32(0x00c00000); 808 809 uart_config.uartdiv.address = __cpu_to_le32(uartdivaddr); 809 810 uart_config.uartdiv.value = __cpu_to_le32(1); 810 811 uart_config.mcr.address = __cpu_to_le32(uartmcraddr); ··· 971 966 goto free_skb; 972 967 } 973 968 if (nxpdev->baudrate_changed != changed) { 969 + nxpdev->new_baudrate = nxpdev->secondary_baudrate; 974 970 if (nxp_fw_change_baudrate(hdev, len)) { 975 971 nxpdev->baudrate_changed = changed; 976 972 serdev_device_set_baudrate(nxpdev->serdev, 977 - HCI_NXP_SEC_BAUDRATE); 973 + nxpdev->secondary_baudrate); 978 974 serdev_device_set_flow_control(nxpdev->serdev, true); 979 - nxpdev->current_baudrate = HCI_NXP_SEC_BAUDRATE; 975 + nxpdev->current_baudrate = nxpdev->secondary_baudrate; 980 976 } 981 977 goto free_skb; 982 978 } ··· 998 992 nxpdev->helper_downloaded = true; 999 993 serdev_device_wait_until_sent(nxpdev->serdev, 0); 1000 994 serdev_device_set_baudrate(nxpdev->serdev, 1001 - HCI_NXP_SEC_BAUDRATE); 995 + HCI_NXP_SEC_BAUDRATE_3M); 1002 996 serdev_device_set_flow_control(nxpdev->serdev, true); 1003 997 } else { 1004 998 clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); ··· 1222 1216 } 1223 1217 1224 1218 if (nxpdev->baudrate_changed != changed) { 1219 + nxpdev->new_baudrate = nxpdev->secondary_baudrate; 1225 1220 if (nxp_fw_change_baudrate(hdev, len)) { 1226 1221 nxpdev->baudrate_changed = cmd_sent; 1227 1222 serdev_device_set_baudrate(nxpdev->serdev, 1228 - HCI_NXP_SEC_BAUDRATE); 1223 + nxpdev->secondary_baudrate); 1229 1224 serdev_device_set_flow_control(nxpdev->serdev, true); 1230 - nxpdev->current_baudrate = HCI_NXP_SEC_BAUDRATE; 1225 + nxpdev->current_baudrate = nxpdev->secondary_baudrate; 1231 1226 } 1232 1227 goto free_skb; 1233 1228 } ··· 1454 1447 struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); 1455 1448 struct ps_data *psdata = &nxpdev->psdata; 1456 1449 1457 - if (nxpdev->current_baudrate != HCI_NXP_SEC_BAUDRATE) { 1458 - nxpdev->new_baudrate = HCI_NXP_SEC_BAUDRATE; 1450 + if (nxpdev->current_baudrate != nxpdev->secondary_baudrate) { 1451 + nxpdev->new_baudrate = nxpdev->secondary_baudrate; 1459 1452 nxp_set_baudrate_cmd(hdev, NULL); 1460 1453 } 1461 1454 if (psdata->cur_h2c_wakeupmode != psdata->h2c_wakeupmode) ··· 1779 1772 &nxpdev->fw_init_baudrate); 1780 1773 if (!nxpdev->fw_init_baudrate) 1781 1774 nxpdev->fw_init_baudrate = FW_INIT_BAUDRATE; 1775 + 1776 + device_property_read_u32(&nxpdev->serdev->dev, "max-speed", 1777 + &nxpdev->secondary_baudrate); 1778 + if (!nxpdev->secondary_baudrate || 1779 + (nxpdev->secondary_baudrate != HCI_NXP_SEC_BAUDRATE_3M && 1780 + nxpdev->secondary_baudrate != HCI_NXP_SEC_BAUDRATE_4M)) { 1781 + if (nxpdev->secondary_baudrate) 1782 + dev_err(&serdev->dev, 1783 + "Invalid max-speed. Using default 3000000."); 1784 + nxpdev->secondary_baudrate = HCI_NXP_SEC_BAUDRATE_3M; 1785 + } 1782 1786 1783 1787 set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); 1784 1788