Kaynağa Gözat

ipa: Update the QMI FC request to support 128 endpoints

A new field was added to the QMI force clear request message
data structure, to accommodate up to 128 possible endpoints.
If this new field is used on newer architectures,
the old field shall be ignored.
This change implements handling of the new field in the
driver code.

Change-Id: I0d75412a7a177e6307477c54c7efcef225e83f78
Signed-off-by: Ilia Lin <[email protected]>
Ilia Lin 4 yıl önce
ebeveyn
işleme
06d187dd08

+ 21 - 5
drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c

@@ -15,6 +15,7 @@
 #include "ipa_common_i.h"
 #include "ipa_pm.h"
 #include "ipa_i.h"
+#include "ipahal.h"
 #include <linux/ipa_fmwk.h>
 
 #define IPA_MHI_DRV_NAME "ipa_mhi_client"
@@ -1003,23 +1004,38 @@ static int ipa_mhi_enable_force_clear(u32 request_id, bool throttle_source)
 	struct ipa_enable_force_clear_datapath_req_msg_v01 req;
 	int i;
 	int res;
+	u32 source_pipe_bitmask = 0;
+	u32 source_pipe_reg_idx = 0;
+	enum ipa_client_type client;
 
 	IPA_MHI_FUNC_ENTRY();
 	memset(&req, 0, sizeof(req));
 	req.request_id = request_id;
-	req.source_pipe_bitmask = 0;
 	for (i = 0; i < IPA_MHI_MAX_UL_CHANNELS; i++) {
 		if (!ipa_mhi_client_ctx->ul_channels[i].valid)
 			continue;
-		req.source_pipe_bitmask |= 1 << ipa_get_ep_mapping(
-				ipa_mhi_client_ctx->ul_channels[i].client);
+		client = ipa_mhi_client_ctx->ul_channels[i].client;
+		source_pipe_bitmask = ipahal_get_ep_bit(client);
+		source_pipe_reg_idx = ipahal_get_ep_reg_idx(client);
+		if (ipa3_ctx->ipa_hw_type < IPA_HW_v5_0) {
+			WARN_ON(source_pipe_reg_idx);
+			req.source_pipe_bitmask |= source_pipe_bitmask;
+		} else {
+			req.source_pipe_bitmask_ext_valid = 1;
+			req.source_pipe_bitmask_ext[source_pipe_reg_idx] |=
+				source_pipe_bitmask;
+		}
 	}
 	if (throttle_source) {
 		req.throttle_source_valid = 1;
 		req.throttle_source = 1;
 	}
