raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.01k stars 4.95k forks source link

Bluetooth is not autodetected with device tree (bcm2837-rpi-3-b.dtb) on Raspberry Pi 3 #3675

Open gentoo-root opened 4 years ago

gentoo-root commented 4 years ago

Is this the right place for my bug report? I hope so, because it's kernel-related and Raspberry Pi-specific.

Describe the bug The upstream device tree (bcm2837-rpi-3-b.dtb) attempts to configure Bluetooth:

/* uart0 communicates with the BT module */
&uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>;
        status = "okay";

        bluetooth {
                compatible = "brcm,bcm43438-bt";
                max-speed = <2000000>;
                shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>;
        };
};

However, the code in drivers/of/platform.c skips the bluetooth subsection, because uart0 is defined in bcm283x.dtsi as follows:

                uart0: serial@7e201000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x7e201000 0x200>;
                        interrupts = <2 25>;
                        clocks = <&clocks BCM2835_CLOCK_UART>,
                                 <&clocks BCM2835_CLOCK_VPU>;
                        clock-names = "uartclk", "apb_pclk";
                        arm,primecell-periphid = <0x00241011>;
                };

It contains "arm,primecell" in compatible, which makes the enumeration code in drivers/of/platform.c to return early and skip enumerating children of uart0, i.e. the bluetooth node. As a result, hci_uart is not autoloaded by udev, and when loaded manually, it doesn't autodetect the Bluetooth hardware, so I need to run btattach or hciattach manually.

Tested on both this kernel (built from the 5.7.y branch) and the upstream kernel (5.7.2).

To reproduce

  1. Have bluez installed. Disable hciuart.service or any other scripts that run hciattach or btattach on boot.
  2. Set device_tree=dtbs/broadcom/bcm2837-rpi-3-b.dtb in /boot/config.txt.
  3. Boot the system.

Expected behaviour Bluetooth adaptor is probed with device tree and is visible in the system (e.g., under /sys/class/bluetooth/hci0).

Actual behaviour /sys/class/bluetooth is empty, bluetoothd doesn't autostart, no Bluetooth functionality in the system.

System Sorry, I use a custom distribution, so I don't have many of the requested commands, but I believe the information below should be enough, the rest doesn't seem relevant.

Copy and paste the results of the raspinfo command in to this section. Alternatively, copy and paste a pastebin link, or add answers to the following questions:

Logs dmesg part with debug output enabled in drivers/of/platform.c:

[    0.105038] Serial: AMBA PL011 UART driver
[    0.105406] OF: of_platform_populate()
[    0.105428] OF:  starting at: 
[    0.105456] OF: of_platform_bus_create() - skipping /system, no compatible prop
[    0.105480] OF: of_platform_bus_create() - skipping /axi, no compatible prop
[    0.105505] OF: of_platform_bus_create() - skipping /aliases, no compatible prop
[    0.105805] OF: of_platform_bus_create() - skipping /reserved-memory, no compatible prop
[    0.105830] OF: of_platform_bus_create() - skipping /thermal-zones, no compatible prop
[    0.106069] OF:    create child: /soc/timer@7e003000
[    0.107054] OF:    create child: /soc/txp@7e004000
[    0.107617] OF:    create child: /soc/cprman@7e101000
[    0.108001] OF:    create child: /soc/mailbox@7e00b880
[    0.108578] OF:    create child: /soc/gpio@7e200000
[    0.109561] OF:    create child: /soc/serial@7e201000
[    0.109593] OF: Creating amba device /soc/serial@7e201000
[    0.110384] OF:    create child: /soc/mmc@7e202000
[    0.110945] OF:    create child: /soc/i2s@7e203000
[    0.110984] OF:    create child: /soc/spi@7e204000
[    0.111022] OF:    create child: /soc/i2c@7e205000
[    0.111578] OF:    create child: /soc/dpi@7e208000
[    0.111617] OF:    create child: /soc/dsi@7e209000
[    0.111655] OF:    create child: /soc/aux@7e215000
[    0.112049] OF:    create child: /soc/serial@7e215040
[    0.112617] OF:    create child: /soc/spi@7e215080
[    0.112656] OF:    create child: /soc/spi@7e2150c0
[    0.112694] OF:    create child: /soc/pwm@7e20c000
[    0.113089] OF:    create child: /soc/sdhci@7e300000
[    0.113647] OF:    create child: /soc/hvs@7e400000
[    0.114182] OF:    create child: /soc/dsi@7e700000
[    0.114222] OF:    create child: /soc/i2c@7e804000
[    0.114805] OF:    create child: /soc/vec@7e806000
[    0.115330] OF:    create child: /soc/usb@7e980000
[    0.115899] OF:    create child: /soc/dma@7e007000
[    0.118636] OF:    create child: /soc/interrupt-controller@7e00b200
[    0.118674] OF:    create child: /soc/watchdog@7e100000
[    0.119157] OF:    create child: /soc/rng@7e104000
[    0.119720] OF:    create child: /soc/pixelvalve@7e206000
[    0.120246] OF:    create child: /soc/pixelvalve@7e207000
[    0.120820] OF:    create child: /soc/thermal@7e212000
[    0.121205] OF:    create child: /soc/i2c@7e805000
[    0.121759] OF:    create child: /soc/pixelvalve@7e807000
[    0.122295] OF:    create child: /soc/hdmi@7e902000
[    0.123099] OF:    create child: /soc/v3d@7ec00000
[    0.123661] OF:    create child: /soc/gpu
[    0.123925] OF:    create child: /soc/local_intc@40000000
[    0.123965] OF:    create child: /soc/firmware
[    0.124249] OF:    create child: /soc/firmware/gpio
[    0.124546] OF:    create child: /soc/power
[    0.124865] OF:    create child: /soc/mailbox@7e00b840
[    0.125413] OF: of_platform_bus_create() - skipping /clocks, no compatible prop
[    0.126712] OF: of_platform_bus_create() - skipping /cpus, no compatible prop
[    0.126963] OF: of_platform_bus_create() - skipping /memory@0, no compatible prop

