diff --git a/drivers/soc/qcom/icnss2/main.c b/drivers/soc/qcom/icnss2/main.c index eec972a1bb34..370b8a9109c0 100644 --- a/drivers/soc/qcom/icnss2/main.c +++ b/drivers/soc/qcom/icnss2/main.c @@ -554,10 +554,6 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv, set_bit(ICNSS_WLFW_CONNECTED, &priv->state); - ret = icnss_hw_power_on(priv); - if (ret) - goto clear_server; - ret = wlfw_ind_register_send_sync_msg(priv); if (ret < 0) { if (ret == -EALREADY) { @@ -565,46 +561,50 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv, goto qmi_registered; } ignore_assert = true; - goto err_power_on; + goto clear_server; } if (priv->device_id == WCN6750_DEVICE_ID) { ret = wlfw_host_cap_send_sync(priv); if (ret < 0) - goto err_power_on; + goto clear_server; } if (priv->device_id == ADRASTEA_DEVICE_ID) { if (!priv->msa_va) { icnss_pr_err("Invalid MSA address\n"); ret = -EINVAL; - goto err_power_on; + goto clear_server; } ret = wlfw_msa_mem_info_send_sync_msg(priv); if (ret < 0) { ignore_assert = true; - goto err_power_on; + goto clear_server; } ret = wlfw_msa_ready_send_sync_msg(priv); if (ret < 0) { ignore_assert = true; - goto err_power_on; + goto clear_server; } } ret = wlfw_cap_send_sync_msg(priv); if (ret < 0) { ignore_assert = true; - goto err_power_on; + goto clear_server; } + ret = icnss_hw_power_on(priv); + if (ret) + goto clear_server; + if (priv->device_id == WCN6750_DEVICE_ID) { ret = wlfw_device_info_send_msg(priv); if (ret < 0) { ignore_assert = true; - goto err_power_on; + goto device_info_failure; } priv->mem_base_va = devm_ioremap(&priv->pdev->dev, @@ -612,7 +612,7 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv, priv->mem_base_size); if (!priv->mem_base_va) { icnss_pr_err("Ioremap failed for bar address\n"); - goto err_power_on; + goto device_info_failure; } icnss_pr_dbg("Non-Secured Bar Address pa: %pa, va: 0x%pK\n", @@ -642,7 +642,7 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv, return ret; -err_power_on: +device_info_failure: icnss_hw_power_off(priv); clear_server: icnss_clear_server(priv); @@ -3229,6 +3229,7 @@ static int icnss_probe(struct platform_device *pdev) priv->pdev = pdev; priv->device_id = device_id->driver_data; + priv->is_chain1_supported = true; INIT_LIST_HEAD(&priv->vreg_list); INIT_LIST_HEAD(&priv->clk_list); icnss_allow_recursive_recovery(dev); diff --git a/drivers/soc/qcom/icnss2/main.h b/drivers/soc/qcom/icnss2/main.h index 58a3b313b9b6..f436ac411740 100644 --- a/drivers/soc/qcom/icnss2/main.h +++ b/drivers/soc/qcom/icnss2/main.h @@ -128,6 +128,7 @@ struct icnss_vreg_cfg { u32 delay_us; u32 need_unvote; bool required; + bool is_supported; }; struct icnss_vreg_info { @@ -418,6 +419,8 @@ struct icnss_priv { void *hang_event_data; struct list_head icnss_tcdev_list; struct mutex tcdev_lock; + bool is_chain1_supported; + bool chain_reg_info_updated; }; struct icnss_reg_info { diff --git a/drivers/soc/qcom/icnss2/power.c b/drivers/soc/qcom/icnss2/power.c index 7fe57aab6d4a..fe19f1f90315 100644 --- a/drivers/soc/qcom/icnss2/power.c +++ b/drivers/soc/qcom/icnss2/power.c @@ -15,17 +15,17 @@ #include "power.h" static struct icnss_vreg_cfg icnss_wcn6750_vreg_list[] = { - {"vdd-cx-mx", 824000, 952000, 0, 0, 0, false}, - {"vdd-1.8-xo", 1872000, 1872000, 0, 0, 0, false}, - {"vdd-1.3-rfa", 1256000, 1352000, 0, 0, 0, false}, + {"vdd-cx-mx", 824000, 952000, 0, 0, 0, false, true}, + {"vdd-1.8-xo", 1872000, 1872000, 0, 0, 0, false, true}, + {"vdd-1.3-rfa", 1256000, 1352000, 0, 0, 0, false, true}, }; static struct icnss_vreg_cfg icnss_adrestea_vreg_list[] = { - {"vdd-cx-mx", 752000, 752000, 0, 0, 0, false}, - {"vdd-1.8-xo", 1800000, 1800000, 0, 0, 0, false}, - {"vdd-1.3-rfa", 1304000, 1304000, 0, 0, 0, false}, - {"vdd-3.3-ch1", 3312000, 3312000, 0, 0, 0, false}, - {"vdd-3.3-ch0", 3312000, 3312000, 0, 0, 0, false}, + {"vdd-cx-mx", 752000, 752000, 0, 0, 0, false, true}, + {"vdd-1.8-xo", 1800000, 1800000, 0, 0, 0, false, true}, + {"vdd-1.3-rfa", 1304000, 1304000, 0, 0, 0, false, true}, + {"vdd-3.3-ch1", 3312000, 3312000, 0, 0, 0, false, true}, + {"vdd-3.3-ch0", 3312000, 3312000, 0, 0, 0, false, true}, }; static struct icnss_clk_cfg icnss_clk_list[] = { @@ -41,6 +41,7 @@ static struct icnss_clk_cfg icnss_adrestea_clk_list[] = { #define ICNSS_CLK_LIST_SIZE ARRAY_SIZE(icnss_clk_list) #define ICNSS_CLK_ADRESTEA_LIST_SIZE ARRAY_SIZE(icnss_adrestea_clk_list) +#define ICNSS_CHAIN1_REGULATOR "vdd-3.3-ch1" #define MAX_PROP_SIZE 32 #define ICNSS_THRESHOLD_HIGH 3600000 #define ICNSS_THRESHOLD_LOW 3450000 @@ -338,8 +339,17 @@ static int icnss_vreg_on(struct icnss_priv *priv) int ret = 0; list_for_each_entry(vreg, vreg_list, list) { - if (IS_ERR_OR_NULL(vreg->reg)) + if (IS_ERR_OR_NULL(vreg->reg) || !vreg->cfg.is_supported) continue; + if (!priv->chain_reg_info_updated && + !strcmp(ICNSS_CHAIN1_REGULATOR, vreg->cfg.name)) { + priv->chain_reg_info_updated = true; + if (!priv->is_chain1_supported) { + vreg->cfg.is_supported = false; + continue; + } + } + ret = icnss_vreg_on_single(vreg); if (ret) break; diff --git a/drivers/soc/qcom/icnss2/qmi.c b/drivers/soc/qcom/icnss2/qmi.c index 296ccaf2bb85..5673f9114899 100644 --- a/drivers/soc/qcom/icnss2/qmi.c +++ b/drivers/soc/qcom/icnss2/qmi.c @@ -686,6 +686,10 @@ int wlfw_cap_send_sync_msg(struct icnss_priv *priv) strlcpy(priv->fw_build_id, resp->fw_build_id, QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1); + if (resp->rd_card_chain_cap_valid && + resp->rd_card_chain_cap == WLFW_RD_CARD_CHAIN_CAP_1x1_V01) + priv->is_chain1_supported = false; + icnss_pr_dbg("Capability, chip_id: 0x%x, chip_family: 0x%x, board_id: 0x%x, soc_id: 0x%x, fw_version: 0x%x, fw_build_timestamp: %s, fw_build_id: %s", priv->chip_info.chip_id, priv->chip_info.chip_family, priv->board_id, priv->soc_id,