ソースを参照

msm: gsi: Add debug code for Flow Control

Increase timeout while waiting for FC command to complete.
For enable FC command wait longer in case PENDING bit is set.

Change-Id: I6d4443b1688d2ae426079638216829a4ddb30d94
Acked-by: Nadav Levintov <[email protected]>
Signed-off-by: Sivan Reinstein <[email protected]>
Sivan Reinstein 3 年 前
コミット
5b713d37b0

+ 20 - 2
drivers/platform/msm/gsi/gsi.c

@@ -24,11 +24,13 @@
 #include <linux/version.h>
 
 #define GSI_CMD_TIMEOUT (5*HZ)
+#define GSI_FC_CMD_TIMEOUT (2*GSI_CMD_TIMEOUT)
 #define GSI_START_CMD_TIMEOUT_MS 1000
 #define GSI_CMD_POLL_CNT 5
 #define GSI_STOP_CMD_TIMEOUT_MS 200
 #define GSI_MAX_CH_LOW_WEIGHT 15
 #define GSI_IRQ_STORM_THR 5
+#define GSI_FC_MAX_TIMEOUT 5
 
 #define GSI_STOP_CMD_POLL_CNT 4
 #define GSI_STOP_IN_PROC_CMD_POLL_CNT 2
@@ -52,6 +54,10 @@
 #define GSI_INST_RAM_FW_VER_FW_MASK			(0x7f)
 #define GSI_INST_RAM_FW_VER_FW_SHIFT		(0)
 
+#define GSI_FC_NUM_WORDS_PER_CHNL_SHRAM		(20)
+#define GSI_FC_STATE_INDEX_SHRAM			(7)
+#define GSI_FC_PENDING_MASK					(0x00080000)
+
 #ifndef CONFIG_DEBUG_FS
 void gsi_debugfs_init(void)
 {
@@ -4833,7 +4839,7 @@ free_lock:
 }
 EXPORT_SYMBOL(gsi_enable_flow_control_ee);
 