As we see, it doesn't traverse the children of /soc/serial@7e201000, instead it creates an AMBA device.

Additional context It sounds weird that there is a guy who claims that device tree autoprobing of Bluetooth worked for him: https://gist.github.com/shenghaoyang/92e6dd65b9f0cc736a419f3e640663c2. He basically adds a part of the upstream device tree as an overlay for the raspberry device tree (bcm2710-rpi-3-b.dtb). This approach hasn't worked for me either, for the same reason explained above.

pelwell commented 4 years ago

I'm happy with how Bluetooth is configured in our kernel for now, but I will give any Pull Request consideration.

macmpi commented 4 years ago

cross-referencing https://github.com/raspberrypi/linux/issues/3459

gentoo-root commented 4 years ago

It turned out that I was missing CONFIG_SERIAL_DEV_CTRL_TTYPORT=y. bcmrpi3_defconfig sets CONFIG_SERIAL_DEV_BUS=m, which is not compatible with CONFIG_SERIAL_DEV_CTRL_TTYPORT. I suggest to set both options to y in the defconfig, this way it works like a charm.

gentoo-root commented 4 years ago

The Bluetooth device under the serial device in the device tree is registered by of_serdev_register_devices, so there is no issue in the behavior I saw and described in the opening post.

macmpi commented 4 years ago

Very interesting indeed. With that, what's the resulting serial interface speed (and flow-control status) once BT is set? Do you get good-enough BT performance in demanding uses-cases such as A2DP? (Pi3 is known to have issues due to missing HW flowcontrol).

pelwell commented 4 years ago

You might want to check that your BDADDR is correct.

gentoo-root commented 4 years ago

With that, what's the resulting serial interface speed (and flow-control status) once BT is set?

How can I check that, given that /dev/ttyAMA0 is missing when it's attached to Bluetooth using device tree?

Do you get good-enough BT performance in demanding uses-cases such as A2DP?

I'm planning to test A2DP (it will be my use case), but for now I still haven't, I'm missing other required things such as alsa.

The autodetection works (that's what this ticket is about), and basic stuff like pairing works too.

Pi3 is known to have issues due to missing HW flowcontrol

Interesting. Is it also the case when I attach Bluetooth with hciattach? Is Pi4 free of these issues?

You might want to check that your BDADDR is correct.

It looks correct and matches the one that btuart would set.

macmpi commented 4 years ago

Dunno how you may check baudrate, but wonders if automated firmware load would not set default baud rate to 115200 which may not be sufficient for A2DP...

Interesting. Is it also the case when I attach Bluetooth with hciattach?

Yes indeed. see this with rev 1.2 (KO) vs rev 1.3 (OK) Pi3 board differences.\ btuart sets it up accordingly.

Is Pi4 free of these issues?

Pi4 , Pi3b+, Pi3 rev 1.3, and PiZeroW have RTS: you may check this and work from @lategoodbye

gentoo-root commented 4 years ago

Thanks for useful links!

wonders if automated firmware load would not set default baud rate to 115200

That is a correct concern. I added some debug prints to amba-pl011.c and hci_bcm.c, and it looks like the baud rate is restored after firmware load:

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index b236cb11c..910b77cdb 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -575,6 +575,7 @@ static int bcm_setup(struct hci_uart *hu)
                bt_dev_info(hu->hdev, "BCM: Patch failed (%d)", err);
                goto finalize;
        }
