Browse Source

video: driver: alter core_init and deinit sequence

Added changes to call do msm_vidc_core_init() inside
msm_vidc_probe_video_device() itself. It will uniform
core init and deinit as part of insmod and rmmod.

follow core_init and core_init_wait for all new session
open sequence.

Change-Id: I081d5ff3632296b5d2086992e6f3388daedfd1d7
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 3 years ago
parent
commit
9ae3c7b5ac

+ 1 - 1
driver/vidc/inc/msm_vidc_core.h

@@ -109,7 +109,7 @@ struct msm_vidc_core {
 	struct msm_vidc_memory_ops            *mem_ops;
 	struct msm_vidc_memory_ops            *mem_ops;
 	u32                                    header_id;
 	u32                                    header_id;
 	u32                                    packet_id;
 	u32                                    packet_id;
-	struct completion                      init_done;
+	u32                                    sys_init_id;
 	bool                                   handoff_done;
 	bool                                   handoff_done;
 	bool                                   hw_power_control;
 	bool                                   hw_power_control;
 	bool                                   pm_suspended;
 	bool                                   pm_suspended;

+ 2 - 0
driver/vidc/inc/msm_vidc_driver.h

@@ -283,6 +283,7 @@ int v4l2_type_to_driver_port(struct msm_vidc_inst *inst, u32 type,
 	const char *func);
 	const char *func);
 const char *allow_name(enum msm_vidc_allow allow);
 const char *allow_name(enum msm_vidc_allow allow);
 const char *state_name(enum msm_vidc_inst_state state);
 const char *state_name(enum msm_vidc_inst_state state);
+const char *core_state_name(enum msm_vidc_core_state state);
 int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
 int msm_vidc_change_inst_state(struct msm_vidc_inst *inst,
 	enum msm_vidc_inst_state request_state, const char *func);
 	enum msm_vidc_inst_state request_state, const char *func);
 int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
 int msm_vidc_create_internal_buffer(struct msm_vidc_inst *inst,
@@ -315,6 +316,7 @@ int msm_vidc_get_inst_capability(struct msm_vidc_inst *inst);
 int msm_vidc_change_core_state(struct msm_vidc_core *core,
 int msm_vidc_change_core_state(struct msm_vidc_core *core,
 	enum msm_vidc_core_state request_state, const char *func);
 	enum msm_vidc_core_state request_state, const char *func);
 int msm_vidc_core_init(struct msm_vidc_core *core);
 int msm_vidc_core_init(struct msm_vidc_core *core);
+int msm_vidc_core_init_wait(struct msm_vidc_core *core);
 int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force);
 int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force);
 int msm_vidc_inst_timeout(struct msm_vidc_inst *inst);
 int msm_vidc_inst_timeout(struct msm_vidc_inst *inst);
 int msm_vidc_print_buffer_info(struct msm_vidc_inst *inst);
 int msm_vidc_print_buffer_info(struct msm_vidc_inst *inst);

+ 2 - 1
driver/vidc/src/hfi_packet.c

@@ -388,6 +388,7 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 	/* HFI_CMD_SYSTEM_INIT */
 	/* HFI_CMD_SYSTEM_INIT */
 	payload = HFI_VIDEO_ARCH_LX;
 	payload = HFI_VIDEO_ARCH_LX;
 	d_vpr_h("%s: arch %d\n", __func__, payload);
 	d_vpr_h("%s: arch %d\n", __func__, payload);
+	core->sys_init_id = core->packet_id++;
 	rc = hfi_create_packet(pkt, pkt_size,
 	rc = hfi_create_packet(pkt, pkt_size,
 				   HFI_CMD_INIT,
 				   HFI_CMD_INIT,
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
 				   (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
@@ -395,7 +396,7 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 				   HFI_HOST_FLAGS_NON_DISCARDABLE),
 				   HFI_HOST_FLAGS_NON_DISCARDABLE),
 				   HFI_PAYLOAD_U32,
 				   HFI_PAYLOAD_U32,
 				   HFI_PORT_NONE,
 				   HFI_PORT_NONE,
-				   core->packet_id++,
+				   core->sys_init_id,
 				   &payload,
 				   &payload,
 				   sizeof(u32));
 				   sizeof(u32));
 	if (rc)
 	if (rc)

+ 4 - 0
driver/vidc/src/msm_vidc.c

@@ -812,6 +812,10 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	if (rc)
 	if (rc)
 		return NULL;
 		return NULL;
 
 
+	rc = msm_vidc_core_init_wait(core);
+	if (rc)
+		return NULL;
+
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
 	if (!inst) {
 	if (!inst) {
 		d_vpr_e("%s: failed to allocate inst memory\n", __func__);
 		d_vpr_e("%s: failed to allocate inst memory\n", __func__);

+ 32 - 38
driver/vidc/src/msm_vidc_driver.c

@@ -3837,6 +3837,12 @@ int msm_vidc_add_session(struct msm_vidc_inst *inst)
 	}
 	}
 
 
 	core_lock(core, __func__);
 	core_lock(core, __func__);
