فهرست منبع

msm: eva: Add session start/stop through FW

New HFI allows FW stop session and notify driver of
its completion. Driver is safe to reclaim resources
allocated for the session.

Change-Id: Ic6a08334a0bafd57f366a635c53f4f5f8f31f77e
Signed-off-by: George Shen <[email protected]>
George Shen 2 سال پیش
والد
کامیت
264f4c7c0d
10فایلهای تغییر یافته به همراه353 افزوده شده و 34 حذف شده
  1. 47 0
      msm/eva/cvp_hfi.c
  2. 8 0
      msm/eva/cvp_hfi.h
  3. 3 0
      msm/eva/cvp_hfi_api.h
  4. 1 1
      msm/eva/cvp_hfi_helper.h
  5. 95 6
      msm/eva/hfi_response_handler.c
  6. 92 9
      msm/eva/msm_cvp.c
  7. 2 0
      msm/eva/msm_cvp.h
  8. 6 4
      msm/eva/msm_cvp_common.c
  9. 81 11
      msm/eva/msm_cvp_dsp.c
  10. 18 3
      msm/eva/msm_cvp_dsp.h

+ 47 - 0
msm/eva/cvp_hfi.c

@@ -2776,6 +2776,50 @@ static int iris_hfi_session_flush(void *sess)
 	return rc;
 }
 
+static int iris_hfi_session_start(void *sess)
+{
+	struct cvp_hal_session *session = sess;
+	struct iris_hfi_device *device;
+	int rc = 0;
+
+	if (!session || !session->device) {
+		dprintk(CVP_ERR, "Invalid Params %s\n", __func__);
+		return -EINVAL;
+	}
+
+	device = session->device;
+
+	mutex_lock(&device->lock);
+
+	rc = __send_session_cmd(session, HFI_CMD_SESSION_EVA_START);
+
+	mutex_unlock(&device->lock);
+
+	return rc;
+}
+
+static int iris_hfi_session_stop(void *sess)
+{
+	struct cvp_hal_session *session = sess;
+	struct iris_hfi_device *device;
+	int rc = 0;
+
+	if (!session || !session->device) {
+		dprintk(CVP_ERR, "Invalid Params %s\n", __func__);
+		return -EINVAL;
+	}
+
+	device = session->device;
+
+	mutex_lock(&device->lock);
+
+	rc = __send_session_cmd(session, HFI_CMD_SESSION_EVA_STOP);
+
+	mutex_unlock(&device->lock);
+
+	return rc;
+}
+
 static void __process_fatal_error(
 		struct iris_hfi_device *device)
 {
@@ -3137,6 +3181,7 @@ static void **get_session_id(struct msm_cvp_cb_info *info)
 	case HAL_SESSION_INIT_DONE:
 	case HAL_SESSION_END_DONE:
 	case HAL_SESSION_ABORT_DONE:
+	case HAL_SESSION_START_DONE:
 	case HAL_SESSION_STOP_DONE:
 	case HAL_SESSION_FLUSH_DONE:
 	case HAL_SESSION_SET_BUFFER_DONE:
@@ -5252,6 +5297,8 @@ static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev)
 	hdev->core_trigger_ssr = iris_hfi_core_trigger_ssr;
 	hdev->session_init = iris_hfi_session_init;
 	hdev->session_end = iris_hfi_session_end;
+	hdev->session_start = iris_hfi_session_start;
+	hdev->session_stop = iris_hfi_session_stop;
 	hdev->session_abort = iris_hfi_session_abort;
 	hdev->session_clean = iris_hfi_session_clean;
 	hdev->session_set_buffers = iris_hfi_session_set_buffers;

+ 8 - 0
msm/eva/cvp_hfi.h

@@ -179,6 +179,10 @@
 	(HFI_CMD_SESSION_CVP_START + 0x081)
 #define  HFI_CMD_SESSION_CVP_SYNX\
 	(HFI_CMD_SESSION_CVP_START + 0x086)
+#define  HFI_CMD_SESSION_EVA_START\
+	(HFI_CMD_SESSION_CVP_START + 0x088)
+#define  HFI_CMD_SESSION_EVA_STOP\
+	(HFI_CMD_SESSION_CVP_START + 0x089)
 #define  HFI_CMD_SESSION_CVP_ICA_FRAME\
 	(HFI_CMD_SESSION_CVP_START + 0x100)
 #define  HFI_CMD_SESSION_CVP_ICA_CONFIG\
