Selaa lähdekoodia

qcacld-3.0: Send HOST wake up to FW over QMI

As part of WOW feature in WCN6750, send HOST wake up
to FW over QMI instead of WMI. To send HOST wake, add
PLD layer and call platform driver API to send QMI
EXIT_POWER_SAVE to FW.
When FW receive EXIT_POWER_SAVE QMI, it will implicitly
consider that it also received HOST_WAKEUP_FROM_SLEEP
and send ACK for it through CE2.

Change-Id: Ia0a3f4c15662f9ee58649f5c6de965f65aeafe32
CRs-Fixed: 2779370
Naman Padhiar 4 vuotta sitten
vanhempi
sitoutus
001338b360

+ 23 - 0
components/target_if/pmo/src/target_if_pmo_suspend_resume.c

@@ -26,6 +26,8 @@
 #include "target_if.h"
 #include "target_if_pmo.h"
 #include "wmi_unified_api.h"
+#include "qdf_types.h"
+#include "pld_common.h"
 
 #define TGT_WILDCARD_PDEV_ID 0x0
 
@@ -275,6 +277,26 @@ bool target_if_pmo_get_runtime_pm_in_progress(
 	return wmi_get_runtime_pm_inprogress(wmi_handle);
 }
 
+#ifdef HOST_WAKEUP_OVER_QMI
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+		struct wlan_objmgr_psoc *psoc)
+{
+	qdf_device_t qdf_dev;
+	int ret;
+
+	qdf_dev = wlan_psoc_get_qdf_dev(psoc);
+	if (!qdf_dev)
+		return QDF_STATUS_E_INVAL;
+
+	ret = pld_exit_power_save(qdf_dev->dev);
+	if (ret) {
+		target_if_err("Failed to exit power save, ret: %d", ret);
+		return qdf_status_from_os_return(ret);
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
 QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
 		struct wlan_objmgr_psoc *psoc)
 {
@@ -288,6 +310,7 @@ QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
 
 	return wmi_unified_host_wakeup_ind_to_fw_cmd(wmi_handle);
 }
+#endif
 
 QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
 		struct wlan_objmgr_psoc *psoc)

+ 9 - 0
core/pld/inc/pld_common.h

@@ -685,6 +685,15 @@ int pld_force_wake_request(struct device *dev);
  *         Non zero failure code for errors
  */
 int pld_force_wake_request_sync(struct device *dev, int timeout_us);
+
+/**
+ * pld_exit_power_save() - Send EXIT_POWER_SAVE QMI to FW
+ * @dev: device
+ *
+ * Return: 0 for success
+ *         Non zero failure code for errors
+ */
+int pld_exit_power_save(struct device *dev);
 int pld_is_device_awake(struct device *dev);
 int pld_force_wake_release(struct device *dev);
 int pld_ce_request_irq(struct device *dev, unsigned int ce_id,

+ 26 - 0
core/pld/src/pld_common.c

@@ -1229,6 +1229,32 @@ int pld_force_wake_request_sync(struct device *dev, int timeout_us)
 	return ret;
 }
 
+int pld_exit_power_save(struct device *dev)
+{
+	int ret = 0;
+	enum pld_bus_type type = pld_get_bus_type(dev);
+
+	switch (type) {
+	case PLD_BUS_TYPE_PCIE:
+	case PLD_BUS_TYPE_PCIE_FW_SIM:
+	case PLD_BUS_TYPE_IPCI_FW_SIM:
+	case PLD_BUS_TYPE_SNOC_FW_SIM:
+	case PLD_BUS_TYPE_SNOC:
+	case PLD_BUS_TYPE_SDIO:
+	case PLD_BUS_TYPE_USB:
+		break;
+	case PLD_BUS_TYPE_IPCI:
+		ret = pld_ipci_exit_power_save(dev);
+		break;
+	default:
+		pr_err("Invalid device type %d\n", type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 /**
  * pld_is_device_awake() - Check if it's ready to access MMIO registers
  * @dev: device

+ 8 - 0
core/pld/src/pld_ipci.h

@@ -176,6 +176,10 @@ static inline int pld_ipci_get_thermal_state(struct device *dev,
 	return 0;
 }
 
+static inline int pld_ipci_exit_power_save(struct device *dev)
+{
+	return 0;
+}
 #else
 int pld_ipci_register_driver(void);
 void pld_ipci_unregister_driver(void);
@@ -310,5 +314,9 @@ static inline int pld_ipci_get_thermal_state(struct device *dev,
 	return icnss_get_curr_therm_cdev_state(dev, thermal_state, mon_id);
 }
 
+static inline int pld_ipci_exit_power_save(struct device *dev)
+{
+	return icnss_exit_power_save(dev);
+}
 #endif
 #endif