+	if (core->state != MSM_VIDC_CORE_INIT) {
+		i_vpr_e(inst, "%s: invalid state %s\n",
+			__func__, core_state_name(core->state));
+		rc = -EINVAL;
+		goto unlock;
+	}
 	list_for_each_entry(i, &core->instances, list)
 	list_for_each_entry(i, &core->instances, list)
 		count++;
 		count++;
 
 
@@ -3847,6 +3853,7 @@ int msm_vidc_add_session(struct msm_vidc_inst *inst)
 			__func__, core->capabilities[MAX_SESSION_COUNT].value, count);
 			__func__, core->capabilities[MAX_SESSION_COUNT].value, count);
 		rc = -EINVAL;
 		rc = -EINVAL;
 	}
 	}
+unlock:
 	core_unlock(core, __func__);
 	core_unlock(core, __func__);
 
 
 	return rc;
 	return rc;
@@ -4442,9 +4449,9 @@ int msm_vidc_core_deinit(struct msm_vidc_core *core, bool force)
 	return rc;
 	return rc;
 }
 }
 
 
-static int msm_vidc_core_init_wait(struct msm_vidc_core *core)
+int msm_vidc_core_init_wait(struct msm_vidc_core *core)
 {
 {
-	const int interval = 40;
+	const int interval = 10;
 	int max_tries, count = 0, rc = 0;
 	int max_tries, count = 0, rc = 0;
 
 
 	if (!core || !core->capabilities) {
 	if (!core || !core->capabilities) {
@@ -4452,21 +4459,18 @@ static int msm_vidc_core_init_wait(struct msm_vidc_core *core)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	rc = __strict_check(core, __func__);
-	if (rc)
-		return rc;
-
-	if (core->state != MSM_VIDC_CORE_INIT_WAIT)
-		return 0;
+	core_lock(core, __func__);
+	if (core->state == MSM_VIDC_CORE_INIT) {
+		rc = 0;
+		goto unlock;
+	} else if (core->state == MSM_VIDC_CORE_DEINIT) {
+		rc = -EINVAL;
+		goto unlock;
+	}
 
 
 	d_vpr_h("%s(): waiting for state change\n", __func__);
 	d_vpr_h("%s(): waiting for state change\n", __func__);
 	max_tries = core->capabilities[HW_RESPONSE_TIMEOUT].value / interval;
 	max_tries = core->capabilities[HW_RESPONSE_TIMEOUT].value / interval;
-	/**
-	 * attempt one more time to ensure triggering init_done
-	 * timeout sequence for 1st session, incase response not
-	 * received in reverse thread.
-	 */
-	while (count < max_tries + 1) {
+	while (count < max_tries) {
 		if (core->state != MSM_VIDC_CORE_INIT_WAIT)
 		if (core->state != MSM_VIDC_CORE_INIT_WAIT)
 			break;
 			break;
 
 
@@ -4478,12 +4482,20 @@ static int msm_vidc_core_init_wait(struct msm_vidc_core *core)
 	d_vpr_h("%s: state %s, interval %u, count %u, max_tries %u\n", __func__,
 	d_vpr_h("%s: state %s, interval %u, count %u, max_tries %u\n", __func__,
 		core_state_name(core->state), interval, count, max_tries);
 		core_state_name(core->state), interval, count, max_tries);
 
 
-	/* treat as fatal and fail session_open */
-	if (core->state == MSM_VIDC_CORE_INIT_WAIT) {
-		d_vpr_e("%s: state change failed\n", __func__);
+	if (core->state == MSM_VIDC_CORE_INIT) {
+		d_vpr_h("%s: sys init successful\n", __func__);
+		rc = 0;
+		goto unlock;
+	} else {
+		d_vpr_h("%s: sys init wait timedout. state %s\n",
+			__func__, core_state_name(core->state));
 		rc = -EINVAL;
 		rc = -EINVAL;
+		goto unlock;
 	}
 	}
-
+unlock:
+	if (rc)
+		msm_vidc_core_deinit_locked(core, true);
+	core_unlock(core, __func__);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -4497,11 +4509,8 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
 	}
 	}
 
 
 	core_lock(core, __func__);
 	core_lock(core, __func__);
-	rc = msm_vidc_core_init_wait(core);
-	if (rc)
-		goto unlock;
-
-	if (core->state == MSM_VIDC_CORE_INIT)
+	if (core->state == MSM_VIDC_CORE_INIT ||
+			core->state == MSM_VIDC_CORE_INIT_WAIT)
 		goto unlock;
 		goto unlock;
 
 
 	msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT_WAIT, __func__);
 	msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT_WAIT, __func__);
@@ -4515,21 +4524,6 @@ int msm_vidc_core_init(struct msm_vidc_core *core)
 		goto unlock;
 		goto unlock;
 	}
 	}
 
 
