فهرست منبع

msm: eva: Send EVA session error to UMD

Through POLL SSR event, only notify the error session. Other
sessions will not be impacted. This is different than SSR
handling.

Change-Id: I5acb4e21c19909b16350816621ae085d54fe05ac
Signed-off-by: George Shen <[email protected]>
George Shen 2 سال پیش
والد
کامیت
43c37a29e1
5فایلهای تغییر یافته به همراه70 افزوده شده و 162 حذف شده
  1. 2 3
      msm/eva/cvp_hfi.c
  2. 4 4
      msm/eva/hfi_response_handler.c
  3. 9 123
      msm/eva/msm_cvp.c
  4. 1 1
      msm/eva/msm_cvp_buf.c
  5. 54 31
      msm/eva/msm_cvp_common.c

+ 2 - 3
msm/eva/cvp_hfi.c

@@ -3305,10 +3305,8 @@ static void **get_session_id(struct msm_cvp_cb_info *info)
 	case HAL_SESSION_PROPERTY_INFO:
 	case HAL_SESSION_EVENT_CHANGE:
 	case HAL_SESSION_DUMP_NOTIFY:
-		session_id = &info->response.cmd.session_id;
-		break;
 	case HAL_SESSION_ERROR:
-		session_id = &info->response.data.session_id;
+		session_id = &info->response.cmd.session_id;
 		break;
 	case HAL_RESPONSE_UNUSED:
 	default:
@@ -3525,6 +3523,7 @@ err_no_work:
 		}
 		dprintk(CVP_HFI, "Processing response %d of %d, type %d\n",
 			(i + 1), num_responses, r->response_type);
+		/* callback = void cvp_handle_cmd_response() */
 		device->callback(r->response_type, rsp);
 	}
 

