Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc169004 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cnss2: Sync code from kernel 4.14"

parents 9b641f7d 63adfad3
Loading
Loading
Loading
Loading
+55 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ Required properties:
  - compatible: "qcom,cnss" for QCA6174 device
                "qcom,cnss-qca6290" for QCA6290 device
                "qcom,cnss-qca6390" for QCA6390 device
                "qcom,cnss-qca-converged" for converged QCA devices
  - wlan-en-gpio: WLAN_EN GPIO signal specified by the chip specifications
  - vdd-wlan-supply: phandle to the regulator device tree node
  - pinctrl-names: Names corresponding to the numbered pinctrl states
@@ -35,6 +36,10 @@ Optional properties:
  - vdd-wlan-xtal-aon-supply: phandle to the LDO-4 regulator. This is needed
                              on platforms where XTAL regulator depends on
                              always on regulator in VDDmin.
  - vdd-wlan-ctrl1-supply: phandle to the DBU1 - 1.8V for QCA6595 or 3.3V for
                           QCA6174 on auto platform.
  - vdd-wlan-ctrl2-supply: phandle to the DBU4 - 2.2V for QCA6595 or 3.85V for
                           QCA6696 on auto platform.
  - vdd-wlan-core-supply: phandle to the 1.3V CORE regulator for QCA6174
  - vdd-wlan-sp2t-supply: phandle to the 2.7V SP2T regulator for QCA6174
  - qcom,smmu-s1-enable: Boolean property to decide whether to enable SMMU
@@ -56,7 +61,32 @@ Optional properties:
                               WLAN_EN pin is a gpio or fixed regulator.
  - qcom,mhi: phandle to indicate the device which needs MHI support.
  - qcom,cap-tsf-gpio: WLAN_TSF_CAPTURED GPIO signal specified by the chip
                       specifications, should be drived depending on products
                       specifications, should be drived depending on products.
  - cnss-daemon-support: Boolean property to decide whether cnss_daemon
                         userspace QMI client is supported.
  - qcom,converged-dt: Boolean property to decide whether it supports multiple
                       chips.
  - qcom,bus-type: U32 property to specify the bus type, is required when
                   'qcom,converged-dt' being present.
  - wlan_vregs: String array to decide which vregs are required, is required
                when 'qcom,converged-dt' being present.
  - <supply-name>-supply: phandle to the regulator device tree node.
                          optional "supply-name" is "vdd-wlan-rfa".
  - qcom,<supply-name>-info: Specifies configuration for supply. Should be
                             specified in <min_uV max_uV load_uA delay_us>.
  - pcie-disable-l1: Boolean property to decide whether to disable PCIe L1 PM.
  - pcie-disable-l1ss: Boolean property to decide whether to disable PCIe L1ss.
  - qcom,set-wlaon-pwr-ctrl: Boolean property to indicate if set
                             WLAON_QFPROM_PWR_CTRL_REG register during power on
                             and off sequences.

List of chip specific sub nodes:
  - chip_cfg@X: represent chip specific configurations
    Each sub node has the following required properties:
       - wlan_vregs: String array to decide which vregs are required, property
                     being present but no values means no additional vregs.
       - supported-ids: U32 array to decide which device ids are supported by
                        sub node.

Example:

@@ -76,3 +106,27 @@ Example:
        qcom,mhi = <&mhi_wlan>;
        qcom,cap-tsf-gpio = <&tlmm 126 1>;
    };

    qcom,cnss-qca-converged {
        compatible = "qcom,cnss-qca-converged";
        qcom,converged-dt;
        qcom,bus-type=<0>;

        vdd-wlan-ctrl1-supply = <&vreg_conn_pa>;
        vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>;
        vdd-wlan-supply = <&vreg_wlan>;
        wlan_vregs = "vdd-wlan-ctrl1", "vdd-wlan-ctrl2";
        qcom,vdd-wlan-ctrl1-info = <0 0 0 0>;
        qcom,vdd-wlan-ctrl2-info = <0 0 0 0>;
        wlan-en-gpio = <&tlmm 169 0>;
        pinctrl-names = "wlan_en_active", "wlan_en_sleep";
        pinctrl-0 = <&cnss_wlan_en_active>;
        pinctrl-1 = <&cnss_wlan_en_sleep>;
        qcom,wlan-rc-num = <0>;

        chip_cfg@1 {
                supported-ids = <0x003e>;
                wlan_vregs = "vdd-wlan";
                qcom,vdd-wlan-info = <0 0 0 10>;
        };
    };
