浏览代码

Merge "video: driver: avoid drain_last_flag to drc state transition"

qctecmdr 4 年之前
父节点
当前提交
34ca840018
共有 3 个文件被更改,包括 87 次插入121 次删除
  1. 0 5
      driver/vidc/inc/msm_vidc_internal.h
  2. 66 73
      driver/vidc/src/msm_vidc_driver.c
  3. 21 43
      driver/vidc/src/venus_hfi_response.c

+ 0 - 5
driver/vidc/inc/msm_vidc_internal.h

@@ -607,11 +607,6 @@ struct msm_vidc_hfi_frame_info {
 	u32                    data_corrupt;
 };
 
-struct msm_vidc_cmd_range {
-	u32 begin;
-	u32 end;
-};
-
 struct msm_vidc_decode_vpp_delay {
 	bool                   enable;
 	u32                    size;

+ 66 - 73
driver/vidc/src/msm_vidc_driver.c

@@ -807,11 +807,50 @@ bool msm_vidc_allow_last_flag(struct msm_vidc_inst *inst)
 	return false;
 }
 
+static int msm_vidc_process_pending_ipsc(struct msm_vidc_inst *inst,
+	enum msm_vidc_inst_state *new_state)
+{
+	struct response_work *resp_work, *dummy = NULL;
+	int rc = 0;
+
+	if (!inst || !new_state) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (list_empty(&inst->response_works))
+		return 0;
+
+	i_vpr_h(inst, "%s: state %s, ipsc pending\n", __func__, state_name(inst->state));
+	list_for_each_entry_safe(resp_work, dummy, &inst->response_works, list) {
+		if (resp_work->type == RESP_WORK_INPUT_PSC) {
+			rc = handle_session_response_work(inst, resp_work);
+			if (rc) {
+				i_vpr_e(inst, "%s: handle ipsc failed\n", __func__);
+				*new_state = MSM_VIDC_ERROR;
+			} else {
+				if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG ||
+					inst->state == MSM_VIDC_DRAIN_START_INPUT) {
+					*new_state = MSM_VIDC_DRC_DRAIN;
+				} else if (inst->state == MSM_VIDC_DRC_LAST_FLAG) {
+					*new_state = MSM_VIDC_DRC;
+				}
+			}
+			list_del(&resp_work->list);
+			kfree(resp_work->data);
+			kfree(resp_work);
+			/* list contains max only one ipsc at anytime */
+			break;
+		}
+	}
+
+	return rc;
+}
+
 int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type)
 {
 	int rc = 0;
 	enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
-	struct response_work *resp_work;
 
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -832,35 +871,19 @@ int msm_vidc_state_change_streamon(struct msm_vidc_inst *inst, u32 type)
 		} else if (inst->state == MSM_VIDC_START_INPUT) {
 			new_state = MSM_VIDC_START;
 		} else if (inst->state == MSM_VIDC_DRAIN_START_INPUT) {
-			i_vpr_h(inst,
-				"%s: streamon(output) in DRAIN_START_INPUT state\n",
-				__func__);
+			i_vpr_h(inst, "%s: streamon(output) in %s state\n",
+				__func__, state_name(inst->state));
 			new_state = MSM_VIDC_DRAIN;
-			if (!list_empty(&inst->response_works)) {
-				resp_work = list_first_entry(&inst->response_works,
-							struct response_work, list);
-				if (resp_work->type == RESP_WORK_INPUT_PSC) {
-					i_vpr_h(inst,
-						"%s: streamon(output) in DRAIN_START_INPUT state, input psc pending\n",
-						__func__);
-					rc = handle_session_response_work(inst, resp_work);
-					if (rc) {
-						i_vpr_e(inst,
-							"%s: handle input psc failed\n", __func__);
-						new_state = MSM_VIDC_ERROR;
-					} else {
-						new_state = MSM_VIDC_DRC_DRAIN;
-					}
-					list_del(&resp_work->list);
-					kfree(resp_work->data);
-					kfree(resp_work);
-				}
+			rc = msm_vidc_process_pending_ipsc(inst, &new_state);
+			if (rc) {
+				i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__);
+				goto state_change;
 			}
 		}
 	}
-	rc = msm_vidc_change_inst_state(inst, new_state, __func__);
-	if (rc)
-		return rc;
+
+state_change:
+	msm_vidc_change_inst_state(inst, new_state, __func__);
 
 	return rc;
 }