-	IPA_MHI_DBG("req_id=0x%x src_pipe_btmk=0x%x throt_src=%d\n",
-		req.request_id, req.source_pipe_bitmask,
+	IPA_MHI_DBG("req_id=0x%x src_pipe_btmk=0x%x,0x%x,0x%x,0x%x throt_src=%d\n",
+		req.request_id,
+		req.source_pipe_bitmask_ext[0],
+		req.source_pipe_bitmask_ext[1],
+		req.source_pipe_bitmask_ext[2],
+		req.source_pipe_bitmask_ext[3],
 		req.throttle_source);
 	res = ipa3_qmi_enable_force_clear_datapath_send(&req);
 	if (res) {

+ 19 - 2
drivers/platform/msm/ipa/ipa_v3/ipa_client.c

@@ -7,6 +7,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include "ipa_i.h"
+#include "ipahal.h"
 #include <linux/msm_gsi.h>
 #include "gsi.h"
 
@@ -1014,7 +1015,14 @@ int ipa3_enable_force_clear(u32 request_id, bool throttle_source,
 
 	memset(&req, 0, sizeof(req));
 	req.request_id = request_id;
-	req.source_pipe_bitmask = source_pipe_bitmask;
+	if (ipa3_ctx->ipa_hw_type < IPA_HW_v5_0) {
+		WARN_ON(source_pipe_reg_idx);
+		req.source_pipe_bitmask = source_pipe_bitmask;
+	} else {
+		req.source_pipe_bitmask_ext_valid = 1;
+		req.source_pipe_bitmask_ext[source_pipe_reg_idx] =
+			source_pipe_bitmask;
+	}
 	if (throttle_source) {
 		req.throttle_source_valid = 1;
 		req.throttle_source = 1;
@@ -1945,10 +1953,19 @@ int ipa3_clear_endpoint_delay(u32 clnt_hdl)
 	ep = &ipa3_ctx->ep[clnt_hdl];
 
 	if (!ipa3_ctx->tethered_flow_control) {
+		u32 source_pipe_bitmask = ipahal_get_ep_bit(clnt_hdl);
+		int source_pipe_reg_idx = ipahal_get_ep_reg_idx(clnt_hdl);
 		IPADBG("APPS flow control is not enabled\n");
 		/* Send a message to modem to disable flow control honoring. */
 		req.request_id = clnt_hdl;
-		req.source_pipe_bitmask = 1 << clnt_hdl;
+		if (ipa3_ctx->ipa_hw_type < IPA_HW_v5_0) {
+			WARN_ON(source_pipe_reg_idx);
+			req.source_pipe_bitmask = source_pipe_bitmask;
+		} else {
+			req.source_pipe_bitmask_ext_valid = 1;
+			req.source_pipe_bitmask_ext[source_pipe_reg_idx] =
+				source_pipe_bitmask;
+		}
 		res = ipa3_qmi_enable_force_clear_datapath_send(&req);
 		if (res) {
 			IPADBG("enable_force_clear_datapath failed %d\n",

+ 9 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c

@@ -1220,7 +1220,15 @@ int ipa3_qmi_enable_force_clear_datapath_send(
 	struct ipa_msg_desc req_desc, resp_desc;
 	int rc = 0;
 
-	if (!req || !req->source_pipe_bitmask) {
+	if (!req ||
+	    !((ipa3_ctx->ipa_hw_type < IPA_HW_v5_0 &&
+	       req->source_pipe_bitmask) ||
+	      (ipa3_ctx->ipa_hw_type >= IPA_HW_v5_0 &&
+	       req->source_pipe_bitmask_ext_valid &&
+	       (req->source_pipe_bitmask_ext[0] ||
+		req->source_pipe_bitmask_ext[1] ||
+		req->source_pipe_bitmask_ext[2] ||
+		req->source_pipe_bitmask_ext[3])))) {
 		IPAWANERR("invalid params\n");
 		return -EINVAL;
 	}

+ 20 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c

@@ -2380,6 +2380,26 @@ struct qmi_elem_info ipa3_enable_force_clear_datapath_req_msg_data_v01_ei[] = {
 			struct ipa_enable_force_clear_datapath_req_msg_v01,
 			throttle_source),
 	},
+	{
+		.data_type	= QMI_OPT_FLAG,
+		.elem_len	= 1,
+		.elem_size	= sizeof(uint8_t),
+		.array_type	= NO_ARRAY,
+		.tlv_type	= 0x11,
+		.offset		= offsetof(
+			struct ipa_enable_force_clear_datapath_req_msg_v01,
+			source_pipe_bitmask_ext_valid),
+	},
+	{
+		.data_type	= QMI_UNSIGNED_4_BYTE,
+		.elem_len	= 4,
+		.elem_size	= sizeof(uint32_t),
+		.array_type	= STATIC_ARRAY,
+		.tlv_type	= 0x11,
+		.offset		= offsetof(
+			struct ipa_enable_force_clear_datapath_req_msg_v01,
+			source_pipe_bitmask_ext),
+	},
 	{
 		.data_type	= QMI_EOTI,
 		.array_type	= NO_ARRAY,

+ 3 - 1
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -4749,6 +4749,7 @@ u32 ipahal_get_ep_bit(u32 ep_num)
 {
 	return IPA_BIT_MAP_CELL_MSK(ep_num);
 }
+EXPORT_SYMBOL(ipahal_get_ep_bit);
 
 /*
  * ipahal_get_ep_reg_idx() - get ep reg index according to ep num
@@ -4757,6 +4758,7 @@ u32 ipahal_get_ep_reg_idx(u32 ep_num)
 {
 	return IPA_BIT_MAP_CELL_NUM(ep_num);
 }
+EXPORT_SYMBOL(ipahal_get_ep_reg_idx);
 
 /*
  * ipahal_read_reg_mn() - Get mn parameterized reg value