-	d_vpr_h("%s(): waiting for sys_init_done, %d ms\n", __func__,
-		core->capabilities[HW_RESPONSE_TIMEOUT].value);
-	core_unlock(core, __func__);
-	rc = wait_for_completion_timeout(&core->init_done, msecs_to_jiffies(
-			core->capabilities[HW_RESPONSE_TIMEOUT].value));
-	core_lock(core, __func__);
-	if (!rc) {
-		d_vpr_e("%s: core init timed out\n", __func__);
-		rc = -ETIMEDOUT;
-	} else {
-		msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT, __func__);
-		d_vpr_h("%s: system init wait completed\n", __func__);
-		rc = 0;
-	}
-
 unlock:
 unlock:
 	if (rc)
 	if (rc)
 		msm_vidc_core_deinit_locked(core, true);
 		msm_vidc_core_deinit_locked(core, true);

+ 9 - 1
driver/vidc/src/msm_vidc_probe.c

@@ -291,7 +291,6 @@ static int msm_vidc_initialize_core(struct msm_vidc_core *core)
 	}
 	}
 
 
 	mutex_init(&core->lock);
 	mutex_init(&core->lock);
-	init_completion(&core->init_done);
 	INIT_LIST_HEAD(&core->instances);
 	INIT_LIST_HEAD(&core->instances);
 	INIT_LIST_HEAD(&core->dangling_instances);
 	INIT_LIST_HEAD(&core->dangling_instances);
 
 
@@ -332,6 +331,7 @@ static int msm_vidc_remove(struct platform_device* pdev)
 	d_vpr_h("%s()\n", __func__);
 	d_vpr_h("%s()\n", __func__);
 
 
 	msm_vidc_core_deinit(core, true);
 	msm_vidc_core_deinit(core, true);
+	of_platform_depopulate(&pdev->dev);
 
 
 	msm_vidc_unregister_video_device(core, MSM_VIDC_ENCODER);
 	msm_vidc_unregister_video_device(core, MSM_VIDC_ENCODER);
 	msm_vidc_unregister_video_device(core, MSM_VIDC_DECODER);
 	msm_vidc_unregister_video_device(core, MSM_VIDC_DECODER);
@@ -466,8 +466,16 @@ static int msm_vidc_probe_video_device(struct platform_device *pdev)
 		goto sub_dev_failed;
 		goto sub_dev_failed;
 	}
 	}
 
 
+	rc = msm_vidc_core_init(core);
+	if (rc) {
+		d_vpr_e("%s: sys init failed\n", __func__);
+		goto core_init_failed;
+	}
+
 	return rc;
 	return rc;
 
 
+core_init_failed:
+	of_platform_depopulate(&pdev->dev);
 sub_dev_failed:
 sub_dev_failed:
 	msm_vidc_unregister_video_device(core, MSM_VIDC_ENCODER);
 	msm_vidc_unregister_video_device(core, MSM_VIDC_ENCODER);
 enc_reg_failed:
 enc_reg_failed:

+ 13 - 2
driver/vidc/src/venus_hfi_response.c

@@ -480,8 +480,19 @@ static int handle_system_init(struct msm_vidc_core *core,
 	struct hfi_packet *pkt)
 	struct hfi_packet *pkt)
 {
 {
 	if (pkt->flags & HFI_FW_FLAGS_SUCCESS) {
 	if (pkt->flags & HFI_FW_FLAGS_SUCCESS) {
-		d_vpr_h("%s: successful\n", __func__);
-		complete(&core->init_done);
+		core_lock(core, __func__);
+		if (core->state == MSM_VIDC_CORE_INIT_WAIT &&
+				pkt->packet_id == core->sys_init_id) {
+			msm_vidc_change_core_state(core, MSM_VIDC_CORE_INIT, __func__);
+			d_vpr_h("%s: successful\n", __func__);
+		} else if (core->state != MSM_VIDC_CORE_INIT_WAIT) {
+			d_vpr_e("%s: invalid core state %s\n", __func__,
+				core_state_name(core->state));
+		} else if (pkt->packet_id != core->sys_init_id) {
+			d_vpr_e("%s: invalid pkt id %u, expected %u\n", __func__,
+				pkt->packet_id, core->sys_init_id);
+		}
+		core_unlock(core, __func__);
 	} else {
 	} else {
 		d_vpr_h("%s: unhandled. flags=%d\n", __func__, pkt->flags);
 		d_vpr_h("%s: unhandled. flags=%d\n", __func__, pkt->flags);
 	}
 	}