Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d14186de authored by Deepak Verma's avatar Deepak Verma
Browse files

msm: vidc: Add support for different errors



When hardware is overloaded or when max number of clients are
reached in driver or firmware, hardware error is sent to video
client. This change is to replace hardware error with actual
errors.

CRs-fixed: 575852
Change-Id: I07e599f894a3716a3dc4fed5eb7c987311f5bdde
Signed-off-by: default avatarDeepak Verma <dverma@codeaurora.org>
parent 738ee921
Loading
Loading
Loading
Loading
+40 −20
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ static enum vidc_status hfi_map_err_status(int hfi_err)
		vidc_err = VIDC_ERR_NOT_SUPPORTED;
		break;
	case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
		vidc_err = VIDC_ERR_MAX_CLIENT;
		vidc_err = VIDC_ERR_MAX_CLIENTS;
		break;
	case HFI_ERR_SYS_SESSION_IN_USE:
		vidc_err = VIDC_ERR_CLIENT_PRESENT;
@@ -112,7 +112,7 @@ static void hfi_process_sess_evt_seq_changed(
	struct hfi_profile_level *profile_level;
	u8 *data_ptr;
	int prop_id;
	dprintk(VIDC_DBG, "RECEIVED: EVENT_NOTIFY\n");
	dprintk(VIDC_DBG, "RECEIVED: EVENT_NOTIFY[%u]\n", pkt->session_id);
	if (sizeof(struct hfi_msg_event_notify_packet)
		> pkt->size) {
		dprintk(VIDC_ERR,
@@ -263,33 +263,38 @@ static void hfi_process_event_notify(

	switch (pkt->event_id) {
	case HFI_EVENT_SYS_ERROR:
		dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR: %d, 0x%x\n",
			pkt->event_data1, pkt->event_data2);
		dprintk(VIDC_ERR, "HFI_EVENT_SYS_ERROR[%u]: %d, 0x%x\n",
			pkt->session_id, pkt->event_data1, pkt->event_data2);
		hfi_process_sys_error(callback, device_id);
		break;
	case HFI_EVENT_SESSION_ERROR:
		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_ERROR\n");
		dprintk(VIDC_INFO,
			"HFI_EVENT_SESSION_ERROR[%u]\n", pkt->session_id);
		if (!validate_session_pkt(sessions, sess, session_lock))
			hfi_process_session_error(callback, device_id, pkt);
		break;
	case HFI_EVENT_SESSION_SEQUENCE_CHANGED:
		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED\n");
		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_SEQUENCE_CHANGED[%u]\n",
			pkt->session_id);
		if (!validate_session_pkt(sessions, sess, session_lock))
			hfi_process_sess_evt_seq_changed(callback,
				device_id, pkt);
		break;
	case HFI_EVENT_SESSION_PROPERTY_CHANGED:
		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED\n");
		dprintk(VIDC_INFO, "HFI_EVENT_SESSION_PROPERTY_CHANGED[%u]\n",
			pkt->session_id);
		break;
	case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
		dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE\n");
		dprintk(VIDC_INFO, "HFI_EVENT_RELEASE_BUFFER_REFERENCE[%u]\n",
			pkt->session_id);
		if (!validate_session_pkt(sessions, sess, session_lock))
			hfi_process_evt_release_buffer_ref(callback,
				device_id, pkt);
		break;
	default:
		dprintk(VIDC_WARN,
				"hal_process_event_notify: unknown_event_id\n");
				"hal_process_event_notify: unknown_event_id[%u]\n",
				pkt->session_id);
		break;
	}
}
@@ -824,7 +829,8 @@ static void hfi_process_session_prop_info(
	struct hfi_profile_level profile_level = {0};
	struct buffer_requirements buff_req;

	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO\n");
	dprintk(VIDC_DBG, "Received SESSION_PROPERTY_INFO[%u]\n",
		pkt->session_id);

	if (pkt->size < sizeof(struct hfi_msg_session_property_info_packet)) {
		dprintk(VIDC_ERR,
@@ -875,7 +881,8 @@ static void hfi_process_session_init_done(
	struct msm_vidc_cb_cmd_done cmd_done;
	struct vidc_hal_session_init_done session_init_done;
	struct hal_session *sess_close = NULL;
	dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_INIT_DONE[%u]\n",
		pkt->session_id);
	if (sizeof(struct hfi_msg_sys_session_init_done_packet)
		> pkt->size) {
		dprintk(VIDC_ERR,
@@ -915,7 +922,8 @@ static void hfi_process_session_load_res_done(
		struct hfi_msg_session_load_resources_done_packet *pkt)
{
	struct msm_vidc_cb_cmd_done cmd_done;
	dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_LOAD_RESOURCES_DONE[%u]\n",
		pkt->session_id);

	if (sizeof(struct hfi_msg_session_load_resources_done_packet) !=
		pkt->size) {
@@ -942,7 +950,8 @@ static void hfi_process_session_flush_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_FLUSH_DONE[%u]\n",
		pkt->session_id);

	if (sizeof(struct hfi_msg_session_flush_done_packet) != pkt->size) {
		dprintk(VIDC_ERR,
@@ -967,7 +976,8 @@ static void hfi_process_session_etb_done(
{
	struct msm_vidc_cb_data_done data_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_ETB_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size <
		sizeof(struct hfi_msg_session_empty_buffer_done_packet)) {
@@ -1010,7 +1020,8 @@ static void hfi_process_session_ftb_done(

	session = (struct hal_session *)
		((struct hal_session *)	pack->session_id)->session_id;
	dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_FTB_DONE[%u]\n",
		pack->session_id);

	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));

@@ -1108,7 +1119,8 @@ static void hfi_process_session_start_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_START_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size !=
		sizeof(struct hfi_msg_session_start_done_packet)) {
@@ -1134,7 +1146,8 @@ static void hfi_process_session_stop_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_STOP_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size !=
		sizeof(struct hfi_msg_session_stop_done_packet)) {
@@ -1160,7 +1173,8 @@ static void hfi_process_session_rel_res_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_RELEASE_RESOURCES_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size !=
		sizeof(struct hfi_msg_session_release_resources_done_packet)) {
@@ -1191,6 +1205,8 @@ static void hfi_process_session_rel_buf_done(
		dprintk(VIDC_ERR, "bad packet/packet size: %d\n", pkt->size);
		return;
	}
	dprintk(VIDC_DBG, "RECEIVED:SESSION_RELEASE_BUFFER_DONE[%u]",
		pkt->session_id);
	memset(&cmd_done, 0, sizeof(struct msm_vidc_cb_cmd_done));
	cmd_done.device_id = device_id;
	cmd_done.size = sizeof(struct msm_vidc_cb_cmd_done);
@@ -1212,7 +1228,8 @@ static void hfi_process_session_end_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_END_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size !=
		sizeof(struct hfi_msg_sys_session_end_done_packet)) {
@@ -1238,7 +1255,8 @@ static void hfi_process_session_abort_done(
{
	struct msm_vidc_cb_cmd_done cmd_done;

	dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE\n");
	dprintk(VIDC_DBG, "RECEIVED: SESSION_ABORT_DONE[%u]\n",
		pkt->session_id);

	if (!pkt || pkt->size !=
		sizeof(struct hfi_msg_sys_session_abort_done_packet)) {
@@ -1268,6 +1286,8 @@ static void hfi_process_session_get_seq_hdr_done(
		dprintk(VIDC_ERR, "bad packet/packet size: %d\n", pkt->size);
		return;
	}
	dprintk(VIDC_DBG, "RECEIVED:SESSION_GET_SEQ_HDR_DONE[%u]",
		pkt->session_id);
	memset(&data_done, 0, sizeof(struct msm_vidc_cb_data_done));
	data_done.device_id = device_id;
	data_done.size = sizeof(struct msm_vidc_cb_data_done);
+33 −9
Original line number Diff line number Diff line
@@ -390,8 +390,9 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
		&inst->completions[SESSION_MSG_INDEX(cmd)],
		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
	if (!rc) {
		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n",
				SESSION_MSG_INDEX(cmd));
		dprintk(VIDC_ERR,
			"%s: Wait interrupted or timeout[%p]: %d\n",
			__func__, inst->session, SESSION_MSG_INDEX(cmd));
		msm_comm_recover_from_session_error(inst);
		rc = -EIO;
	} else {
@@ -439,6 +440,21 @@ static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
	mutex_unlock(&inst->lock);
}

static void msm_comm_generate_max_clients_error(struct msm_vidc_inst *inst)
{
	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid input parameters\n", __func__);
		return;
	}
	mutex_lock(&inst->sync_lock);
	inst->session = NULL;
	inst->state = MSM_VIDC_CORE_INVALID;
	msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_MAX_CLIENTS);
	dprintk(VIDC_ERR,
			"%s: Too many clients\n", __func__);
	mutex_unlock(&inst->sync_lock);
}

static void handle_session_init_done(enum command_response cmd, void *data)
{
	struct msm_vidc_cb_cmd_done *response = data;
@@ -474,6 +490,9 @@ static void handle_session_init_done(enum command_response cmd, void *data)
			dprintk(VIDC_ERR,
				"Session init response from FW : 0x%x\n",
				response->status);
			if (response->status == VIDC_ERR_MAX_CLIENTS)
				msm_comm_generate_max_clients_error(inst);
			else
				msm_comm_generate_session_error(inst);
		}
		signal_session_msg_receipt(cmd, inst);
@@ -1466,8 +1485,8 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst)
		&core->completions[SYS_MSG_INDEX(SYS_INIT_DONE)],
		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
	if (!rc) {
		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n",
				SYS_MSG_INDEX(SYS_INIT_DONE));
		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n",
				__func__, SYS_MSG_INDEX(SYS_INIT_DONE));
		rc = -EIO;
		goto exit;
	} else {
@@ -2625,7 +2644,8 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
	if (!rc) {
		dprintk(VIDC_ERR,
			"Wait interrupted or timeout: %d\n",
			"%s: Wait interrupted or timeout[%p]: %d\n",
			__func__, inst->session,
			SESSION_MSG_INDEX(SESSION_PROPERTY_INFO));
		inst->state = MSM_VIDC_CORE_INVALID;
		msm_comm_recover_from_session_error(inst);
@@ -3419,7 +3439,10 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
		mutex_lock(&inst->sync_lock);
		inst->state = MSM_VIDC_CORE_INVALID;
		mutex_unlock(&inst->sync_lock);
		msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
		msm_vidc_queue_v4l2_event(inst,
					V4L2_EVENT_MSM_VIDC_HW_OVERLOAD);
		dprintk(VIDC_WARN,
			"%s: Hardware is overloaded\n", __func__);
		wake_up(&inst->kernel_event_queue);
	}
	return rc;
@@ -3470,8 +3493,9 @@ int msm_comm_recover_from_session_error(struct msm_vidc_inst *inst)
		&inst->completions[SESSION_MSG_INDEX(SESSION_ABORT_DONE)],
		msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
	if (!rc) {
		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n",
			__func__, SESSION_MSG_INDEX(SESSION_ABORT_DONE));
		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout[%p]: %d\n",
			__func__, inst->session,
			SESSION_MSG_INDEX(SESSION_ABORT_DONE));
		msm_comm_generate_sys_error(inst);
	} else
		change_inst_state(inst, MSM_VIDC_CLOSE_DONE);
+2 −1
Original line number Diff line number Diff line
@@ -2553,7 +2553,8 @@ static void venus_hfi_pm_hndlr(struct work_struct *work)
	rc = wait_for_completion_timeout(&pc_prep_done,
			msecs_to_jiffies(msm_vidc_hw_rsp_timeout));
	if (!rc) {
		dprintk(VIDC_ERR, "Wait interrupted or timeout: %d\n", rc);
		dprintk(VIDC_ERR, "%s: Wait interrupted or timeout: %d\n",
			__func__, rc);
		return;
	}

+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ enum vidc_status {
	VIDC_ERR_BAD_HANDLE,
	VIDC_ERR_NOT_SUPPORTED,
	VIDC_ERR_BAD_STATE,
	VIDC_ERR_MAX_CLIENT,
	VIDC_ERR_MAX_CLIENTS,
	VIDC_ERR_IFRAME_EXPECTED,
	VIDC_ERR_HW_FATAL,
	VIDC_ERR_BITSTREAM_ERR,
+2 −0
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@
#define VDEC_MSG_EVT_HW_ERROR	(VDEC_MSG_BASE + 14)
#define VDEC_MSG_EVT_INFO_CONFIG_CHANGED	(VDEC_MSG_BASE + 15)
#define VDEC_MSG_EVT_INFO_FIELD_DROPPED	(VDEC_MSG_BASE + 16)
#define VDEC_MSG_EVT_HW_OVERLOAD	(VDEC_MSG_BASE + 17)
#define VDEC_MSG_EVT_MAX_CLIENTS	(VDEC_MSG_BASE + 18)

/*Buffer flags bits masks.*/
#define VDEC_BUFFERFLAG_EOS	0x00000001
Loading