Pārlūkot izejas kodu

Merge 882ac969c2e1eea60a0113d46059961aa1856023 on remote branch

Change-Id: I4a68b7c4b35ec36379c318f33fcb0753abc5d209
Linux Build Service Account 1 gadu atpakaļ
vecāks
revīzija
ba6587aeaf
9 mainītis faili ar 167 papildinājumiem un 61 dzēšanām
  1. 7 2
      cnss2/main.c
  2. 46 29
      cnss2/pci.c
  3. 0 1
      cnss2/pineapple_gki_defconfig
  4. 18 1
      cnss2/qmi.c
  5. 2 3
      icnss2/main.c
  6. 10 1
      icnss2/main.h
  7. 0 1
      icnss2/pineapple_gki_defconfig
  8. 78 22
      icnss2/power.c
  9. 6 1
      inc/cnss2.h

+ 7 - 2
cnss2/main.c

@@ -3243,9 +3243,14 @@ int cnss_do_host_ramdump(struct cnss_plat_data *plat_priv,
 		[CNSS_HOST_WMI_COMMAND_LOG_IDX] = "wmi_command_log_idx",
 		[CNSS_HOST_WMI_EVENT_LOG_IDX] = "wmi_event_log_idx",
 		[CNSS_HOST_WMI_RX_EVENT_IDX] = "wmi_rx_event_idx",
-		[CNSS_HOST_HIF_CE_DESC_HISTORY] = "hif_ce_desc_history",
 		[CNSS_HOST_HIF_CE_DESC_HISTORY_BUFF] = "hif_ce_desc_history_buff",
-		[CNSS_HOST_HANG_EVENT_DATA] = "hang_event_data"
+		[CNSS_HOST_HANG_EVENT_DATA] = "hang_event_data",
+		[CNSS_HOST_CE_DESC_HIST] = "hif_ce_desc_hist",
+		[CNSS_HOST_CE_COUNT_MAX] = "hif_ce_count_max",
+		[CNSS_HOST_CE_HISTORY_MAX] = "hif_ce_history_max",
+		[CNSS_HOST_ONLY_FOR_CRIT_CE] = "hif_ce_only_for_crit",
+		[CNSS_HOST_HIF_EVENT_HISTORY] = "hif_event_history",
+		[CNSS_HOST_HIF_EVENT_HIST_MAX] = "hif_event_hist_max"
 	};
 	int i;
 	int ret = 0;

+ 46 - 29
cnss2/pci.c

@@ -1424,7 +1424,8 @@ int cnss_suspend_pci_link(struct cnss_pci_data *pci_priv)
 	pci_disable_device(pci_priv->pci_dev);
 
 	if (pci_priv->pci_dev->device != QCA6174_DEVICE_ID) {
-		if (pci_set_power_state(pci_priv->pci_dev, PCI_D3hot))
+		ret = pci_set_power_state(pci_priv->pci_dev, PCI_D3hot);
+		if (ret)
 			cnss_pr_err("Failed to set D3Hot, err =  %d\n", ret);
 	}
 
@@ -2828,6 +2829,7 @@ int cnss_pci_call_driver_probe(struct cnss_pci_data *pci_priv)
 		if (ret) {
 			cnss_pr_err("Failed to probe host driver, err = %d\n",
 				    ret);
+			complete_all(&plat_priv->power_up_complete);
 			goto out;
 		}
 		clear_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state);
@@ -7044,28 +7046,6 @@ static bool cnss_should_suspend_pwroff(struct pci_dev *pci_dev)
 }
 #endif
 
-static void cnss_pci_suspend_pwroff(struct pci_dev *pci_dev)
-{
-	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
-	int rc_num = pci_dev->bus->domain_nr;
-	struct cnss_plat_data *plat_priv;
-	int ret = 0;
-	bool suspend_pwroff = cnss_should_suspend_pwroff(pci_dev);
-
-	plat_priv = cnss_get_plat_priv_by_rc_num(rc_num);
-
-	if (suspend_pwroff) {
-		ret = cnss_suspend_pci_link(pci_priv);
-		if (ret)
-			cnss_pr_err("Failed to suspend PCI link, err = %d\n",
-				    ret);
-		cnss_power_off_device(plat_priv);
-	} else {
-		cnss_pr_dbg("bus suspend and dev power off disabled for device [0x%x]\n",
-			    pci_dev->device);
-	}
-}
-
 #ifdef CONFIG_CNSS2_ENUM_WITH_LOW_SPEED
 static void
 cnss_pci_downgrade_rc_speed(struct cnss_plat_data *plat_priv, u32 rc_num)
