summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandeep Singh <quic_sandsing@quicinc.com>2023-02-15 11:34:54 +0530
committerMadan Koyyalamudi <quic_mkoyyala@quicinc.com>2023-02-28 23:33:51 -0800
commitaec346c6bc2cfbe468b37ca5d1eb6616eddb53ca (patch)
tree5f5ecf8d098c2cc5ac93038131b296c008d2fd24
parentecd2be21ed2ec2818afe705170d3dbce5ef4b192 (diff)
downloadwlan-platform-aec346c6bc2cfbe468b37ca5d1eb6616eddb53ca.tar.gz
icnss2: Add support for WLAN WCN6450 device
Add corresponding driver support for WCN6450 device. This change adds compatible dtsi entry, msi config, v3 shadow register config and vreg regulator details along with enabling bootup sequence for WCN6450 device. Change-Id: I406c92cdc2815ffd1108331d382c4972befad998 CRs-Fixed: 3404702
-rw-r--r--icnss2/debug.c2
-rw-r--r--icnss2/main.c72
-rw-r--r--icnss2/main.h2
-rw-r--r--icnss2/power.c16
-rw-r--r--icnss2/qmi.c22
-rw-r--r--inc/icnss2.h6
6 files changed, 93 insertions, 27 deletions
diff --git a/icnss2/debug.c b/icnss2/debug.c
index 44308f1..ac1c9d7 100644
--- a/icnss2/debug.c
+++ b/icnss2/debug.c
@@ -475,7 +475,7 @@ static int icnss_stats_show(struct seq_file *s, void *data)
ICNSS_STATS_DUMP(s, priv, pm_stay_awake);
ICNSS_STATS_DUMP(s, priv, pm_relax);
- if (priv->device_id != WCN6750_DEVICE_ID) {
+ if (priv->device_id == ADRASTEA_DEVICE_ID) {
seq_puts(s, "\n<------------------ MSA stats ------------------->\n");
ICNSS_STATS_DUMP(s, priv, msa_info_req);
ICNSS_STATS_DUMP(s, priv, msa_info_resp);
diff --git a/icnss2/main.c b/icnss2/main.c
index 4a037ae..b254558 100644
--- a/icnss2/main.c
+++ b/icnss2/main.c
@@ -896,7 +896,8 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv,
}
}
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
if (!icnss_get_temperature(priv, &temp)) {
icnss_pr_dbg("Temperature: %d\n", temp);
if (temp < WLAN_EN_TEMP_THRESHOLD)
@@ -938,7 +939,8 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv,
if (ret)
goto fail;
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
ret = wlfw_device_info_send_msg(priv);
if (ret < 0) {
ignore_assert = true;
@@ -978,7 +980,8 @@ static int icnss_driver_event_server_arrive(struct icnss_priv *priv,
goto device_info_failure;
}
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
if (!priv->fw_soc_wake_ack_irq)
register_soc_wake_notif(&priv->pdev->dev);
@@ -1163,7 +1166,8 @@ static int icnss_driver_event_fw_ready_ind(struct icnss_priv *priv, void *data)
clear_bit(ICNSS_MODE_ON, &priv->state);
atomic_set(&priv->soc_wake_ref_count, 0);
- if (priv->device_id == WCN6750_DEVICE_ID)
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID)
icnss_free_qdss_mem(priv);
icnss_pr_info("WLAN FW is ready: 0x%lx\n", priv->state);
@@ -1598,7 +1602,8 @@ static int icnss_driver_event_pd_service_down(struct icnss_priv *priv,
if (priv->force_err_fatal)
ICNSS_ASSERT(0);
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
icnss_send_smp2p(priv, ICNSS_RESET_MSG,
ICNSS_SMP2P_OUT_SOC_WAKE);
icnss_send_smp2p(priv, ICNSS_RESET_MSG,
@@ -2614,7 +2619,8 @@ static int icnss_register_ramdump_devices(struct icnss_priv *priv)
return -ENOMEM;
}
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
priv->m3_dump_phyareg = icnss_create_ramdump_device(priv,
ICNSS_M3_SEGMENT(
ICNSS_M3_SEGMENT_PHYAREG));
@@ -2970,7 +2976,7 @@ out:
}
EXPORT_SYMBOL(icnss_unregister_driver);
-static struct icnss_msi_config msi_config = {
+static struct icnss_msi_config msi_config_wcn6750 = {
.total_vectors = 28,
.total_users = 2,
.users = (struct icnss_msi_user[]) {
@@ -2979,9 +2985,20 @@ static struct icnss_msi_config msi_config = {
},
};
+static struct icnss_msi_config msi_config_wcn6450 = {
+ .total_vectors = 10,
+ .total_users = 1,
+ .users = (struct icnss_msi_user[]) {
+ { .name = "CE", .num_vectors = 10, .base_vector = 0 },
+ },
+};
+
static int icnss_get_msi_assignment(struct icnss_priv *priv)
{
- priv->msi_config = &msi_config;
+ if (priv->device_id == WCN6750_DEVICE_ID)
+ priv->msi_config = &msi_config_wcn6750;
+ else
+ priv->msi_config = &msi_config_wcn6450;
return 0;
}
@@ -3918,7 +3935,7 @@ static ssize_t wlan_en_delay_store(struct device *dev,
struct icnss_priv *priv = dev_get_drvdata(dev);
uint32_t wlan_en_delay = 0;
- if (priv->device_id != WCN6750_DEVICE_ID)
+ if (priv->device_id == ADRASTEA_DEVICE_ID)
return count;
if (sscanf(buf, "%du", &wlan_en_delay) != 1) {
@@ -4085,7 +4102,8 @@ static int icnss_resource_parse(struct icnss_priv *priv)
priv->is_slate_rfa = true;
icnss_pr_err("SLATE rfa is enabled\n");
}
- } else if (priv->device_id == WCN6750_DEVICE_ID) {
+ } else if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"msi_addr");
if (!res) {
@@ -4122,7 +4140,7 @@ static int icnss_resource_parse(struct icnss_priv *priv)
priv->msi_base_data, int_prop);
icnss_get_msi_assignment(priv);
- for (i = 0; i < msi_config.total_vectors; i++) {
+ for (i = 0; i < priv->msi_config->total_vectors; i++) {
res = platform_get_resource(priv->pdev,
IORESOURCE_IRQ, i);
if (!res) {
@@ -4273,7 +4291,8 @@ static int icnss_smmu_dt_parse(struct icnss_priv *priv)
if (!ret && !strcmp("fastmap", iommu_dma_type)) {
icnss_pr_dbg("SMMU S1 stage enabled\n");
priv->smmu_s1_enable = true;
- if (priv->device_id == WCN6750_DEVICE_ID)
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID)
iommu_set_fault_handler(priv->iommu_domain,
icnss_smmu_fault_handler,
priv);
@@ -4339,16 +4358,19 @@ void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name,
if (priv->device_id == ADRASTEA_DEVICE_ID)
scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
ADRASTEA_PATH_PREFIX "%s", name);
- else
+ else if (priv->device_id == WCN6750_DEVICE_ID)
scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
QCA6750_PATH_PREFIX "%s", name);
-
+ else if (priv->device_id == WCN6450_DEVICE_ID)
+ scnprintf(prefix_name, ICNSS_MAX_FILE_NAME,
+ WCN6450_PATH_PREFIX "%s", name);
icnss_pr_dbg("File added with prefix: %s\n", prefix_name);
}
static const struct platform_device_id icnss_platform_id_table[] = {
{ .name = "wcn6750", .driver_data = WCN6750_DEVICE_ID, },
{ .name = "adrastea", .driver_data = ADRASTEA_DEVICE_ID, },
+ { .name = "wcn6450", .driver_data = WCN6450_DEVICE_ID, },
{ },
};
@@ -4359,6 +4381,9 @@ static const struct of_device_id icnss_dt_match[] = {
{
.compatible = "qcom,icnss",
.data = (void *)&icnss_platform_id_table[1]},
+ {
+ .compatible = "qcom,wcn6450",
+ .data = (void *)&icnss_platform_id_table[2]},
{ },
};
@@ -4532,7 +4557,8 @@ static int icnss_probe(struct platform_device *pdev)
if (priv->is_slate_rfa)
init_completion(&priv->slate_boot_complete);
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
priv->soc_wake_wq = alloc_workqueue("icnss_soc_wake_event",
WQ_UNBOUND|WQ_HIGHPRI, 1);
if (!priv->soc_wake_wq) {
@@ -4654,7 +4680,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_pdr_unregister_notifier(priv);
}
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
icnss_genl_exit();
icnss_runtime_pm_deinit(priv);
if (!IS_ERR_OR_NULL(priv->mbox_chan))
@@ -4727,7 +4754,8 @@ static int icnss_pm_suspend(struct device *dev)
ret = priv->ops->pm_suspend(dev);
if (ret == 0) {
- if (priv->device_id == WCN6750_DEVICE_ID) {
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
if (test_bit(ICNSS_PD_RESTART, &priv->state) ||
!test_bit(ICNSS_MODE_ON, &priv->state))
return 0;
@@ -4836,7 +4864,7 @@ static int icnss_pm_runtime_suspend(struct device *dev)
struct icnss_priv *priv = dev_get_drvdata(dev);
int ret = 0;
- if (priv->device_id != WCN6750_DEVICE_ID) {
+ if (priv->device_id == ADRASTEA_DEVICE_ID) {
icnss_pr_err("Ignore runtime suspend:\n");
goto out;
}
@@ -4870,8 +4898,8 @@ static int icnss_pm_runtime_resume(struct device *dev)
struct icnss_priv *priv = dev_get_drvdata(dev);
int ret = 0;
- if (priv->device_id != WCN6750_DEVICE_ID) {
- icnss_pr_err("Ignore runtime resume:\n");
+ if (priv->device_id == ADRASTEA_DEVICE_ID) {
+ icnss_pr_err("Ignore runtime resume\n");
goto out;
}
@@ -4897,8 +4925,8 @@ static int icnss_pm_runtime_idle(struct device *dev)
{
struct icnss_priv *priv = dev_get_drvdata(dev);
- if (priv->device_id != WCN6750_DEVICE_ID) {
- icnss_pr_err("Ignore runtime idle:\n");
+ if (priv->device_id == ADRASTEA_DEVICE_ID) {
+ icnss_pr_err("Ignore runtime idle\n");
goto out;
}
diff --git a/icnss2/main.h b/icnss2/main.h
index d7b0c6f..48bebcf 100644
--- a/icnss2/main.h
+++ b/icnss2/main.h
@@ -22,12 +22,14 @@
#include <linux/timer.h>
#define WCN6750_DEVICE_ID 0x6750
+#define WCN6450_DEVICE_ID 0x6450
#define ADRASTEA_DEVICE_ID 0xabcd
#define THERMAL_NAME_LENGTH 20
#define ICNSS_SMEM_VALUE_MASK 0xFFFFFFFF
#define ICNSS_SMEM_SEQ_NO_POS 16
#define QCA6750_PATH_PREFIX "qca6750/"
#define ADRASTEA_PATH_PREFIX "adrastea/"
+#define WCN6450_PATH_PREFIX "wcn6450/"
#define ICNSS_MAX_FILE_NAME 35
#define ICNSS_PCI_EP_WAKE_OFFSET 4
#define ICNSS_DISABLE_M3_SSR 0
diff --git a/icnss2/power.c b/icnss2/power.c
index adbea83..d45fb8a 100644
--- a/icnss2/power.c
+++ b/icnss2/power.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/delay.h>
@@ -38,6 +39,13 @@ static struct icnss_battery_level icnss_battery_level[] = {
{0, 2850000},
};
+static struct icnss_vreg_cfg icnss_wcn6450_vreg_list[] = {
+ {"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},
+ {"vdd-aon", 1256000, 1352000, 0, 0, 0, false, true},
+};
+
static struct icnss_clk_cfg icnss_clk_list[] = {
{"rf_clk", 0, 0},
};
@@ -48,6 +56,7 @@ static struct icnss_clk_cfg icnss_adrestea_clk_list[] = {
#define ICNSS_VREG_LIST_SIZE ARRAY_SIZE(icnss_wcn6750_vreg_list)
#define ICNSS_VREG_ADRESTEA_LIST_SIZE ARRAY_SIZE(icnss_adrestea_vreg_list)
+#define ICNSS_VREG_EVROS_LIST_SIZE ARRAY_SIZE(icnss_wcn6450_vreg_list)
#define ICNSS_CLK_LIST_SIZE ARRAY_SIZE(icnss_clk_list)
#define ICNSS_CLK_ADRESTEA_LIST_SIZE ARRAY_SIZE(icnss_adrestea_clk_list)
@@ -311,6 +320,10 @@ static struct icnss_vreg_cfg *get_vreg_list(u32 *vreg_list_size,
*vreg_list_size = ICNSS_VREG_ADRESTEA_LIST_SIZE;
return icnss_adrestea_vreg_list;
+ case WCN6450_DEVICE_ID:
+ *vreg_list_size = ICNSS_VREG_EVROS_LIST_SIZE;
+ return icnss_wcn6450_vreg_list;
+
default:
icnss_pr_err("Unsupported device_id 0x%x\n", device_id);
*vreg_list_size = 0;
@@ -524,7 +537,8 @@ int icnss_get_clk(struct icnss_priv *priv)
if (priv->device_id == ADRASTEA_DEVICE_ID) {
clk_cfg = icnss_adrestea_clk_list;
clk_list_size = ICNSS_CLK_ADRESTEA_LIST_SIZE;
- } else if (priv->device_id == WCN6750_DEVICE_ID) {
+ } else if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
clk_cfg = icnss_clk_list;
clk_list_size = ICNSS_CLK_LIST_SIZE;
}
diff --git a/icnss2/qmi.c b/icnss2/qmi.c
index 5ee261f..63d8526 100644
--- a/icnss2/qmi.c
+++ b/icnss2/qmi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#define pr_fmt(fmt) "icnss2_qmi: " fmt
@@ -55,6 +55,9 @@
#define DMS_MAC_NOT_PROVISIONED 16
#define BDWLAN_SIZE 6
#define UMC_CHIP_ID 0x4320
+#define MAX_SHADOW_REG_RESERVED 2
+#define MAX_NUM_SHADOW_REG_V3 (QMI_WLFW_MAX_NUM_SHADOW_REG_V3_USAGE_V01 - \
+ MAX_SHADOW_REG_RESERVED)
#ifdef CONFIG_ICNSS2_DEBUG
bool ignore_fw_timeout;
@@ -546,7 +549,8 @@ int wlfw_ind_register_send_sync_msg(struct icnss_priv *priv)
req->rejuvenate_enable_valid = 1;
req->rejuvenate_enable = 1;
}
- } else if (priv->device_id == WCN6750_DEVICE_ID) {
+ } else if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID) {
req->fw_init_done_enable_valid = 1;
req->fw_init_done_enable = 1;
req->cal_done_enable_valid = 1;
@@ -2969,7 +2973,8 @@ int icnss_register_fw_service(struct icnss_priv *priv)
if (ret < 0)
return ret;
- if (priv->device_id == WCN6750_DEVICE_ID)
+ if (priv->device_id == WCN6750_DEVICE_ID ||
+ priv->device_id == WCN6450_DEVICE_ID)
ret = qmi_add_lookup(&priv->qmi, WLFW_SERVICE_ID_V01,
WLFW_SERVICE_VERS_V01,
WLFW_SERVICE_WCN_INS_ID_V01);
@@ -3060,6 +3065,17 @@ int icnss_send_wlan_enable_to_fw(struct icnss_priv *priv,
memcpy(req.shadow_reg, config->shadow_reg_cfg,
sizeof(struct wlfw_msi_cfg_s_v01) * req.shadow_reg_len);
+ } else if (priv->device_id == WCN6450_DEVICE_ID) {
+ req.shadow_reg_v3_valid = 1;
+ if (config->num_shadow_reg_v3_cfg >
+ MAX_NUM_SHADOW_REG_V3)
+ req.shadow_reg_v3_len = MAX_NUM_SHADOW_REG_V3;
+ else
+ req.shadow_reg_v3_len = config->num_shadow_reg_v3_cfg;
+
+ memcpy(req.shadow_reg_v3, config->shadow_reg_v3_cfg,
+ sizeof(struct wlfw_shadow_reg_v3_cfg_s_v01)
+ * req.shadow_reg_v3_len);
}
ret = wlfw_wlan_cfg_send_sync_msg(priv, &req);
diff --git a/inc/icnss2.h b/inc/icnss2.h
index 51e4e39..c32bec8 100644
--- a/inc/icnss2.h
+++ b/inc/icnss2.h
@@ -95,6 +95,10 @@ struct icnss_shadow_reg_v2_cfg {
u32 addr;
};
+struct icnss_shadow_reg_v3_cfg {
+ u32 addr;
+};
+
struct icnss_rri_over_ddr_cfg {
u32 base_addr_low;
u32 base_addr_high;
@@ -109,6 +113,8 @@ struct icnss_wlan_enable_cfg {
struct icnss_shadow_reg_cfg *shadow_reg_cfg;
u32 num_shadow_reg_v2_cfg;
struct icnss_shadow_reg_v2_cfg *shadow_reg_v2_cfg;
+ u32 num_shadow_reg_v3_cfg;
+ struct icnss_shadow_reg_v3_cfg *shadow_reg_v3_cfg;
bool rri_over_ddr_cfg_valid;
struct icnss_rri_over_ddr_cfg rri_over_ddr_cfg;
};