+ 4 - 4
msm/eva/hfi_response_handler.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/bitops.h>
@@ -93,8 +94,9 @@ static int hfi_process_session_error(u32 device_id,
 	cmd_done.device_id = device_id;
 	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
 	cmd_done.status = hfi_map_err_status(pkt->event_data1);
+	cmd_done.size = pkt->event_data2;
 	info->response.cmd = cmd_done;
-	dprintk(CVP_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n",
+	dprintk(CVP_WARN, "Received: SESSION_ERROR with event data 1 2: %#x %#x\n",
 		pkt->event_data1, pkt->event_data2);
 	switch (pkt->event_data1) {
 	/* Ignore below errors */
@@ -108,7 +110,7 @@ static int hfi_process_session_error(u32 device_id,
 			"%s: session %x id %#x, data1 %#x, data2 %#x\n",
 			__func__, pkt->session_id, pkt->event_id,
 			pkt->event_data1, pkt->event_data2);
-		info->response_type = HAL_RESPONSE_UNUSED;
+		info->response_type = HAL_SESSION_ERROR;
 		break;
 	}
 
@@ -135,8 +137,6 @@ static int hfi_process_event_notify(u32 device_id,
 		return hfi_process_sys_error(device_id, pkt, info);
 
 	case HFI_EVENT_SESSION_ERROR:
-		dprintk(CVP_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n",
-				pkt->session_id);
 		return hfi_process_session_error(device_id, pkt, info);
 
 	default:

+ 9 - 123
msm/eva/msm_cvp.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "msm_cvp.h"
@@ -94,9 +95,8 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst,
 	if (wait_event_timeout(sq->wq,
 		cvp_msg_pending(sq, &msg, ktid), timeout) == 0) {
 		dprintk(CVP_WARN, "session queue wait timeout\n");
-		if(inst && inst->core && inst->core->device){
+		if (inst && inst->core && inst->core->device && inst->state != MSM_CVP_CORE_INVALID)
 			print_hfi_queue_info(inst->core->device);
-		}
 		rc = -ETIMEDOUT;
 		goto exit;
 	}
@@ -184,6 +184,11 @@ static int msm_cvp_session_process_hfi(
 		return -EINVAL;
 	}
 
+	if (inst->state == MSM_CVP_CORE_INVALID) {
+		dprintk(CVP_ERR, "sess %pK INVALIDim reject new HFIs\n", inst);
+		return -ECONNRESET;
+	}
+
 	s = cvp_get_inst_validate(inst->core, inst);
 	if (!s)
 		return -ECONNRESET;
@@ -474,121 +479,8 @@ exit:
 static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
 					struct eva_kmd_arg *arg)
 {
-	int rc = 0;
-	int idx;
-	struct eva_kmd_hfi_fence_packet *fence_pkt;
-	struct eva_kmd_hfi_synx_packet *synx_pkt;
-	struct eva_kmd_fence_ctrl *kfc;
-	struct cvp_hfi_cmd_session_hdr *pkt;
-	unsigned int offset = 0, buf_num = 0, in_offset, in_buf_num;
-	struct msm_cvp_inst *s;
-	struct cvp_fence_command *f;
-	struct cvp_fence_queue *q;
-	u32 *fence;
-	enum op_mode mode;
-	bool is_config_pkt;
-
-	if (!inst || !inst->core || !arg || !inst->core->device) {
-		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-
-	s = cvp_get_inst_validate(inst->core, inst);
-	if (!s)
-		return -ECONNRESET;
-
-	q = &inst->fence_cmd_queue;
-
-	mutex_lock(&q->lock);
-	mode = q->mode;
-	mutex_unlock(&q->lock);
-
-	if (mode == OP_DRAINING) {
-		dprintk(CVP_SYNX, "%s: flush in progress\n", __func__);
-		rc = -EBUSY;
-		goto exit;
-	}
-
-	in_offset = arg->buf_offset;
-	in_buf_num = arg->buf_num;
-
-	fence_pkt = &arg->data.hfi_fence_pkt;
-	pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data;
-	idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt);
-
-	if (idx < 0 ||
-		(pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) {
-		dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__,
-				pkt->size, pkt->packet_type);
-		goto exit;
-	} else {
-		is_config_pkt = cvp_hfi_defs[idx].is_config_pkt;
-	}
-
-	if (in_offset && in_buf_num) {
-		offset = in_offset;
-		buf_num = in_buf_num;
-	}
-
-	if (!is_buf_param_valid(buf_num, offset)) {
-		dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n");
-		goto exit;
-	}
-
-	if (is_config_pkt)
-		pr_info(CVP_DBG_TAG "inst %pK config %s\n",
-			"pkt", inst, cvp_hfi_defs[idx].name);
-
-	rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset,
-				buf_num);
-	if (rc)
-		goto exit;
-
-	rc = cvp_alloc_fence_data(&f, pkt->size);
-	if (rc)
-		goto exit;
-
-	f->type = cvp_hfi_defs[idx].type;
-	f->mode = OP_NORMAL;
-
-	synx_pkt = &arg->data.hfi_synx_pkt;
-	if (synx_pkt->fence_data[0] != 0xFEEDFACE) {
-		dprintk(CVP_ERR, "%s deprecated synx path\n", __func__);
-		cvp_free_fence_data(f);
-		msm_cvp_unmap_frame(inst, pkt->client_data.kdata);
-		goto exit;
-	} else {
-		kfc = &synx_pkt->fc;
-		fence = (u32 *)&kfc->fences;
-		f->frame_id = kfc->frame_id;
-		f->signature = 0xFEEDFACE;
-		f->num_fences = kfc->num_fences;
-		f->output_index = kfc->output_index;
-	}
-
-
-	dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n",
-			__func__, f->frame_id, pkt->client_data.kdata);
-
-	memcpy(f->pkt, pkt, pkt->size);
-
-	f->pkt->client_data.kdata |= FENCE_BIT;
-
-	rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, fence);
-	if (rc) {
-		cvp_free_fence_data(f);
-		goto exit;
-	}
-
-	mutex_lock(&q->lock);
-	list_add_tail(&f->list, &inst->fence_cmd_queue.wait_list);
-	mutex_unlock(&q->lock);
-
-	wake_up(&inst->fence_cmd_queue.wq);
-
-exit:
-	cvp_put_inst(s);
-	return rc;
+	dprintk(CVP_WARN, "Deprecated IOCTL command %s\n", __func__);
+	return -EINVAL;
 }
 
 