@@ -7092,15 +7072,24 @@ cnss_pci_restore_rc_speed(struct cnss_pci_data *pci_priv)
 		if (ret)
 			cnss_pr_err("Failed to reset max PCIe RC%x link speed to default, err = %d\n",
 				     plat_priv->rc_num, ret);
+	}
+}
 
-		/* suspend/resume will trigger retain to re-establish link speed */
-		ret = cnss_suspend_pci_link(pci_priv);
-		if (ret)
-			cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
+static void
+cnss_pci_link_retrain_trigger(struct cnss_pci_data *pci_priv)
+{
+	int ret;
 
-		ret = cnss_resume_pci_link(pci_priv);
+	/* suspend/resume will trigger retain to re-establish link speed */
+	ret = cnss_suspend_pci_link(pci_priv);
+	if (ret)
+		cnss_pr_err("Failed to suspend PCI link, err = %d\n", ret);
+
+	ret = cnss_resume_pci_link(pci_priv);
+	if (ret)
 		cnss_pr_err("Failed to resume PCI link, err = %d\n", ret);
-	}
+
+	cnss_pci_get_link_status(pci_priv);
 }
 #else
 static void
@@ -7112,8 +7101,36 @@ static void
 cnss_pci_restore_rc_speed(struct cnss_pci_data *pci_priv)
 {
 }
+
+static void
+cnss_pci_link_retrain_trigger(struct cnss_pci_data *pci_priv)
+{
+}
 #endif
 
