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 <quic_sqiao@quicinc.com>
This commit is contained in:
George Shen
2023-02-22 23:20:08 -08:00
committed by Gerrit - the friendly Code Review server
parent 0aa70a4811
commit 264f4c7c0d
10 changed files with 353 additions and 34 deletions

View File

@@ -2776,6 +2776,50 @@ static int iris_hfi_session_flush(void *sess)
return rc; 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( static void __process_fatal_error(
struct iris_hfi_device *device) 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_INIT_DONE:
case HAL_SESSION_END_DONE: case HAL_SESSION_END_DONE:
case HAL_SESSION_ABORT_DONE: case HAL_SESSION_ABORT_DONE:
case HAL_SESSION_START_DONE:
case HAL_SESSION_STOP_DONE: case HAL_SESSION_STOP_DONE:
case HAL_SESSION_FLUSH_DONE: case HAL_SESSION_FLUSH_DONE:
case HAL_SESSION_SET_BUFFER_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->core_trigger_ssr = iris_hfi_core_trigger_ssr;
hdev->session_init = iris_hfi_session_init; hdev->session_init = iris_hfi_session_init;
hdev->session_end = iris_hfi_session_end; 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_abort = iris_hfi_session_abort;
hdev->session_clean = iris_hfi_session_clean; hdev->session_clean = iris_hfi_session_clean;
hdev->session_set_buffers = iris_hfi_session_set_buffers; hdev->session_set_buffers = iris_hfi_session_set_buffers;

View File

@@ -179,6 +179,10 @@
(HFI_CMD_SESSION_CVP_START + 0x081) (HFI_CMD_SESSION_CVP_START + 0x081)
#define HFI_CMD_SESSION_CVP_SYNX\ #define HFI_CMD_SESSION_CVP_SYNX\
(HFI_CMD_SESSION_CVP_START + 0x086) (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\ #define HFI_CMD_SESSION_CVP_ICA_FRAME\
(HFI_CMD_SESSION_CVP_START + 0x100) (HFI_CMD_SESSION_CVP_START + 0x100)
#define HFI_CMD_SESSION_CVP_ICA_CONFIG\ #define HFI_CMD_SESSION_CVP_ICA_CONFIG\
@@ -256,6 +260,10 @@
#define HFI_MSG_SESSION_CVP_FLUSH\ #define HFI_MSG_SESSION_CVP_FLUSH\
(HFI_MSG_SESSION_CVP_START + 0x004A) (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_MAX_PKT_SIZE 1024
#define CVP_IFACEQ_MED_PKT_SIZE 768 #define CVP_IFACEQ_MED_PKT_SIZE 768

View File

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

View File

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

View File

@@ -170,8 +170,8 @@ static int hfi_process_sys_init_done(u32 device_id,
status = hfi_map_err_status(pkt->error_type); status = hfi_map_err_status(pkt->error_type);
if (status) { if (status) {
dprintk(CVP_ERR, "%s: status %#x\n", dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n",
__func__, status); __func__, status, pkt->packet_type, pkt->error_type);
goto err_no_prop; 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); status = hfi_map_err_status(pkt->error_type);
if (status) { 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; return status;
} }
@@ -246,6 +247,9 @@ static int hfi_process_session_init_done(u32 device_id,
cmd_done.device_id = device_id; cmd_done.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type); 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.data.session_init_done = session_init_done;
cmd_done.size = sizeof(struct cvp_hal_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.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type); 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; cmd_done.size = 0;
info->response_type = HAL_SESSION_END_DONE; 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.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type); 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; cmd_done.size = 0;
info->response_type = HAL_SESSION_ABORT_DONE; 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.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
cmd_done.status = hfi_map_err_status(get_msg_errorcode(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; cmd_done.size = 0;
info->response_type = HAL_SESSION_SET_BUFFER_DONE; 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, static int hfi_process_session_flush_done(u32 device_id,
void *hdr, struct msm_cvp_cb_info *info) void *hdr, struct msm_cvp_cb_info *info)
{ {
struct cvp_hfi_msg_sys_session_flush_done_packet *pkt = struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt =
(struct cvp_hfi_msg_sys_session_flush_done_packet *)hdr; (struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr;
struct msm_cvp_cb_cmd_done cmd_done = {0}; struct msm_cvp_cb_cmd_done cmd_done = {0};
dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n",
pkt->session_id); pkt->session_id);
if (!pkt || pkt->size < 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", dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n",
__func__, pkt ? pkt->size : 0); __func__, pkt ? pkt->size : 0);
return -E2BIG; return -E2BIG;
@@ -353,6 +366,9 @@ static int hfi_process_session_flush_done(u32 device_id,
cmd_done.device_id = device_id; cmd_done.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type); 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; cmd_done.size = 0;
info->response_type = HAL_SESSION_FLUSH_DONE; info->response_type = HAL_SESSION_FLUSH_DONE;
@@ -361,6 +377,67 @@ static int hfi_process_session_flush_done(u32 device_id,
return 0; 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, static int hfi_process_session_rel_buf_done(u32 device_id,
void *hdr, struct msm_cvp_cb_info *info) 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.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt);
cmd_done.status = hfi_map_err_status(get_msg_errorcode(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; cmd_done.size = 0;
info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; 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.device_id = device_id;
cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id;
cmd_done.status = hfi_map_err_status(pkt->error_type); 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; cmd_done.size = 0;
info->response_type = HAL_SESSION_DUMP_NOTIFY; 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: case HFI_MSG_SESSION_CVP_FLUSH:
pkt_func = (pkt_func_def)hfi_process_session_flush_done; pkt_func = (pkt_func_def)hfi_process_session_flush_done;
break; 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: case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY:
pkt_func = (pkt_func_def)hfi_process_session_dump_notify; pkt_func = (pkt_func_def)hfi_process_session_dump_notify;
break; break;

View File

@@ -880,11 +880,18 @@ static int cvp_fence_thread_stop(struct msm_cvp_inst *inst)
return 0; 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 eva_kmd_arg *arg)
{ {
struct cvp_session_queue *sq; struct cvp_session_queue *sq;
struct cvp_hfi_device *hdev; 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; sq = &inst->session_queue;
spin_lock(&sq->lock); 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", dprintk(CVP_ERR, "session start failed queue not empty%d\n",
sq->msg_count); sq->msg_count);
spin_unlock(&sq->lock); spin_unlock(&sq->lock);
return -EINVAL; rc = -EINVAL;
goto exit;
} }
old_state = sq->state;
sq->state = QUEUE_START; sq->state = QUEUE_START;
spin_unlock(&sq->lock); spin_unlock(&sq->lock);
hdev = inst->core->device;
if (inst->prop.type == HFI_SESSION_FD if (inst->prop.type == HFI_SESSION_FD
|| inst->prop.type == HFI_SESSION_DMM) { || inst->prop.type == HFI_SESSION_DMM) {
spin_lock(&inst->core->resources.pm_qos.lock); spin_lock(&inst->core->resources.pm_qos.lock);
inst->core->resources.pm_qos.off_vote_cnt++; inst->core->resources.pm_qos.off_vote_cnt++;
spin_unlock(&inst->core->resources.pm_qos.lock); spin_unlock(&inst->core->resources.pm_qos.lock);
hdev = inst->core->device;
call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); 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 eva_kmd_arg *arg)
{ {
struct cvp_session_queue *sq; 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; sq = &inst->session_queue;
@@ -920,9 +980,11 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
if (sq->msg_count) { if (sq->msg_count) {
dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n",
sq->msg_count); sq->msg_count);
if (sc)
sc->ctrl_data[0] = sq->msg_count; sc->ctrl_data[0] = sq->msg_count;
spin_unlock(&sq->lock); spin_unlock(&sq->lock);
return -EUCLEAN; rc = -EUCLEAN;
goto exit;
} }
sq->state = QUEUE_STOP; sq->state = QUEUE_STOP;
@@ -930,9 +992,30 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
inst, hash32_ptr(inst->session)); inst, hash32_ptr(inst->session));
spin_unlock(&sq->lock); 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); 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) int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)

