While adding support for the BCM4354, I discovered a few more things
that weren't working as they should have.
First, we disallow serdev from setting the baudrate on BCM4354. Serdev
sets the oper_speed first before calling hu->setup() in
hci_uart_setup(). On the BCM4354, this results in bcm_setup() failing
when the hci reset times out.
Next, we add support for setting the PCM parameters, which consists of
a pair of vendor specific opcodes to set the pcm parameters. The
documentation for these params are available in the brcm_patchram_plus
package (i.e. https://github.com/balena-os/brcm_patchram_plus). This is
necessary for PCM to work properly.
All changes were tested with rk3288-veyron-minnie.dts.
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
Abhishek Pandit-Subedi (4):
Bluetooth: hci_bcm: Disallow set_baudrate for BCM4354
Bluetooth: btbcm: Support pcm configuration
Bluetooth: hci_bcm: Support pcm params in dts
dt-bindings: net: broadcom-bluetooth: Add pcm config
.../bindings/net/broadcom-bluetooth.txt | 11 +++
drivers/bluetooth/btbcm.c | 18 +++++
drivers/bluetooth/btbcm.h | 8 +++
drivers/bluetooth/hci_bcm.c | 69 ++++++++++++++++++-
4 files changed, 105 insertions(+), 1 deletion(-)
--
2.24.0.rc1.363.gb1bccd3e3d-goog
Without updating the patchram, the BCM4354 does not support a higher
operating speed. The normal bcm_setup follows the correct order
(init_speed, patchram and then oper_speed) but the serdev driver will
set the operating speed before calling the hu->setup function. Thus,
for the BCM4354, disallow setting the operating speed before patchram.
If set_baudrate is called before setup, it will return -EBUSY.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
@@ -79,6 +87,7 @@*@hu:pointertoHCIUARTcontrollerstruct,*usedtodisableflowcontrolduringruntimesuspendandsystemsleep*@is_suspended:whetherflowcontroliscurrentlydisabled+*@disallow_set_baudrate:don'tallowset_baudrate*/structbcm_device{/* Must be the first member, hci_serdev.c expects this. */
@@ -551,6 +565,12 @@ static int bcm_setup(struct hci_uart *hu)gotofinalize;}+/* If we disallow early set baudrate, we can re-enable it now that+*patchramisdone+*/+if(bcm->dev&&bcm->dev->disallow_set_baudrate)+bcm->dev->disallow_set_baudrate=false;+/* Init speed if any */if(hu->init_speed)speed=hu->init_speed;
@@ -1408,6 +1437,8 @@ static int bcm_serdev_probe(struct serdev_device *serdev)if(err)dev_err(&serdev->dev,"Failed to power down\n");+bcm_configure_device_data(bcmdev);+returnhci_uart_register_device(&bcmdev->serdev_hu,&bcm_proto);}
Add BCM vendor specific command to configure PCM parameters. The new
vendor opcode allows us to set the sco routing, the pcm interface rate,
and a few other pcm specific options (frame sync, sync mode, and clock
mode). See broadcom-bluetooth.txt in Documentation for more information
about valid values for those settings.
Here is an example trace where this opcode was used to configure
a BCM4354:
< HCI Command: Vendor (0x3f|0x001c) plen 5
01 02 00 01 01
> HCI Event: Command Complete (0x0e) plen 4
Vendor (0x3f|0x001c) ncmd 1
Status: Success (0x00)
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/btbcm.c | 18 ++++++++++++++++++
drivers/bluetooth/btbcm.h | 8 ++++++++
2 files changed, 26 insertions(+)
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
@@ -88,6 +88,8 @@ struct bcm_device_data {*usedtodisableflowcontrolduringruntimesuspendandsystemsleep*@is_suspended:whetherflowcontroliscurrentlydisabled*@disallow_set_baudrate:don'tallowset_baudrate+*@has_pcm_params:whetherPCMparametersneedtobeconfigured+*@pcm_params:PCMandroutingparameters*/structbcm_device{/* Must be the first member, hci_serdev.c expects this. */
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
Without updating the patchram, the BCM4354 does not support a higher
operating speed. The normal bcm_setup follows the correct order
(init_speed, patchram and then oper_speed) but the serdev driver will
set the operating speed before calling the hu->setup function. Thus,
for the BCM4354, disallow setting the operating speed before patchram.
If set_baudrate is called before setup, it will return -EBUSY.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
@@ -79,6 +87,7 @@ * @hu: pointer to HCI UART controller struct, * used to disable flow control during runtime suspend and system sleep * @is_suspended: whether flow control is currently disabled+ * @disallow_set_baudrate: don't allow set_baudrate */
struct bcm_device {
/* Must be the first member, hci_serdev.c expects this. */
@@ -551,6 +565,12 @@ static int bcm_setup(struct hci_uart *hu)
goto finalize;
}
+ /* If we disallow early set baudrate, we can re-enable it now that
+ * patchram is done
+ */
+ if (bcm->dev && bcm->dev->disallow_set_baudrate)
+ bcm->dev->disallow_set_baudrate = false;
+
Lets not hack a different behavior of bcm_set_baudrate that magically changes based on a bool.
Actually wouldn’t be setting hu->oper_speed to 0 have the same affect and bcm_set_baudrate will not be called after setting the init speed. We should be ensuring that in the case where we do not want the baudrate change before calling ->setup() is somehow covered in hci_ldisc directly and not hacked into the ->set_baudrate callback.
quoted hunk
/* Init speed if any */
if (hu->init_speed)
speed = hu->init_speed;
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
Hi Marcel,
On Tue, Nov 12, 2019 at 4:18 PM Marcel Holtmann [off-list ref] wrote:
Hi Abhishek,
quoted
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
@@ -596,6 +601,16 @@ static int bcm_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); }+ /* PCM parameters if any*/+ if (bcm->dev && bcm->dev->has_pcm_params) {+ err = btbcm_set_pcm_int_params(hu->hdev, &bcm->dev->pcm_params);++ if (err) {+ bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)",+ err);+ }+ }+
finalize:
release_firmware(fw);
@@ -1132,7 +1147,24 @@ static int bcm_acpi_probe(struct bcm_device *dev)
static int bcm_of_probe(struct bcm_device *bdev)
{
+ int err;
+
device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
+
+ err = device_property_read_u8(bdev->dev, "brcm,bt-sco-routing",
+ &bdev->pcm_params.routing);
+ if (!err)
+ bdev->has_pcm_params = true;
I think in case of HCI as routing path, these should be using the default or zero values as defined by Broadcom.
I'm not sure what these default values should be. Wouldn't it be
reasonable to expect the user/developer to set the various brcm
parameters in device tree?
If unset, it's just 0.
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
* used to disable flow control during runtime suspend and system sleep
* @is_suspended: whether flow control is currently disabled
* @disallow_set_baudrate: don't allow set_baudrate
+ * @has_pcm_params: whether PCM parameters need to be configured
+ * @pcm_params: PCM and routing parameters
*/
struct bcm_device {
/* Must be the first member, hci_serdev.c expects this. */
@@ -596,6 +601,16 @@ static int bcm_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); }+ /* PCM parameters if any*/+ if (bcm->dev && bcm->dev->has_pcm_params) {+ err = btbcm_set_pcm_int_params(hu->hdev, &bcm->dev->pcm_params);++ if (err) {+ bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)",+ err);+ }+ }+
finalize:
release_firmware(fw);
@@ -1132,7 +1147,24 @@ static int bcm_acpi_probe(struct bcm_device *dev)
static int bcm_of_probe(struct bcm_device *bdev)
{
+ int err;
+
device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
+
+ err = device_property_read_u8(bdev->dev, "brcm,bt-sco-routing",
+ &bdev->pcm_params.routing);
+ if (!err)
+ bdev->has_pcm_params = true;
I think in case of HCI as routing path, these should be using the default or zero values as defined by Broadcom.
I'm not sure what these default values should be. Wouldn't it be
reasonable to expect the user/developer to set the various brcm
parameters in device tree?
If unset, it's just 0.
if that works with the hardware I am fine with that. The other option is to actually first read the current values. And then only change the ones that are supplied by the DT.
Regards
Marcel
On Wed, Nov 13, 2019 at 9:29 PM Marcel Holtmann [off-list ref] wrote:
Hi Abhishek,
quoted
quoted
quoted
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
* used to disable flow control during runtime suspend and system sleep
* @is_suspended: whether flow control is currently disabled
* @disallow_set_baudrate: don't allow set_baudrate
+ * @has_pcm_params: whether PCM parameters need to be configured
+ * @pcm_params: PCM and routing parameters
*/
struct bcm_device {
/* Must be the first member, hci_serdev.c expects this. */
@@ -596,6 +601,16 @@ static int bcm_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); }+ /* PCM parameters if any*/+ if (bcm->dev && bcm->dev->has_pcm_params) {+ err = btbcm_set_pcm_int_params(hu->hdev, &bcm->dev->pcm_params);++ if (err) {+ bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)",+ err);+ }+ }+
finalize:
release_firmware(fw);
@@ -1132,7 +1147,24 @@ static int bcm_acpi_probe(struct bcm_device *dev)
static int bcm_of_probe(struct bcm_device *bdev)
{
+ int err;
+
device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
+
+ err = device_property_read_u8(bdev->dev, "brcm,bt-sco-routing",
+ &bdev->pcm_params.routing);
+ if (!err)
+ bdev->has_pcm_params = true;
I think in case of HCI as routing path, these should be using the default or zero values as defined by Broadcom.
I'm not sure what these default values should be. Wouldn't it be
reasonable to expect the user/developer to set the various brcm
parameters in device tree?
If unset, it's just 0.
if that works with the hardware I am fine with that. The other option is to actually first read the current values. And then only change the ones that are supplied by the DT.
I don't know of a read pcm params command (this would be nice to have).
I think it might be prudent to default the frame_mode and clock_mode
to master (0x1). I'll test how the hardware responds to 0x0 and update
the default to 0x1 if things fail badly.
BCM chips may require configuration of PCM to operate correctly and
there is a vendor specific HCI command to do this. Add support in the
hci_bcm driver to parse this from devicetree and configure the chip.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
drivers/bluetooth/hci_bcm.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
* used to disable flow control during runtime suspend and system sleep
* @is_suspended: whether flow control is currently disabled
* @disallow_set_baudrate: don't allow set_baudrate
+ * @has_pcm_params: whether PCM parameters need to be configured
+ * @pcm_params: PCM and routing parameters
*/
struct bcm_device {
/* Must be the first member, hci_serdev.c expects this. */
@@ -596,6 +601,16 @@ static int bcm_setup(struct hci_uart *hu) host_set_baudrate(hu, speed); }+ /* PCM parameters if any*/+ if (bcm->dev && bcm->dev->has_pcm_params) {+ err = btbcm_set_pcm_int_params(hu->hdev, &bcm->dev->pcm_params);++ if (err) {+ bt_dev_info(hu->hdev, "BCM: Set pcm params failed (%d)",+ err);+ }+ }+
finalize:
release_firmware(fw);
@@ -1132,7 +1147,24 @@ static int bcm_acpi_probe(struct bcm_device *dev)
static int bcm_of_probe(struct bcm_device *bdev)
{
+ int err;
+
device_property_read_u32(bdev->dev, "max-speed", &bdev->oper_speed);
+
+ err = device_property_read_u8(bdev->dev, "brcm,bt-sco-routing",
+ &bdev->pcm_params.routing);
+ if (!err)
+ bdev->has_pcm_params = true;
I think in case of HCI as routing path, these should be using the default or zero values as defined by Broadcom.
I'm not sure what these default values should be. Wouldn't it be
reasonable to expect the user/developer to set the various brcm
parameters in device tree?
If unset, it's just 0.
if that works with the hardware I am fine with that. The other option is to actually first read the current values. And then only change the ones that are supplied by the DT.
I don't know of a read pcm params command (this would be nice to have).
I think it might be prudent to default the frame_mode and clock_mode
to master (0x1). I'll test how the hardware responds to 0x0 and update
the default to 0x1 if things fail badly.
it is either one opcode down or one opcode up. Look at monitor/broadcom.c since we do actually decode some of these.
Regards
Marcel
From: Doug Anderson <dianders@chromium.org> Date: 2019-11-14 17:29:49
Hi,
On Tue, Nov 12, 2019 at 3:10 PM Abhishek Pandit-Subedi
[off-list ref] wrote:
quoted hunk
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
Since these are optional your patch should describe what happens if
they are not present. I think in patch #3 of the series you guys are
discussing it, but whatever you end up with should be documented here.
That actually made me realize that this is patch #4 in the series. To
be pedantic, bindings are supposed to be _earlier_ in the series than
the code that implements them.
I'm at least marginally curious why your example has a leading 0 for
all numbers. It makes me think you intend them to be represented in
octal, though I don't know offhand if dtc uses that format for octal.
I guess it doesn't matter since all your numbers are between 0 and 5,
but it does seem strange.
-Doug
On Wed, Nov 13, 2019 at 01:21:06AM +0100, Marcel Holtmann wrote:
Hi Abhishek,
quoted
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
My personal taste would be to add a comment after each entry that gives the human readable setting.
I'd suggest to define constants in include/dt-bindings/bluetooth/brcm.h
and use them instead of literals, with this we wouldn't rely on (optional)
comments to make the configuration human readable.
On Thu, Nov 14, 2019 at 9:29 AM Doug Anderson [off-list ref] wrote:
Hi,
On Tue, Nov 12, 2019 at 3:10 PM Abhishek Pandit-Subedi
[off-list ref] wrote:
quoted
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
Since these are optional your patch should describe what happens if
they are not present. I think in patch #3 of the series you guys are
discussing it, but whatever you end up with should be documented here.
Yes, I think I will document the default values here as well.
That actually made me realize that this is patch #4 in the series. To
be pedantic, bindings are supposed to be _earlier_ in the series than
the code that implements them.
I'm at least marginally curious why your example has a leading 0 for
all numbers. It makes me think you intend them to be represented in
octal, though I don't know offhand if dtc uses that format for octal.
I guess it doesn't matter since all your numbers are between 0 and 5,
but it does seem strange.
On Thu, Nov 14, 2019 at 9:58 AM Matthias Kaehlcke [off-list ref] wrote:
On Wed, Nov 13, 2019 at 01:21:06AM +0100, Marcel Holtmann wrote:
quoted
Hi Abhishek,
quoted
Add documentation for pcm parameters.
Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
---
Changes in v4:
- Fix incorrect function name in hci_bcm
Changes in v3:
- Change disallow baudrate setting to return -EBUSY if called before
ready. bcm_proto is no longer modified and is back to being const.
- Changed btbcm_set_pcm_params to btbcm_set_pcm_int_params
- Changed brcm,sco-routing to brcm,bt-sco-routing
Changes in v2:
- Use match data to disallow baudrate setting
- Parse pcm parameters by name instead of as a byte string
- Fix prefix for dt-bindings commit
.../devicetree/bindings/net/broadcom-bluetooth.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
My personal taste would be to add a comment after each entry that gives the human readable setting.
I'd suggest to define constants in include/dt-bindings/bluetooth/brcm.h
and use them instead of literals, with this we wouldn't rely on (optional)
comments to make the configuration human readable.
:+1: Sounds like a good idea; expect it in next patch revision
I'm at least marginally curious why your example has a leading 0 for
all numbers. It makes me think you intend them to be represented in
octal, though I don't know offhand if dtc uses that format for octal.
I guess it doesn't matter since all your numbers are between 0 and 5,
but it does seem strange.
Oh, right! ...except that now it's just one value and not an array of
values, just make it a normal number. Don't worry about the fact that
it'll take up 4 bytes instead of 1--it's clearer for it to just be a
normal number.
...I would also note that the definition of the properties talks
nothing about them being a bytestring. ;-)
-Doug