+static void cnss_pci_suspend_pwroff(struct pci_dev *pci_dev)
+{
+	struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
+	int rc_num = pci_dev->bus->domain_nr;
+	struct cnss_plat_data *plat_priv;
+	int ret = 0;
+	bool suspend_pwroff = cnss_should_suspend_pwroff(pci_dev);
+
+	plat_priv = cnss_get_plat_priv_by_rc_num(rc_num);
+
+	if (suspend_pwroff) {
+		ret = cnss_suspend_pci_link(pci_priv);
+		if (ret)
+			cnss_pr_err("Failed to suspend PCI link, err = %d\n",
+				    ret);
+		cnss_power_off_device(plat_priv);
+	} else {
+		cnss_pr_dbg("bus suspend and dev power off disabled for device [0x%x]\n",
+			    pci_dev->device);
+		cnss_pci_link_retrain_trigger(pci_priv);
+	}
+}
+
 static int cnss_pci_probe(struct pci_dev *pci_dev,
 			  const struct pci_device_id *id)
 {

+ 0 - 1
cnss2/pineapple_gki_defconfig

@@ -8,4 +8,3 @@ CONFIG_CNSS_HW_SECURE_DISABLE=y
 CONFIG_CNSS2_SMMU_DB_SUPPORT=y
 CONFIG_CNSS_PLAT_IPC_QMI_SVC=m
 CONFIG_WCNSS_MEM_PRE_ALLOC=m
-CONFIG_CNSS2_DEBUG=y

+ 18 - 1
cnss2/qmi.c

@@ -779,6 +779,9 @@ int cnss_wlfw_ini_file_send_sync(struct cnss_plat_data *plat_priv,
 	unsigned int remaining;
 	bool backup_supported = false;
 
+	cnss_pr_dbg("Sending QMI_WLFW_INI_FILE_DOWNLOAD_REQ_V01 message for ini_type: %d, state: 0x%lx\n",
+		    file_type, plat_priv->driver_state);
+
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
 	if (!req)
 		return -ENOMEM;
@@ -802,19 +805,27 @@ int cnss_wlfw_ini_file_send_sync(struct cnss_plat_data *plat_priv,
 	}
 
 	snprintf(filename, sizeof(filename), "%s%s", tmp_filename, INI_EXT);
+
+	cnss_pr_dbg("Invoke firmware_request_nowarn for %s\n", filename);
 	/* Fetch the file */
 	ret = firmware_request_nowarn(&fw, filename, &plat_priv->plat_dev->dev);
 	if (ret) {
+		cnss_pr_dbg("Failed to read %s, ret: %d\n", filename, ret);
 		if (!backup_supported)
 			goto err_req_fw;
 
 		snprintf(filename, sizeof(filename),
 			 "%s-%s%s", tmp_filename, "backup", INI_EXT);
 
+		cnss_pr_dbg("Invoke firmware_request_nowarn for %s\n",
+			    filename);
 		ret = firmware_request_nowarn(&fw, filename,
 					      &plat_priv->plat_dev->dev);
-		if (ret)
+		if (ret) {
+			cnss_pr_dbg("Failed to read %s, ret: %d\n", filename,
+				    ret);
 			goto err_req_fw;
+		}
 	}
 
 	temp = fw->data;
@@ -926,6 +937,7 @@ int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
 	if (ret)
 		goto err_req_fw;
 
+	cnss_pr_dbg("Invoke firmware_request_nowarn for %s\n", filename);
 	if (bdf_type == CNSS_BDF_REGDB)
 		ret = cnss_request_firmware_direct(plat_priv, &fw_entry,
 						   filename);
@@ -1494,6 +1506,9 @@ int cnss_wlfw_qdss_dnld_send_sync(struct cnss_plat_data *plat_priv)
 
 	cnss_get_qdss_cfg_filename(plat_priv, qdss_cfg_filename,
 				   sizeof(qdss_cfg_filename), false);
+
+	cnss_pr_dbg("Invoke firmware_request_nowarn for %s\n",
+		    qdss_cfg_filename);
 	ret = cnss_request_firmware_direct(plat_priv, &fw_entry,
 					   qdss_cfg_filename);
 	if (ret) {
@@ -1502,6 +1517,8 @@ int cnss_wlfw_qdss_dnld_send_sync(struct cnss_plat_data *plat_priv)
 		cnss_get_qdss_cfg_filename(plat_priv, qdss_cfg_filename,
 					   sizeof(qdss_cfg_filename),
 					   true);
+		cnss_pr_dbg("Invoke firmware_request_nowarn for %s\n",
+			    qdss_cfg_filename);
 		ret = cnss_request_firmware_direct(plat_priv, &fw_entry,
 						   qdss_cfg_filename);
 		if (ret) {

+ 2 - 3
icnss2/main.c

@@ -4753,7 +4753,7 @@ static int icnss_probe(struct platform_device *pdev)
 
 		init_completion(&priv->smp2p_soc_wake_wait);
 		icnss_runtime_pm_init(priv);
-		icnss_aop_mbox_init(priv);
+		icnss_aop_interface_init(priv);
 		set_bit(ICNSS_COLD_BOOT_CAL, &priv->state);
 		priv->bdf_download_support = true;
 		register_trace_android_vh_rproc_recovery_set(rproc_restart_level_notifier, NULL);
@@ -4865,8 +4865,6 @@ static int icnss_remove(struct platform_device *pdev)
 	    priv->device_id == WCN6450_DEVICE_ID) {
 		icnss_genl_exit();
 		icnss_runtime_pm_deinit(priv);
-		if (!IS_ERR_OR_NULL(priv->mbox_chan))
-			mbox_free_channel(priv->mbox_chan);
 		unregister_trace_android_vh_rproc_recovery_set(rproc_restart_level_notifier, NULL);
 		complete_all(&priv->smp2p_soc_wake_wait);
 		icnss_destroy_ramdump_device(priv->m3_dump_phyareg);
@@ -4876,6 +4874,7 @@ static int icnss_remove(struct platform_device *pdev)
 		icnss_destroy_ramdump_device(priv->m3_dump_phyapdmem);
 		if (priv->soc_wake_wq)
 			destroy_workqueue(priv->soc_wake_wq);
+		icnss_aop_interface_deinit(priv);
 	}
 
 	class_destroy(priv->icnss_ramdump_class);

+ 10 - 1
icnss2/main.h

@@ -12,6 +12,10 @@
 #include <linux/platform_device.h>
 #include <linux/ipc_logging.h>
 #include <linux/power_supply.h>
+#if IS_ENABLED(CONFIG_MSM_QMP)
+#include <linux/mailbox/qmp.h>
+#include <linux/soc/qcom/qcom_aoss.h>
+#endif
 #ifdef CONFIG_CNSS_OUT_OF_TREE
 #include "icnss2.h"
 #else
@@ -485,6 +489,10 @@ struct icnss_priv {
 	bool root_pd_shutdown;
 	struct mbox_client mbox_client_data;
 	struct mbox_chan *mbox_chan;
+#if IS_ENABLED(CONFIG_MSM_QMP)
+	struct qmp *qmp;
+#endif
+	bool use_direct_qmp;
 	u32 wlan_en_delay_ms;
 	u32 wlan_en_delay_ms_user;
 	struct class *icnss_ramdump_class;
@@ -542,7 +550,8 @@ int icnss_get_iova_ipa(struct icnss_priv *priv, u64 *addr, u64 *size);
 int icnss_update_cpr_info(struct icnss_priv *priv);
 void icnss_add_fw_prefix_name(struct icnss_priv *priv, char *prefix_name,
 			      char *name);
-int icnss_aop_mbox_init(struct icnss_priv *priv);
+int icnss_aop_interface_init(struct icnss_priv *priv);
+void icnss_aop_interface_deinit(struct icnss_priv *priv);
 void icnss_recovery_timeout_hdlr(struct timer_list *t);
 void icnss_wpss_ssr_timeout_hdlr(struct timer_list *t);
 #endif

+ 0 - 1
icnss2/pineapple_gki_defconfig

@@ -1,5 +1,4 @@
 CONFIG_ICNSS2=m
-CONFIG_ICNSS2_DEBUG=y
 CONFIG_ICNSS2_QMI=y
 CONFIG_CNSS_QMI_SVC=m
 CONFIG_CNSS_QCA6750=y

+ 78 - 22
icnss2/power.c

@@ -5,9 +5,6 @@
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
-#if IS_ENABLED(CONFIG_MSM_QMP)
-#include <linux/mailbox/qmp.h>
-#endif
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/regulator/consumer.h>
@@ -736,7 +733,18 @@ void icnss_put_resources(struct icnss_priv *priv)
 	icnss_put_vreg(priv);
 }
 
-int icnss_aop_mbox_init(struct icnss_priv *priv)
+
+#if IS_ENABLED(CONFIG_MSM_QMP)
+/**
+ * icnss_aop_interface_init: Initialize AOP interface: either mbox channel or direct QMP
+ * @priv: Pointer to icnss platform data
+ *
+ * Device tree file should have either mbox or qmp configured, but not both.
+ * Based on device tree configuration setup mbox channel or QMP
+ *
+ * Return: 0 for success, otherwise error code
+*/
+int icnss_aop_interface_init(struct icnss_priv *priv)
 {
 	struct mbox_client *mbox = &priv->mbox_client_data;
 	struct mbox_chan *chan;
@@ -756,19 +764,50 @@ int icnss_aop_mbox_init(struct icnss_priv *priv)
 	mbox->knows_txdone = false;
 
 	priv->mbox_chan = NULL;
+	priv->qmp = NULL;
+	priv->use_direct_qmp = false;
+	/* First try to get mbox channel, if it fails then try qmp_get
+	 * In device tree file there should be either mboxes or qmp,
+	 * cannot have both properties at the same time.
+	 */
 	chan = mbox_request_channel(mbox, 0);
 	if (IS_ERR(chan)) {
 		ret = PTR_ERR(chan);
-		icnss_pr_err("Failed to get mbox channel with err %d\n", ret);
-		return ret;
+		icnss_pr_dbg("Failed to get mbox channel with err %d\n", ret);
+		priv->qmp = qmp_get(&priv->pdev->dev);
+		if (IS_ERR(priv->qmp)) {
+			icnss_pr_err("Failed to get qmp\n");
+			return PTR_ERR(priv->qmp);
+		} else {
+			priv->use_direct_qmp = true;
+			icnss_pr_dbg("QMP initialized\n");
+		}
+	} else {
+		priv->mbox_chan = chan;
+		icnss_pr_dbg("Mbox channel initialized\n");
 	}
-	priv->mbox_chan = chan;
+	return ret;
+}
 
-	icnss_pr_dbg("Mbox channel initialized\n");
-	return 0;
+/**
+ * cnss_aop_interface_deinit: Cleanup AOP interface
+ * @priv: Pointer to icnss platform data
+ *
+ * Cleanup mbox channel or QMP whichever was configured during initialization.
+ *
+ * Return: None
+ */
+void icnss_aop_interface_deinit(struct icnss_priv *priv)
+{
+	if (!IS_ERR_OR_NULL(priv->mbox_chan))
+		mbox_free_channel(priv->mbox_chan);
+
+	if (!IS_ERR_OR_NULL(priv->qmp)) {
+		qmp_put(priv->qmp);
+		priv->use_direct_qmp = false;
+	}
 }
 
-#if IS_ENABLED(CONFIG_MSM_QMP)
 static int icnss_aop_set_vreg_param(struct icnss_priv *priv,
 				    const char *vreg_name,
 				    enum icnss_vreg_param param,
@@ -786,21 +825,38 @@ static int icnss_aop_set_vreg_param(struct icnss_priv *priv,
 	snprintf(mbox_msg, ICNSS_MBOX_MSG_MAX_LEN,
 		 "{class: wlan_pdc, res: %s.%s, %s: %d}", vreg_name,
 		 vreg_param_str[param], tcs_seq_str[seq], val);
+	if (priv->use_direct_qmp) {
+		icnss_pr_dbg("Sending AOP QMP msg: %s\n", mbox_msg);
+		ret = qmp_send(priv->qmp, mbox_msg, ICNSS_MBOX_MSG_MAX_LEN);
+		if (ret < 0)
+			icnss_pr_err("Failed to send AOP QMP msg: %s\n", mbox_msg);
+		else
+			ret = 0;
+	} else {
+		icnss_pr_dbg("Sending AOP Mbox msg: %s\n", mbox_msg);
+		pkt.size = ICNSS_MBOX_MSG_MAX_LEN;
+		pkt.data = mbox_msg;
 
-	icnss_pr_dbg("Sending AOP Mbox msg: %s\n", mbox_msg);
-	pkt.size = ICNSS_MBOX_MSG_MAX_LEN;
-	pkt.data = mbox_msg;
-
-	ret = mbox_send_message(priv->mbox_chan, &pkt);
-	if (ret < 0)
-		icnss_pr_err("Failed to send AOP mbox msg: %s,ret: %d\n",
-			     mbox_msg, ret);
-	else
-		ret = 0;
+		ret = mbox_send_message(priv->mbox_chan, &pkt);
+		if (ret < 0)
+			icnss_pr_err("Failed to send AOP mbox msg: %s,ret: %d\n",
+				     mbox_msg, ret);
+		else
+			ret = 0;
+	}
 
 	return ret;
 }
 #else
+int icnss_aop_interface_init(struct icnss_priv *priv)
+{
+	return 0;
+}
+
+void icnss_aop_interface_deinit(struct icnss_priv *priv)
+{
+}
+
 static int icnss_aop_set_vreg_param(struct icnss_priv *priv,
 				    const char *vreg_name,
 				    enum icnss_vreg_param param,
@@ -814,8 +870,8 @@ int icnss_update_cpr_info(struct icnss_priv *priv)
 {
 	struct icnss_cpr_info *cpr_info = &priv->cpr_info;
 
-	if (!cpr_info->vreg_ol_cpr || !priv->mbox_chan) {
-		icnss_pr_dbg("Mbox channel / OL CPR Vreg not configured\n");
+	if (!cpr_info->vreg_ol_cpr || (!priv->mbox_chan && !priv->qmp)) {
+		icnss_pr_dbg("Mbox channel / QMP / OL CPR Vreg not configured\n");
 		return 0;
 	}
 

+ 6 - 1
inc/cnss2.h

@@ -105,9 +105,14 @@ enum cnss_host_dump_type {
 	CNSS_HOST_WMI_COMMAND_LOG_IDX,
 	CNSS_HOST_WMI_EVENT_LOG_IDX,
 	CNSS_HOST_WMI_RX_EVENT_IDX,
-	CNSS_HOST_HIF_CE_DESC_HISTORY,
 	CNSS_HOST_HIF_CE_DESC_HISTORY_BUFF,
 	CNSS_HOST_HANG_EVENT_DATA,
+	CNSS_HOST_CE_DESC_HIST,
+	CNSS_HOST_CE_COUNT_MAX,
+	CNSS_HOST_CE_HISTORY_MAX,
+	CNSS_HOST_ONLY_FOR_CRIT_CE,
+	CNSS_HOST_HIF_EVENT_HISTORY,
+	CNSS_HOST_HIF_EVENT_HIST_MAX,
 	CNSS_HOST_DUMP_TYPE_MAX,
 };