From 264f4c7c0d42b07eac4bd86b80677969807ccf8f Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 22 Feb 2023 23:20:08 -0800 Subject: [PATCH] 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 --- msm/eva/cvp_hfi.c | 47 +++++++++++++++ msm/eva/cvp_hfi.h | 8 +++ msm/eva/cvp_hfi_api.h | 3 + msm/eva/cvp_hfi_helper.h | 2 +- msm/eva/hfi_response_handler.c | 101 +++++++++++++++++++++++++++++++-- msm/eva/msm_cvp.c | 101 ++++++++++++++++++++++++++++++--- msm/eva/msm_cvp.h | 2 + msm/eva/msm_cvp_common.c | 10 ++-- msm/eva/msm_cvp_dsp.c | 92 ++++++++++++++++++++++++++---- msm/eva/msm_cvp_dsp.h | 21 ++++++- 10 files changed, 353 insertions(+), 34 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a52af9233d..6481b70a67 100644 --- a/msm/eva/cvp_hfi.c +++ b/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; diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 8e31974c9f..1f2f2b0d40 100644 --- a/msm/eva/cvp_hfi.h +++ b/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 diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 705db12cca..e69d057345 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/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); diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index a66782d4d7..4423c17018 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/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; diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 8b14cc021f..f28de04bf4 100644 --- a/msm/eva/hfi_response_handler.c +++ b/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; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 6313f1944f..e4cdbf107c 100644 --- a/msm/eva/msm_cvp.c +++ b/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) diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index d64f91ab22..eab8e0a3e9 100644 --- a/msm/eva/msm_cvp.h +++ b/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); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 3739bc6cc2..61e24755cf 100644 --- a/msm/eva/msm_cvp_common.c +++ b/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: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 6b93d184fd..e0e98ec5b0 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/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); diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 0232a7ddc0..e94cefaa9b 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/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 */