+1 −0
Original line number Diff line number Diff line
@@ -6,4 +6,5 @@ cnss2-y += debug.o
cnss2-y += pci.o
cnss2-y += usb.o
cnss2-y += power.o
cnss2-$(CONFIG_CNSS2_DEBUG) += genl.o
cnss2-$(CONFIG_CNSS2_QMI) += qmi.o wlan_firmware_service_v01.o
+77 −19
Original line number Diff line number Diff line
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -29,40 +29,52 @@ 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;
	u32 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)
			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_EMULATION_DEVICE_ID:
	case QCA6290_DEVICE_ID:
		return CNSS_BUS_PCI;
	case QCA6390_DEVICE_ID:
	case QCN7605_DEVICE_ID:
		bus_type = CNSS_BUS_PCI;
		break;
	case QCN7605_COMPOSITE_DEVICE_ID:
	case QCN7605_STANDALONE_DEVICE_ID:
		return CNSS_BUS_USB;
		bus_type = CNSS_BUS_USB;
		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;
}

bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv)
{
	if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
	if (cnss_get_bus_type(plat_priv) == CNSS_BUS_USB)
		return false;
	else
		return true;
}

bool cnss_bus_dev_cal_rep_valid(struct cnss_plat_data *plat_priv)
{
	bool ret = false;

	if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
		ret = true;

	return ret;
}

void *cnss_bus_dev_to_bus_priv(struct device *dev)
{
	if (!dev)
@@ -161,6 +173,37 @@ int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv)
	}
}

int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv)
{
	if (!plat_priv)
		return -ENODEV;

	switch (plat_priv->bus_type) {
	case CNSS_BUS_PCI:
		return cnss_pci_alloc_qdss_mem(plat_priv->bus_priv);
	default:
		cnss_pr_err("Unsupported bus type: %d\n",
			    plat_priv->bus_type);
		return -EINVAL;
	}
}

void cnss_bus_free_qdss_mem(struct cnss_plat_data *plat_priv)
{
	if (!plat_priv)
		return;

	switch (plat_priv->bus_type) {
	case CNSS_BUS_PCI:
		cnss_pci_free_qdss_mem(plat_priv->bus_priv);
		return;
	default:
		cnss_pr_err("Unsupported bus type: %d\n",
			    plat_priv->bus_type);
		return;
	}
}

u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv)
{
	if (!plat_priv)
@@ -388,3 +431,18 @@ int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
		return -EINVAL;
	}
}

int cnss_get_msi_assignment(struct cnss_plat_data *plat_priv,
			    char *msi_name,
			    int *num_vectors, u32 *user_base_data,
			    u32 *base_vector)
{
	struct cnss_pci_data *pci_priv;

	pci_priv = plat_priv->bus_priv;
	return cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
					    msi_name,
					    num_vectors,
					    user_base_data,
					    base_vector);
}
+14 −11
Original line number Diff line number Diff line
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -22,27 +22,28 @@
#define QCA6174_REV3_2_VERSION		0x5030000
#define QCA6290_VENDOR_ID		0x17CB
#define QCA6290_DEVICE_ID		0x1100
#define QCA6290_EMULATION_VENDOR_ID	0x168C
#define QCA6290_EMULATION_DEVICE_ID	0xABCD
#define QCA6390_VENDOR_ID		0x17CB
#define QCA6390_EMULATION_DEVICE_ID	0x0108
#define QCA6390_DEVICE_ID		0x1101
#define QCN7605_VENDOR_ID               0x17CB
#define QCN7605_DEVICE_ID               0x1102