@@ -960,7 +983,6 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
 	enum msm_vidc_inst_state new_state = MSM_VIDC_ERROR;
-	struct response_work *resp_work;
 
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -969,57 +991,28 @@ int msm_vidc_state_change_start(struct msm_vidc_inst *inst)
 
 	if (inst->state == MSM_VIDC_DRAIN_LAST_FLAG ||
 		inst->state == MSM_VIDC_DRC_LAST_FLAG) {
-			new_state = MSM_VIDC_START;
-		if (!list_empty(&inst->response_works)) {
-			resp_work = list_first_entry(&inst->response_works,
-				struct response_work, list);
-			if (resp_work->type == RESP_WORK_INPUT_PSC) {
-				i_vpr_h(inst,
-					"%s: start in DRC(DRAIN)_LAST_FLAG state, input psc pending\n",
-					__func__);
-				rc = handle_session_response_work(inst, resp_work);
-				if (rc) {
-					i_vpr_e(inst,
-						"%s: handle input psc failed\n", __func__);
-					new_state = MSM_VIDC_ERROR;
-				} else {
-					new_state = MSM_VIDC_DRC;
-				}
-				list_del(&resp_work->list);
-				kfree(resp_work->data);
-				kfree(resp_work);
-			}
+		new_state = MSM_VIDC_START;
+		rc = msm_vidc_process_pending_ipsc(inst, &new_state);
+		if (rc) {
+			i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__);
+			goto state_change;
 		}
 	} else if (inst->state == MSM_VIDC_DRC_DRAIN_LAST_FLAG) {
-			new_state = MSM_VIDC_DRAIN;
-		if (!list_empty(&inst->response_works)) {
-			resp_work = list_first_entry(&inst->response_works,
-				struct response_work, list);
-			if (resp_work->type == RESP_WORK_INPUT_PSC) {
-				i_vpr_h(inst,
-					"%s: start in DRC_DRAIN_LAST_FLAG state, input psc pending\n");
-				rc = handle_session_response_work(inst, resp_work);
-				if (rc) {
-					i_vpr_e(inst,
-						"%s: handle input psc failed\n", __func__);
-					new_state = MSM_VIDC_ERROR;
-				} else {
-					new_state = MSM_VIDC_DRC_DRAIN;
-				}
-				list_del(&resp_work->list);
-				kfree(resp_work->data);
-				kfree(resp_work);
-			}
+		new_state = MSM_VIDC_DRAIN;
+		rc = msm_vidc_process_pending_ipsc(inst, &new_state);
+		if (rc) {
+			i_vpr_e(inst, "%s: process pending ipsc failed\n", __func__);
+			goto state_change;
 		}
 	} else {
-		i_vpr_e(inst, "%s: wrong state %s\n",
-			__func__, state_name(inst->state));
-		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
-		return -EINVAL;
+		i_vpr_e(inst, "%s: wrong state %s\n", __func__, state_name(inst->state));
+		new_state = MSM_VIDC_ERROR;
+		rc = -EINVAL;
+		goto state_change;
 	}
-	rc = msm_vidc_change_inst_state(inst, new_state, __func__);
-	if (rc)
-		return rc;
+
+state_change:
+	msm_vidc_change_inst_state(inst, new_state, __func__);
 
 	return rc;
 }

+ 21 - 43
driver/vidc/src/venus_hfi_response.c

@@ -10,7 +10,14 @@
 #include "msm_vidc_driver.h"
 #include "msm_vdec.h"
 
+#define in_range(range, val) (((range.begin) < (val)) && ((range.end) > (val)))
+
 extern struct msm_vidc_core *g_core;
+struct msm_vidc_hfi_range {
+	u32 begin;
+	u32 end;
+	int (*handle)(struct msm_vidc_inst *inst, struct hfi_packet *pkt);
+};
 
 void print_psc_properties(u32 tag, const char *str, struct msm_vidc_inst *inst,
 	struct msm_vidc_subscription_params subsc_params)
@@ -1198,32 +1205,6 @@ exit:
 	return rc;
 }
 
