Loading drivers/media/platform/msm/cvp/msm_cvp.c +17 −86 Original line number Diff line number Diff line Loading @@ -209,7 +209,8 @@ static int msm_cvp_session_process_hfi( return -EINVAL; } pkt_type = in_pkt->pkt_data[1]; if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS) if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); Loading Loading @@ -278,68 +279,6 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return true; } static int cvp_fence_dme(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) { int rc = 0; unsigned long timeout; u64 ktid; int synx_state = SYNX_STATE_SIGNALED_SUCCESS; struct cvp_hfi_device *hdev; struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr *hdr; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); hdev = inst->core->device; sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) goto exit; rc = call_hfi_op(hdev, session_send, (void *)inst->session, (struct cvp_kmd_hfi_packet *)pkt); if (rc) { dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", current->comm, __func__, pkt->size, pkt->packet_type); synx_state = SYNX_STATE_SIGNALED_ERROR; goto exit; } timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, (struct cvp_kmd_hfi_packet *)pkt); hdr = (struct cvp_hfi_msg_session_hdr *)pkt; hfi_err = hdr->error_type; if (rc) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", current->comm, __func__, rc); synx_state = SYNX_STATE_SIGNALED_ERROR; goto exit; } if (hfi_err == HFI_ERR_SESSION_FLUSHED) { dprintk(CVP_SYNX, "%s %s: cvp_wait_process_message flushed\n", current->comm, __func__); synx_state = SYNX_STATE_SIGNALED_CANCEL; } else if (hfi_err == HFI_ERR_SESSION_STREAM_CORRUPT) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_msg non-fatal %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_SUCCESS; } else if (hfi_err != HFI_ERR_NONE) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi err %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_CANCEL; } exit: rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); return rc; } static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) Loading @@ -359,8 +298,10 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) { msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; } rc = call_hfi_op(hdev, session_send, (void *)inst->session, (struct cvp_kmd_hfi_packet *)pkt); Loading Loading @@ -461,31 +402,18 @@ static int cvp_fence_thread(void *data) synx = (u32 *)f->synx; ktid = pkt->client_data.kdata & (FENCE_BIT - 1); dprintk(CVP_SYNX, "%s starts working on frame %llu frameID %llu\n", current->comm, ktid, f->frame_id); dprintk(CVP_SYNX, "%s pkt type %d on ktid %llu frameID %llu\n", current->comm, pkt->packet_type, ktid, f->frame_id); switch (f->type) { case HFI_CMD_SESSION_CVP_DME_FRAME: rc = cvp_fence_dme(inst, f, pkt); break; case HFI_CMD_SESSION_CVP_FD_FRAME: rc = cvp_fence_proc(inst, f, pkt); break; default: dprintk(CVP_ERR, "%s: unknown hfi cmd type 0x%x\n", __func__, f->type); rc = -EINVAL; goto exit; break; } mutex_lock(&q->lock); cvp_release_synx(inst, f); list_del_init(&f->list); mutex_unlock(&q->lock); dprintk(CVP_SYNX, "%s is done with frame %llu frameID %llu\n", current->comm, ktid, f->frame_id); dprintk(CVP_SYNX, "%s done with %d ktid %llu frameID %llu rc %d\n", current->comm, pkt->packet_type, ktid, f->frame_id, rc); cvp_free_fence_data(f); Loading Loading @@ -557,7 +485,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, if (!is_buf_param_valid(buf_num, offset)) { dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); return -EINVAL; goto exit; } rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, buf_num); Loading @@ -573,8 +501,10 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, synx_pkt = &arg->data.hfi_synx_pkt; if (synx_pkt->fence_data[0] != 0xFEEDFACE) { fence = (u32 *)&fence_pkt->fence_data; f->frame_id = arg->data.hfi_fence_pkt.frame_id; dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); cvp_free_fence_data(f); msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; } else { kfc = &synx_pkt->fc; fence = (u32 *)&kfc->fences; Loading @@ -585,7 +515,8 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, } dprintk(CVP_SYNX, "%s: frameID %llu\n", __func__, f->frame_id); dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n", __func__, f->frame_id, pkt->client_data.kdata); memcpy(f->pkt, pkt, pkt->size); Loading drivers/media/platform/msm/cvp/msm_cvp_buf.c +51 −43 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { print_client_buffer(CVP_ERR, "map failed", inst, buf); goto exit; Loading Loading @@ -164,7 +164,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) exit: if (smem->device_addr) msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap dsp"); kmem_cache_free(cvp_driver->buf_cache, cbuf); cbuf = NULL; kmem_cache_free(cvp_driver->smem_cache, smem); Loading Loading @@ -217,7 +217,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) } if (cbuf->smem->device_addr) msm_cvp_unmap_smem(cbuf->smem); msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); mutex_lock(&inst->cvpdspbufs.lock); list_del(&cbuf->list); Loading Loading @@ -301,12 +301,13 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, set_bit(inst->dma_cache.nr, &inst->dma_cache.usage_bitmap); smem->bitmap_index = inst->dma_cache.nr; inst->dma_cache.nr++; i = smem->bitmap_index; } else { i = find_first_zero_bit(&inst->dma_cache.usage_bitmap, MAX_DMABUF_NUMS); if (i < MAX_DMABUF_NUMS) { smem2 = inst->dma_cache.entries[i]; msm_cvp_unmap_smem(smem2); msm_cvp_unmap_smem(inst, smem2, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem2->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem2); Loading @@ -322,6 +323,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, atomic_inc(&smem->refcount); mutex_unlock(&inst->dma_cache.lock); dprintk(CVP_MEM, "Add entry %d into cache\n", i); return 0; } Loading @@ -329,7 +331,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, struct cvp_buf_type *buf) { int rc = 0; int rc = 0, found = 1; struct msm_cvp_smem *smem = NULL; struct dma_buf *dma_buf = NULL; Loading @@ -346,13 +348,14 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem = msm_cvp_session_find_smem(inst, dma_buf); if (!smem) { found = 0; smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); if (!smem) return NULL; smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; rc = msm_cvp_map_smem(inst, smem); rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; Loading @@ -364,13 +367,19 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, if (buf->size > smem->size || buf->size > smem->size - buf->offset) { dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", __func__, buf->offset, buf->size); if (found) { mutex_lock(&inst->dma_cache.lock); atomic_dec(&smem->refcount); mutex_unlock(&inst->dma_cache.lock); return NULL; } goto exit2; } return smem; exit2: msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); exit: msm_cvp_smem_put_dma_buf(dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); Loading Loading @@ -477,7 +486,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_buf_put(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); buf->smem = NULL; Loading Loading @@ -527,7 +536,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, struct cvp_hfi_cmd_session_hdr *cmd_hdr; struct cvp_internal_buf *pbuf, *dummy; u64 ktid; int i, rc = 0; int rc = 0; struct msm_cvp_smem *smem = NULL; if (!offset || !buf_num) Loading @@ -536,10 +545,8 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); for (i = 0; i < buf_num; i++) { mutex_lock(&inst->persistbufs.lock); list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { if (pbuf->ktid == ktid && pbuf->ownership == CLIENT) { list_del(&pbuf->list); smem = pbuf->smem; Loading @@ -550,7 +557,8 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_buf_put(smem->dma_buf); kmem_cache_free( cvp_driver->smem_cache, Loading @@ -563,11 +571,9 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, } kmem_cache_free(cvp_driver->buf_cache, pbuf); break; } } mutex_unlock(&inst->persistbufs.lock); } return rc; } Loading Loading @@ -599,8 +605,10 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, mutex_lock(&inst->persistbufs.lock); list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { if (pbuf->fd == buf->fd && pbuf->size == buf->size && pbuf->ownership == CLIENT) { if (pbuf->ownership == CLIENT) { if (pbuf->fd == buf->fd && pbuf->size == buf->size) buf->fd = pbuf->smem->device_addr; rc = 1; break; } Loading @@ -612,7 +620,6 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, rc = -EFAULT; break; } buf->fd = pbuf->smem->device_addr; pbuf->ktid = ktid; rc = 0; } Loading Loading @@ -675,6 +682,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, frame->ktid = ktid; frame->nr = 0; frame->pkt_type = cmd_hdr->packet_type; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; Loading Loading @@ -728,7 +736,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } else { print_smem(CVP_WARN, "in use", inst, smem); } msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); inst->dma_cache.entries[i] = NULL; Loading @@ -748,7 +756,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) "%s: failed dsp deregistration fd=%d rc=%d", __func__, cbuf->fd, rc); msm_cvp_unmap_smem(cbuf->smem); msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); list_del(&cbuf->list); kmem_cache_free(cvp_driver->buf_cache, cbuf); Loading drivers/media/platform/msm/cvp/msm_cvp_buf.h +6 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ struct msm_cvp_frame { struct cvp_internal_buf bufs[MAX_FRAME_BUFFER_NUMS]; u32 nr; u64 ktid; u32 pkt_type; }; void print_cvp_buffer(u32 tag, const char *str, Loading @@ -155,8 +156,11 @@ struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, struct msm_cvp_platform_resources *res, unsigned long ion_flags); int msm_cvp_map_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); int msm_cvp_unmap_smem(struct msm_cvp_smem *smem); struct msm_cvp_smem *smem, const char *str); int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, const char *str); struct dma_buf *msm_cvp_smem_get_dma_buf(int fd); void msm_cvp_smem_put_dma_buf(void *dma_buf); int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, Loading drivers/media/platform/msm/cvp/msm_cvp_core.c +55 −0 Original line number Diff line number Diff line Loading @@ -250,13 +250,68 @@ void *msm_cvp_open(int core_id, int session_type) } EXPORT_SYMBOL(msm_cvp_open); static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst, struct cvp_session_queue *sq) { struct cvp_session_msg *mptr, *dummy; u64 ktid; spin_lock(&sq->lock); if (sq->msg_count && sq->state != QUEUE_ACTIVE) { list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { ktid = mptr->pkt.client_data.kdata; if (ktid) { list_del_init(&mptr->node); sq->msg_count--; msm_cvp_unmap_frame(inst, ktid); kmem_cache_free(cvp_driver->msg_cache, mptr); } } } spin_unlock(&sq->lock); } static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; int max_retries; struct msm_cvp_frame *frame; struct cvp_session_queue *sq, *sqf; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return; } sqf = &inst->session_queue_fence; sq = &inst->session_queue; max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait: mutex_lock(&inst->frames.lock); empty = list_empty(&inst->frames.list); if (!empty && max_retries > 0) { mutex_unlock(&inst->frames.lock); usleep_range(1000, 2000); msm_cvp_clean_sess_queue(inst, sqf); msm_cvp_clean_sess_queue(inst, sq); max_retries--; goto wait; } mutex_unlock(&inst->frames.lock); if (!empty) { dprintk(CVP_WARN, "Failed to process frames before session close\n"); mutex_lock(&inst->frames.lock); list_for_each_entry(frame, &inst->frames.list, list) dprintk(CVP_WARN, "Unprocessed frame %d\n", frame->pkt_type); mutex_unlock(&inst->frames.lock); cvp_dump_fence_queue(inst); } if (cvp_release_arp_buffers(inst)) dprintk(CVP_ERR, "Failed to release persist buffers\n"); Loading drivers/media/platform/msm/cvp/msm_cvp_synx.c +33 −358 Original line number Diff line number Diff line Loading @@ -9,69 +9,39 @@ #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" static int cvp_import_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *fence, u32 *synx) void cvp_dump_fence_queue(struct msm_cvp_inst *inst) { int rc = 0; int i; int start = 0, end = 0; struct cvp_fence_type *f; struct synx_import_params params; s32 h_synx; struct cvp_fence_queue *q; struct cvp_fence_command *f; struct synx_session ssid; int i; f = (struct cvp_fence_type *)fence; q = &inst->fence_cmd_queue; ssid = inst->synx_session_id; mutex_lock(&q->lock); dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n", hash32_ptr(inst->session), q->mode, ssid.client_id); switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 0; end = HFI_DME_BUF_NUM; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in = fence[0]; u32 out = fence[1]; dprintk(CVP_WARN, "fence cmdq wait list:\n"); list_for_each_entry(f, &q->wait_list, list) { dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); for (i = 0; i < f->output_index; i++) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); if (in > MAX_HFI_FENCE_SIZE || out > MAX_HFI_FENCE_SIZE || in > MAX_HFI_FENCE_SIZE - out) { dprintk(CVP_ERR, "%s: failed!\n", __func__); rc = -EINVAL; return rc; } synx[0] = (in << 16) | out; start = 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } dprintk(CVP_WARN, "fence cmdq schedule list:\n"); list_for_each_entry(f, &q->sched_list, list) { dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); for (i = 0; i < f->output_index; i++) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); for (i = start; i < end; ++i) { h_synx = f[i].h_synx; if (h_synx) { params.h_synx = h_synx; params.secure_key = f[i].secure_key; params.new_h_synx = &synx[i]; rc = synx_import(ssid, ¶ms); if (rc) { dprintk(CVP_ERR, "%s: synx_import failed\n", __func__); return rc; } } } return rc; mutex_unlock(&q->lock); } int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, Loading @@ -84,9 +54,10 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, s32 h_synx; struct synx_session ssid; if (fc->signature != 0xFEEDFACE) return cvp_import_synx_deprecate(inst, fc->type, fence, fc->synx); if (fc->signature != 0xFEEDFACE) { dprintk(CVP_ERR, "%s Deprecated synx path\n", __func__); return -EINVAL; } fs = (struct cvp_fence_type *)fence; ssid = inst->synx_session_id; Loading @@ -112,55 +83,6 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, return 0; } static int cvp_release_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; s32 h_synx; struct synx_session ssid; int start = 0, end = 0; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 0; end = HFI_DME_BUF_NUM; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in = synx[0] >> 16; u32 out = synx[0] & 0xFFFF; start = 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_release(ssid, h_synx); if (rc) dprintk(CVP_ERR, "%s: synx_release %d failed\n", __func__, i); } } return rc; } int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) { int rc = 0; Loading @@ -168,8 +90,10 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) s32 h_synx; struct synx_session ssid; if (fc->signature != 0xFEEDFACE) return cvp_release_synx_deprecate(inst, fc->type, fc->synx); if (fc->signature != 0xFEEDFACE) { dprintk(CVP_ERR, "%s deprecated synx_path\n", __func__); return -EINVAL; } ssid = inst->synx_session_id; for (i = 0; i < fc->num_fences; ++i) { Loading @@ -185,108 +109,6 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) return rc; } static int cvp_cancel_input_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; int h_synx; struct synx_session ssid; int start = 0, end = 0; int synx_state = SYNX_STATE_SIGNALED_CANCEL; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 1; end = HFI_DME_BUF_NUM - 1; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in, out; in = synx[0] >> 16; out = synx[0] & 0xFFFF; start = 1; end = in + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc && rc != -EALREADY) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", __func__, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } } return rc; } static int cvp_cancel_output_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; int h_synx; struct synx_session ssid; int start = 0, end = 0; int synx_state = SYNX_STATE_SIGNALED_CANCEL; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = FENCE_DME_OUTPUT_IDX; end = FENCE_DME_OUTPUT_IDX + 1; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in, out; in = synx[0] >> 16; out = synx[0] & 0xFFFF; start = in + 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", __func__, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } } return rc; } static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc) Loading Loading @@ -332,139 +154,13 @@ int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc) { if (fc->signature != 0xFEEDFACE) { if (type == CVP_INPUT_SYNX) return cvp_cancel_input_synx_deprecate(inst, fc->type, fc->synx); else if (type == CVP_OUTPUT_SYNX) return cvp_cancel_output_synx_deprecate(inst, fc->type, fc->synx); else { dprintk(CVP_ERR, "Incorrect synx type %d\n", type); dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); return -EINVAL; } } return cvp_cancel_synx_impl(inst, type, fc); } static int cvp_wait_dme_synx_deprecate(struct synx_session ssid, u32 *synx, u32 *synx_state) { int i, rc = 0; int h_synx; unsigned long timeout_ms = 1000; i = 0; while (i < HFI_DME_BUF_NUM - 1) { h_synx = synx[i]; if (h_synx) { rc = synx_wait(ssid, h_synx, timeout_ms); if (rc) { dprintk(CVP_ERR, "%s %s: synx_wait %d failed\n", current->comm, __func__, i); *synx_state = SYNX_STATE_SIGNALED_ERROR; return -EINVAL; } /* * Increase loop count to skip fence * waiting on downscale image where i == 1. */ if (i == FENCE_DME_ICA_ENABLED_IDX) ++i; } ++i; } return rc; } static int cvp_signal_dme_synx_deprecate(struct synx_session ssid, u32 *synx, u32 synx_state) { int rc = 0; int h_synx; if (synx[FENCE_DME_ICA_ENABLED_IDX]) { h_synx = synx[FENCE_DME_DS_IDX]; rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n", current->comm, __func__, FENCE_DME_DS_IDX); synx_state = SYNX_STATE_SIGNALED_ERROR; } } h_synx = synx[FENCE_DME_OUTPUT_IDX]; rc = synx_signal(ssid, h_synx, synx_state); if (rc) dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n", current->comm, __func__, FENCE_DME_OUTPUT_IDX); return rc; } static int cvp_wait_fd_synx_deprecate(struct synx_session ssid, u32 *synx, u32 *synx_state) { int i, rc = 0; unsigned long timeout_ms = 1000; int h_synx; u32 in; in = synx[0] >> 16; i = 1; while (i <= in) { h_synx = synx[i]; if (h_synx) { rc = synx_wait(ssid, h_synx, timeout_ms); if (rc) { *synx_state = synx_get_status(ssid, h_synx); if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) { dprintk(CVP_SYNX, "%s: synx_wait %d cancel %d state %d\n", current->comm, i, rc, *synx_state); } else { dprintk(CVP_ERR, "%s: synx_wait %d failed %d state %d\n", current->comm, i, rc, *synx_state); *synx_state = SYNX_STATE_SIGNALED_ERROR; } return rc; } } ++i; } return rc; } static int cvp_signal_fd_synx_deprecate(struct synx_session ssid, u32 *synx, u32 synx_state) { int i, rc = 0; u32 in, out; int h_synx; in = synx[0] >> 16; out = synx[0] & 0xFFFF; i = in + 1; while (i <= in + out) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", current->comm, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } ++i; } return rc; } static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, u32 *synx_state) { Loading Loading @@ -525,29 +221,8 @@ int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, ssid = inst->synx_session_id; if (fc->signature != 0xFEEDFACE) { if (fc->type == HFI_CMD_SESSION_CVP_DME_FRAME) { if (type == CVP_INPUT_SYNX) return cvp_wait_dme_synx_deprecate(ssid, fc->synx, synx_state); else if (type == CVP_OUTPUT_SYNX) return cvp_signal_dme_synx_deprecate(ssid, fc->synx, *synx_state); else dprintk(CVP_ERR, "%s deprecated synx, type %d\n", __func__); return -EINVAL; } else if (fc->type == HFI_CMD_SESSION_CVP_FD_FRAME) { if (type == CVP_INPUT_SYNX) return cvp_wait_fd_synx_deprecate(ssid, fc->synx, synx_state); else if (type == CVP_OUTPUT_SYNX) return cvp_signal_fd_synx_deprecate(ssid, fc->synx, *synx_state); else return -EINVAL; } else { dprintk(CVP_ERR, "%s Incorrect pkt type\n", __func__); return -EINVAL; } } if (type == CVP_INPUT_SYNX) { Loading Loading
drivers/media/platform/msm/cvp/msm_cvp.c +17 −86 Original line number Diff line number Diff line Loading @@ -209,7 +209,8 @@ static int msm_cvp_session_process_hfi( return -EINVAL; } pkt_type = in_pkt->pkt_data[1]; if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS) if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); Loading Loading @@ -278,68 +279,6 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return true; } static int cvp_fence_dme(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) { int rc = 0; unsigned long timeout; u64 ktid; int synx_state = SYNX_STATE_SIGNALED_SUCCESS; struct cvp_hfi_device *hdev; struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr *hdr; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); hdev = inst->core->device; sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) goto exit; rc = call_hfi_op(hdev, session_send, (void *)inst->session, (struct cvp_kmd_hfi_packet *)pkt); if (rc) { dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", current->comm, __func__, pkt->size, pkt->packet_type); synx_state = SYNX_STATE_SIGNALED_ERROR; goto exit; } timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, (struct cvp_kmd_hfi_packet *)pkt); hdr = (struct cvp_hfi_msg_session_hdr *)pkt; hfi_err = hdr->error_type; if (rc) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", current->comm, __func__, rc); synx_state = SYNX_STATE_SIGNALED_ERROR; goto exit; } if (hfi_err == HFI_ERR_SESSION_FLUSHED) { dprintk(CVP_SYNX, "%s %s: cvp_wait_process_message flushed\n", current->comm, __func__); synx_state = SYNX_STATE_SIGNALED_CANCEL; } else if (hfi_err == HFI_ERR_SESSION_STREAM_CORRUPT) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_msg non-fatal %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_SUCCESS; } else if (hfi_err != HFI_ERR_NONE) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi err %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_CANCEL; } exit: rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); return rc; } static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) Loading @@ -359,8 +298,10 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) { msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; } rc = call_hfi_op(hdev, session_send, (void *)inst->session, (struct cvp_kmd_hfi_packet *)pkt); Loading Loading @@ -461,31 +402,18 @@ static int cvp_fence_thread(void *data) synx = (u32 *)f->synx; ktid = pkt->client_data.kdata & (FENCE_BIT - 1); dprintk(CVP_SYNX, "%s starts working on frame %llu frameID %llu\n", current->comm, ktid, f->frame_id); dprintk(CVP_SYNX, "%s pkt type %d on ktid %llu frameID %llu\n", current->comm, pkt->packet_type, ktid, f->frame_id); switch (f->type) { case HFI_CMD_SESSION_CVP_DME_FRAME: rc = cvp_fence_dme(inst, f, pkt); break; case HFI_CMD_SESSION_CVP_FD_FRAME: rc = cvp_fence_proc(inst, f, pkt); break; default: dprintk(CVP_ERR, "%s: unknown hfi cmd type 0x%x\n", __func__, f->type); rc = -EINVAL; goto exit; break; } mutex_lock(&q->lock); cvp_release_synx(inst, f); list_del_init(&f->list); mutex_unlock(&q->lock); dprintk(CVP_SYNX, "%s is done with frame %llu frameID %llu\n", current->comm, ktid, f->frame_id); dprintk(CVP_SYNX, "%s done with %d ktid %llu frameID %llu rc %d\n", current->comm, pkt->packet_type, ktid, f->frame_id, rc); cvp_free_fence_data(f); Loading Loading @@ -557,7 +485,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, if (!is_buf_param_valid(buf_num, offset)) { dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); return -EINVAL; goto exit; } rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, buf_num); Loading @@ -573,8 +501,10 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, synx_pkt = &arg->data.hfi_synx_pkt; if (synx_pkt->fence_data[0] != 0xFEEDFACE) { fence = (u32 *)&fence_pkt->fence_data; f->frame_id = arg->data.hfi_fence_pkt.frame_id; dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); cvp_free_fence_data(f); msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; } else { kfc = &synx_pkt->fc; fence = (u32 *)&kfc->fences; Loading @@ -585,7 +515,8 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, } dprintk(CVP_SYNX, "%s: frameID %llu\n", __func__, f->frame_id); dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n", __func__, f->frame_id, pkt->client_data.kdata); memcpy(f->pkt, pkt, pkt->size); Loading
drivers/media/platform/msm/cvp/msm_cvp_buf.c +51 −43 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { print_client_buffer(CVP_ERR, "map failed", inst, buf); goto exit; Loading Loading @@ -164,7 +164,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) exit: if (smem->device_addr) msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap dsp"); kmem_cache_free(cvp_driver->buf_cache, cbuf); cbuf = NULL; kmem_cache_free(cvp_driver->smem_cache, smem); Loading Loading @@ -217,7 +217,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) } if (cbuf->smem->device_addr) msm_cvp_unmap_smem(cbuf->smem); msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); mutex_lock(&inst->cvpdspbufs.lock); list_del(&cbuf->list); Loading Loading @@ -301,12 +301,13 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, set_bit(inst->dma_cache.nr, &inst->dma_cache.usage_bitmap); smem->bitmap_index = inst->dma_cache.nr; inst->dma_cache.nr++; i = smem->bitmap_index; } else { i = find_first_zero_bit(&inst->dma_cache.usage_bitmap, MAX_DMABUF_NUMS); if (i < MAX_DMABUF_NUMS) { smem2 = inst->dma_cache.entries[i]; msm_cvp_unmap_smem(smem2); msm_cvp_unmap_smem(inst, smem2, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem2->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem2); Loading @@ -322,6 +323,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, atomic_inc(&smem->refcount); mutex_unlock(&inst->dma_cache.lock); dprintk(CVP_MEM, "Add entry %d into cache\n", i); return 0; } Loading @@ -329,7 +331,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, struct cvp_buf_type *buf) { int rc = 0; int rc = 0, found = 1; struct msm_cvp_smem *smem = NULL; struct dma_buf *dma_buf = NULL; Loading @@ -346,13 +348,14 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem = msm_cvp_session_find_smem(inst, dma_buf); if (!smem) { found = 0; smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); if (!smem) return NULL; smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; rc = msm_cvp_map_smem(inst, smem); rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; Loading @@ -364,13 +367,19 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, if (buf->size > smem->size || buf->size > smem->size - buf->offset) { dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", __func__, buf->offset, buf->size); if (found) { mutex_lock(&inst->dma_cache.lock); atomic_dec(&smem->refcount); mutex_unlock(&inst->dma_cache.lock); return NULL; } goto exit2; } return smem; exit2: msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); exit: msm_cvp_smem_put_dma_buf(dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); Loading Loading @@ -477,7 +486,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_buf_put(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); buf->smem = NULL; Loading Loading @@ -527,7 +536,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, struct cvp_hfi_cmd_session_hdr *cmd_hdr; struct cvp_internal_buf *pbuf, *dummy; u64 ktid; int i, rc = 0; int rc = 0; struct msm_cvp_smem *smem = NULL; if (!offset || !buf_num) Loading @@ -536,10 +545,8 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); for (i = 0; i < buf_num; i++) { mutex_lock(&inst->persistbufs.lock); list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { if (pbuf->ktid == ktid && pbuf->ownership == CLIENT) { list_del(&pbuf->list); smem = pbuf->smem; Loading @@ -550,7 +557,8 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_buf_put(smem->dma_buf); kmem_cache_free( cvp_driver->smem_cache, Loading @@ -563,11 +571,9 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, } kmem_cache_free(cvp_driver->buf_cache, pbuf); break; } } mutex_unlock(&inst->persistbufs.lock); } return rc; } Loading Loading @@ -599,8 +605,10 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, mutex_lock(&inst->persistbufs.lock); list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { if (pbuf->fd == buf->fd && pbuf->size == buf->size && pbuf->ownership == CLIENT) { if (pbuf->ownership == CLIENT) { if (pbuf->fd == buf->fd && pbuf->size == buf->size) buf->fd = pbuf->smem->device_addr; rc = 1; break; } Loading @@ -612,7 +620,6 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, rc = -EFAULT; break; } buf->fd = pbuf->smem->device_addr; pbuf->ktid = ktid; rc = 0; } Loading Loading @@ -675,6 +682,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, frame->ktid = ktid; frame->nr = 0; frame->pkt_type = cmd_hdr->packet_type; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; Loading Loading @@ -728,7 +736,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } else { print_smem(CVP_WARN, "in use", inst, smem); } msm_cvp_unmap_smem(smem); msm_cvp_unmap_smem(inst, smem, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); inst->dma_cache.entries[i] = NULL; Loading @@ -748,7 +756,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) "%s: failed dsp deregistration fd=%d rc=%d", __func__, cbuf->fd, rc); msm_cvp_unmap_smem(cbuf->smem); msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); list_del(&cbuf->list); kmem_cache_free(cvp_driver->buf_cache, cbuf); Loading
drivers/media/platform/msm/cvp/msm_cvp_buf.h +6 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ struct msm_cvp_frame { struct cvp_internal_buf bufs[MAX_FRAME_BUFFER_NUMS]; u32 nr; u64 ktid; u32 pkt_type; }; void print_cvp_buffer(u32 tag, const char *str, Loading @@ -155,8 +156,11 @@ struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, struct msm_cvp_platform_resources *res, unsigned long ion_flags); int msm_cvp_map_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); int msm_cvp_unmap_smem(struct msm_cvp_smem *smem); struct msm_cvp_smem *smem, const char *str); int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, const char *str); struct dma_buf *msm_cvp_smem_get_dma_buf(int fd); void msm_cvp_smem_put_dma_buf(void *dma_buf); int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, Loading
drivers/media/platform/msm/cvp/msm_cvp_core.c +55 −0 Original line number Diff line number Diff line Loading @@ -250,13 +250,68 @@ void *msm_cvp_open(int core_id, int session_type) } EXPORT_SYMBOL(msm_cvp_open); static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst, struct cvp_session_queue *sq) { struct cvp_session_msg *mptr, *dummy; u64 ktid; spin_lock(&sq->lock); if (sq->msg_count && sq->state != QUEUE_ACTIVE) { list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { ktid = mptr->pkt.client_data.kdata; if (ktid) { list_del_init(&mptr->node); sq->msg_count--; msm_cvp_unmap_frame(inst, ktid); kmem_cache_free(cvp_driver->msg_cache, mptr); } } } spin_unlock(&sq->lock); } static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; int max_retries; struct msm_cvp_frame *frame; struct cvp_session_queue *sq, *sqf; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return; } sqf = &inst->session_queue_fence; sq = &inst->session_queue; max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait: mutex_lock(&inst->frames.lock); empty = list_empty(&inst->frames.list); if (!empty && max_retries > 0) { mutex_unlock(&inst->frames.lock); usleep_range(1000, 2000); msm_cvp_clean_sess_queue(inst, sqf); msm_cvp_clean_sess_queue(inst, sq); max_retries--; goto wait; } mutex_unlock(&inst->frames.lock); if (!empty) { dprintk(CVP_WARN, "Failed to process frames before session close\n"); mutex_lock(&inst->frames.lock); list_for_each_entry(frame, &inst->frames.list, list) dprintk(CVP_WARN, "Unprocessed frame %d\n", frame->pkt_type); mutex_unlock(&inst->frames.lock); cvp_dump_fence_queue(inst); } if (cvp_release_arp_buffers(inst)) dprintk(CVP_ERR, "Failed to release persist buffers\n"); Loading
drivers/media/platform/msm/cvp/msm_cvp_synx.c +33 −358 Original line number Diff line number Diff line Loading @@ -9,69 +9,39 @@ #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" static int cvp_import_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *fence, u32 *synx) void cvp_dump_fence_queue(struct msm_cvp_inst *inst) { int rc = 0; int i; int start = 0, end = 0; struct cvp_fence_type *f; struct synx_import_params params; s32 h_synx; struct cvp_fence_queue *q; struct cvp_fence_command *f; struct synx_session ssid; int i; f = (struct cvp_fence_type *)fence; q = &inst->fence_cmd_queue; ssid = inst->synx_session_id; mutex_lock(&q->lock); dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n", hash32_ptr(inst->session), q->mode, ssid.client_id); switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 0; end = HFI_DME_BUF_NUM; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in = fence[0]; u32 out = fence[1]; dprintk(CVP_WARN, "fence cmdq wait list:\n"); list_for_each_entry(f, &q->wait_list, list) { dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); for (i = 0; i < f->output_index; i++) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); if (in > MAX_HFI_FENCE_SIZE || out > MAX_HFI_FENCE_SIZE || in > MAX_HFI_FENCE_SIZE - out) { dprintk(CVP_ERR, "%s: failed!\n", __func__); rc = -EINVAL; return rc; } synx[0] = (in << 16) | out; start = 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } dprintk(CVP_WARN, "fence cmdq schedule list:\n"); list_for_each_entry(f, &q->sched_list, list) { dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); for (i = 0; i < f->output_index; i++) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); for (i = start; i < end; ++i) { h_synx = f[i].h_synx; if (h_synx) { params.h_synx = h_synx; params.secure_key = f[i].secure_key; params.new_h_synx = &synx[i]; rc = synx_import(ssid, ¶ms); if (rc) { dprintk(CVP_ERR, "%s: synx_import failed\n", __func__); return rc; } } } return rc; mutex_unlock(&q->lock); } int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, Loading @@ -84,9 +54,10 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, s32 h_synx; struct synx_session ssid; if (fc->signature != 0xFEEDFACE) return cvp_import_synx_deprecate(inst, fc->type, fence, fc->synx); if (fc->signature != 0xFEEDFACE) { dprintk(CVP_ERR, "%s Deprecated synx path\n", __func__); return -EINVAL; } fs = (struct cvp_fence_type *)fence; ssid = inst->synx_session_id; Loading @@ -112,55 +83,6 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, return 0; } static int cvp_release_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; s32 h_synx; struct synx_session ssid; int start = 0, end = 0; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 0; end = HFI_DME_BUF_NUM; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in = synx[0] >> 16; u32 out = synx[0] & 0xFFFF; start = 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_release(ssid, h_synx); if (rc) dprintk(CVP_ERR, "%s: synx_release %d failed\n", __func__, i); } } return rc; } int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) { int rc = 0; Loading @@ -168,8 +90,10 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) s32 h_synx; struct synx_session ssid; if (fc->signature != 0xFEEDFACE) return cvp_release_synx_deprecate(inst, fc->type, fc->synx); if (fc->signature != 0xFEEDFACE) { dprintk(CVP_ERR, "%s deprecated synx_path\n", __func__); return -EINVAL; } ssid = inst->synx_session_id; for (i = 0; i < fc->num_fences; ++i) { Loading @@ -185,108 +109,6 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) return rc; } static int cvp_cancel_input_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; int h_synx; struct synx_session ssid; int start = 0, end = 0; int synx_state = SYNX_STATE_SIGNALED_CANCEL; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = 1; end = HFI_DME_BUF_NUM - 1; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in, out; in = synx[0] >> 16; out = synx[0] & 0xFFFF; start = 1; end = in + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc && rc != -EALREADY) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", __func__, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } } return rc; } static int cvp_cancel_output_synx_deprecate(struct msm_cvp_inst *inst, u32 type, u32 *synx) { int rc = 0; int i; int h_synx; struct synx_session ssid; int start = 0, end = 0; int synx_state = SYNX_STATE_SIGNALED_CANCEL; ssid = inst->synx_session_id; switch (type) { case HFI_CMD_SESSION_CVP_DME_FRAME: { start = FENCE_DME_OUTPUT_IDX; end = FENCE_DME_OUTPUT_IDX + 1; break; } case HFI_CMD_SESSION_CVP_FD_FRAME: { u32 in, out; in = synx[0] >> 16; out = synx[0] & 0xFFFF; start = in + 1; end = in + out + 1; break; } default: dprintk(CVP_ERR, "%s: unknown fence type\n", __func__); rc = -EINVAL; return rc; } for (i = start; i < end; ++i) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", __func__, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } } return rc; } static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc) Loading Loading @@ -332,139 +154,13 @@ int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc) { if (fc->signature != 0xFEEDFACE) { if (type == CVP_INPUT_SYNX) return cvp_cancel_input_synx_deprecate(inst, fc->type, fc->synx); else if (type == CVP_OUTPUT_SYNX) return cvp_cancel_output_synx_deprecate(inst, fc->type, fc->synx); else { dprintk(CVP_ERR, "Incorrect synx type %d\n", type); dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); return -EINVAL; } } return cvp_cancel_synx_impl(inst, type, fc); } static int cvp_wait_dme_synx_deprecate(struct synx_session ssid, u32 *synx, u32 *synx_state) { int i, rc = 0; int h_synx; unsigned long timeout_ms = 1000; i = 0; while (i < HFI_DME_BUF_NUM - 1) { h_synx = synx[i]; if (h_synx) { rc = synx_wait(ssid, h_synx, timeout_ms); if (rc) { dprintk(CVP_ERR, "%s %s: synx_wait %d failed\n", current->comm, __func__, i); *synx_state = SYNX_STATE_SIGNALED_ERROR; return -EINVAL; } /* * Increase loop count to skip fence * waiting on downscale image where i == 1. */ if (i == FENCE_DME_ICA_ENABLED_IDX) ++i; } ++i; } return rc; } static int cvp_signal_dme_synx_deprecate(struct synx_session ssid, u32 *synx, u32 synx_state) { int rc = 0; int h_synx; if (synx[FENCE_DME_ICA_ENABLED_IDX]) { h_synx = synx[FENCE_DME_DS_IDX]; rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n", current->comm, __func__, FENCE_DME_DS_IDX); synx_state = SYNX_STATE_SIGNALED_ERROR; } } h_synx = synx[FENCE_DME_OUTPUT_IDX]; rc = synx_signal(ssid, h_synx, synx_state); if (rc) dprintk(CVP_ERR, "%s %s: synx_signal %d failed\n", current->comm, __func__, FENCE_DME_OUTPUT_IDX); return rc; } static int cvp_wait_fd_synx_deprecate(struct synx_session ssid, u32 *synx, u32 *synx_state) { int i, rc = 0; unsigned long timeout_ms = 1000; int h_synx; u32 in; in = synx[0] >> 16; i = 1; while (i <= in) { h_synx = synx[i]; if (h_synx) { rc = synx_wait(ssid, h_synx, timeout_ms); if (rc) { *synx_state = synx_get_status(ssid, h_synx); if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) { dprintk(CVP_SYNX, "%s: synx_wait %d cancel %d state %d\n", current->comm, i, rc, *synx_state); } else { dprintk(CVP_ERR, "%s: synx_wait %d failed %d state %d\n", current->comm, i, rc, *synx_state); *synx_state = SYNX_STATE_SIGNALED_ERROR; } return rc; } } ++i; } return rc; } static int cvp_signal_fd_synx_deprecate(struct synx_session ssid, u32 *synx, u32 synx_state) { int i, rc = 0; u32 in, out; int h_synx; in = synx[0] >> 16; out = synx[0] & 0xFFFF; i = in + 1; while (i <= in + out) { h_synx = synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc) { dprintk(CVP_ERR, "%s: synx_signal %d failed\n", current->comm, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } } ++i; } return rc; } static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, u32 *synx_state) { Loading Loading @@ -525,29 +221,8 @@ int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, ssid = inst->synx_session_id; if (fc->signature != 0xFEEDFACE) { if (fc->type == HFI_CMD_SESSION_CVP_DME_FRAME) { if (type == CVP_INPUT_SYNX) return cvp_wait_dme_synx_deprecate(ssid, fc->synx, synx_state); else if (type == CVP_OUTPUT_SYNX) return cvp_signal_dme_synx_deprecate(ssid, fc->synx, *synx_state); else dprintk(CVP_ERR, "%s deprecated synx, type %d\n", __func__); return -EINVAL; } else if (fc->type == HFI_CMD_SESSION_CVP_FD_FRAME) { if (type == CVP_INPUT_SYNX) return cvp_wait_fd_synx_deprecate(ssid, fc->synx, synx_state); else if (type == CVP_OUTPUT_SYNX) return cvp_signal_fd_synx_deprecate(ssid, fc->synx, *synx_state); else return -EINVAL; } else { dprintk(CVP_ERR, "%s Incorrect pkt type\n", __func__); return -EINVAL; } } if (type == CVP_INPUT_SYNX) { Loading