-int gsi_flow_control_ee(unsigned int chan_idx, unsigned int ee,
+int gsi_flow_control_ee(unsigned int chan_idx, int ep_id, unsigned int ee,
 				bool enable, bool prmy_scnd_fc, int *code)
 {
 	struct gsihal_reg_gsi_ee_generic_cmd cmd;
@@ -4841,6 +4847,8 @@ int gsi_flow_control_ee(unsigned int chan_idx, unsigned int ee,
 					GSI_GEN_EE_CMD_ENABLE_FLOW_CHANNEL :
 					GSI_GEN_EE_CMD_DISABLE_FLOW_CHANNEL;
 	int res;
+	int wait_due_pending = 0;
+	uint32_t fc_pending = 0;
 
 	if (!gsi_ctx) {
 		pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
@@ -4873,10 +4881,20 @@ int gsi_flow_control_ee(unsigned int chan_idx, unsigned int ee,
 	gsihal_write_reg_n_fields(
 		GSI_EE_n_GSI_EE_GENERIC_CMD, gsi_ctx->per.ee, &cmd);
 
+wait_again:
+	fc_pending = gsihal_read_reg_n(GSI_GSI_SHRAM_n,
+		(ep_id * GSI_FC_NUM_WORDS_PER_CHNL_SHRAM) + GSI_FC_STATE_INDEX_SHRAM) &
+		GSI_FC_PENDING_MASK;
 	res = wait_for_completion_timeout(&gsi_ctx->gen_ee_cmd_compl,
-		msecs_to_jiffies(GSI_CMD_TIMEOUT));
+		msecs_to_jiffies(GSI_FC_CMD_TIMEOUT));
 	if (res == 0) {
 		GSIERR("chan_idx=%u ee=%u timed out\n", chan_idx, ee);
+		if (op == GSI_GEN_EE_CMD_ENABLE_FLOW_CHANNEL &&
+			wait_due_pending < GSI_FC_MAX_TIMEOUT &&
+			fc_pending) {
+			wait_due_pending++;
+			goto wait_again;
+		}
 		res = -GSI_STATUS_TIMED_OUT;
 		GSI_ASSERT();
 		goto free_lock;

+ 2 - 2
drivers/platform/msm/gsi/gsi.h

@@ -2393,8 +2393,8 @@ int gsi_get_hw_profiling_stats(struct gsi_hw_profiling_data *stats);
  */
 int gsi_get_fw_version(struct gsi_fw_version *ver);
 
-int gsi_flow_control_ee(unsigned int chan_idx, unsigned int ee,
-				bool enable, bool prmy_scnd_fc, int *code);
+int gsi_flow_control_ee(unsigned int chan_idx, int ep_id, unsigned int ee,
+    bool enable, bool prmy_scnd_fc, int *code);
 int gsi_query_flow_control_state_ee(unsigned int chan_idx, unsigned int ee,
 						bool prmy_scnd_fc, int *code);
 /*

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

@@ -3872,7 +3872,7 @@ static void ipa3_q6_pipe_flow_control(bool delay)
 			IPADBG("pipe setting V2 flow control\n");
 			/* Configurig primary flow control on Q6 pipes*/
 			result = gsi_flow_control_ee(
-					gsi_ep_cfg->ipa_gsi_chan_num,
+					gsi_ep_cfg->ipa_gsi_chan_num, ep_idx,
 					gsi_ep_cfg->ee, delay, false, &code);
 			if (result == GSI_STATUS_SUCCESS) {
 				IPADBG("sussess gsi ch %d with code %d\n",

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

@@ -1166,8 +1166,8 @@ int ipa3_remove_secondary_flow_ctrl(int gsi_chan_hdl)
 	result = gsi_query_flow_control_state_ee(gsi_chan_hdl, 0, 1, &code);
 	if (result == GSI_STATUS_SUCCESS) {
 		code = 0;
-		result = gsi_flow_control_ee(gsi_chan_hdl, 0, false, true,
-							&code);
+		result = gsi_flow_control_ee(gsi_chan_hdl,
+			ipa3_get_ep_mapping_from_gsi(gsi_chan_hdl), 0, false, true, &code);
 		if (result == GSI_STATUS_SUCCESS) {
 			IPADBG("flow control sussess ch %d code %d\n",
 					gsi_chan_hdl, code);

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

@@ -2974,6 +2974,7 @@ int ipa3_add_interrupt_handler(enum ipa_irq_type interrupt,
  * Miscellaneous
  */
 int ipa3_get_ep_mapping(enum ipa_client_type client);
+int ipa3_get_ep_mapping_from_gsi(int ch_id);
 
 bool ipa3_is_ready(void);
 

+ 32 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c

@@ -6886,6 +6886,37 @@ int ipa3_get_ep_mapping(enum ipa_client_type client)
 	return ipa_ep_idx;
 }
 
+/**
+ * ipa3_get_ep_mapping_from_gsi() - provide endpoint mapping
+ * @ch_id: GSI Virt CH id
+ *
+ * Return value: endpoint mapping
+ */
+int ipa3_get_ep_mapping_from_gsi(int ch_id)
+{
+	int ipa_ep_idx = IPA_EP_NOT_ALLOCATED;
+	u8 hw_idx;
+	int i = 0;
+
+	hw_idx = ipa3_ctx->hw_type_index;
+
+	if (ch_id >= GSI_CHAN_MAX || ch_id < 0) {
+		IPAERR_RL("Bad ch_id number! ch_id =%d\n", ch_id);
+		return IPA_EP_NOT_ALLOCATED;
+	}
+
+	for (i = 0; i < IPA_CLIENT_MAX; i++) {
+		if (ipa3_ep_mapping[hw_idx][i].valid &&
+			ipa3_ep_mapping[hw_idx][i].ipa_gsi_ep_info.ipa_gsi_chan_num
+			== ch_id) {
+			ipa_ep_idx = ipa3_ep_mapping[hw_idx][i].ipa_gsi_ep_info.ipa_ep_num;
+			break;
+		}
+	}
+
+	return ipa_ep_idx;
+}
+
 /**
  * ipa3_get_gsi_ep_info() - provide gsi ep information
  * @client: IPA client value
@@ -7776,7 +7807,7 @@ int ipa3_cfg_ep_ctrl(u32 clnt_hdl, const struct ipa_ep_cfg_ctrl *ep_ctrl)
 		else
 			primary_secondry = false;
 
-		result = gsi_flow_control_ee(ep->gsi_chan_hdl, 0,
+		result = gsi_flow_control_ee(ep->gsi_chan_hdl, clnt_hdl, 0,
 				ep_ctrl->ipa_ep_delay, primary_secondry, &code);
 		if (result == GSI_STATUS_SUCCESS) {
 			IPADBG("flow control sussess gsi ch %d with code %d\n",