+       bt_dev_info(hu->hdev, "Firmware loaded");

        /* Init speed if any */
        if (hu->init_speed)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 322ae13d1..a24e7505c 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2004,6 +2004,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
         */
        baud = uart_get_baud_rate(port, termios, old, 0,
                                  port->uartclk / clkdiv);
+       pr_info("PL011: set baud rate %d\b", baud);
 #ifdef CONFIG_DMA_ENGINE
        /*
         * Adjust RX DMA polling rate with baud rate if not specified.
[   16.605640] PL011: set baud rate 9600
[   16.606966] PL011: set baud rate 115200
[   16.651770] PL011: set baud rate 2000000
[   16.757733] Bluetooth: hci0: BCM: chip id 94
[   16.772321] Bluetooth: hci0: BCM: features 0x2e
[   16.783062] Bluetooth: hci0: BCM43430A1
[   16.789767] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000
[   17.316599] Bluetooth: hci0: Firmware loaded
[   17.333797] PL011: set baud rate 115200
[   17.348009] PL011: set baud rate 2000000

So, it looks promising, but I haven't tested A2DP yet.

gentoo-root commented 4 years ago

Tested A2DP (Raspberry Pi was the sink), the sound goes smoothly, so I suppose the baud rate is indeed set correctly (and the debug prints above confirm it).

There are a few instabilities, though.

I got such bursts once or twice (the sound disappeared for less than a second):

[ 1209.257673] Bluetooth: hci0: Frame reassembly failed (-90)
[ 1209.264184] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.270632] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.301414] Bluetooth: hci0: Frame reassembly failed (-90)
[ 1209.307873] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.314325] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.320779] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.343905] Bluetooth: hci0: Frame reassembly failed (-90)
[ 1209.350398] Bluetooth: hci0: Frame reassembly failed (-84)
[ 1209.356825] Bluetooth: hci0: Frame reassembly failed (-84)

Sometimes Bluetooth doesn't come up on boot:

[   15.797659] Bluetooth: hci0: BCM: chip id 94
[   15.805400] Bluetooth: hci0: BCM: features 0x2e
[   15.814517] Bluetooth: hci0: BCM43430A1
[   15.820923] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0000
[   16.605100] Bluetooth: hci0: BCM43430A1 (001.002.009) build 0493
[   18.788514] Bluetooth: hci0: command 0x1002 tx timeout
[   20.836494] Bluetooth: hci0: command 0x0c52 tx timeout
[   22.884496] Bluetooth: hci0: command 0x0c45 tx timeout

Could it be caused by the missing hardware flow control? I.e. if I upgrade to Pi4, will those timeouts disappear?

P.S. I have never tested it with hciattach yet, I'll probably also compile it and check whether it also suffers from "command tx timeout".

pelwell commented 4 years ago

Without flow control, 2Mbaud is very ambitious. With hciattach we run it at 921600 baud, and even then some users have to reduce it to 460800 for reliability over throughput.

gentoo-root commented 4 years ago

Tried 460800 — sound got choppy, but these tx timeout errors still happen sometimes on boot, making Bluetooth unusable:

[   12.324440] Bluetooth: hci0: command 0x0c14 tx timeout
[   20.452510] Bluetooth: hci0: BCM: Reading local name failed (-110)
lategoodbye commented 4 years ago

Disclaimer: i'm not that Bluetooth expert

AFAIR the problem with btbcm driver was that it operates with H4 protocol, which requires hardware flow control. So a better solution would be to make the driver use H5 protocol for Raspberry Pi 3 B rev 1.2.

Edit: According to BCM43340 datasheet page 52 (table 11) the baud rates 921600 and 460800 are not ideal because they have an error rate of 0.16 % .

gentoo-root commented 4 years ago

make the driver use H5 protocol for Raspberry Pi 3 B rev 1.2.

That's really a good idea, I didn't know that BCM43340 also supports H5, but now I see in the datasheet you cited that it does. However, converting the driver to use H5 is more effort, so I'll try it if I happen to have enough free time. In the meanwhile, I'll test hciattach to see if it also suffers from the same errors, and if the device tree configuration doesn't have functional drawbacks compared to hciattach, I'll submit a pull request to change the defconfig and add a DT overlay that would allow people to choose the way they configure Bluetooth (DT or hciattach).

the baud rates 921600 and 460800 are not ideal because they have an error rate of 0.16 % .

Thanks for the hint. I'll stay with 2000000 for now, the datasheet says the error rate is 0%.

pelwell commented 4 years ago

I like the overlay idea because it provides an easily reversible migration path.