Loading drivers/media/platform/msm/cvp/cvp_hfi.c +11 −2 Original line number Diff line number Diff line Loading @@ -80,7 +80,13 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .buf_num = HFI_PERSIST_BUF_NUM, .resp = HAL_NO_RESP, }, { .size = HFI_DS_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DS, .buf_offset = HFI_DS_BUFFERS_OFFSET, .buf_num = HFI_DS_BUF_NUM, .resp = HAL_NO_RESP, }, }; static struct hal_device_data hal_ctxt; Loading Loading @@ -118,7 +124,7 @@ const struct msm_cvp_gov_data CVP_DEFAULT_BUS_VOTE = { .data_count = 0, }; const int cvp_max_packets = 1000; const int cvp_max_packets = 32; static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); Loading Loading @@ -3268,6 +3274,9 @@ static int __response_handler(struct venus_hfi_device *device) "Corrupt/unknown packet found, discarding\n"); --packet_count; continue; } else if (info->response_type == HAL_NO_RESP) { --packet_count; continue; } /* Process the packet types that we're interested in */ Loading drivers/media/platform/msm/cvp/cvp_hfi_api.h +5 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,10 @@ #define HFI_PERSIST_BUFFERS_OFFSET 7 #define HFI_PERSIST_BUF_NUM 2 #define HFI_DS_CMD_SIZE 54 #define HFI_DS_BUFFERS_OFFSET 48 #define HFI_DS_BUF_NUM 3 enum cvp_status { CVP_ERR_NONE = 0x0, Loading Loading @@ -1270,6 +1274,7 @@ struct msm_cvp_cb_cmd_done { enum cvp_status status; u32 size; union { struct hfi_msg_session_hdr msg_hdr; struct cvp_resource_hdr resource_hdr; struct cvp_buffer_addr_info buffer_addr_info; struct cvp_frame_plane_config frame_plane_config; Loading drivers/media/platform/msm/cvp/cvp_hfi_helper.h +1 −1 Original line number Diff line number Diff line Loading @@ -1020,7 +1020,7 @@ struct hfi_cmd_session_cvp_release_buffers_packet { u32 buffer_idx; }; struct hfi_msg_session_cvp_release_buffers_done_packet { struct hfi_msg_session_hdr { u32 size; u32 packet_type; u32 session_id; Loading drivers/media/platform/msm/cvp/hfi_response_handler.c +89 −15 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ #include "cvp_hfi_io.h" #include "msm_cvp_debug.h" #include "cvp_hfi.h" #include "msm_cvp_common.h" extern struct msm_cvp_drv *cvp_driver; static enum cvp_status hfi_map_err_status(u32 hfi_err) { Loading Loading @@ -823,12 +826,12 @@ static int hfi_process_session_set_buf_done(u32 device_id, static int hfi_process_session_rel_buf_done(u32 device_id, struct hfi_msg_session_cvp_release_buffers_done_packet *pkt, struct hfi_msg_session_hdr *pkt, struct msm_cvp_cb_info *info) { struct msm_cvp_cb_cmd_done cmd_done = {0}; unsigned int pkt_size = sizeof(struct hfi_msg_session_cvp_release_buffers_done_packet); sizeof(struct hfi_msg_session_hdr); if (!pkt || pkt->size < pkt_size) { dprintk(CVP_ERR, "bad packet/packet size %d\n", Loading Loading @@ -921,6 +924,84 @@ static int hfi_process_session_cvp_dfs(u32 device_id, return 0; } static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core, void *session_id) { struct msm_cvp_inst *inst = NULL; bool match = false; if (!core || !session_id) return NULL; mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (hash32_ptr(inst->session) == (unsigned int)session_id) { match = true; break; } } inst = match ? inst : NULL; mutex_unlock(&core->lock); return inst; } static int hfi_process_session_cvp_msg(u32 device_id, struct hfi_msg_session_hdr *pkt, struct msm_cvp_cb_info *info) { struct session_msg *sess_msg; struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core; void *session_id; if (!pkt) { dprintk(CVP_ERR, "%s: invalid param\n", __func__); return -EINVAL; } else if (pkt->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) { dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); return -E2BIG; } session_id = (void *)(uintptr_t)pkt->session_id; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); inst = cvp_get_inst_from_id(core, session_id); if (!inst) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); return -EINVAL; } sess_msg = kmem_cache_alloc(inst->session_queue.msg_cache, GFP_KERNEL); if (sess_msg == NULL) { dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); return -ENOMEM; } memcpy(&sess_msg->pkt, pkt, sizeof(struct hfi_msg_session_hdr)); spin_lock(&inst->session_queue.lock); if (inst->session_queue.msg_count >= MAX_NUM_MSGS_PER_SESSION) { dprintk(CVP_ERR, "Reached session queue size limit\n"); goto error_handle_msg; } list_add_tail(&sess_msg->node, &inst->session_queue.msgs); inst->session_queue.msg_count++; spin_unlock(&inst->session_queue.lock); wake_up_all(&inst->session_queue.wq); info->response_type = HAL_NO_RESP; return 0; error_handle_msg: spin_unlock(&inst->session_queue.lock); kmem_cache_free(inst->session_queue.msg_cache, sess_msg); return -ENOMEM; } static int hfi_process_session_cvp_dme(u32 device_id, struct hfi_msg_session_cvp_dme_packet_type *pkt, struct msm_cvp_cb_info *info) Loading @@ -930,9 +1011,8 @@ static int hfi_process_session_cvp_dme(u32 device_id, if (!pkt) { dprintk(CVP_ERR, "%s: invalid param\n", __func__); return -EINVAL; } else if (pkt->size < sizeof(*pkt)) { dprintk(CVP_ERR, "%s: bad_pkt_size\n", __func__); } else if (pkt->size > sizeof(*pkt)) { dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); return -E2BIG; } Loading Loading @@ -1068,7 +1148,7 @@ int cvp_hfi_process_msg_packet(u32 device_id, return -EINVAL; } dprintk(CVP_DBG, "Parse response %#x\n", msg_hdr->packet); dprintk(CVP_DBG, "Received HFI MSG with type %d\n", msg_hdr->packet); switch (msg_hdr->packet) { case HFI_MSG_EVENT_NOTIFY: pkt_func = (pkt_func_def)hfi_process_event_notify; Loading @@ -1095,27 +1175,21 @@ int cvp_hfi_process_msg_packet(u32 device_id, pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_OPERATION_CONFIG from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_operation_config; break; case HFI_MSG_SESSION_CVP_DFS: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_DFS from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_dfs; break; case HFI_MSG_SESSION_CVP_DME: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_DME from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_dme; break; case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_PERSIST from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_persist; break; case HFI_MSG_SESSION_CVP_DS: pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; break; default: dprintk(CVP_DBG, "Unable to parse message: %#x\n", msg_hdr->packet); Loading drivers/media/platform/msm/cvp/msm_cvp.c +66 −5 Original line number Diff line number Diff line Loading @@ -217,6 +217,65 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst, return rc; } static bool _cvp_msg_pending(struct msm_cvp_inst *inst, struct cvp_session_queue *sq, struct session_msg **msg) { struct session_msg *mptr = NULL; bool result = false; spin_lock(&sq->lock); if (!kref_read(&inst->kref)) { /* The session is being deleted */ spin_unlock(&sq->lock); *msg = NULL; return true; } result = list_empty(&sq->msgs); if (!result) { mptr = list_first_entry(&sq->msgs, struct session_msg, node); list_del_init(&mptr->node); sq->msg_count--; } spin_unlock(&sq->lock); *msg = mptr; return !result; } static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *out_pkt) { unsigned long wait_time; struct session_msg *msg = NULL; struct cvp_session_queue *sq; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); return -EINVAL; } sq = &inst->session_queue; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); if (wait_event_timeout(sq->wq, _cvp_msg_pending(inst, sq, &msg), wait_time) == 0) { dprintk(CVP_ERR, "session queue wait timeout\n"); return -ETIMEDOUT; } if (msg == NULL) { dprintk(CVP_ERR, "%s: session is deleted, no msg\n", __func__); return -EINVAL; } memcpy(out_pkt, &msg->pkt, sizeof(struct hfi_msg_session_hdr)); kmem_cache_free(inst->session_queue.msg_cache, msg); return 0; } static int msm_cvp_session_process_hfi( struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *in_pkt) Loading Loading @@ -600,11 +659,6 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, hdev = inst->core->device; print_client_buffer(CVP_DBG, "unregister", inst, buf); if (!buf->index) { dprintk(CVP_ERR, "Missing index when unregister buf\n"); return 0; } mutex_lock(&inst->cvpbufs.lock); found = false; list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { Loading Loading @@ -690,6 +744,13 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) rc = msm_cvp_send_cmd(inst, send_cmd); break; } case CVP_KMD_RECEIVE_MSG_PKT: { struct cvp_kmd_hfi_packet *out_pkt = (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; rc = msm_cvp_session_receive_hfi(inst, out_pkt); break; } case CVP_KMD_SEND_CMD_PKT: case CVP_KMD_HFI_DFS_CONFIG_CMD: case CVP_KMD_HFI_DFS_FRAME_CMD: Loading Loading
drivers/media/platform/msm/cvp/cvp_hfi.c +11 −2 Original line number Diff line number Diff line Loading @@ -80,7 +80,13 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .buf_num = HFI_PERSIST_BUF_NUM, .resp = HAL_NO_RESP, }, { .size = HFI_DS_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DS, .buf_offset = HFI_DS_BUFFERS_OFFSET, .buf_num = HFI_DS_BUF_NUM, .resp = HAL_NO_RESP, }, }; static struct hal_device_data hal_ctxt; Loading Loading @@ -118,7 +124,7 @@ const struct msm_cvp_gov_data CVP_DEFAULT_BUS_VOTE = { .data_count = 0, }; const int cvp_max_packets = 1000; const int cvp_max_packets = 32; static void venus_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(venus_hfi_pm_work, venus_hfi_pm_handler); Loading Loading @@ -3268,6 +3274,9 @@ static int __response_handler(struct venus_hfi_device *device) "Corrupt/unknown packet found, discarding\n"); --packet_count; continue; } else if (info->response_type == HAL_NO_RESP) { --packet_count; continue; } /* Process the packet types that we're interested in */ Loading
drivers/media/platform/msm/cvp/cvp_hfi_api.h +5 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,10 @@ #define HFI_PERSIST_BUFFERS_OFFSET 7 #define HFI_PERSIST_BUF_NUM 2 #define HFI_DS_CMD_SIZE 54 #define HFI_DS_BUFFERS_OFFSET 48 #define HFI_DS_BUF_NUM 3 enum cvp_status { CVP_ERR_NONE = 0x0, Loading Loading @@ -1270,6 +1274,7 @@ struct msm_cvp_cb_cmd_done { enum cvp_status status; u32 size; union { struct hfi_msg_session_hdr msg_hdr; struct cvp_resource_hdr resource_hdr; struct cvp_buffer_addr_info buffer_addr_info; struct cvp_frame_plane_config frame_plane_config; Loading
drivers/media/platform/msm/cvp/cvp_hfi_helper.h +1 −1 Original line number Diff line number Diff line Loading @@ -1020,7 +1020,7 @@ struct hfi_cmd_session_cvp_release_buffers_packet { u32 buffer_idx; }; struct hfi_msg_session_cvp_release_buffers_done_packet { struct hfi_msg_session_hdr { u32 size; u32 packet_type; u32 session_id; Loading
drivers/media/platform/msm/cvp/hfi_response_handler.c +89 −15 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ #include "cvp_hfi_io.h" #include "msm_cvp_debug.h" #include "cvp_hfi.h" #include "msm_cvp_common.h" extern struct msm_cvp_drv *cvp_driver; static enum cvp_status hfi_map_err_status(u32 hfi_err) { Loading Loading @@ -823,12 +826,12 @@ static int hfi_process_session_set_buf_done(u32 device_id, static int hfi_process_session_rel_buf_done(u32 device_id, struct hfi_msg_session_cvp_release_buffers_done_packet *pkt, struct hfi_msg_session_hdr *pkt, struct msm_cvp_cb_info *info) { struct msm_cvp_cb_cmd_done cmd_done = {0}; unsigned int pkt_size = sizeof(struct hfi_msg_session_cvp_release_buffers_done_packet); sizeof(struct hfi_msg_session_hdr); if (!pkt || pkt->size < pkt_size) { dprintk(CVP_ERR, "bad packet/packet size %d\n", Loading Loading @@ -921,6 +924,84 @@ static int hfi_process_session_cvp_dfs(u32 device_id, return 0; } static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core, void *session_id) { struct msm_cvp_inst *inst = NULL; bool match = false; if (!core || !session_id) return NULL; mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { if (hash32_ptr(inst->session) == (unsigned int)session_id) { match = true; break; } } inst = match ? inst : NULL; mutex_unlock(&core->lock); return inst; } static int hfi_process_session_cvp_msg(u32 device_id, struct hfi_msg_session_hdr *pkt, struct msm_cvp_cb_info *info) { struct session_msg *sess_msg; struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core; void *session_id; if (!pkt) { dprintk(CVP_ERR, "%s: invalid param\n", __func__); return -EINVAL; } else if (pkt->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) { dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); return -E2BIG; } session_id = (void *)(uintptr_t)pkt->session_id; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); inst = cvp_get_inst_from_id(core, session_id); if (!inst) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); return -EINVAL; } sess_msg = kmem_cache_alloc(inst->session_queue.msg_cache, GFP_KERNEL); if (sess_msg == NULL) { dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); return -ENOMEM; } memcpy(&sess_msg->pkt, pkt, sizeof(struct hfi_msg_session_hdr)); spin_lock(&inst->session_queue.lock); if (inst->session_queue.msg_count >= MAX_NUM_MSGS_PER_SESSION) { dprintk(CVP_ERR, "Reached session queue size limit\n"); goto error_handle_msg; } list_add_tail(&sess_msg->node, &inst->session_queue.msgs); inst->session_queue.msg_count++; spin_unlock(&inst->session_queue.lock); wake_up_all(&inst->session_queue.wq); info->response_type = HAL_NO_RESP; return 0; error_handle_msg: spin_unlock(&inst->session_queue.lock); kmem_cache_free(inst->session_queue.msg_cache, sess_msg); return -ENOMEM; } static int hfi_process_session_cvp_dme(u32 device_id, struct hfi_msg_session_cvp_dme_packet_type *pkt, struct msm_cvp_cb_info *info) Loading @@ -930,9 +1011,8 @@ static int hfi_process_session_cvp_dme(u32 device_id, if (!pkt) { dprintk(CVP_ERR, "%s: invalid param\n", __func__); return -EINVAL; } else if (pkt->size < sizeof(*pkt)) { dprintk(CVP_ERR, "%s: bad_pkt_size\n", __func__); } else if (pkt->size > sizeof(*pkt)) { dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); return -E2BIG; } Loading Loading @@ -1068,7 +1148,7 @@ int cvp_hfi_process_msg_packet(u32 device_id, return -EINVAL; } dprintk(CVP_DBG, "Parse response %#x\n", msg_hdr->packet); dprintk(CVP_DBG, "Received HFI MSG with type %d\n", msg_hdr->packet); switch (msg_hdr->packet) { case HFI_MSG_EVENT_NOTIFY: pkt_func = (pkt_func_def)hfi_process_event_notify; Loading @@ -1095,27 +1175,21 @@ int cvp_hfi_process_msg_packet(u32 device_id, pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_OPERATION_CONFIG from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_operation_config; break; case HFI_MSG_SESSION_CVP_DFS: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_DFS from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_dfs; break; case HFI_MSG_SESSION_CVP_DME: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_DME from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_dme; break; case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: dprintk(CVP_DBG, "Received HFI_MSG_SESSION_CVP_PERSIST from firmware"); pkt_func = (pkt_func_def)hfi_process_session_cvp_persist; break; case HFI_MSG_SESSION_CVP_DS: pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; break; default: dprintk(CVP_DBG, "Unable to parse message: %#x\n", msg_hdr->packet); Loading
drivers/media/platform/msm/cvp/msm_cvp.c +66 −5 Original line number Diff line number Diff line Loading @@ -217,6 +217,65 @@ static int msm_cvp_map_buf(struct msm_cvp_inst *inst, return rc; } static bool _cvp_msg_pending(struct msm_cvp_inst *inst, struct cvp_session_queue *sq, struct session_msg **msg) { struct session_msg *mptr = NULL; bool result = false; spin_lock(&sq->lock); if (!kref_read(&inst->kref)) { /* The session is being deleted */ spin_unlock(&sq->lock); *msg = NULL; return true; } result = list_empty(&sq->msgs); if (!result) { mptr = list_first_entry(&sq->msgs, struct session_msg, node); list_del_init(&mptr->node); sq->msg_count--; } spin_unlock(&sq->lock); *msg = mptr; return !result; } static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *out_pkt) { unsigned long wait_time; struct session_msg *msg = NULL; struct cvp_session_queue *sq; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); return -EINVAL; } sq = &inst->session_queue; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); if (wait_event_timeout(sq->wq, _cvp_msg_pending(inst, sq, &msg), wait_time) == 0) { dprintk(CVP_ERR, "session queue wait timeout\n"); return -ETIMEDOUT; } if (msg == NULL) { dprintk(CVP_ERR, "%s: session is deleted, no msg\n", __func__); return -EINVAL; } memcpy(out_pkt, &msg->pkt, sizeof(struct hfi_msg_session_hdr)); kmem_cache_free(inst->session_queue.msg_cache, msg); return 0; } static int msm_cvp_session_process_hfi( struct msm_cvp_inst *inst, struct cvp_kmd_hfi_packet *in_pkt) Loading Loading @@ -600,11 +659,6 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, hdev = inst->core->device; print_client_buffer(CVP_DBG, "unregister", inst, buf); if (!buf->index) { dprintk(CVP_ERR, "Missing index when unregister buf\n"); return 0; } mutex_lock(&inst->cvpbufs.lock); found = false; list_for_each_entry(cbuf, &inst->cvpbufs.list, list) { Loading Loading @@ -690,6 +744,13 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) rc = msm_cvp_send_cmd(inst, send_cmd); break; } case CVP_KMD_RECEIVE_MSG_PKT: { struct cvp_kmd_hfi_packet *out_pkt = (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; rc = msm_cvp_session_receive_hfi(inst, out_pkt); break; } case CVP_KMD_SEND_CMD_PKT: case CVP_KMD_HFI_DFS_CONFIG_CMD: case CVP_KMD_HFI_DFS_FRAME_CMD: Loading