From: Cai Yu <caiyu7372@gmail.com>
To: Marcel Holtmann <marcel@holtmann.org>,
Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 4/4] Bluetooth: hci_intel: download the CcP firmware at 921.6 kbaud
Date: Sat, 26 Sep 2026 07:40:43 +0800 [thread overview]
Message-ID: <20260925234043.707679-5-caiyu7372@gmail.com> (raw)
In-Reply-To: <20260925234043.707679-1-caiyu7372@gmail.com>
The CcP bootloader stops acknowledging firmware fragments when the image
is transferred at the operating speed of the driver (3 Mbaud): on a
ThinkPad X1 Fold Gen1 the 801 KB image aborts with a "command 0xfc09 tx
timeout" after ~4 s at 2 and at 3 Mbaud (3 Mbaud completed only 3 out of
11 boots), while 921.6 kbaud completed on every boot in 12.5 s (115.2
kbaud needs 83 s).
This is not a baudrate mismatch: the host divisor is exact for all of
these rates (verified through the clock framework and the dw8250 divisor
helpers) and short commands are answered correctly at 2 and 3 Mbaud - the
link loses a frame on long transfers.
Switch to 921.6 kbaud for the download and restore init_speed before the
firmware is started, which is where the operational firmware expects to
be: this controller does not follow a vendor speed change once its
firmware is running.
Speed measurements for the same controller and image:
115200 -> 83 s 230400 -> 43 s 921600 -> 12.5 s (5/5)
2000000 -> aborts immediately 3000000 -> 3/11
Signed-off-by: Cai Yu <caiyu7372@gmail.com>
---
drivers/bluetooth/hci_intel.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
index 5926d1f..41f8e1a 100644
--- a/drivers/bluetooth/hci_intel.c
+++ b/drivers/bluetooth/hci_intel.c
@@ -36,6 +36,11 @@
#define STATE_SUSPENDED 7
#define STATE_LPM_TRANSACTION 8
+/* The CcP bootloader cannot transfer the firmware image at the rates the
+ * driver uses for the operating mode: see the comment in intel_setup().
+ */
+#define INTEL_CCP_DOWNLOAD_SPEED 921600
+
#define HCI_LPM_WAKE_PKT 0xf0
#define HCI_LPM_PKT 0xf1
#define HCI_LPM_MAX_SIZE 10
@@ -539,6 +544,7 @@ static int intel_setup(struct hci_uart *hu)
ktime_t calltime, delta, rettime;
unsigned long long duration;
unsigned int init_speed, oper_speed;
+ bool download_speed_change = false;
int speed_change = 0;
int err;
@@ -652,6 +658,29 @@ static int intel_setup(struct hci_uart *hu)
return -ENODEV;
}
+ /* The controller starts in bootloader mode and does not keep its
+ * firmware across a power cycle, so the image has to be downloaded on
+ * every boot. This bootloader stops acknowledging firmware fragments
+ * when the transfer runs at the operating speed of the driver: on the
+ * ThinkPad X1 Fold Gen1 the 801 KB image aborts with a "command 0xfc09
+ * tx timeout" after ~4 s at 2 and at 3 Mbaud (3 Mbaud completed only 3
+ * out of 11 boots), while 921.6 kbaud completed on every boot in 12.5 s
+ * and 115.2 kbaud needs 83 s. Short commands at the same speeds are
+ * answered correctly, so this is not a baudrate mismatch - the link
+ * loses a frame on long transfers.
+ *
+ * Use 921.6 kbaud for the download and restore init_speed before the
+ * firmware is started: this controller does not follow a vendor speed
+ * change once its firmware is running.
+ */
+ if (hu->serdev && ver.hw_variant == 0x14) {
+ err = intel_set_baudrate(hu, INTEL_CCP_DOWNLOAD_SPEED);
+ if (err)
+ return err;
+
+ download_speed_change = true;
+ }
+
/* Read the secure boot parameters to identify the operating
* details of the bootloader.
*/
@@ -807,7 +836,7 @@ done:
return err;
/* We need to restore the default speed before Intel reset */
- if (speed_change) {
+ if (speed_change || download_speed_change) {
err = intel_set_baudrate(hu, init_speed);
if (err)
return err;
prev parent reply other threads:[~2026-09-25 23:40 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-25 23:40 [RFC PATCH 0/4] Bluetooth: hci_intel: support the CcP controller (X1 Fold Gen1) Cai Yu
2026-09-25 23:40 ` [RFC PATCH 1/4] Bluetooth: hci_intel: fix tty-only assumptions in the LPM paths Cai Yu
2026-09-26 1:11 ` Bluetooth: hci_intel: support the CcP controller (X1 Fold Gen1) bluez.test.bot
2026-09-25 23:40 ` [RFC PATCH 2/4] Bluetooth: hci_intel: add the CcP controller (hardware variant 0x14) Cai Yu
2026-09-25 23:40 ` [RFC PATCH 3/4] Bluetooth: hci_intel: add serdev support for the CcP controller Cai Yu
2026-09-25 23:40 ` Cai Yu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260925234043.707679-5-caiyu7372@gmail.com \
--to=caiyu7372@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.