@@ -256,6 +260,10 @@
 
 #define HFI_MSG_SESSION_CVP_FLUSH\
 	(HFI_MSG_SESSION_CVP_START + 0x004A)
+#define HFI_MSG_SESSION_EVA_START\
+	(HFI_MSG_SESSION_CVP_START + 0x0058)
+#define HFI_MSG_SESSION_EVA_STOP\
+	(HFI_MSG_SESSION_CVP_START + 0x0059)
 
 #define CVP_IFACEQ_MAX_PKT_SIZE       1024
 #define CVP_IFACEQ_MED_PKT_SIZE       768

+ 3 - 0
msm/eva/cvp_hfi_api.h

@@ -131,6 +131,7 @@ enum hal_command_response {
 	HAL_SESSION_END_DONE,
 	HAL_SESSION_SET_BUFFER_DONE,
 	HAL_SESSION_ABORT_DONE,
+	HAL_SESSION_START_DONE,
 	HAL_SESSION_STOP_DONE,
 	HAL_SESSION_CVP_OPERATION_CONFIG,
 	HAL_SESSION_FLUSH_DONE,
@@ -254,6 +255,8 @@ struct cvp_hfi_device {
 	int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type);
 	int (*session_init)(void *device, void *session_id, void **new_session);
 	int (*session_end)(void *session);
+	int (*session_start)(void *session);
+	int (*session_stop)(void *session);
 	int (*session_abort)(void *session);
 	int (*session_set_buffers)(void *sess, u32 iova, u32 size);
 	int (*session_release_buffers)(void *sess);

+ 1 - 1
msm/eva/cvp_hfi_helper.h

@@ -511,7 +511,7 @@ struct cvp_hfi_cmd_sys_test_ssr_packet {
 	u32 trigger_type;
 };
 
-struct cvp_hfi_msg_sys_session_flush_done_packet {
+struct cvp_hfi_msg_sys_session_ctrl_done_packet {
 	u32 size;
 	u32 packet_type;
 	u32 session_id;

+ 95 - 6
msm/eva/hfi_response_handler.c

@@ -170,8 +170,8 @@ static int hfi_process_sys_init_done(u32 device_id,
 
 	status = hfi_map_err_status(pkt->error_type);
 	if (status) {
-		dprintk(CVP_ERR, "%s: status %#x\n",
-			__func__, status);
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, status, pkt->packet_type, pkt->error_type);
 		goto err_no_prop;
 	}
 
@@ -212,7 +212,8 @@ enum cvp_status cvp_hfi_process_sys_init_done_prop_read(
 
 	status = hfi_map_err_status(pkt->error_type);
 	if (status) {
-		dprintk(CVP_ERR, "%s: status %#x\n", __func__, status);
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, status, pkt->packet_type, pkt->error_type);
 		return status;
 	}
 
@@ -246,6 +247,9 @@ static int hfi_process_session_init_done(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->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.data.session_init_done = session_init_done;
 	cmd_done.size = sizeof(struct cvp_hal_session_init_done);
 
@@ -272,6 +276,9 @@ static int hfi_process_session_end_done(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->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_END_DONE;
@@ -299,6 +306,9 @@ static int hfi_process_session_abort_done(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->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_ABORT_DONE;
@@ -326,6 +336,9 @@ static int hfi_process_session_set_buf_done(u32 device_id,
 	cmd_done.device_id = device_id;
 	cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
 	cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt));
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_SET_BUFFER_DONE;
@@ -337,15 +350,15 @@ static int hfi_process_session_set_buf_done(u32 device_id,
 static int hfi_process_session_flush_done(u32 device_id,
 		void *hdr, struct msm_cvp_cb_info *info)
 {
-	struct cvp_hfi_msg_sys_session_flush_done_packet *pkt =
-		(struct cvp_hfi_msg_sys_session_flush_done_packet *)hdr;
+	struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
+		(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
 	struct msm_cvp_cb_cmd_done cmd_done = {0};
 
 	dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
 			pkt->session_id);
 
 	if (!pkt || pkt->size <
-		sizeof(struct cvp_hfi_msg_sys_session_flush_done_packet)) {
+		sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
 		dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
 				__func__, pkt ? pkt->size : 0);
 		return -E2BIG;
@@ -353,6 +366,9 @@ static int hfi_process_session_flush_done(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->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_FLUSH_DONE;
@@ -361,6 +377,67 @@ static int hfi_process_session_flush_done(u32 device_id,
 	return 0;
 }
 
+static int hfi_process_session_start_done(u32 device_id,
+		void *hdr, struct msm_cvp_cb_info *info)
+{
+	struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
+		(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
+	struct msm_cvp_cb_cmd_done cmd_done = {0};
+
+	dprintk(CVP_SESS, "RECEIVED: SESSION_START_DONE[%#x]\n",
+			pkt->session_id);
+
+	if (!pkt || pkt->size <
+		sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
+		dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
+				__func__, pkt ? pkt->size : 0);
+		return -E2BIG;
+	}
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
+	cmd_done.status = hfi_map_err_status(pkt->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
+	cmd_done.size = 0;
+
+	info->response_type = HAL_SESSION_START_DONE;
+	info->response.cmd = cmd_done;
+
+	return 0;
+}
+
+static int hfi_process_session_stop_done(u32 device_id,
+		void *hdr, struct msm_cvp_cb_info *info)
+{
+	struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
+		(struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
+	struct msm_cvp_cb_cmd_done cmd_done = {0};
+
+	dprintk(CVP_SESS, "RECEIVED: SESSION_STOP_DONE[%#x]\n",
+			pkt->session_id);
+
+	if (!pkt || pkt->size <
+		sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) {
+		dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
+				__func__, pkt ? pkt->size : 0);
+		return -E2BIG;
+	}
+	cmd_done.device_id = device_id;
+	cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
+	cmd_done.status = hfi_map_err_status(pkt->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
+	cmd_done.size = 0;
+
+	info->response_type = HAL_SESSION_STOP_DONE;
+	info->response.cmd = cmd_done;
+
+	return 0;
+}
+
+
 static int hfi_process_session_rel_buf_done(u32 device_id,
 		void *hdr, struct msm_cvp_cb_info *info)
 {
@@ -380,6 +457,9 @@ static int hfi_process_session_rel_buf_done(u32 device_id,
 	cmd_done.device_id = device_id;
 	cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
 	cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt));
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE;
@@ -458,6 +538,9 @@ static int hfi_process_session_dump_notify(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->error_type);
+	if (cmd_done.status)
+		dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
+			__func__, cmd_done.status, pkt->packet_type, pkt->error_type);
 	cmd_done.size = 0;
 
 	info->response_type = HAL_SESSION_DUMP_NOTIFY;
@@ -640,6 +723,12 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr,
 	case HFI_MSG_SESSION_CVP_FLUSH:
 		pkt_func = (pkt_func_def)hfi_process_session_flush_done;
 		break;
+	case HFI_MSG_SESSION_EVA_START:
+		pkt_func = (pkt_func_def)hfi_process_session_start_done;
+		break;
+	case HFI_MSG_SESSION_EVA_STOP:
+		pkt_func = (pkt_func_def)hfi_process_session_stop_done;
+		break;
 	case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY:
 		pkt_func = (pkt_func_def)hfi_process_session_dump_notify;
 		break;

+ 92 - 9
msm/eva/msm_cvp.c

@@ -880,11 +880,18 @@ static int cvp_fence_thread_stop(struct msm_cvp_inst *inst)
 	return 0;
 }
 
-static int msm_cvp_session_start(struct msm_cvp_inst *inst,
+int msm_cvp_session_start(struct msm_cvp_inst *inst,
 		struct eva_kmd_arg *arg)
 {
 	struct cvp_session_queue *sq;
 	struct cvp_hfi_device *hdev;
+	int rc;
+	enum queue_state old_state;
+
+	if (!inst || !inst->core) {
+		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
 
 	sq = &inst->session_queue;
 	spin_lock(&sq->lock);
@@ -892,27 +899,80 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst,
 		dprintk(CVP_ERR, "session start failed queue not empty%d\n",
 			sq->msg_count);
 		spin_unlock(&sq->lock);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto exit;
 	}
+	old_state = sq->state;
 	sq->state = QUEUE_START;
 	spin_unlock(&sq->lock);
 
+	hdev = inst->core->device;
 	if (inst->prop.type == HFI_SESSION_FD
 		|| inst->prop.type == HFI_SESSION_DMM) {
 		spin_lock(&inst->core->resources.pm_qos.lock);
 		inst->core->resources.pm_qos.off_vote_cnt++;
 		spin_unlock(&inst->core->resources.pm_qos.lock);
-		hdev = inst->core->device;
 		call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data);
 	}
-	return cvp_fence_thread_start(inst);
+	/*
+	 * cvp_fence_thread_start will increment reference to instance.
+	 * It guarantees the EVA session won't be deleted. Use of session
+	 * functions, such as session_start requires the session to be valid.
+	 */
+	rc = cvp_fence_thread_start(inst);
+	if (rc)
+		goto restore_state;
+
+	/* Send SESSION_START command */
+	rc = call_hfi_op(hdev, session_start, (void *)inst->session);
+	if (rc) {
+		dprintk(CVP_WARN, "%s: session start failed rc %d\n",
+				__func__, rc);
+		goto stop_thread;
+	}
+
+	/* Wait for FW response */
+	rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_START_DONE);
+	if (rc) {
+		dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n",
+				__func__, rc);
+		goto stop_thread;
+	}
+
+	dprintk(CVP_SESS, "session %llx (%#x) started\n", inst, hash32_ptr(inst->session));
+
+	return 0;
+
+stop_thread:
+	cvp_fence_thread_stop(inst);
+restore_state:
+	spin_lock(&sq->lock);
+	sq->state = old_state;
+	spin_unlock(&sq->lock);
+exit:
+	return rc;
 }
 
-static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
+int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 		struct eva_kmd_arg *arg)
 {
 	struct cvp_session_queue *sq;
-	struct eva_kmd_session_control *sc = &arg->data.session_ctrl;
+	struct eva_kmd_session_control *sc = NULL;
+	struct msm_cvp_inst *s;
+	struct cvp_hfi_device *hdev;
+	int rc;
+
+	if (!inst || !inst->core) {
+		dprintk(CVP_ERR, "%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (arg)
+		sc = &arg->data.session_ctrl;
+
+	s = cvp_get_inst_validate(inst->core, inst);
+	if (!s)
+		return -ECONNRESET;
 
 	sq = &inst->session_queue;
 
@@ -920,9 +980,11 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 	if (sq->msg_count) {
 		dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n",
 			sq->msg_count);
-		sc->ctrl_data[0] = sq->msg_count;
+		if (sc)
+			sc->ctrl_data[0] = sq->msg_count;
 		spin_unlock(&sq->lock);
-		return -EUCLEAN;
+		rc =  -EUCLEAN;
+		goto exit;
 	}
 	sq->state = QUEUE_STOP;
 
@@ -930,9 +992,30 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
 			inst, hash32_ptr(inst->session));
 	spin_unlock(&sq->lock);
 
+	hdev = inst->core->device;
+	/* Send SESSION_STOP command */
+	rc = call_hfi_op(hdev, session_stop, (void *)inst->session);
+	if (rc) {
+		dprintk(CVP_WARN, "%s: session stop failed rc %d\n",
+				__func__, rc);
+		goto stop_thread;
+	}
+
+	/* Wait for FW response */
+	rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE);
+	if (rc) {
+		dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n",
+				__func__, rc);
+		goto stop_thread;
+	}
+
+stop_thread:
 	wake_up_all(&inst->session_queue.wq);
 
-	return cvp_fence_thread_stop(inst);
+	cvp_fence_thread_stop(inst);
+exit:
+	cvp_put_inst(s);
+	return rc;
 }
 
 int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)

+ 2 - 0
msm/eva/msm_cvp.h

@@ -35,6 +35,8 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
 int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst);
 int msm_cvp_session_create(struct msm_cvp_inst *inst);
 int msm_cvp_session_delete(struct msm_cvp_inst *inst);
+int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg);
+int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg);
 int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session);
 int msm_cvp_update_power(struct msm_cvp_inst *inst);
 int cvp_clean_session_queues(struct msm_cvp_inst *inst);