#define QCN7605_USB_VENDOR_ID             0x05C6
#define QCN7605_COMPOSITE_DEVICE_ID     QCN7605_COMPOSITE_PRODUCT_ID
#define QCN7605_STANDALONE_DEVICE_ID    QCN7605_STANDALONE_PRODUCT_ID

#define QCN7605_STANDALONE_PRODUCT_ID    0x9900
#define QCN7605_COMPOSITE_PRODUCT_ID     0x9901

#define QCN7605_COMPOSITE_DEVICE_ID     QCN7605_COMPOSITE_PRODUCT_ID
#define QCN7605_STANDALONE_DEVICE_ID    QCN7605_STANDALONE_PRODUCT_ID

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);
void cnss_bus_deinit(struct cnss_plat_data *plat_priv);
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv);
int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv);
int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv);
void cnss_bus_free_qdss_mem(struct cnss_plat_data *plat_priv);
u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv);
int cnss_bus_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv);
void cnss_bus_fw_boot_timeout_hdlr(unsigned long data);
@@ -60,8 +61,10 @@ int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
				      int modem_current_status);
int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
			   enum cnss_driver_status status);
int cnss_bus_recovery_update_status(struct cnss_plat_data *plat_priv);
bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv);
bool cnss_bus_dev_cal_rep_valid(struct cnss_plat_data *plat_priv);

