Loading drivers/media/platform/msm/vidc_3x/msm_vidc.c +7 −1 Original line number Diff line number Diff line Loading @@ -1084,7 +1084,7 @@ static inline int vb2_bufq_init(struct msm_vidc_inst *inst, q->ops = msm_venc_get_vb2q_ops(); q->mem_ops = &msm_vidc_vb2_mem_ops; q->drv_priv = inst; q->allow_zero_bytesused = 1; q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type); return vb2_queue_init(q); } Loading Loading @@ -1206,6 +1206,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->pending_getpropq); INIT_MSM_VIDC_LIST(&inst->outputbufs); INIT_MSM_VIDC_LIST(&inst->registeredbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); kref_init(&inst->kref); Loading Loading @@ -1292,6 +1293,7 @@ void *msm_vidc_open(int core_id, int session_type) msm_comm_ctrl_deinit(inst); msm_smem_delete_client(inst->mem_client); fail_mem_client: DEINIT_MSM_VIDC_LIST(&inst->eosbufs); kfree(inst); inst = NULL; err_invalid_core: Loading Loading @@ -1323,6 +1325,8 @@ static void cleanup_instance(struct msm_vidc_inst *inst) "Failed to release persist buffers\n"); } msm_comm_release_eos_buffers(inst); if (msm_comm_release_output_buffers(inst)) { dprintk(VIDC_ERR, "Failed to release output buffers\n"); Loading Loading @@ -1364,6 +1368,8 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) for (i = 0; i < MAX_PORT_NUM; i++) vb2_queue_release(&inst->bufq[i].vb2_bufq); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); Loading drivers/media/platform/msm/vidc_3x/msm_vidc_common.c +104 −2 Original line number Diff line number Diff line Loading @@ -1774,6 +1774,27 @@ static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq, return vb; } static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) { struct eos_buf *temp, *next; bool found = false; mutex_lock(&inst->eosbufs.lock); list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) { if (temp->smem.device_addr == device_addr) { found = true; list_del(&temp->list); msm_comm_smem_free(inst, &temp->smem); kfree(temp); break; } } mutex_unlock(&inst->eosbufs.lock); return found; } static void handle_ebd(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_data_done *response = data; Loading Loading @@ -1808,6 +1829,13 @@ static void handle_ebd(enum hal_command_response cmd, void *data) response->clnt_data) dprintk(VIDC_INFO, "Client data != bufaddr\n"); empty_buf_done = (struct vidc_hal_ebd *)&response->input_done; /* If this is internal EOS buffer, handle it in driver */ if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) { dprintk(VIDC_DBG, "Received EOS buffer %pK\n", (void *)empty_buf_done->packet_buffer); goto exit; } if (empty_buf_done) { if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) { dprintk(VIDC_INFO, Loading Loading @@ -1844,7 +1872,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD); } exit: put_inst(inst); } Loading Loading @@ -3502,7 +3530,6 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) flags = dec->flags; } switch (which_cmd) { case V4L2_QCOM_CMD_FLUSH: if (core->state != VIDC_CORE_INVALID && Loading Loading @@ -3552,6 +3579,61 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) } break; } case V4L2_DEC_CMD_STOP: { struct vidc_frame_data data = {0}; struct hfi_device *hdev = NULL; struct eos_buf *binfo = NULL; u32 smem_flags = 0; if (inst->state != MSM_VIDC_START_DONE) { dprintk(VIDC_DBG, "Inst = %pK is not ready for EOS\n", inst); rc = -EINVAL; break; } if (inst->session_type != MSM_VIDC_DECODER) { dprintk(VIDC_DBG, "Non-Decoder session. DEC_STOP is not valid\n"); rc = -EINVAL; break; } binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { dprintk(VIDC_ERR, "%s: Out of memory\n", __func__); rc = -ENOMEM; break; } if (inst->flags & VIDC_SECURE) smem_flags |= SMEM_SECURE; msm_comm_smem_alloc(inst, SZ_4K, 1, smem_flags, HAL_BUFFER_INPUT, 0); mutex_lock(&inst->eosbufs.lock); list_add_tail(&binfo->list, &inst->eosbufs.list); mutex_unlock(&inst->eosbufs.lock); data.alloc_len = binfo->smem.size; data.device_addr = binfo->smem.device_addr; data.clnt_data = data.device_addr; data.buffer_type = HAL_BUFFER_INPUT; data.filled_len = 0; data.offset = 0; data.flags = HAL_BUFFERFLAG_EOS; data.timestamp = LLONG_MAX; data.extradata_addr = data.device_addr; data.extradata_size = 0; dprintk(VIDC_DBG, "Queueing EOS buffer %pK\n", (void *)data.device_addr); hdev = inst->core->device; rc = call_hfi_op(hdev, session_etb, inst->session, &data); break; } default: dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd); rc = -ENOTSUPP; Loading Loading @@ -4268,6 +4350,26 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, return rc; } void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst) { struct eos_buf *buf, *next; if (!inst) { dprintk(VIDC_ERR, "Invalid instance pointer = %pK\n", inst); return; } mutex_lock(&inst->eosbufs.lock); list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) { list_del(&buf->list); kfree(buf); } INIT_LIST_HEAD(&inst->eosbufs.list); mutex_unlock(&inst->eosbufs.lock); } int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) { struct msm_smem *handle; Loading drivers/media/platform/msm/vidc_3x/msm_vidc_common.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags); int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, bool check_for_reuse); int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst); void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst); int msm_comm_release_output_buffers(struct msm_vidc_inst *inst); int msm_comm_force_cleanup(struct msm_vidc_inst *inst); int msm_comm_suspend(int core_id); Loading drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,10 @@ static inline void INIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) INIT_LIST_HEAD(&mlist->list); } static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) { mutex_destroy(&mlist->lock); } enum buffer_owner { DRIVER, FIRMWARE, Loading @@ -128,6 +132,11 @@ enum buffer_owner { MAX_OWNER }; struct eos_buf { struct list_head list; struct msm_smem smem; }; struct internal_buf { struct list_head list; enum hal_buffer buffer_type; Loading Loading @@ -268,6 +277,7 @@ struct msm_vidc_inst { struct msm_vidc_list persistbufs; struct msm_vidc_list pending_getpropq; struct msm_vidc_list outputbufs; struct msm_vidc_list eosbufs; struct msm_vidc_list registeredbufs; struct buffer_requirements buff_req; void *mem_client; Loading Loading
drivers/media/platform/msm/vidc_3x/msm_vidc.c +7 −1 Original line number Diff line number Diff line Loading @@ -1084,7 +1084,7 @@ static inline int vb2_bufq_init(struct msm_vidc_inst *inst, q->ops = msm_venc_get_vb2q_ops(); q->mem_ops = &msm_vidc_vb2_mem_ops; q->drv_priv = inst; q->allow_zero_bytesused = 1; q->allow_zero_bytesused = !V4L2_TYPE_IS_OUTPUT(type); return vb2_queue_init(q); } Loading Loading @@ -1206,6 +1206,7 @@ void *msm_vidc_open(int core_id, int session_type) INIT_MSM_VIDC_LIST(&inst->pending_getpropq); INIT_MSM_VIDC_LIST(&inst->outputbufs); INIT_MSM_VIDC_LIST(&inst->registeredbufs); INIT_MSM_VIDC_LIST(&inst->eosbufs); kref_init(&inst->kref); Loading Loading @@ -1292,6 +1293,7 @@ void *msm_vidc_open(int core_id, int session_type) msm_comm_ctrl_deinit(inst); msm_smem_delete_client(inst->mem_client); fail_mem_client: DEINIT_MSM_VIDC_LIST(&inst->eosbufs); kfree(inst); inst = NULL; err_invalid_core: Loading Loading @@ -1323,6 +1325,8 @@ static void cleanup_instance(struct msm_vidc_inst *inst) "Failed to release persist buffers\n"); } msm_comm_release_eos_buffers(inst); if (msm_comm_release_output_buffers(inst)) { dprintk(VIDC_ERR, "Failed to release output buffers\n"); Loading Loading @@ -1364,6 +1368,8 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) for (i = 0; i < MAX_PORT_NUM; i++) vb2_queue_release(&inst->bufq[i].vb2_bufq); DEINIT_MSM_VIDC_LIST(&inst->eosbufs); mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->bufq[CAPTURE_PORT].lock); mutex_destroy(&inst->bufq[OUTPUT_PORT].lock); Loading
drivers/media/platform/msm/vidc_3x/msm_vidc_common.c +104 −2 Original line number Diff line number Diff line Loading @@ -1774,6 +1774,27 @@ static struct vb2_buffer *get_vb_from_device_addr(struct buf_queue *bufq, return vb; } static bool is_eos_buffer(struct msm_vidc_inst *inst, u32 device_addr) { struct eos_buf *temp, *next; bool found = false; mutex_lock(&inst->eosbufs.lock); list_for_each_entry_safe(temp, next, &inst->eosbufs.list, list) { if (temp->smem.device_addr == device_addr) { found = true; list_del(&temp->list); msm_comm_smem_free(inst, &temp->smem); kfree(temp); break; } } mutex_unlock(&inst->eosbufs.lock); return found; } static void handle_ebd(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_data_done *response = data; Loading Loading @@ -1808,6 +1829,13 @@ static void handle_ebd(enum hal_command_response cmd, void *data) response->clnt_data) dprintk(VIDC_INFO, "Client data != bufaddr\n"); empty_buf_done = (struct vidc_hal_ebd *)&response->input_done; /* If this is internal EOS buffer, handle it in driver */ if (is_eos_buffer(inst, empty_buf_done->packet_buffer)) { dprintk(VIDC_DBG, "Received EOS buffer %pK\n", (void *)empty_buf_done->packet_buffer); goto exit; } if (empty_buf_done) { if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) { dprintk(VIDC_INFO, Loading Loading @@ -1844,7 +1872,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data) mutex_unlock(&inst->bufq[OUTPUT_PORT].lock); msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD); } exit: put_inst(inst); } Loading Loading @@ -3502,7 +3530,6 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) flags = dec->flags; } switch (which_cmd) { case V4L2_QCOM_CMD_FLUSH: if (core->state != VIDC_CORE_INVALID && Loading Loading @@ -3552,6 +3579,61 @@ int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd) } break; } case V4L2_DEC_CMD_STOP: { struct vidc_frame_data data = {0}; struct hfi_device *hdev = NULL; struct eos_buf *binfo = NULL; u32 smem_flags = 0; if (inst->state != MSM_VIDC_START_DONE) { dprintk(VIDC_DBG, "Inst = %pK is not ready for EOS\n", inst); rc = -EINVAL; break; } if (inst->session_type != MSM_VIDC_DECODER) { dprintk(VIDC_DBG, "Non-Decoder session. DEC_STOP is not valid\n"); rc = -EINVAL; break; } binfo = kzalloc(sizeof(*binfo), GFP_KERNEL); if (!binfo) { dprintk(VIDC_ERR, "%s: Out of memory\n", __func__); rc = -ENOMEM; break; } if (inst->flags & VIDC_SECURE) smem_flags |= SMEM_SECURE; msm_comm_smem_alloc(inst, SZ_4K, 1, smem_flags, HAL_BUFFER_INPUT, 0); mutex_lock(&inst->eosbufs.lock); list_add_tail(&binfo->list, &inst->eosbufs.list); mutex_unlock(&inst->eosbufs.lock); data.alloc_len = binfo->smem.size; data.device_addr = binfo->smem.device_addr; data.clnt_data = data.device_addr; data.buffer_type = HAL_BUFFER_INPUT; data.filled_len = 0; data.offset = 0; data.flags = HAL_BUFFERFLAG_EOS; data.timestamp = LLONG_MAX; data.extradata_addr = data.device_addr; data.extradata_size = 0; dprintk(VIDC_DBG, "Queueing EOS buffer %pK\n", (void *)data.device_addr); hdev = inst->core->device; rc = call_hfi_op(hdev, session_etb, inst->session, &data); break; } default: dprintk(VIDC_ERR, "Unknown Command %d\n", which_cmd); rc = -ENOTSUPP; Loading Loading @@ -4268,6 +4350,26 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, return rc; } void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst) { struct eos_buf *buf, *next; if (!inst) { dprintk(VIDC_ERR, "Invalid instance pointer = %pK\n", inst); return; } mutex_lock(&inst->eosbufs.lock); list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) { list_del(&buf->list); kfree(buf); } INIT_LIST_HEAD(&inst->eosbufs.list); mutex_unlock(&inst->eosbufs.lock); } int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) { struct msm_smem *handle; Loading
drivers/media/platform/msm/vidc_3x/msm_vidc_common.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags); int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, bool check_for_reuse); int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst); void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst); int msm_comm_release_output_buffers(struct msm_vidc_inst *inst); int msm_comm_force_cleanup(struct msm_vidc_inst *inst); int msm_comm_suspend(int core_id); Loading
drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,10 @@ static inline void INIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) INIT_LIST_HEAD(&mlist->list); } static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist) { mutex_destroy(&mlist->lock); } enum buffer_owner { DRIVER, FIRMWARE, Loading @@ -128,6 +132,11 @@ enum buffer_owner { MAX_OWNER }; struct eos_buf { struct list_head list; struct msm_smem smem; }; struct internal_buf { struct list_head list; enum hal_buffer buffer_type; Loading Loading @@ -268,6 +277,7 @@ struct msm_vidc_inst { struct msm_vidc_list persistbufs; struct msm_vidc_list pending_getpropq; struct msm_vidc_list outputbufs; struct msm_vidc_list eosbufs; struct msm_vidc_list registeredbufs; struct buffer_requirements buff_req; void *mem_client; Loading