> -----Original Message----- > From: Neeraj Sanjay Kale <neeraj.sanjaykale@xxxxxxx> > Sent: Wednesday, June 18, 2025 10:20 PM > To: marcel@xxxxxxxxxxxx; luiz.dentz@xxxxxxxxx; robh@xxxxxxxxxx; > krzk+dt@xxxxxxxxxx; conor+dt@xxxxxxxxxx > Cc: linux-bluetooth@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; > devicetree@xxxxxxxxxxxxxxx; Amitkumar Karwar > <amitkumar.karwar@xxxxxxx>; Neeraj Sanjay Kale > <neeraj.sanjaykale@xxxxxxx>; Sherry Sun <sherry.sun@xxxxxxx>; Manjeet > Gupta <manjeet.gupta@xxxxxxx> > Subject: [PATCH v2 2/2] 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. > > 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. > > Signed-off-by: Neeraj Sanjay Kale <neeraj.sanjaykale@xxxxxxx> > --- > v2: Change DT property to 'max-speed'. (Krzysztof) > Add support for 4M baudrate to w8987. Update commit message. > (Sherry) > --- > drivers/bluetooth/btnxpuart.c | 30 +++++++++++++++++++++--------- > 1 file changed, 21 insertions(+), 9 deletions(-) > > diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c > index 6b13feed06df..c9b3e158f438 100644 > --- a/drivers/bluetooth/btnxpuart.c > +++ b/drivers/bluetooth/btnxpuart.c > @@ -73,7 +73,8 @@ > #define FW_AUTH_ENC 0xc0 > > #define HCI_NXP_PRI_BAUDRATE 115200 > -#define HCI_NXP_SEC_BAUDRATE 3000000 > +#define HCI_NXP_SEC_BAUDRATE_3M 3000000 > +#define HCI_NXP_SEC_BAUDRATE_4M 4000000 > > #define MAX_FW_FILE_NAME_LEN 50 > > @@ -201,6 +202,7 @@ struct btnxpuart_dev { > u32 new_baudrate; > u32 current_baudrate; > u32 fw_init_baudrate; > + u32 secondary_baudrate; > enum bootloader_param_change timeout_changed; > enum bootloader_param_change baudrate_changed; > bool helper_downloaded; > @@ -802,7 +804,10 @@ static bool nxp_fw_change_baudrate(struct hci_dev > *hdev, u16 req_len) > nxpdev->fw_v3_offset_correction += req_len; > } else if (req_len == sizeof(uart_config)) { > uart_config.clkdiv.address = __cpu_to_le32(clkdivaddr); > - uart_config.clkdiv.value = __cpu_to_le32(0x00c00000); > + if (nxpdev->new_baudrate == HCI_NXP_SEC_BAUDRATE_4M) > + uart_config.clkdiv.value = > __cpu_to_le32(0x01000000); > + else > + uart_config.clkdiv.value = > __cpu_to_le32(0x00c00000); > uart_config.uartdiv.address = __cpu_to_le32(uartdivaddr); > uart_config.uartdiv.value = __cpu_to_le32(1); > uart_config.mcr.address = __cpu_to_le32(uartmcraddr); @@ > -966,12 +971,13 @@ static int nxp_recv_fw_req_v1(struct hci_dev *hdev, > struct sk_buff *skb) > goto free_skb; > } > if (nxpdev->baudrate_changed != changed) { > + nxpdev->new_baudrate = nxpdev- > >secondary_baudrate; > if (nxp_fw_change_baudrate(hdev, len)) { > nxpdev->baudrate_changed = changed; > serdev_device_set_baudrate(nxpdev->serdev, > - > HCI_NXP_SEC_BAUDRATE); > + nxpdev- > >secondary_baudrate); > serdev_device_set_flow_control(nxpdev- > >serdev, true); > - nxpdev->current_baudrate = > HCI_NXP_SEC_BAUDRATE; > + nxpdev->current_baudrate = nxpdev- > >secondary_baudrate; > } > goto free_skb; > } > @@ -992,7 +998,7 @@ static int nxp_recv_fw_req_v1(struct hci_dev *hdev, > struct sk_buff *skb) > nxpdev->helper_downloaded = true; > serdev_device_wait_until_sent(nxpdev->serdev, 0); > serdev_device_set_baudrate(nxpdev->serdev, > - HCI_NXP_SEC_BAUDRATE); > + > HCI_NXP_SEC_BAUDRATE_3M); > serdev_device_set_flow_control(nxpdev->serdev, > true); > } else { > clear_bit(BTNXPUART_FW_DOWNLOADING, > &nxpdev->tx_state); @@ -1216,12 +1222,13 @@ static int > nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb) > } > > if (nxpdev->baudrate_changed != changed) { > + nxpdev->new_baudrate = nxpdev->secondary_baudrate; > if (nxp_fw_change_baudrate(hdev, len)) { > nxpdev->baudrate_changed = cmd_sent; > serdev_device_set_baudrate(nxpdev->serdev, > - HCI_NXP_SEC_BAUDRATE); > + nxpdev- > >secondary_baudrate); > serdev_device_set_flow_control(nxpdev->serdev, > true); > - nxpdev->current_baudrate = > HCI_NXP_SEC_BAUDRATE; > + nxpdev->current_baudrate = nxpdev- > >secondary_baudrate; > } > goto free_skb; > } > @@ -1447,8 +1454,8 @@ static int nxp_post_init(struct hci_dev *hdev) > struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev); > struct ps_data *psdata = &nxpdev->psdata; > > - if (nxpdev->current_baudrate != HCI_NXP_SEC_BAUDRATE) { > - nxpdev->new_baudrate = HCI_NXP_SEC_BAUDRATE; > + if (nxpdev->current_baudrate != nxpdev->secondary_baudrate) { > + nxpdev->new_baudrate = nxpdev->secondary_baudrate; > nxp_set_baudrate_cmd(hdev, NULL); > } > if (psdata->cur_h2c_wakeupmode != psdata->h2c_wakeupmode) @@ > -1773,6 +1780,11 @@ static int nxp_serdev_probe(struct serdev_device > *serdev) > if (!nxpdev->fw_init_baudrate) > nxpdev->fw_init_baudrate = FW_INIT_BAUDRATE; > > + device_property_read_u32(&nxpdev->serdev->dev, "max-speed", > + &nxpdev->secondary_baudrate); > + if (!nxpdev->secondary_baudrate) > + nxpdev->secondary_baudrate = > HCI_NXP_SEC_BAUDRATE_3M; Hi Neeraj, Seems you missed my comment here in V1 patch, attach again. What if the user sets the wrong secondary_baudrate/max-speed in dts (not 3M or 4M)? Need to add the corresponding error handling here. Make sure the value is 3M or 4M, otherwise report an error. Best Regards Sherry > + > set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state); > > crc8_populate_msb(crc8_table, POLYNOMIAL8); > -- > 2.34.1