-static int process_response_packet(struct msm_vidc_inst *inst,
-		struct hfi_packet *packet)
-{
-	int rc = 0;
-
-	if (packet->type > HFI_CMD_BEGIN &&
-		packet->type < HFI_CMD_END) {
-		rc = handle_session_command(inst, packet);
-	} else if (packet->type > HFI_PROP_BEGIN &&
-		packet->type < HFI_PROP_END) {
-		rc = handle_session_property(inst, packet);
-	} else if (packet->type > HFI_SESSION_ERROR_BEGIN &&
-		packet->type < HFI_SESSION_ERROR_END) {
-		rc = handle_session_error(inst, packet);
-	} else if (packet->type > HFI_INFORMATION_BEGIN &&
-		packet->type < HFI_INFORMATION_END) {
-		rc = handle_session_info(inst, packet);
-	} else {
-		i_vpr_e(inst, "%s: Unknown packet type: %#x\n",
-			__func__, packet->type);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
 int handle_session_response_work(struct msm_vidc_inst *inst,
 		struct response_work *resp_work)
 {
@@ -1233,12 +1214,11 @@ int handle_session_response_work(struct msm_vidc_inst *inst,
 	u8 *pkt, *start_pkt;
 	u32 hfi_cmd_type = 0;
 	int i, j;
-	struct msm_vidc_cmd_range be[5] = {
-		{HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END},
-		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END},
-		{HFI_INFORMATION_BEGIN, HFI_INFORMATION_END},
-		{HFI_PROP_BEGIN, HFI_PROP_END},
-		{HFI_CMD_BEGIN, HFI_CMD_END},
+	struct msm_vidc_hfi_range be[] = {
+		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, handle_session_error},
+		{HFI_INFORMATION_BEGIN,   HFI_INFORMATION_END,   handle_session_info},
+		{HFI_PROP_BEGIN,          HFI_PROP_END,          handle_session_property},
+		{HFI_CMD_BEGIN,           HFI_CMD_END,           handle_session_command},
 	};
 
 	if (!inst || !resp_work) {
@@ -1273,8 +1253,7 @@ int handle_session_response_work(struct msm_vidc_inst *inst,
 		pkt = start_pkt;
 		for (j = 0; j < hdr->num_packets; j++) {
 			packet = (struct hfi_packet * ) pkt;
-			if (packet->type > be[i].begin
-				&& packet->type < be[i].end) {
+			if (in_range(be[i], packet->type)) {
 				if (hfi_cmd_type == HFI_CMD_SETTINGS_CHANGE) {
 					i_vpr_e(inst,
 						"%s: invalid packet type %d in port settings change\n",
@@ -1282,7 +1261,7 @@ int handle_session_response_work(struct msm_vidc_inst *inst,
 					rc = -EINVAL;
 				}
 				hfi_cmd_type = packet->type;
-				rc = process_response_packet(inst, packet);
+				rc = be[i].handle(inst, packet);
 				if (rc)
 					goto exit;
 			}
@@ -1400,12 +1379,11 @@ static int handle_session_response(struct msm_vidc_core *core,
 	u32 hfi_cmd_type = 0;
 	u32 hfi_port = 0;
 	int i, j;
-	struct msm_vidc_cmd_range be[5] = {
-		{HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END},
-		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END},
-		{HFI_INFORMATION_BEGIN, HFI_INFORMATION_END},
-		{HFI_PROP_BEGIN, HFI_PROP_END},
-		{HFI_CMD_BEGIN, HFI_CMD_END},
+	struct msm_vidc_hfi_range be[] = {
+		{HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, handle_session_error},
+		{HFI_INFORMATION_BEGIN,   HFI_INFORMATION_END,   handle_session_info},
+		{HFI_PROP_BEGIN,          HFI_PROP_END,          handle_session_property},
+		{HFI_CMD_BEGIN,           HFI_CMD_END,           handle_session_command},
 	};
 
 	inst = get_inst(core, hdr->session_id);
@@ -1460,9 +1438,9 @@ static int handle_session_response(struct msm_vidc_core *core,
 		pkt = start_pkt;
 		for (j = 0; j < hdr->num_packets; j++) {
 			packet = (struct hfi_packet * ) pkt;
-			if (packet->type > be[i].begin && packet->type < be[i].end) {
+			if (in_range(be[i], packet->type)) {
 				hfi_cmd_type = packet->type;
-				rc = process_response_packet(inst, packet);
+				rc = be[i].handle(inst, packet);
 				if (rc)
 					goto exit;
 			}