+ 6 - 4
msm/eva/msm_cvp_common.c

@@ -503,7 +503,7 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data)
 	cvp_put_inst(inst);
 }
 
-static void handle_session_flush(enum hal_command_response cmd, void *data)
+static void handle_session_ctrl(enum hal_command_response cmd, void *data)
 {
 	struct msm_cvp_cb_cmd_done *response = data;
 	struct msm_cvp_inst *inst;
@@ -523,8 +523,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data)
 	}
 
 	if (response->status)
-		dprintk(CVP_ERR, "HFI sess flush err 0x%x\n",
-			response->status);
+		dprintk(CVP_ERR, "HFI sess ctrl err 0x%x HAL cmd %d\n",
+			response->status, cmd);
 
 	inst->error_code = response->status;
 	signal_session_msg_receipt(cmd, inst);
@@ -748,7 +748,9 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data)
 		handle_event_change(cmd, data);
 		break;
 	case HAL_SESSION_FLUSH_DONE:
-		handle_session_flush(cmd, data);
+	case HAL_SESSION_START_DONE:
+	case HAL_SESSION_STOP_DONE:
+		handle_session_ctrl(cmd, data);
 		break;
 	case HAL_SYS_WATCHDOG_TIMEOUT:
 	case HAL_SYS_ERROR:

