mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 20:33:58 -04:00
Merge "cnss2: Update driver to support multiple devices"
This commit is contained in:
commit
18b2685bee
9 changed files with 318 additions and 36 deletions
|
|
@ -19,18 +19,39 @@ enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
|
|||
return CNSS_BUS_NONE;
|
||||
}
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
switch (device_id) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
enum cnss_dev_bus_type bus_type = CNSS_BUS_NONE;
|
||||
|
||||
if (plat_priv->is_converged_dt) {
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
ret = of_property_read_u32(dev->of_node, "qcom,bus-type",
|
||||
&bus_type);
|
||||
if (!ret && bus_type <= CNSS_BUS_USB)
|
||||
cnss_pr_dbg("Got bus type[%u] from dt\n", bus_type);
|
||||
else
|
||||
cnss_pr_err("No bus type for converged dt\n");
|
||||
|
||||
return bus_type;
|
||||
}
|
||||
|
||||
/* Get bus type according to device id if it's not converged DT */
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
return CNSS_BUS_PCI;
|
||||
bus_type = CNSS_BUS_PCI;
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
|
||||
return CNSS_BUS_NONE;
|
||||
cnss_pr_err("Unknown device: 0x%lx\n", plat_priv->device_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return bus_type;
|
||||
}
|
||||
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev)
|
||||
|
|
@ -544,3 +565,26 @@ int cnss_bus_get_iova_ipa(struct cnss_plat_data *plat_priv, u64 *addr,
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv,
|
||||
char *msi_name,
|
||||
int *num_vectors,
|
||||
u32 *user_base_data,
|
||||
u32 *base_vector)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_get_user_msi_assignment(plat_priv->bus_priv,
|
||||
msi_name,
|
||||
num_vectors,
|
||||
user_base_data,
|
||||
base_vector);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,15 @@
|
|||
#define QCA6290_DEVICE_ID 0x1100
|
||||
#define QCA6390_VENDOR_ID 0x17CB
|
||||
#define QCA6390_DEVICE_ID 0x1101
|
||||
#define QCN7605_VENDOR_ID 0x17CB
|
||||
#define QCN7605_DEVICE_ID 0x1102
|
||||
#define QCA6490_VENDOR_ID 0x17CB
|
||||
#define QCA6490_DEVICE_ID 0x1103
|
||||
#define WCN7850_VENDOR_ID 0x17CB
|
||||
#define WCN7850_DEVICE_ID 0x1107
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev);
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id);
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv);
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev);
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev);
|
||||
int cnss_bus_init(struct cnss_plat_data *plat_priv);
|
||||
|
|
@ -62,4 +64,9 @@ int cnss_bus_debug_reg_write(struct cnss_plat_data *plat_priv, u32 offset,
|
|||
int cnss_bus_get_iova(struct cnss_plat_data *plat_priv, u64 *addr, u64 *size);
|
||||
int cnss_bus_get_iova_ipa(struct cnss_plat_data *plat_priv, u64 *addr,
|
||||
u64 *size);
|
||||
int cnss_bus_get_msi_assignment(struct cnss_plat_data *plat_priv,
|
||||
char *msi_name,
|
||||
int *num_vectors,
|
||||
u32 *user_base_data,
|
||||
u32 *base_vector);
|
||||
#endif /* _CNSS_BUS_H */
|
||||
|
|
|
|||
|
|
@ -301,6 +301,9 @@ int cnss_wlan_enable(struct device *dev,
|
|||
if (mode == CNSS_WALTEST || mode == CNSS_CCPM)
|
||||
goto skip_cfg;
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
config->send_msi_ce = true;
|
||||
|
||||
ret = cnss_wlfw_wlan_cfg_send_sync(plat_priv, config, host_version);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -435,11 +438,17 @@ static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
|
||||
cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_REGDB);
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
plat_priv->ctrl_params.bdf_type = CNSS_BDF_BIN;
|
||||
|
||||
ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv,
|
||||
plat_priv->ctrl_params.bdf_type);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
ret = cnss_bus_load_m3(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -1596,8 +1605,13 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv,
|
|||
cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
|
||||
cnss_bus_free_qdss_mem(plat_priv);
|
||||
cnss_release_antenna_sharing(plat_priv);
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
goto skip_shutdown;
|
||||
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
msleep(COLD_BOOT_CAL_SHUTDOWN_DELAY_MS);
|
||||
|
||||
skip_shutdown:
|
||||
complete(&plat_priv->cal_complete);
|
||||
clear_bit(CNSS_IN_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
set_bit(CNSS_COLD_BOOT_CAL_DONE, &plat_priv->driver_state);
|
||||
|
|
@ -2183,7 +2197,7 @@ static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
|
|||
dev = &plat_priv->plat_dev->dev;
|
||||
ramdump_info = &plat_priv->ramdump_info;
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
|
||||
if (of_property_read_u32(plat_priv->dev_node, "qcom,wlan-ramdump-dynamic",
|
||||
&ramdump_size) == 0) {
|
||||
ramdump_info->ramdump_va =
|
||||
dma_alloc_coherent(dev, ramdump_size,
|
||||
|
|
@ -2261,13 +2275,13 @@ static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
|
|||
struct cnss_ramdump_info_v2 *info_v2;
|
||||
struct cnss_dump_data *dump_data;
|
||||
struct msm_dump_entry dump_entry;
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
u32 ramdump_size = 0;
|
||||
|
||||
info_v2 = &plat_priv->ramdump_info_v2;
|
||||
dump_data = &info_v2->dump_data;
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
|
||||
if (of_property_read_u32(plat_priv->dev_node,
|
||||
"qcom,wlan-ramdump-dynamic",
|
||||
&ramdump_size) == 0)
|
||||
info_v2->ramdump_size = ramdump_size;
|
||||
|
||||
|
|
@ -2334,6 +2348,7 @@ int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
ret = cnss_register_ramdump_v2(plat_priv);
|
||||
|
|
@ -2354,6 +2369,7 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
cnss_unregister_ramdump_v2(plat_priv);
|
||||
|
|
@ -2477,7 +2493,7 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
|
|||
* For different interconnect path configured in device tree setup voting data
|
||||
* for list of bandwidth requirements.
|
||||
*
|
||||
* Result: 0 for success. -EINVAL if not configured
|
||||
* Result: 0 for success. -ENOMEM if cannot allocate memory
|
||||
*/
|
||||
static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
|
|
@ -2491,8 +2507,8 @@ static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
|
|||
"qcom,icc-path-count",
|
||||
&plat_priv->icc.path_count);
|
||||
if (ret) {
|
||||
cnss_pr_err("Platform Bus Interconnect path not configured\n");
|
||||
return -EINVAL;
|
||||
cnss_pr_dbg("Platform Bus Interconnect path not configured\n");
|
||||
return 0;
|
||||
}
|
||||
ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,bus-bw-cfg-count",
|
||||
|
|
@ -2967,6 +2983,7 @@ static const struct platform_device_id cnss_platform_id_table[] = {
|
|||
{ .name = "qca6390", .driver_data = QCA6390_DEVICE_ID, },
|
||||
{ .name = "qca6490", .driver_data = QCA6490_DEVICE_ID, },
|
||||
{ .name = "wcn7850", .driver_data = WCN7850_DEVICE_ID, },
|
||||
{ .name = "qcaconv", .driver_data = 0},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
@ -2986,6 +3003,9 @@ static const struct of_device_id cnss_of_match_table[] = {
|
|||
{
|
||||
.compatible = "qcom,cnss-wcn7850",
|
||||
.data = (void *)&cnss_platform_id_table[4]},
|
||||
{
|
||||
.compatible = "qcom,cnss-qca-converged",
|
||||
.data = (void *)&cnss_platform_id_table[5]},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cnss_of_match_table);
|
||||
|
|
@ -2997,6 +3017,12 @@ cnss_use_nv_mac(struct cnss_plat_data *plat_priv)
|
|||
"use-nv-mac");
|
||||
}
|
||||
|
||||
static inline bool
|
||||
cnss_is_converged_dt(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return of_property_read_bool(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,converged-dt");
|
||||
}
|
||||
static int cnss_probe(struct platform_device *plat_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -3028,7 +3054,9 @@ static int cnss_probe(struct platform_device *plat_dev)
|
|||
|
||||
plat_priv->plat_dev = plat_dev;
|
||||
plat_priv->device_id = device_id->driver_data;
|
||||
plat_priv->bus_type = cnss_get_bus_type(plat_priv->device_id);
|
||||
plat_priv->is_converged_dt = cnss_is_converged_dt(plat_priv);
|
||||
plat_priv->dev_node = plat_priv->plat_dev->dev.of_node;
|
||||
plat_priv->bus_type = cnss_get_bus_type(plat_priv);
|
||||
plat_priv->use_nv_mac = cnss_use_nv_mac(plat_priv);
|
||||
plat_priv->use_fw_path_with_prefix =
|
||||
cnss_use_fw_path_with_prefix(plat_priv);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
enum cnss_dev_bus_type {
|
||||
CNSS_BUS_NONE = -1,
|
||||
CNSS_BUS_PCI,
|
||||
CNSS_BUS_USB,
|
||||
};
|
||||
|
||||
struct cnss_vreg_cfg {
|
||||
|
|
@ -493,6 +494,8 @@ struct cnss_plat_data {
|
|||
struct cnss_dms_data dms;
|
||||
int power_up_error;
|
||||
u32 hw_trc_override;
|
||||
u32 is_converged_dt;
|
||||
struct device_node *dev_node;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_QCOM
|
||||
|
|
@ -558,5 +561,5 @@ int cnss_enable_int_pow_amp_vreg(struct cnss_plat_data *plat_priv);
|
|||
int cnss_get_tcs_info(struct cnss_plat_data *plat_priv);
|
||||
unsigned int cnss_get_timeout(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_timeout_type);
|
||||
|
||||
int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv);
|
||||
#endif /* _CNSS_MAIN_H */
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/msi.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
|
|
@ -43,6 +44,7 @@
|
|||
#define QCA6390_PATH_PREFIX "qca6390/"
|
||||
#define QCA6490_PATH_PREFIX "qca6490/"
|
||||
#define WCN7850_PATH_PREFIX "wcn7850/"
|
||||
#define QCN7605_PATH_PREFIX "qcn7605/"
|
||||
#define DEFAULT_M3_FILE_NAME "m3.bin"
|
||||
#define DEFAULT_FW_FILE_NAME "amss.bin"
|
||||
#define FW_V2_FILE_NAME "amss20.bin"
|
||||
|
|
@ -2594,6 +2596,7 @@ int cnss_pci_dev_powerup(struct cnss_pci_data *pci_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
ret = cnss_qca6290_powerup(pci_priv);
|
||||
|
|
@ -2622,6 +2625,7 @@ int cnss_pci_dev_shutdown(struct cnss_pci_data *pci_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
ret = cnss_qca6290_shutdown(pci_priv);
|
||||
|
|
@ -2650,6 +2654,7 @@ int cnss_pci_dev_crash_shutdown(struct cnss_pci_data *pci_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
cnss_qca6290_crash_shutdown(pci_priv);
|
||||
|
|
@ -2678,6 +2683,7 @@ int cnss_pci_dev_ramdump(struct cnss_pci_data *pci_priv)
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
ret = cnss_qca6290_ramdump(pci_priv);
|
||||
|
|
@ -3980,18 +3986,24 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||
struct pci_dev *pci_dev = pci_priv->pci_dev;
|
||||
struct cnss_plat_data *plat_priv = pci_priv->plat_priv;
|
||||
struct device_node *of_node;
|
||||
struct resource res_tmp;
|
||||
struct resource *res;
|
||||
const char *iommu_dma_type;
|
||||
u32 addr_win[2];
|
||||
int ret = 0;
|
||||
int index;
|
||||
|
||||
of_node = of_parse_phandle(pci_dev->dev.of_node, "qcom,iommu-group", 0);
|
||||
if (!of_node)
|
||||
if (!of_node) {
|
||||
cnss_pr_err("No iommu group configuration\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Initializing SMMU\n");
|
||||
|
||||
pci_priv->iommu_domain = iommu_get_domain_for_dev(&pci_dev->dev);
|
||||
if (!pci_priv->iommu_domain)
|
||||
cnss_pr_err("No iommu domain found\n");
|
||||
ret = of_property_read_string(of_node, "qcom,iommu-dma",
|
||||
&iommu_dma_type);
|
||||
if (!ret && !strcmp("fastmap", iommu_dma_type)) {
|
||||
|
|
@ -4005,8 +4017,7 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||
addr_win, ARRAY_SIZE(addr_win));
|
||||
if (ret) {
|
||||
cnss_pr_err("Invalid SMMU size window, err = %d\n", ret);
|
||||
of_node_put(of_node);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pci_priv->smmu_iova_start = addr_win[0];
|
||||
|
|
@ -4015,8 +4026,28 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||
&pci_priv->smmu_iova_start,
|
||||
pci_priv->smmu_iova_len);
|
||||
|
||||
res = platform_get_resource_byname(plat_priv->plat_dev, IORESOURCE_MEM,
|
||||
"smmu_iova_ipa");
|
||||
if (plat_priv->is_converged_dt) {
|
||||
index = of_property_match_string(plat_priv->dev_node, "reg-names",
|
||||
"smmu_iova_ipa");
|
||||
if (index < 0) {
|
||||
cnss_pr_err("failed to find reg smmu_iova_ipa\n");
|
||||
ret = index;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(plat_priv->dev_node, index, &res_tmp);
|
||||
if (ret) {
|
||||
cnss_pr_err("failed to get resource\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
res = &res_tmp;
|
||||
} else {
|
||||
res = platform_get_resource_byname(plat_priv->plat_dev,
|
||||
IORESOURCE_MEM,
|
||||
"smmu_iova_ipa");
|
||||
}
|
||||
|
||||
if (res) {
|
||||
pci_priv->smmu_iova_ipa_start = res->start;
|
||||
pci_priv->smmu_iova_ipa_current = res->start;
|
||||
|
|
@ -4029,10 +4060,10 @@ static int cnss_pci_init_smmu(struct cnss_pci_data *pci_priv)
|
|||
pci_priv->iommu_geometry = of_property_read_bool(of_node,
|
||||
"qcom,iommu-geometry");
|
||||
cnss_pr_dbg("iommu_geometry: %d\n", pci_priv->iommu_geometry);
|
||||
|
||||
out:
|
||||
of_node_put(of_node);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_pci_deinit_smmu(struct cnss_pci_data *pci_priv)
|
||||
|
|
@ -4299,6 +4330,19 @@ static void cnss_pci_disable_msi(struct cnss_pci_data *pci_priv)
|
|||
pci_free_irq_vectors(pci_priv->pci_dev);
|
||||
}
|
||||
|
||||
int cnss_pci_get_user_msi_assignment(struct cnss_pci_data *pci_priv,
|
||||
char *user_name,
|
||||
int *num_vectors,
|
||||
u32 *user_base_data,
|
||||
u32 *base_vector)
|
||||
{
|
||||
return cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
user_name,
|
||||
num_vectors,
|
||||
user_base_data,
|
||||
base_vector);
|
||||
}
|
||||
|
||||
int cnss_get_user_msi_assignment(struct device *dev, char *user_name,
|
||||
int *num_vectors, u32 *user_base_data,
|
||||
u32 *base_vector)
|
||||
|
|
@ -4380,9 +4424,9 @@ u32 cnss_pci_get_wake_msi(struct cnss_pci_data *pci_priv)
|
|||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
||||
ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
WAKE_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
ret = cnss_pci_get_user_msi_assignment(pci_priv,
|
||||
WAKE_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
if (ret) {
|
||||
cnss_pr_err("WAKE MSI is not valid\n");
|
||||
return 0;
|
||||
|
|
@ -4930,6 +4974,10 @@ void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv,
|
|||
}
|
||||
|
||||
switch (pci_priv->device_id) {
|
||||
case QCN7605_DEVICE_ID:
|
||||
scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
|
||||
QCN7605_PATH_PREFIX "%s", name);
|
||||
break;
|
||||
case QCA6390_DEVICE_ID:
|
||||
scnprintf(prefix_name, MAX_FIRMWARE_NAME_LEN,
|
||||
QCA6390_PATH_PREFIX "%s", name);
|
||||
|
|
@ -5129,9 +5177,9 @@ static int cnss_pci_get_mhi_msi(struct cnss_pci_data *pci_priv)
|
|||
u32 user_base_data, base_vector;
|
||||
int *irq;
|
||||
|
||||
ret = cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
MHI_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
ret = cnss_pci_get_user_msi_assignment(pci_priv,
|
||||
MHI_MSI_NAME, &num_vectors,
|
||||
&user_base_data, &base_vector);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -5245,7 +5293,7 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv)
|
|||
|
||||
mhi_ctrl->priv_data = pci_priv;
|
||||
mhi_ctrl->dev = &pci_dev->dev;
|
||||
mhi_ctrl->of_node = (&plat_priv->plat_dev->dev)->of_node;
|
||||
mhi_ctrl->of_node = plat_priv->dev_node;
|
||||
mhi_ctrl->dev_id = pci_priv->device_id;
|
||||
mhi_ctrl->domain = pci_domain_nr(pci_dev->bus);
|
||||
mhi_ctrl->bus = pci_dev->bus->number;
|
||||
|
|
@ -5284,7 +5332,12 @@ static int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv)
|
|||
mhi_ctrl->rddm_size = pci_priv->plat_priv->ramdump_info_v2.ramdump_size;
|
||||
if (!mhi_ctrl->rddm_size)
|
||||
mhi_ctrl->rddm_size = RAMDUMP_SIZE_DEFAULT;
|
||||
mhi_ctrl->sbl_size = SZ_512K;
|
||||
|
||||
if (pci_priv->device_id == QCN7605_DEVICE_ID)
|
||||
mhi_ctrl->sbl_size = SZ_256K;
|
||||
else
|
||||
mhi_ctrl->sbl_size = SZ_512K;
|
||||
|
||||
mhi_ctrl->seg_len = SZ_512K;
|
||||
mhi_ctrl->fbc_download = true;
|
||||
mhi_ctrl->rddm_supported = true;
|
||||
|
|
@ -5512,6 +5565,52 @@ static struct dev_pm_domain cnss_pm_domain = {
|
|||
}
|
||||
};
|
||||
|
||||
static int cnss_pci_get_dev_cfg_node(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct device_node *child;
|
||||
u32 id, i;
|
||||
int id_n, ret;
|
||||
|
||||
if (!plat_priv->is_converged_dt)
|
||||
return 0;
|
||||
|
||||
if (!plat_priv->device_id) {
|
||||
cnss_pr_err("Invalid device id\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(plat_priv->plat_dev->dev.of_node,
|
||||
child) {
|
||||
if (strcmp(child->name, "chip_cfg"))
|
||||
continue;
|
||||
|
||||
id_n = of_property_count_u32_elems(child, "supported-ids");
|
||||
if (id_n <= 0) {
|
||||
cnss_pr_err("Device id is NOT set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < id_n; i++) {
|
||||
ret = of_property_read_u32_index(child,
|
||||
"supported-ids",
|
||||
i, &id);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to read supported ids\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (id == plat_priv->device_id) {
|
||||
plat_priv->dev_node = child;
|
||||
cnss_pr_dbg("got node[%s@%d] for device[0x%x]\n",
|
||||
child->name, i, id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int cnss_pci_probe(struct pci_dev *pci_dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
|
|
@ -5544,6 +5643,16 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
|
|||
if (plat_priv->use_pm_domain)
|
||||
dev->pm_domain = &cnss_pm_domain;
|
||||
|
||||
ret = cnss_pci_get_dev_cfg_node(plat_priv);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to get device cfg node, err = %d\n", ret);
|
||||
goto reset_ctx;
|
||||
}
|
||||
|
||||
ret = cnss_dev_specific_power_on(plat_priv);
|
||||
if (ret)
|
||||
goto reset_ctx;
|
||||
|
||||
cnss_pci_of_reserved_mem_device_init(pci_priv);
|
||||
|
||||
ret = cnss_register_subsys(plat_priv);
|
||||
|
|
@ -5583,6 +5692,7 @@ static int cnss_pci_probe(struct pci_dev *pci_dev,
|
|||
break;
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case WCN7850_DEVICE_ID:
|
||||
cnss_pci_set_wlaon_pwr_ctrl(pci_priv, false, false, false);
|
||||
|
|
@ -5671,6 +5781,7 @@ static const struct pci_device_id cnss_pci_id_table[] = {
|
|||
{ QCA6174_VENDOR_ID, QCA6174_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ QCA6290_VENDOR_ID, QCA6290_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ QCA6390_VENDOR_ID, QCA6390_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ QCN7605_VENDOR_ID, QCN7605_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID},
|
||||
{ QCA6490_VENDOR_ID, QCA6490_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ WCN7850_VENDOR_ID, WCN7850_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0 }
|
||||
|
|
|
|||
|
|
@ -248,5 +248,9 @@ int cnss_pci_debug_reg_write(struct cnss_pci_data *pci_priv, u32 offset,
|
|||
int cnss_pci_get_iova(struct cnss_pci_data *pci_priv, u64 *addr, u64 *size);
|
||||
int cnss_pci_get_iova_ipa(struct cnss_pci_data *pci_priv, u64 *addr,
|
||||
u64 *size);
|
||||
|
||||
int cnss_pci_get_user_msi_assignment(struct cnss_pci_data *pci_priv,
|
||||
char *user_name,
|
||||
int *num_vectors,
|
||||
u32 *user_base_data,
|
||||
u32 *base_vector);
|
||||
#endif /* _CNSS_PCI_H */
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ static struct cnss_clk_cfg cnss_clk_list[] = {
|
|||
#define XO_CLK_GPIO "qcom,xo-clk-gpio"
|
||||
#define WLAN_EN_ACTIVE "wlan_en_active"
|
||||
#define WLAN_EN_SLEEP "wlan_en_sleep"
|
||||
#define WLAN_VREGS_PROP "wlan_vregs"
|
||||
|
||||
#define BOOTSTRAP_DELAY 1000
|
||||
#define WLAN_ENABLE_DELAY 1000
|
||||
|
|
@ -97,7 +98,7 @@ static int cnss_get_vreg_single(struct cnss_plat_data *plat_priv,
|
|||
snprintf(prop_name, MAX_PROP_SIZE, "qcom,%s-config",
|
||||
vreg->cfg.name);
|
||||
|
||||
prop = of_get_property(dev->of_node, prop_name, &len);
|
||||
prop = of_get_property(plat_priv->dev_node, prop_name, &len);
|
||||
if (!prop || len != (5 * sizeof(__be32))) {
|
||||
cnss_pr_dbg("Property %s %s, use default\n", prop_name,
|
||||
prop ? "invalid format" : "doesn't exist");
|
||||
|
|
@ -269,18 +270,51 @@ static int cnss_get_vreg(struct cnss_plat_data *plat_priv,
|
|||
int i;
|
||||
struct cnss_vreg_info *vreg;
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
int id_n;
|
||||
|
||||
if (!list_empty(vreg_list)) {
|
||||
if (!list_empty(&plat_priv->vreg_list) &&
|
||||
!plat_priv->is_converged_dt) {
|
||||
cnss_pr_dbg("Vregs have already been updated\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < vreg_list_size; i++) {
|
||||
if (plat_priv->is_converged_dt) {
|
||||
id_n = of_property_count_strings(plat_priv->dev_node,
|
||||
WLAN_VREGS_PROP);
|
||||
if (id_n <= 0) {
|
||||
if (id_n == -ENODATA) {
|
||||
cnss_pr_dbg("No additional vregs for: %s:%lx\n",
|
||||
plat_priv->dev_node->name,
|
||||
plat_priv->device_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_pr_err("property %s is invalid or missed: %s:%lx\n",
|
||||
WLAN_VREGS_PROP, plat_priv->dev_node->name,
|
||||
plat_priv->device_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
id_n = vreg_list_size;
|
||||
}
|
||||
|
||||
for (i = 0; i < id_n; i++) {
|
||||
vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
|
||||
if (!vreg)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(&vreg->cfg, &vreg_cfg[i], sizeof(vreg->cfg));
|
||||
if (plat_priv->is_converged_dt) {
|
||||
ret = of_property_read_string_index(plat_priv->dev_node,
|
||||
WLAN_VREGS_PROP, i,
|
||||
&vreg->cfg.name);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to read vreg ids\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
memcpy(&vreg->cfg, &vreg_cfg[i], sizeof(vreg->cfg));
|
||||
}
|
||||
|
||||
ret = cnss_get_vreg_single(plat_priv, vreg);
|
||||
if (ret != 0) {
|
||||
if (ret == -ENODEV) {
|
||||
|
|
@ -1146,3 +1180,18 @@ int cnss_enable_int_pow_amp_vreg(struct cnss_plat_data *plat_priv)
|
|||
cnss_pr_dbg("Setup S3E TCS Addr: %x Data: %d\n", addr_val, data_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!plat_priv->is_converged_dt)
|
||||
return 0;
|
||||
|
||||
ret = cnss_get_vreg_type(plat_priv, CNSS_VREG_PRIM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
plat_priv->powered_on = false;
|
||||
return cnss_power_on_device(plat_priv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#define DEBUG_STR "debug"
|
||||
#define HW_V1_NUMBER "v1"
|
||||
#define HW_V2_NUMBER "v2"
|
||||
#define CE_MSI_NAME "CE"
|
||||
|
||||
#define QMI_WLFW_TIMEOUT_MS (plat_priv->ctrl_params.qmi_timeout)
|
||||
#define QMI_WLFW_TIMEOUT_JF msecs_to_jiffies(QMI_WLFW_TIMEOUT_MS)
|
||||
|
|
@ -1277,7 +1278,7 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
struct wlfw_wlan_cfg_req_msg_v01 *req;
|
||||
struct wlfw_wlan_cfg_resp_msg_v01 *resp;
|
||||
struct qmi_txn txn;
|
||||
u32 i;
|
||||
u32 i, ce_id, num_vectors, user_base_data, base_vector;
|
||||
int ret = 0;
|
||||
|
||||
if (!plat_priv)
|
||||
|
|
@ -1323,7 +1324,17 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
req->svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
|
||||
req->svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
|
||||
}
|
||||
|
||||
if (config->num_shadow_reg_cfg) {
|
||||
req->shadow_reg_valid = 1;
|
||||
if (config->num_shadow_reg_cfg >
|
||||
QMI_WLFW_MAX_NUM_SHADOW_REG_V01)
|
||||
req->shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01;
|
||||
else
|
||||
req->shadow_reg_len = config->num_shadow_reg_cfg;
|
||||
memcpy(req->shadow_reg, config->shadow_reg_cfg,
|
||||
sizeof(struct wlfw_shadow_reg_cfg_s_v01)
|
||||
* req->shadow_reg_len);
|
||||
}
|
||||
req->shadow_reg_v2_valid = 1;
|
||||
if (config->num_shadow_reg_v2_cfg >
|
||||
QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01)
|
||||
|
|
@ -1334,6 +1345,30 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
memcpy(req->shadow_reg_v2, config->shadow_reg_v2_cfg,
|
||||
sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01)
|
||||
* req->shadow_reg_v2_len);
|
||||
if (config->rri_over_ddr_cfg_valid) {
|
||||
req->rri_over_ddr_cfg_valid = 1;
|
||||
req->rri_over_ddr_cfg.base_addr_low =
|
||||
config->rri_over_ddr_cfg.base_addr_low;
|
||||
req->rri_over_ddr_cfg.base_addr_high =
|
||||
config->rri_over_ddr_cfg.base_addr_high;
|
||||
}
|
||||
if (config->send_msi_ce) {
|
||||
ret = cnss_bus_get_msi_assignment(plat_priv,
|
||||
CE_MSI_NAME,
|
||||
&num_vectors,
|
||||
&user_base_data,
|
||||
&base_vector);
|
||||
if (!ret) {
|
||||
req->msi_cfg_valid = 1;
|
||||
req->msi_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
|
||||
for (ce_id = 0; ce_id < QMI_WLFW_MAX_NUM_CE_V01;
|
||||
ce_id++) {
|
||||
req->msi_cfg[ce_id].ce_id = ce_id;
|
||||
req->msi_cfg[ce_id].msi_vector =
|
||||
(ce_id % num_vectors) + base_vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = qmi_txn_init(&plat_priv->qmi_wlfw, &txn,
|
||||
wlfw_wlan_cfg_resp_msg_v01_ei, resp);
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ struct cnss_wlan_enable_cfg {
|
|||
struct cnss_shadow_reg_v2_cfg *shadow_reg_v2_cfg;
|
||||
bool rri_over_ddr_cfg_valid;
|
||||
struct cnss_rri_over_ddr_cfg rri_over_ddr_cfg;
|
||||
bool send_msi_ce;
|
||||
};
|
||||
|
||||
enum cnss_driver_mode {
|
||||
|
|
|
|||
Loading…
Reference in a new issue