int cnss_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 */
+151 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -85,6 +85,12 @@ static int cnss_stats_show_state(struct seq_file *s,
		case CNSS_DRIVER_UNLOADING:
			seq_puts(s, "DRIVER_UNLOADING");
			continue;
		case CNSS_DRIVER_IDLE_RESTART:
			seq_puts(s, "IDLE_RESTART");
			continue;
		case CNSS_DRIVER_IDLE_SHUTDOWN:
			seq_puts(s, "IDLE_SHUTDOWN");
			continue;
		case CNSS_DRIVER_PROBED:
			seq_puts(s, "DRIVER_PROBED");
			continue;
@@ -100,6 +106,9 @@ static int cnss_stats_show_state(struct seq_file *s,
		case CNSS_DRIVER_DEBUG:
			seq_puts(s, "DRIVER_DEBUG");
			continue;
		case CNSS_IN_SUSPEND_RESUME:
			seq_puts(s, "IN_SUSPEND_RESUME");
			continue;
		}

		seq_printf(s, "UNKNOWN-%d", i);
@@ -504,6 +513,145 @@ static const struct file_operations cnss_runtime_pm_debug_fops = {
	.llseek		= seq_lseek,
};

static ssize_t cnss_control_params_debug_write(struct file *fp,
					       const char __user *user_buf,
					       size_t count, loff_t *off)
{
	struct cnss_plat_data *plat_priv =
		((struct seq_file *)fp->private_data)->private;
	char buf[64];
	char *sptr, *token;
	char *cmd;
	u32 val;
	unsigned int len = 0;
	const char *delim = " ";

	if (!plat_priv)
		return -ENODEV;

	len = min(count, sizeof(buf) - 1);
	if (copy_from_user(buf, user_buf, len))
		return -EFAULT;

	buf[len] = '\0';
	sptr = buf;

	token = strsep(&sptr, delim);
	if (!token)
		return -EINVAL;
	if (!sptr)
		return -EINVAL;
	cmd = token;

	token = strsep(&sptr, delim);
	if (!token)
		return -EINVAL;
	if (kstrtou32(token, 0, &val))
		return -EINVAL;

	if (strcmp(cmd, "quirks") == 0)
		plat_priv->ctrl_params.quirks = val;
	else if (strcmp(cmd, "mhi_timeout") == 0)
		plat_priv->ctrl_params.mhi_timeout = val;
	else if (strcmp(cmd, "qmi_timeout") == 0)
		plat_priv->ctrl_params.qmi_timeout = val;
	else if (strcmp(cmd, "bdf_type") == 0)
		plat_priv->ctrl_params.bdf_type = val;
	else
		return -EINVAL;

	return count;
}

static int cnss_show_quirks_state(struct seq_file *s,
				  struct cnss_plat_data *plat_priv)
{
	enum cnss_debug_quirks i;
	int skip = 0;
	unsigned long state;

	seq_printf(s, "quirks: 0x%lx (", plat_priv->ctrl_params.quirks);
	for (i = 0, state = plat_priv->ctrl_params.quirks;
	     state != 0; state >>= 1, i++) {
		if (!(state & 0x1))
			continue;
		if (skip++)
			seq_puts(s, " | ");

		switch (i) {
		case LINK_DOWN_SELF_RECOVERY:
			seq_puts(s, "LINK_DOWN_SELF_RECOVERY");
			continue;
		case SKIP_DEVICE_BOOT:
			seq_puts(s, "SKIP_DEVICE_BOOT");
			continue;
		case USE_CORE_ONLY_FW:
			seq_puts(s, "USE_CORE_ONLY_FW");
			continue;
		case SKIP_RECOVERY:
			seq_puts(s, "SKIP_RECOVERY");
			continue;
		case QMI_BYPASS:
			seq_puts(s, "QMI_BYPASS");
			continue;
		case ENABLE_WALTEST:
			seq_puts(s, "WALTEST");
			continue;
		case ENABLE_PCI_LINK_DOWN_PANIC:
			seq_puts(s, "PCI_LINK_DOWN_PANIC");
			continue;
		case FBC_BYPASS:
			seq_puts(s, "FBC_BYPASS");
			continue;
		case ENABLE_DAEMON_SUPPORT:
			seq_puts(s, "DAEMON_SUPPORT");
			continue;
		case IGNORE_PCI_LINK_FAILURE:
			seq_puts(s, "IGNORE_PCI_LINK_FAILURE");
			continue;
		}

		seq_printf(s, "UNKNOWN-%d", i);
	}
	seq_puts(s, ")\n");
	return 0;
}

static int cnss_control_params_debug_show(struct seq_file *s, void *data)
{
	struct cnss_plat_data *cnss_priv = s->private;

	seq_puts(s, "\nUsage: echo <params_name> <value> > <debugfs_path>/cnss/control_params\n");
	seq_puts(s, "<params_name> can be one of below:\n");
	seq_puts(s, "quirks: Debug quirks for driver\n");
	seq_puts(s, "mhi_timeout: Timeout for MHI operation in milliseconds\n");
	seq_puts(s, "qmi_timeout: Timeout for QMI message in milliseconds\n");
	seq_puts(s, "bdf_type: Type of board data file to be downloaded\n");

	seq_puts(s, "\nCurrent value:\n");
	cnss_show_quirks_state(s, cnss_priv);
	seq_printf(s, "mhi_timeout: %u\n", cnss_priv->ctrl_params.mhi_timeout);
	seq_printf(s, "qmi_timeout: %u\n", cnss_priv->ctrl_params.qmi_timeout);
	seq_printf(s, "bdf_type: %u\n", cnss_priv->ctrl_params.bdf_type);

	return 0;
}

static int cnss_control_params_debug_open(struct inode *inode,
					  struct file *file)
{
	return single_open(file, cnss_control_params_debug_show,
			   inode->i_private);
}

static const struct file_operations cnss_control_params_debug_fops = {
	.read = seq_read,
	.write = cnss_control_params_debug_write,
	.open = cnss_control_params_debug_open,
	.owner = THIS_MODULE,
	.llseek = seq_lseek,
};

#ifdef CONFIG_CNSS2_DEBUG
static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv)
{
@@ -517,6 +665,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv)
			    &cnss_reg_write_debug_fops);
	debugfs_create_file("runtime_pm", 0600, root_dentry, plat_priv,
			    &cnss_runtime_pm_debug_fops);
	debugfs_create_file("control_params", 0600, root_dentry, plat_priv,
			    &cnss_control_params_debug_fops);

	return 0;
}
Loading