+ 81 - 11
msm/eva/msm_cvp_dsp.c

@@ -457,17 +457,17 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev,
 			goto exit;
 		}
 	} else if (rsp->type < CVP_DSP_MAX_CMD &&
-			len == sizeof(struct cvp_dsp2cpu_cmd_msg)) {
+			len == sizeof(struct cvp_dsp2cpu_cmd)) {
 		if (me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) {
 			dprintk(CVP_ERR,
 				"%s: DSP2CPU cmd:%d pending %d %d expect %d\n",
 					__func__, rsp->type,
 				me->pending_dsp2cpu_cmd.type, len,
-				sizeof(struct cvp_dsp2cpu_cmd_msg));
+				sizeof(struct cvp_dsp2cpu_cmd));
 			goto exit;
 		}
 		memcpy(&me->pending_dsp2cpu_cmd, rsp,
-			sizeof(struct cvp_dsp2cpu_cmd_msg));
+			sizeof(struct cvp_dsp2cpu_cmd));
 		complete(&me->completions[CPU2DSP_MAX_CMD]);
 	} else {
 		dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type);
@@ -1240,7 +1240,7 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit)
 {
 	struct cvp_dsp_apps *me = &gfa_cv;
 	struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x pid %#x, f %d\n",
 		__func__, handle, dsp2cpu_cmd->pid, (uint32_t)force_exit);