@@ -1534,7 +1426,6 @@ check_sched:
 int cvp_clean_session_queues(struct msm_cvp_inst *inst)
 {
 	struct cvp_fence_queue *q;
-	struct cvp_session_queue *sq;
 	u32 count = 0, max_retries = 100;
 
 	q = &inst->fence_cmd_queue;
@@ -1563,11 +1454,6 @@ retry:
 		return -EBUSY;
 
 	goto retry;
-
-	sq = &inst->session_queue_fence;
-	spin_lock(&sq->lock);
-	sq->state = QUEUE_INVALID;
-	spin_unlock(&sq->lock);
 }
 
 static int cvp_flush_all(struct msm_cvp_inst *inst)

+ 1 - 1
msm/eva/msm_cvp_buf.c

@@ -2079,7 +2079,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst)
 				HAL_SESSION_RELEASE_BUFFER_DONE);
 			if (rc)
 				dprintk(CVP_WARN,
-				"%s: wait for signal failed, rc %d\n",
+				"%s: wait release_arp signal failed, rc %d\n",
 				__func__, rc);
 			mutex_lock(&inst->persistbufs.lock);
 		} else {

+ 54 - 31
msm/eva/msm_cvp_common.c

@@ -384,7 +384,8 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst,
 	if (!rc) {
 		dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n",
 				SESSION_MSG_INDEX(cmd));
-		print_hfi_queue_info(hdev);
+		if (inst->state != MSM_CVP_CORE_INVALID)
+			print_hfi_queue_info(hdev);
 		rc = -ETIMEDOUT;
 	} else if (inst->state == MSM_CVP_CORE_INVALID) {
 		rc = -ECONNRESET;
@@ -541,6 +542,8 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
 	struct msm_cvp_cb_cmd_done *response = data;
 	struct cvp_hfi_device *hdev = NULL;
 	struct msm_cvp_inst *inst = NULL;
+	unsigned long flags = 0;
+	int i;
 
 	if (!response) {
 		dprintk(CVP_ERR,
@@ -559,6 +562,19 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
 	hdev = inst->core->device;
 	dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n",
 		response->status, inst, hash32_ptr(inst->session));
+	cvp_print_inst(CVP_WARN, inst);
+	if (inst->state != MSM_CVP_CORE_INVALID) {
+		change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID);
+		if (cvp_clean_session_queues(inst))
+			dprintk(CVP_WARN, "Failed to clean sess queues\n");
+		for (i = 0; i < ARRAY_SIZE(inst->completions); i++)
+			complete(&inst->completions[i]);
+		spin_lock_irqsave(&inst->event_handler.lock, flags);
+		inst->event_handler.event = CVP_SSR_EVENT;
+		spin_unlock_irqrestore(
+			&inst->event_handler.lock, flags);
+		wake_up_all(&inst->event_handler.wq);
+	}
 
 	cvp_put_inst(inst);
 }
@@ -994,13 +1010,6 @@ int msm_cvp_deinit_core(struct msm_cvp_inst *inst)
 	hdev = core->device;
 
 	mutex_lock(&core->lock);
-	if (core->state == CVP_CORE_UNINIT) {
-		dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n",
-				core->id, core->state);
-		goto core_already_uninited;
-	}
-
-core_already_uninited:
 	change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT);
 	mutex_unlock(&core->lock);
 	return 0;
