video: rockchip: rga3: batch mode supports asynchronous calls

Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
Change-Id: I0d38d9a478a77a79d85cac0eb91906ebfae59544
This commit is contained in:
Yu Qiaowei
2022-06-15 18:31:35 +08:00
committed by Tao Huang
parent 17638eab67
commit 77de161fde
4 changed files with 58 additions and 37 deletions

View File

@@ -25,7 +25,7 @@ struct rga_fence_waiter {
int rga_fence_context_init(struct rga_fence_context **ctx);
void rga_fence_context_remove(struct rga_fence_context **ctx);
struct dma_fence *rga_dma_fence_alloc(spinlock_t *lock);
struct dma_fence *rga_dma_fence_alloc(void);
int rga_dma_fence_get_fd(struct dma_fence *fence);
struct dma_fence *rga_get_dma_fence_from_fd(int fence_fd);
int rga_dma_fence_wait(struct dma_fence *fence);
@@ -50,7 +50,7 @@ static inline int rga_dma_fence_get_status(struct dma_fence *fence)
}
#else
static inline struct dma_fence *rga_dma_fence_alloc(spinlock_t *lock)
static inline struct dma_fence *rga_dma_fence_alloc(void)
{
return NULL;
}

View File

@@ -729,11 +729,18 @@ static long rga_ioctl_request_submit(unsigned long arg, bool run_enbale)
return -EFAULT;
}
if (request->sync_mode == RGA_BLIT_SYNC) {
mutex_lock(&request_manager->lock);
rga_request_put(request);
mutex_unlock(&request_manager->lock);
if (request->sync_mode == RGA_BLIT_ASYNC) {
user_request.release_fence_fd = request->release_fence_fd;
if (copy_to_user((struct rga_req *)arg,
&user_request, sizeof(user_request))) {
pr_err("copy_to_user failed\n");
return -EFAULT;
}
}
mutex_lock(&request_manager->lock);
rga_request_put(request);
mutex_unlock(&request_manager->lock);
}
return 0;
@@ -813,12 +820,14 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
memset(&request, 0x0, sizeof(request));
request.sync_mode = cmd;
request.acquire_fence_fd = req_rga.in_fence_fd;
request.use_batch_mode = false;
request.is_running = false;
request.session = session;
request.task_list = &req_rga;
request.task_count = 1;
ret = rga_request_commit(&request);
ret = rga_request_submit(&request);
if (ret < 0) {
if (ret == -ERESTARTSYS) {
if (DEBUGGER_EN(MSG))
@@ -830,6 +839,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
break;
}
req_rga.out_fence_fd = request.release_fence_fd;
if (copy_to_user((struct rga_req *)arg,
&req_rga, sizeof(struct rga_req))) {
pr_err("copy_to_user failed\n");

View File

@@ -51,7 +51,7 @@ void rga_fence_context_remove(struct rga_fence_context **ctx)
*ctx = NULL;
}
struct dma_fence *rga_dma_fence_alloc(spinlock_t *lock)
struct dma_fence *rga_dma_fence_alloc(void)
{
struct rga_fence_context *fence_ctx = rga_drvdata->fence_ctx;
struct dma_fence *fence = NULL;
@@ -65,8 +65,8 @@ struct dma_fence *rga_dma_fence_alloc(spinlock_t *lock)
if (!fence)
return ERR_PTR(-ENOMEM);
dma_fence_init(fence, &rga_fence_ops, lock,
fence_ctx->context, ++fence_ctx->seqno);
dma_fence_init(fence, &rga_fence_ops, &fence_ctx->spinlock,
fence_ctx->context, ++fence_ctx->seqno);
return fence;
}

View File

@@ -112,8 +112,6 @@ static void rga_job_put_current_mm(struct rga_job *job)
static void rga_job_free(struct rga_job *job)
{
rga_dma_fence_put(job->out_fence);
if (~job->flags & RGA_JOB_USE_HANDLE)
rga_job_put_current_mm(job);
@@ -581,11 +579,11 @@ static inline int rga_job_wait(struct rga_job *job)
return ret;
}
static int rga_job_alloc_release_fence(struct dma_fence **release_fence, spinlock_t *lock)
static int rga_job_alloc_release_fence(struct dma_fence **release_fence)
{
struct dma_fence *fence;
fence = rga_dma_fence_alloc(lock);
fence = rga_dma_fence_alloc();
if (IS_ERR(fence)) {
pr_err("Can not alloc release fence!\n");
return IS_ERR(fence);
@@ -606,9 +604,10 @@ static int rga_job_add_acquire_fence_callback(int acquire_fence_fd, void *privat
pr_info("acquire_fence_fd = %d", acquire_fence_fd);
acquire_fence = rga_get_dma_fence_from_fd(acquire_fence_fd);
if (IS_ERR(acquire_fence)) {
pr_err("%s: failed to get acquire dma_fence\n", __func__);
return PTR_ERR(acquire_fence);
if (IS_ERR_OR_NULL(acquire_fence)) {
pr_err("%s: failed to get acquire dma_fence from[%d]\n",
__func__, acquire_fence_fd);
return -EINVAL;
}
/* close acquire fence fd */
ksys_close(acquire_fence_fd);
@@ -645,6 +644,7 @@ struct rga_job *rga_job_commit(struct rga_req *rga_command_base, struct rga_requ
job->use_batch_mode = request->use_batch_mode;
job->request_id = request->id;
job->session = request->session;
job->out_fence = request->release_fence;
if (!(job->flags & RGA_JOB_USE_HANDLE)) {
ret = rga_mm_get_external_buffer(job);
@@ -804,16 +804,6 @@ int rga_request_commit(struct rga_request *request)
int i = 0;
struct rga_job *job = NULL;
if (request->sync_mode == RGA_BLIT_ASYNC) {
ret = rga_job_alloc_release_fence(&request->release_fence, &request->fence_lock);
if (ret < 0) {
pr_err("Failed to alloc release fence fd!\n");
return ret;
}
request->release_fence_fd = ret;
}
if (request->use_batch_mode) {
for (i = 0; i < request->task_count; i++) {
job = rga_job_commit(&(request->task_list[i]), request);
@@ -958,10 +948,12 @@ struct rga_request *rga_request_config(struct rga_user_request *user_request)
spin_lock_irqsave(&request->lock, flags);
request->use_batch_mode = true;
request->task_list = task_list;
request->task_count = user_request->task_num;
request->sync_mode = user_request->sync_mode;
request->mpi_config_flags = user_request->mpi_config_flags;
request->acquire_fence_fd = user_request->acquire_fence_fd;
spin_unlock_irqrestore(&request->lock, flags);
@@ -990,30 +982,47 @@ int rga_request_submit(struct rga_request *request)
return -EINVAL;
}
request->use_batch_mode = true;
request->is_running = true;
spin_unlock_irqrestore(&request->lock, flags);
if (request->sync_mode == RGA_BLIT_ASYNC && request->acquire_fence_fd > 0) {
ret = rga_job_add_acquire_fence_callback(request->acquire_fence_fd,
(void *)request,
rga_request_acquire_fence_signaled_cb);
if (ret == 1) {
goto request_commit;
} else {
pr_err("Failed to wait acquire fence fd[%d]!\n", request->acquire_fence_fd);
if (request->sync_mode == RGA_BLIT_ASYNC) {
ret = rga_job_alloc_release_fence(&request->release_fence);
if (ret < 0) {
pr_err("Failed to alloc release fence fd!\n");
return ret;
}
request->release_fence_fd = ret;
if (request->acquire_fence_fd > 0) {
ret = rga_job_add_acquire_fence_callback(
request->acquire_fence_fd,
(void *)request,
rga_request_acquire_fence_signaled_cb);
if (ret == 0) {
return ret;
} else if (ret == 1) {
goto request_commit;
} else {
pr_err("Failed to add callback with acquire fence fd[%d]!\n",
request->acquire_fence_fd);
goto error_release_fence_put;
}
}
}
request_commit:
ret = rga_request_commit(request);
if (ret < 0) {
pr_err("rga request commit failed!\n");
return ret;
goto error_release_fence_put;
}
return 0;
error_release_fence_put:
rga_dma_fence_put(request->release_fence);
return ret;
}
@@ -1067,6 +1076,8 @@ static void rga_request_kref_release(struct kref *ref)
spin_lock_irqsave(&request->lock, flags);
rga_dma_fence_put(request->release_fence);
if (!request->is_running || request->finished_task_count >= request->task_count) {
spin_unlock_irqrestore(&request->lock, flags);
goto free_request;