@@ -1437,7 +1437,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd)
 	struct msm_cvp_inst *inst = NULL;
 	uint64_t inst_handle = 0;
 	int rc = 0;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 	struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
 	struct pid *pid_s = NULL;
 	struct task_struct *task = NULL;
@@ -1544,7 +1544,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd)
 	struct cvp_dsp_apps *me = &gfa_cv;
 	struct msm_cvp_inst *inst;
 	int rc;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 	struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
 	struct task_struct *task = NULL;
 	struct cvp_hfi_device *hdev;
@@ -1614,7 +1614,7 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd)
 	struct cvp_dsp_apps *me = &gfa_cv;
 	struct msm_cvp_inst *inst;
 	int rc;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	cmd->ret = 0;
 	dprintk(CVP_DSP,
@@ -1672,7 +1672,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd)
 	struct eva_kmd_arg *kmd;
 	struct eva_kmd_buffer *kmd_buf;
 	int rc;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	cmd->ret = 0;
 
@@ -1730,7 +1730,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd)
 	struct eva_kmd_arg *kmd;
 	struct eva_kmd_buffer *kmd_buf;
 	int rc;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	cmd->ret = 0;
 
@@ -1782,7 +1782,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd)
 	struct msm_cvp_inst *inst;
 	int rc;
 	struct cvp_internal_buf *buf = NULL;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 	uint64_t v_dsp_addr = 0;
 
 	struct fastrpc_device *frpc_device = NULL;
@@ -1867,7 +1867,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd)
 	struct cvp_internal_buf *buf = NULL;
 	struct list_head *ptr = NULL, *next = NULL;
 	struct msm_cvp_list *buf_list = NULL;
-	struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
 
 	struct fastrpc_device *frpc_device = NULL;
 	struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
@@ -1948,6 +1948,64 @@ fail_fastrpc_dev_unmap_dma:
 	cvp_put_fastrpc_node(frpc_node);
 }
 