@@ -1113,38 +1122,48 @@ int msm_cvp_comm_suspend(int core_id)
 
 static int get_flipped_state(int present_state, int desired_state)
 {
-	int flipped_state = present_state;
-
-	if (flipped_state < MSM_CVP_CLOSE && desired_state > MSM_CVP_CLOSE) {
-		flipped_state = MSM_CVP_CLOSE + (MSM_CVP_CLOSE - flipped_state);
-		flipped_state &= 0xFFFE;
-		flipped_state = flipped_state - 1;
-	} else if (flipped_state > MSM_CVP_CLOSE
-			&& desired_state < MSM_CVP_CLOSE) {
-		flipped_state = MSM_CVP_CLOSE -
-			(flipped_state - MSM_CVP_CLOSE + 1);
-		flipped_state &= 0xFFFE;
-		flipped_state = flipped_state - 1;
-	}
+	int flipped_state;
+
+	if (present_state == MSM_CVP_CORE_INIT_DONE && desired_state > MSM_CVP_CLOSE)
+		flipped_state = MSM_CVP_CORE_UNINIT;
+	else if (present_state == MSM_CVP_CORE_INVALID)
+		flipped_state = MSM_CVP_CLOSE;
+	else
+		flipped_state = present_state;
+
 	return flipped_state;
 }
 
+static char state_names[MSM_CVP_CORE_INVALID + 1][32] = {
+	"Invlid entry",
+	"CORE_UNINIT_DONE",
+	"CORE_INIT",
+	"CORE_INIT_DONE",
+	"OPEN",
+	"OPEN_DONE",
+	"CLOSE",
+	"CLOSE_DONE",
+	"CORE_UNINIT",
+	"CORE_INVALID"
+};
+
 int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
 {
 	int rc = 0;
 	int flipped_state;
+	struct msm_cvp_core *core;
+
+	core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
 
 	if (!inst) {
 		dprintk(CVP_ERR, "%s: invalid params %pK", __func__, inst);
 		return -EINVAL;
 	}
-	dprintk(CVP_SESS,
-		"Trying to move inst: %pK (%#x) from: %#x to %#x\n",
-		inst, hash32_ptr(inst->session), inst->state, state);
 
 	mutex_lock(&inst->sync_lock);
-	if (inst->state == MSM_CVP_CORE_INVALID) {
-		dprintk(CVP_ERR, "%s: inst %pK is in invalid\n",
+	if (inst->state == MSM_CVP_CORE_INVALID &&
+				core->state == CVP_CORE_UNINIT) {
+		dprintk(CVP_ERR, "%s: inst %pK & core are in invalid\n",
 			__func__, inst);
 		mutex_unlock(&inst->sync_lock);
 		return -EINVAL;
@@ -1152,8 +1171,10 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
 
 	flipped_state = get_flipped_state(inst->state, state);
 	dprintk(CVP_SESS,
-		"inst: %pK (%#x) flipped_state = %#x %x\n",
-		inst, hash32_ptr(inst->session), flipped_state, state);
+		"inst: %pK (%#x) cur_state %s dest_state %s flipped_state = %s\n",
+		inst, hash32_ptr(inst->session), state_names[inst->state],
+		state_names[state], state_names[flipped_state]);
+
 	switch (flipped_state) {
 	case MSM_CVP_CORE_UNINIT_DONE:
 	case MSM_CVP_CORE_INIT:
@@ -1208,9 +1229,11 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
 
 	if (rc == -ETIMEDOUT) {
 		dprintk(CVP_ERR,
-				"Timedout move from state: %d to %d\n",
-				inst->state, state);
-		msm_cvp_comm_kill_session(inst);
+				"Timedout move from state: %s to %s\n",
+				state_names[inst->state],
+				state_names[state]);
+		if (inst->state != MSM_CVP_CORE_INVALID)
+			msm_cvp_comm_kill_session(inst);
 	}
 	return rc;
 }