Re: [PATCH v2 1/3] Bluetooth: hci_qca: Add support for QTI Bluetooth chip wcn6750

2021-04-20 Thread Matthias Kaehlcke
On Tue, Apr 20, 2021 at 09:56:48PM +0530, Venkata Lakshmi Narayana Gubba wrote:
> Added regulators,GPIOs and changes required to power on/off wcn6750.
> Added support for firmware download for wcn6750.
> 
> Changes done in detail:
> 1. Added regulators and corresponding current values.
> 2. Added sw_ctrl GPIO pin which is output from BT SoC and indicates
>status of clock supply to BT SoC.
> 3. Added inline function to check if the SoC type is wcn399x or wcn6750.
> 4. Modified the function qca_wcn3990_init() to support wcn6750 and
>renamed it to qca_regulator_init().
> 5. Added BT_ON and BT_OFF macros.
> 6. Added support to download mbn type firmware image as wcn6750 supports
>mbn type image.
> 7. If mbn type image is not present then we will check for tlv type image.
> 8. Moved extracting rom version info to common place as this code is
>common in all if else ladder in qca_uart_setup.
> 
> Signed-off-by: Venkata Lakshmi Narayana Gubba 
> ---
>  drivers/bluetooth/btqca.c   |  88 ++--
>  drivers/bluetooth/btqca.h   |  15 ++-
>  drivers/bluetooth/hci_qca.c | 106 
> ++--
>  3 files changed, 161 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> index 25114f0..eec391a 100644
> --- a/drivers/bluetooth/btqca.c
> +++ b/drivers/bluetooth/btqca.c
> @@ -182,7 +182,8 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
>  }
>  EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
>  
> -static void qca_tlv_check_data(struct qca_fw_config *config,
> +static void qca_tlv_check_data(struct hci_dev *hdev,
> +struct qca_fw_config *config,
>   const struct firmware *fw, enum qca_btsoc_type soc_type)
>  {
>   const u8 *data;
> @@ -194,19 +195,21 @@ static void qca_tlv_check_data(struct qca_fw_config 
> *config,
>   struct tlv_type_nvm *tlv_nvm;
>   uint8_t nvm_baud_rate = config->user_baud_rate;
>  
> - tlv = (struct tlv_type_hdr *)fw->data;
> -
> - type_len = le32_to_cpu(tlv->type_len);
> - length = (type_len >> 8) & 0x00ff;
> -
> - BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
> - BT_DBG("Length\t\t : %d bytes", length);
> -
>   config->dnld_mode = QCA_SKIP_EVT_NONE;
>   config->dnld_type = QCA_SKIP_EVT_NONE;
>  
>   switch (config->type) {
> + case ELF_TYPE_PATCH:
> + config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
> + config->dnld_type = QCA_SKIP_EVT_VSE_CC;
> +
> + bt_dev_dbg(hdev, "File Class: 0x%x", fw->data[4]);
> + bt_dev_dbg(hdev, "Data Encoding : 0x%x", fw->data[5]);
> + bt_dev_dbg(hdev, "File version  : 0x%x", fw->data[6]);
> + break;
>   case TLV_TYPE_PATCH:
> + tlv = (struct tlv_type_hdr *)fw->data;
> + type_len = le32_to_cpu(tlv->type_len);
>   tlv_patch = (struct tlv_type_patch *)tlv->data;
>  
>   /* For Rome version 1.1 to 3.1, all segment commands
> @@ -218,6 +221,7 @@ static void qca_tlv_check_data(struct qca_fw_config 
> *config,
>   config->dnld_mode = tlv_patch->download_mode;
>   config->dnld_type = config->dnld_mode;
>  
> + BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
>   BT_DBG("Total Length   : %d bytes",
>  le32_to_cpu(tlv_patch->total_size));
>   BT_DBG("Patch Data Length  : %d bytes",
> @@ -243,6 +247,14 @@ static void qca_tlv_check_data(struct qca_fw_config 
> *config,
>   break;
>  
>   case TLV_TYPE_NVM:
> + tlv = (struct tlv_type_hdr *)fw->data;
> +
> + type_len = le32_to_cpu(tlv->type_len);
> + length = (type_len >> 8) & 0x00ff;
> +
> + BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
> + BT_DBG("Length\t\t : %d bytes", length);
> +

To keep the wcn6750 shorther you could consider to have a separate patch
for the ELF type and the additional logging.

>   idx = 0;
>   data = tlv->data;
>   while (idx < length) {
> @@ -387,7 +399,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev 
> *hdev)
>  
>  static int qca_download_firmware(struct hci_dev *hdev,
>struct qca_fw_config *config,
> -  enum qca_btsoc_type soc_type)
> +  enum qca_btsoc_type soc_type,
> +  u8 rom_ver)
>  {
>   const struct firmware *fw;
>   const u8 *segment;
> @@ -397,12 +410,29 @@ static int qca_download_firmware(struct hci_dev *hdev,
>  
>   ret = request_firmware(, config->fwname, >dev);
>   if (ret) {
> - bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
> -config->fwname, ret);
> - return ret;
> + /* For WCN6750, if mbn file is not 

[PATCH v2 1/3] Bluetooth: hci_qca: Add support for QTI Bluetooth chip wcn6750

2021-04-20 Thread Venkata Lakshmi Narayana Gubba
Added regulators,GPIOs and changes required to power on/off wcn6750.
Added support for firmware download for wcn6750.

Changes done in detail:
1. Added regulators and corresponding current values.
2. Added sw_ctrl GPIO pin which is output from BT SoC and indicates
   status of clock supply to BT SoC.
3. Added inline function to check if the SoC type is wcn399x or wcn6750.
4. Modified the function qca_wcn3990_init() to support wcn6750 and
   renamed it to qca_regulator_init().
5. Added BT_ON and BT_OFF macros.
6. Added support to download mbn type firmware image as wcn6750 supports
   mbn type image.
7. If mbn type image is not present then we will check for tlv type image.
8. Moved extracting rom version info to common place as this code is
   common in all if else ladder in qca_uart_setup.

Signed-off-by: Venkata Lakshmi Narayana Gubba 
---
 drivers/bluetooth/btqca.c   |  88 ++--
 drivers/bluetooth/btqca.h   |  15 ++-
 drivers/bluetooth/hci_qca.c | 106 ++--
 3 files changed, 161 insertions(+), 48 deletions(-)

diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 25114f0..eec391a 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -182,7 +182,8 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
 
-static void qca_tlv_check_data(struct qca_fw_config *config,
+static void qca_tlv_check_data(struct hci_dev *hdev,
+  struct qca_fw_config *config,
const struct firmware *fw, enum qca_btsoc_type soc_type)
 {
const u8 *data;
@@ -194,19 +195,21 @@ static void qca_tlv_check_data(struct qca_fw_config 
*config,
struct tlv_type_nvm *tlv_nvm;
uint8_t nvm_baud_rate = config->user_baud_rate;
 
-   tlv = (struct tlv_type_hdr *)fw->data;
-
-   type_len = le32_to_cpu(tlv->type_len);
-   length = (type_len >> 8) & 0x00ff;
-
-   BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
-   BT_DBG("Length\t\t : %d bytes", length);
-
config->dnld_mode = QCA_SKIP_EVT_NONE;
config->dnld_type = QCA_SKIP_EVT_NONE;
 
switch (config->type) {
+   case ELF_TYPE_PATCH:
+   config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
+   config->dnld_type = QCA_SKIP_EVT_VSE_CC;
+
+   bt_dev_dbg(hdev, "File Class: 0x%x", fw->data[4]);
+   bt_dev_dbg(hdev, "Data Encoding : 0x%x", fw->data[5]);
+   bt_dev_dbg(hdev, "File version  : 0x%x", fw->data[6]);
+   break;
case TLV_TYPE_PATCH:
+   tlv = (struct tlv_type_hdr *)fw->data;
+   type_len = le32_to_cpu(tlv->type_len);
tlv_patch = (struct tlv_type_patch *)tlv->data;
 
/* For Rome version 1.1 to 3.1, all segment commands
@@ -218,6 +221,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
config->dnld_mode = tlv_patch->download_mode;
config->dnld_type = config->dnld_mode;
 
+   BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
BT_DBG("Total Length   : %d bytes",
   le32_to_cpu(tlv_patch->total_size));
BT_DBG("Patch Data Length  : %d bytes",
@@ -243,6 +247,14 @@ static void qca_tlv_check_data(struct qca_fw_config 
*config,
break;
 
case TLV_TYPE_NVM:
+   tlv = (struct tlv_type_hdr *)fw->data;
+
+   type_len = le32_to_cpu(tlv->type_len);
+   length = (type_len >> 8) & 0x00ff;
+
+   BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x00ff);
+   BT_DBG("Length\t\t : %d bytes", length);
+
idx = 0;
data = tlv->data;
while (idx < length) {
@@ -387,7 +399,8 @@ static int qca_inject_cmd_complete_event(struct hci_dev 
*hdev)
 
 static int qca_download_firmware(struct hci_dev *hdev,
 struct qca_fw_config *config,
-enum qca_btsoc_type soc_type)
+enum qca_btsoc_type soc_type,
+u8 rom_ver)
 {
const struct firmware *fw;
const u8 *segment;
@@ -397,12 +410,29 @@ static int qca_download_firmware(struct hci_dev *hdev,
 
ret = request_firmware(, config->fwname, >dev);
if (ret) {
-   bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
-  config->fwname, ret);
-   return ret;
+   /* For WCN6750, if mbn file is not present then check for
+* tlv file.
+*/
+   if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) {
+   bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",
+  config->fwname, ret);
+