+static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd)
+{
+	struct cvp_dsp_apps *me = &gfa_cv;
+	struct msm_cvp_inst *inst;
+	int rc;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+
+	cmd->ret = 0;
+
+	dprintk(CVP_DSP,
+		"%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n",
+		__func__, dsp2cpu_cmd->session_id,
+		dsp2cpu_cmd->session_cpu_low,
+		dsp2cpu_cmd->session_cpu_high,
+		dsp2cpu_cmd->pid);
+
+	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+			dsp2cpu_cmd->session_cpu_high,
+			dsp2cpu_cmd->session_cpu_low);
+
+	rc = msm_cvp_session_start(inst, (struct eva_kmd_arg *)NULL);
+	if (rc) {
+		dprintk(CVP_ERR, "%s Failed to start session\n", __func__);
+		cmd->ret = -1;
+		return;
+	}
+	dprintk(CVP_DSP, "%s session started\n", __func__);
+}
+
+static void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd)
+{
+	struct cvp_dsp_apps *me = &gfa_cv;
+	struct msm_cvp_inst *inst;
+	int rc;
+	struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd;
+
+	cmd->ret = 0;
+
+	dprintk(CVP_DSP,
+		"%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n",
+		__func__, dsp2cpu_cmd->session_id,
+		dsp2cpu_cmd->session_cpu_low,
+		dsp2cpu_cmd->session_cpu_high,
+		dsp2cpu_cmd->pid);
+
+	inst = (struct msm_cvp_inst *)ptr_dsp2cpu(
+			dsp2cpu_cmd->session_cpu_high,
+			dsp2cpu_cmd->session_cpu_low);
+
+	rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL);
+	if (rc) {
+		dprintk(CVP_ERR, "%s Failed to stop session\n", __func__);
+		cmd->ret = -1;
+		return;
+	}
+	dprintk(CVP_DSP, "%s session stoppd\n", __func__);
+}
+
 static int cvp_dsp_thread(void *data)
 {
 	int rc = 0, old_state;
@@ -2068,6 +2126,18 @@ wait_dsp:
 
 			break;
 		}
+		case DSP2CPU_START_SESSION:
+		{
+			__dsp_cvp_sess_start(&cmd);
+
+			break;
+		}
+		case DSP2CPU_STOP_SESSION:
+		{
+			__dsp_cvp_sess_stop(&cmd);
+
+			break;
+		}
 		default:
 			dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n",
 					me->pending_dsp2cpu_cmd.type);

+ 18 - 3
msm/eva/msm_cvp_dsp.h

@@ -96,7 +96,9 @@ enum CVP_DSP_COMMAND {
 	DSP2CPU_DEREGISTER_BUFFER = 18,
 	DSP2CPU_MEM_ALLOC = 19,
 	DSP2CPU_MEM_FREE = 20,
-	CVP_DSP_MAX_CMD = 21,
+	DSP2CPU_START_SESSION = 21,
+	DSP2CPU_STOP_SESSION = 22,
+	CVP_DSP_MAX_CMD = 23,
 };
 
 struct eva_power_req {
@@ -127,6 +129,17 @@ struct eva_mem_remote {
 	uint64_t v_dsp_addr;
 };
 
+/*
+ * command: defined as a packet initiated from one party.
+ * message: defined as a packet sent as response to a command
+ */
+
+/*
+ * cvp_dsp_cmd_msg contains
+ * the message sent from CPU to DSP
+ * or
+ * the command sent from CPU to DSP
+ */
 struct cvp_dsp_cmd_msg {
 	uint32_t type;
 	int32_t ret;
@@ -153,6 +166,7 @@ struct cvp_dsp_cmd_msg {
 	uint32_t reserved2;
 };
 
+/* cvp_dsp_rsp_msg contains the message sent from DSP to CPU */
 struct cvp_dsp_rsp_msg {
 	uint32_t type;
 	int32_t ret;
@@ -160,7 +174,8 @@ struct cvp_dsp_rsp_msg {
 	uint32_t reserved[CVP_DSP_MAX_RESERVED - 1];
 };
 
-struct cvp_dsp2cpu_cmd_msg {
+/* cvp_dsp2cpu_cmd contains the command sent from DSP to cpu*/
+struct cvp_dsp2cpu_cmd {
 	uint32_t type;
 	uint32_t ver;
 	uint32_t len;
@@ -222,7 +237,7 @@ struct cvp_dsp_apps {
 	uint64_t addr;
 	uint32_t size;
 	struct completion completions[CPU2DSP_MAX_CMD + 1];
-	struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd;
+	struct cvp_dsp2cpu_cmd pending_dsp2cpu_cmd;
 	struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp;
 	struct task_struct *dsp_thread;
 	/* dsp buffer mapping, set of dma function pointer */