|
@@ -47,26 +47,49 @@ static const struct dma_fence_ops msm_vidc_dma_fence_ops = {
|
|
|
.release = msm_vidc_dma_fence_release,
|
|
|
};
|
|
|
|
|
|
-int msm_vidc_fence_create(struct msm_vidc_inst *inst,
|
|
|
- struct msm_vidc_buffer *buf)
|
|
|
+struct msm_vidc_fence *msm_vidc_fence_create(struct msm_vidc_inst *inst)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
struct msm_vidc_fence *fence;
|
|
|
|
|
|
if (!inst) {
|
|
|
d_vpr_e("%s: invalid params\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
|
|
|
- if (!fence)
|
|
|
- return -ENOMEM;
|
|
|
+ if (!fence) {
|
|
|
+ i_vpr_e(inst, "%s: failed to allocate memory for fence\n",
|
|
|
+ __func__);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
|
|
|
spin_lock_init(&fence->lock);
|
|
|
dma_fence_init(&fence->dma_fence, &msm_vidc_dma_fence_ops,
|
|
|
- &fence->lock, inst->fence.ctx_num, inst->fence.seq_num++);
|
|
|
+ &fence->lock, inst->fence_context.ctx_num,
|
|
|
+ ++inst->fence_context.seq_num);
|
|
|
snprintf(fence->name, sizeof(fence->name), "%s: %llu",
|
|
|
- inst->fence.name, inst->fence.seq_num);
|
|
|
+ inst->fence_context.name, inst->fence_context.seq_num);
|
|
|
+
|
|
|
+ /* reset seqno to avoid going beyond INT_MAX */
|
|
|
+ if (inst->fence_context.seq_num >= INT_MAX)
|
|
|
+ inst->fence_context.seq_num = 0;
|
|
|
+
|
|
|
+ INIT_LIST_HEAD(&fence->list);
|
|
|
+ list_add_tail(&fence->list, &inst->fence_list);
|
|
|
+ i_vpr_l(inst, "%s: created %s\n", __func__, fence->name);
|
|
|
+
|
|
|
+ return fence;
|
|
|
+}
|
|
|
+
|
|
|
+int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
|
|
|
+ struct msm_vidc_fence *fence)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+
|
|
|
+ if (!inst || !fence) {
|
|
|
+ d_vpr_e("%s: invalid params\n", __func__);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
|
|
|
fence->fd = get_unused_fd_flags(0);
|
|
|
if (fence->fd < 0) {
|
|
@@ -82,54 +105,78 @@ int msm_vidc_fence_create(struct msm_vidc_inst *inst,
|
|
|
goto err_sync_file;
|
|
|
}
|
|
|
fd_install(fence->fd, fence->sync_file->file);
|
|
|
-
|
|
|
- buf->fence = fence;
|
|
|
- i_vpr_h(inst, "%s: created %s\n", __func__, fence->name);
|
|
|
- return 0;
|
|
|
+ i_vpr_l(inst, "%s: created fd %d for fence %s id: %llu\n", __func__,
|
|
|
+ fence->fd, fence->name, fence->dma_fence.seqno);
|
|
|
|
|
|
err_sync_file:
|
|
|
put_unused_fd(fence->fd);
|
|
|
err_fd:
|
|
|
- dma_fence_put(&fence->dma_fence);
|
|
|
- buf->fence = NULL;
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int msm_vidc_fence_signal(struct msm_vidc_inst *inst,
|
|
|
- struct msm_vidc_buffer *buf)
|
|
|
+int msm_vidc_fence_signal(struct msm_vidc_inst *inst, u32 fence_id)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
+ struct msm_vidc_fence *fence, *dummy_fence;
|
|
|
+ bool found = false;
|
|
|
|
|
|
- if (!inst || !buf) {
|
|
|
+ if (!inst) {
|
|
|
d_vpr_e("%s: invalid params\n", __func__);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- if (!buf->fence)
|
|
|
- return 0;
|
|
|
|
|
|
- i_vpr_l(inst, "%s: fence %s\n", __func__, buf->fence->name);
|
|
|
- dma_fence_signal(&buf->fence->dma_fence);
|
|
|
- dma_fence_put(&buf->fence->dma_fence);
|
|
|
- buf->fence = NULL;
|
|
|
+ list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
|
|
+ if (fence->dma_fence.seqno == (u64)fence_id) {
|
|
|
+ found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!found) {
|
|
|
+ i_vpr_e(inst, "%s: no fence available to signal with id: %u",
|
|
|
+ __func__, fence_id);
|
|
|
+ rc = -EINVAL;
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+ i_vpr_l(inst, "%s: fence %s\n", __func__, fence->name);
|
|
|
+ dma_fence_signal(&fence->dma_fence);
|
|
|
+ dma_fence_put(&fence->dma_fence);
|
|
|
+ list_del_init(&fence->list);
|
|
|
|
|
|
+exit:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
void msm_vidc_fence_destroy(struct msm_vidc_inst *inst,
|
|
|
- struct msm_vidc_buffer *buf)
|
|
|
+ struct msm_vidc_fence *fence_to_destroy)
|
|
|
{
|
|
|
- if (!inst || !buf) {
|
|
|
+ struct msm_vidc_fence *fence, *dummy_fence;
|
|
|
+ bool found = false;
|
|
|
+
|
|
|
+ if (!inst || !fence_to_destroy) {
|
|
|
d_vpr_e("%s: invalid params\n", __func__);
|
|
|
return;
|
|
|
}
|
|
|
- if (!buf->fence)
|
|
|
+
|
|
|
+ list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
|
|
|
+ if (fence->dma_fence.seqno ==
|
|
|
+ fence_to_destroy->dma_fence.seqno) {
|
|
|
+ found = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!found) {
|
|
|
+ i_vpr_e(inst, "%s: no fence available to destroy with id: %llu",
|
|
|
+ __func__, fence_to_destroy->dma_fence.seqno);
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
- i_vpr_e(inst, "%s: fence %s\n", __func__, buf->fence->name);
|
|
|
- dma_fence_set_error(&buf->fence->dma_fence, -EINVAL);
|
|
|
- dma_fence_signal(&buf->fence->dma_fence);
|
|
|
- dma_fence_put(&buf->fence->dma_fence);
|
|
|
- buf->fence = NULL;
|
|
|
+ i_vpr_e(inst, "%s: fence %s\n", __func__, fence->name);
|
|
|
+ dma_fence_set_error(&fence->dma_fence, -EINVAL);
|
|
|
+ dma_fence_signal(&fence->dma_fence);
|
|
|
+ dma_fence_put(&fence->dma_fence);
|
|
|
+ list_del_init(&fence->list);
|
|
|
}
|
|
|
|
|
|
int msm_vidc_fence_init(struct msm_vidc_inst *inst)
|
|
@@ -141,13 +188,13 @@ int msm_vidc_fence_init(struct msm_vidc_inst *inst)
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- inst->fence.ctx_num = dma_fence_context_alloc(1);
|
|
|
- snprintf(inst->fence.name, sizeof(inst->fence.name),
|
|
|
+ inst->fence_context.ctx_num = dma_fence_context_alloc(1);
|
|
|
+ snprintf(inst->fence_context.name, sizeof(inst->fence_context.name),
|
|
|
"msm_vidc_fence: %s: %llu", inst->debug_str,
|
|
|
- inst->fence.ctx_num);
|
|
|
- i_vpr_h(inst, "%s: %s\n", __func__, inst->fence.name);
|
|
|
+ inst->fence_context.ctx_num);
|
|
|
+ i_vpr_h(inst, "%s: %s\n", __func__, inst->fence_context.name);
|
|
|
|
|
|
- return rc;
|
|
|
+ return rc;
|
|
|
}
|
|
|
|
|
|
void msm_vidc_fence_deinit(struct msm_vidc_inst *inst)
|
|
@@ -156,7 +203,8 @@ void msm_vidc_fence_deinit(struct msm_vidc_inst *inst)
|
|
|
d_vpr_e("%s: invalid params\n", __func__);
|
|
|
return;
|
|
|
}
|
|
|
- i_vpr_h(inst, "%s: %s\n", __func__, inst->fence.name);
|
|
|
- inst->fence.ctx_num = 0;
|
|
|
- snprintf(inst->fence.name, sizeof(inst->fence.name), "%s", "");
|
|
|
+ i_vpr_h(inst, "%s: %s\n", __func__, inst->fence_context.name);
|
|
|
+ inst->fence_context.ctx_num = 0;
|
|
|
+ snprintf(inst->fence_context.name, sizeof(inst->fence_context.name),
|
|
|
+ "%s", "");
|
|
|
}
|