View File

@@ -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_queue_stop(struct msm_cvp_inst *inst);
int msm_cvp_session_create(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_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_get_session_info(struct msm_cvp_inst *inst, u32 *session);
int msm_cvp_update_power(struct msm_cvp_inst *inst); int msm_cvp_update_power(struct msm_cvp_inst *inst);
int cvp_clean_session_queues(struct msm_cvp_inst *inst); int cvp_clean_session_queues(struct msm_cvp_inst *inst);

View File

@@ -503,7 +503,7 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data)
cvp_put_inst(inst); 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_cb_cmd_done *response = data;
struct msm_cvp_inst *inst; struct msm_cvp_inst *inst;
@@ -523,8 +523,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data)
} }
if (response->status) if (response->status)
dprintk(CVP_ERR, "HFI sess flush err 0x%x\n", dprintk(CVP_ERR, "HFI sess ctrl err 0x%x HAL cmd %d\n",
response->status); response->status, cmd);
inst->error_code = response->status; inst->error_code = response->status;
signal_session_msg_receipt(cmd, inst); 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); handle_event_change(cmd, data);
break; break;
case HAL_SESSION_FLUSH_DONE: 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; break;
case HAL_SYS_WATCHDOG_TIMEOUT: case HAL_SYS_WATCHDOG_TIMEOUT:
case HAL_SYS_ERROR: case HAL_SYS_ERROR:

View File

