Ver código fonte

msm: ipa3: Support PM API For WLAN.

Adding wrapper API to support PM
approach for WLAN.

Change-Id: I8c234f71ff4a254dcbd9d68add893d439bcfb0cb
Signed-off-by: Piyush Dhyani <[email protected]>
Piyush Dhyani 4 anos atrás
pai
commit
d07a70bb2c

+ 12 - 4
drivers/platform/msm/ipa/ipa_clients/ipa_wdi3.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/ipa_wdi3.h>
@@ -769,18 +769,26 @@ static int ipa_wdi_disable_pipes_internal(void)
 
 static int ipa_wdi_set_perf_profile_internal(struct ipa_wdi_perf_profile *profile)
 {
+	int res = 0;
+
 	if (profile == NULL) {
 		IPA_WDI_ERR("Invalid input\n");
 		return -EINVAL;
 	}
 
-	if (ipa_pm_set_throughput(ipa_wdi_ctx->ipa_pm_hdl,
-		profile->max_supported_bw_mbps)) {
+	if (ipa3_ctx->use_pm_wrapper) {
+		res = ipa_pm_wrapper_wdi_set_perf_profile_internal(profile);
+	} else {
+		res = ipa_pm_set_throughput(ipa_wdi_ctx->ipa_pm_hdl,
+			profile->max_supported_bw_mbps);
+	}
+
+	if (res) {
 		IPA_WDI_ERR("fail to set pm throughput\n");
 		return -EFAULT;
 	}
 
-	return 0;
+	return res;
 }
 
 void ipa_wdi3_register(void)

+ 21 - 4
drivers/platform/msm/ipa/ipa_v3/ipa.c

@@ -6615,12 +6615,20 @@ static inline void ipa3_register_to_fmwk(void)
 	data.ipa_rmnet_ctl_xmit = ipa3_rmnet_ctl_xmit;
 	data.ipa_register_rmnet_ctl_cb = ipa3_register_rmnet_ctl_cb;
 	data.ipa_unregister_rmnet_ctl_cb = ipa3_unregister_rmnet_ctl_cb;
-	data.ipa_enable_wdi_pipe = ipa3_enable_wdi_pipe;
-	data.ipa_disable_wdi_pipe = ipa3_disable_wdi_pipe;
+	if (ipa3_ctx->use_pm_wrapper) {
+		data.ipa_enable_wdi_pipe = ipa_pm_wrapper_enable_wdi_pipe;
+		data.ipa_disable_wdi_pipe = ipa_pm_wrapper_disable_pipe;
+		data.ipa_connect_wdi_pipe = ipa_pm_wrapper_connect_wdi_pipe;
+		data.ipa_disconnect_wdi_pipe = ipa_pm_wrapper_disconnect_wdi_pipe;
+	}
+	else {
+		data.ipa_enable_wdi_pipe = ipa3_enable_wdi_pipe;
+		data.ipa_disable_wdi_pipe = ipa3_disable_wdi_pipe;
+		data.ipa_connect_wdi_pipe = ipa3_connect_wdi_pipe;
+		data.ipa_disconnect_wdi_pipe = ipa3_disconnect_wdi_pipe;
+	}
 	data.ipa_resume_wdi_pipe = ipa3_resume_wdi_pipe;
 	data.ipa_suspend_wdi_pipe = ipa3_suspend_wdi_pipe;
-	data.ipa_connect_wdi_pipe = ipa3_connect_wdi_pipe;
-	data.ipa_disconnect_wdi_pipe = ipa3_disconnect_wdi_pipe;
 	data.ipa_uc_reg_rdyCB = ipa3_uc_reg_rdyCB;
 	data.ipa_uc_dereg_rdyCB = ipa3_uc_dereg_rdyCB;
 
@@ -7826,6 +7834,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
 	ipa3_ctx->ulso_supported = resource_p->ulso_supported;
 	ipa3_ctx->ulso_ip_id_min = resource_p->ulso_ip_id_min;
 	ipa3_ctx->ulso_ip_id_max = resource_p->ulso_ip_id_max;
+	ipa3_ctx->use_pm_wrapper = resource_p->use_pm_wrapper;
 
 	if (resource_p->gsi_fw_file_name) {
 		ipa3_ctx->gsi_fw_file_name =
@@ -9043,6 +9052,14 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
 		ipa_drv_res->gsi_ch20_wa
 		? "Needed" : "Not needed");
 
+	ipa_drv_res->use_pm_wrapper = false;
+	ipa_drv_res->use_pm_wrapper =
+		of_property_read_bool(pdev->dev.of_node,
+		"qcom,use-wrapper-pm-support");
+	IPADBG(": Use PM wrapper Support = %s\n",
+		ipa_drv_res->use_pm_wrapper
+		? "Needed" : "Not needed");
+
 	elem_num = of_property_count_elems_of_size(pdev->dev.of_node,
 		"qcom,mhi-event-ring-id-limits", sizeof(u32));
 

+ 8 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_i.h

@@ -2228,6 +2228,7 @@ struct ipa3_context {
 	bool ulso_supported;
 	u16 ulso_ip_id_min;
 	u16 ulso_ip_id_max;
+	bool use_pm_wrapper;
 };
 
 struct ipa3_plat_drv_res {
@@ -2304,6 +2305,7 @@ struct ipa3_plat_drv_res {
 	bool ulso_supported;
 	u16 ulso_ip_id_min;
 	u16 ulso_ip_id_max;
+	bool use_pm_wrapper;
 };
 
 /**
@@ -2777,6 +2779,12 @@ int ipa3_connect_gsi_wdi_pipe(struct ipa_wdi_in_params *in,
 
 int ipa3_disconnect_wdi_pipe(u32 clnt_hdl);
 int ipa3_enable_wdi_pipe(u32 clnt_hdl);
+int ipa_pm_wrapper_wdi_set_perf_profile_internal(struct ipa_wdi_perf_profile *profile);
+int ipa_pm_wrapper_connect_wdi_pipe(struct ipa_wdi_in_params *in,
+			struct ipa_wdi_out_params *out);
+int ipa_pm_wrapper_disconnect_wdi_pipe(u32 clnt_hdl);
+int ipa_pm_wrapper_enable_wdi_pipe(u32 clnt_hdl);
+int ipa_pm_wrapper_disable_pipe(u32 clnt_hdl);
 int ipa3_enable_gsi_wdi_pipe(u32 clnt_hdl);
 int ipa3_disable_wdi_pipe(u32 clnt_hdl);
 int ipa3_disable_gsi_wdi_pipe(u32 clnt_hdl);

+ 169 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_uc_wdi.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
 #include "ipa_i.h"
@@ -30,6 +30,26 @@
 
 #define GSI_STOP_MAX_RETRY_CNT 10
 
+enum ipa_pm_state_wdi_info {
+	IPA_PM_WDI_PM_REGISTERED = 0x0,
+	IPA_PM_WDI_PM_ACTIVATE = 0x1,
+	IPA_PM_WDI_PM_DEACTIVATE_IN_PROC = 0x2,
+	IPA_PM_WDI_PM_DEACTIVATE = 0x3,
+	IPA_PM_WDI_PM_DEREGISTER_IN_PROC = 0x4,
+	IPA_PM_WDI_PM_DEREGISTERED = 0x5
+};
+
+struct ipa_pm_wdi_context {
+	enum ipa_pm_state_wdi_info curr_pm_state;
+	u32 ipa_wrapper_pm_hdl;
+};
+
+static struct ipa_pm_wdi_context ipa_pm_wdi_ctx = {
+	.curr_pm_state = IPA_PM_WDI_PM_DEREGISTERED,
+	.ipa_wrapper_pm_hdl = 0
+};
+
+
 struct ipa_wdi_res {
 	struct ipa_wdi_buffer_info *res;
 	unsigned int nents;
@@ -3146,3 +3166,151 @@ int ipa3_release_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info)
 	return ret;
 }
 EXPORT_SYMBOL(ipa3_release_wdi_mapping);
+
+static void ipa_wdi_pm_wrapper_cb(void *p, enum ipa_pm_cb_event event)
+{
+	IPADBG("received pm event %d\n", event);
+}
+
+int ipa_pm_wrapper_wdi_set_perf_profile_internal(struct ipa_wdi_perf_profile *profile)
+{
+	int res = 0;
+
+	if (profile == NULL) {
+		IPAERR("Invalid input\n");
+		return -EINVAL;
+	}
+
+	res = ipa_pm_set_throughput(ipa_pm_wdi_ctx.ipa_wrapper_pm_hdl,
+			profile->max_supported_bw_mbps);
+	if (res) {
+		IPAERR("fail to set pm throughput\n");
+		return -EFAULT;
+	}
+
+	 return 0;
+}
+EXPORT_SYMBOL(ipa_pm_wrapper_wdi_set_perf_profile_internal);
+
+int ipa_pm_wrapper_connect_wdi_pipe(struct ipa_wdi_in_params *in,
+				struct ipa_wdi_out_params *out)
+{
+	int ret = 0;
+	struct ipa_pm_register_params pm_params;
+
+	if (!(in && out)) {
+		IPAERR("empty parameters. in=%pK out=%pK\n", in, out);
+		return -EINVAL;
+	}
+	if (ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_DEREGISTERED &&
+		ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_REGISTERED) {
+		IPAERR("Unexpected current ipa pm state\n");
+		return -EINVAL;
+	}
+
+	if (ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_REGISTERED) {
+		memset(&pm_params, 0, sizeof(pm_params));
+		pm_params.name = "wdi";
+		pm_params.callback = ipa_wdi_pm_wrapper_cb;
+		pm_params.user_data = NULL;
+		pm_params.group = IPA_PM_GROUP_DEFAULT;
+		if (ipa_pm_register(&pm_params, &ipa_pm_wdi_ctx.ipa_wrapper_pm_hdl)) {
+			IPAERR("fail to register ipa pm\n");
+			ret = -EFAULT;
+			return ret;
+		}
+		ipa_pm_wdi_ctx.curr_pm_state = IPA_PM_WDI_PM_REGISTERED;
+	}
+
+	if (ipa3_connect_wdi_pipe(in,out)) {
+		IPAERR("fail to setup pipe\n");
+		ret = -EFAULT;
+		return ret;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ipa_pm_wrapper_connect_wdi_pipe);
+
+int ipa_pm_wrapper_disconnect_wdi_pipe(u32 clnt_hdl)
+{
+	int ret = 0;
+	if (ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEACTIVATE_IN_PROC ||
+		ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_ACTIVATE) {
+		IPAERR("Unexpected current ipa pm state\n");
+		return -EFAULT;
+	}
+	if (ipa3_disconnect_wdi_pipe(clnt_hdl)) {
+		IPAERR("fail to tear down pipe\n");
+		return -EFAULT;
+	}
+
+	if (ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_DEREGISTER_IN_PROC) {
+		ipa_pm_wdi_ctx.curr_pm_state  = IPA_PM_WDI_PM_DEREGISTER_IN_PROC;
+	}
+	else {
+		if (ipa_pm_deregister(ipa_pm_wdi_ctx.ipa_wrapper_pm_hdl)) {
+			IPAERR("fail to deregister ipa pm\n");
+			return -EFAULT;
+		}
+		ipa_pm_wdi_ctx.curr_pm_state = IPA_PM_WDI_PM_DEREGISTERED;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ipa_pm_wrapper_disconnect_wdi_pipe);
+
+int ipa_pm_wrapper_enable_wdi_pipe(u32 clnt_hdl)
+{
+	int ret = 0;
+	if (ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEREGISTER_IN_PROC ||
+		ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEREGISTERED ||
+			ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEACTIVATE_IN_PROC) {
+		IPAERR("Unexpected current ipa pm state\n");
+		return -EFAULT;
+	}
+
+	if (ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_ACTIVATE) {
+		if (ipa_pm_activate_sync(ipa_pm_wdi_ctx.ipa_wrapper_pm_hdl)) {
+			IPAERR("fail to activate ipa pm\n");
+			return -EFAULT;
+		}
+		ipa_pm_wdi_ctx.curr_pm_state = IPA_PM_WDI_PM_ACTIVATE;
+	}
+
+	if (ipa3_enable_wdi_pipe(clnt_hdl)) {
+		IPAERR("fail to enable wdi pipe\n");
+		return -EFAULT;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ipa_pm_wrapper_enable_wdi_pipe);
+
+int ipa_pm_wrapper_disable_pipe(u32 clnt_hdl)
+{
+	int ret = 0;
+	if (ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_REGISTERED ||
+		ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEREGISTER_IN_PROC ||
+			ipa_pm_wdi_ctx.curr_pm_state == IPA_PM_WDI_PM_DEREGISTERED) {
+		IPAERR("Unexpected current ipa pm state\n");
+		return -EFAULT;
+	}
+
+	if (ipa3_disable_wdi_pipe(clnt_hdl)) {
+		IPAERR("fail to disable wdi pipe\n");
+		return -EFAULT;
+	}
+
+	if (ipa_pm_wdi_ctx.curr_pm_state != IPA_PM_WDI_PM_DEACTIVATE_IN_PROC) {
+		ipa_pm_wdi_ctx.curr_pm_state = IPA_PM_WDI_PM_DEACTIVATE_IN_PROC;
+	}
+	else {
+		if(ipa_pm_deactivate_sync(ipa_pm_wdi_ctx.ipa_wrapper_pm_hdl)) {
+			IPAERR("fail to deactivate ipa pm\n");
+			return -EFAULT;
+		}
+		ipa_pm_wdi_ctx.curr_pm_state = IPA_PM_WDI_PM_DEACTIVATE;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ipa_pm_wrapper_disable_pipe);