@@ -457,17 +457,17 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev,
goto exit; goto exit;
} }
} else if (rsp->type < CVP_DSP_MAX_CMD && } 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) { if (me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) {
dprintk(CVP_ERR, dprintk(CVP_ERR,
"%s: DSP2CPU cmd:%d pending %d %d expect %d\n", "%s: DSP2CPU cmd:%d pending %d %d expect %d\n",
__func__, rsp->type, __func__, rsp->type,
me->pending_dsp2cpu_cmd.type, len, me->pending_dsp2cpu_cmd.type, len,
sizeof(struct cvp_dsp2cpu_cmd_msg)); sizeof(struct cvp_dsp2cpu_cmd));
goto exit; goto exit;
} }
memcpy(&me->pending_dsp2cpu_cmd, rsp, memcpy(&me->pending_dsp2cpu_cmd, rsp,
sizeof(struct cvp_dsp2cpu_cmd_msg)); sizeof(struct cvp_dsp2cpu_cmd));
complete(&me->completions[CPU2DSP_MAX_CMD]); complete(&me->completions[CPU2DSP_MAX_CMD]);
} else { } else {
dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); 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_apps *me = &gfa_cv;
struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; 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", dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x pid %#x, f %d\n",
__func__, handle, dsp2cpu_cmd->pid, (uint32_t)force_exit); __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; struct msm_cvp_inst *inst = NULL;
uint64_t inst_handle = 0; uint64_t inst_handle = 0;
int rc = 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 cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
struct pid *pid_s = NULL; struct pid *pid_s = NULL;
struct task_struct *task = 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 cvp_dsp_apps *me = &gfa_cv;
struct msm_cvp_inst *inst; struct msm_cvp_inst *inst;
int rc; 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 cvp_dsp_fastrpc_driver_entry *frpc_node = NULL;
struct task_struct *task = NULL; struct task_struct *task = NULL;
struct cvp_hfi_device *hdev; 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 cvp_dsp_apps *me = &gfa_cv;
struct msm_cvp_inst *inst; struct msm_cvp_inst *inst;
int rc; 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; cmd->ret = 0;
dprintk(CVP_DSP, 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_arg *kmd;
struct eva_kmd_buffer *kmd_buf; struct eva_kmd_buffer *kmd_buf;
int rc; 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; 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_arg *kmd;
struct eva_kmd_buffer *kmd_buf; struct eva_kmd_buffer *kmd_buf;
int rc; 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; cmd->ret = 0;
@@ -1782,7 +1782,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd)
struct msm_cvp_inst *inst; struct msm_cvp_inst *inst;
int rc; int rc;
struct cvp_internal_buf *buf = NULL; 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; uint64_t v_dsp_addr = 0;
struct fastrpc_device *frpc_device = NULL; 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 cvp_internal_buf *buf = NULL;
struct list_head *ptr = NULL, *next = NULL; struct list_head *ptr = NULL, *next = NULL;
struct msm_cvp_list *buf_list = 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 fastrpc_device *frpc_device = NULL;
struct cvp_dsp_fastrpc_driver_entry *frpc_node = 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); 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) static int cvp_dsp_thread(void *data)
{ {
int rc = 0, old_state; int rc = 0, old_state;
@@ -2068,6 +2126,18 @@ wait_dsp:
break; break;
} }
case DSP2CPU_START_SESSION:
{
__dsp_cvp_sess_start(&cmd);
break;
}
case DSP2CPU_STOP_SESSION:
{
__dsp_cvp_sess_stop(&cmd);
break;
}
default: default:
dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n",
me->pending_dsp2cpu_cmd.type); me->pending_dsp2cpu_cmd.type);

View File

@@ -96,7 +96,9 @@ enum CVP_DSP_COMMAND {
DSP2CPU_DEREGISTER_BUFFER = 18, DSP2CPU_DEREGISTER_BUFFER = 18,
DSP2CPU_MEM_ALLOC = 19, DSP2CPU_MEM_ALLOC = 19,
DSP2CPU_MEM_FREE = 20, 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 { struct eva_power_req {
@@ -127,6 +129,17 @@ struct eva_mem_remote {
uint64_t v_dsp_addr; 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 { struct cvp_dsp_cmd_msg {
uint32_t type; uint32_t type;
int32_t ret; int32_t ret;
@@ -153,6 +166,7 @@ struct cvp_dsp_cmd_msg {
uint32_t reserved2; uint32_t reserved2;
}; };
/* cvp_dsp_rsp_msg contains the message sent from DSP to CPU */
struct cvp_dsp_rsp_msg { struct cvp_dsp_rsp_msg {
uint32_t type; uint32_t type;
int32_t ret; int32_t ret;
@@ -160,7 +174,8 @@ struct cvp_dsp_rsp_msg {
uint32_t reserved[CVP_DSP_MAX_RESERVED - 1]; 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 type;
uint32_t ver; uint32_t ver;
uint32_t len; uint32_t len;
@@ -222,7 +237,7 @@ struct cvp_dsp_apps {
uint64_t addr; uint64_t addr;
uint32_t size; uint32_t size;
struct completion completions[CPU2DSP_MAX_CMD + 1]; 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 cvp_dsp_rsp_msg pending_dsp2cpu_rsp;
struct task_struct *dsp_thread; struct task_struct *dsp_thread;
/* dsp buffer mapping, set of dma function pointer */ /* dsp buffer mapping, set of dma function pointer */