diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index bd0f908ab5a0..64093e1ec155 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -43,6 +43,7 @@ int rga_request_free(struct rga_request *request); int rga_request_alloc(uint32_t flags, struct rga_session *session); struct rga_request *rga_request_config(struct rga_user_request *user_request); +struct rga_request *rga_request_kernel_config(struct rga_user_request *user_request); int rga_request_submit(struct rga_request *request); int rga_request_mpi_submit(struct rga_req *req, struct rga_request *request); int rga_request_release_signal(struct rga_scheduler_t *scheduler, struct rga_job *job); diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index c247a072c8dd..bd6980221256 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -40,6 +40,9 @@ static const struct rga_backend_ops rga2_ops = { .soft_reset = rga2_soft_reset }; +static struct rga_session *rga_session_init(void); +static int rga_session_deinit(struct rga_session *session); + static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, struct rga_img_info_t *channel_info, struct rga_session *session) @@ -260,29 +263,76 @@ EXPORT_SYMBOL_GPL(rga_mpi_commit); int rga_kernel_commit(struct rga_req *cmd) { int ret = 0; - struct rga_request request; + int request_id; + struct rga_user_request kernel_request; + struct rga_request *request = NULL; + struct rga_session *session = NULL; + struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; - if (DEBUGGER_EN(MSG)) - rga_cmd_print_debug_info(cmd); - - request.sync_mode = RGA_BLIT_SYNC; - request.use_batch_mode = false; - request.task_list = cmd; - request.task_count = 1; - - ret = rga_request_commit(&request); - if (ret < 0) { - if (ret == -ERESTARTSYS) { - if (DEBUGGER_EN(MSG)) - pr_err("%s, commit kernel job failed, by a software interrupt.\n", - __func__); - } else { - pr_err("%s, commit kernel job failed\n", __func__); - } + session = rga_session_init(); + if (!session) + return -ENOMEM; + request_id = rga_request_alloc(0, session); + if (request_id < 0) { + pr_err("request alloc error!\n"); + ret = request_id; return ret; } + memset(&kernel_request, 0, sizeof(kernel_request)); + kernel_request.id = request_id; + kernel_request.task_ptr = (uint64_t)(unsigned long)cmd; + kernel_request.task_num = 1; + kernel_request.sync_mode = RGA_BLIT_SYNC; + + ret = rga_request_check(&kernel_request); + if (ret < 0) { + pr_err("user request check error!\n"); + goto err_free_request_by_id; + } + + request = rga_request_kernel_config(&kernel_request); + if (IS_ERR(request)) { + pr_err("request[%d] config failed!\n", kernel_request.id); + ret = -EFAULT; + goto err_free_request_by_id; + } + + if (DEBUGGER_EN(MSG)) { + pr_info("kernel blit mode: request id = %d", kernel_request.id); + rga_cmd_print_debug_info(cmd); + } + + ret = rga_request_submit(request); + if (ret < 0) { + pr_err("request[%d] submit failed!\n", kernel_request.id); + goto err_put_request; + } + +err_put_request: + mutex_lock(&request_manager->lock); + rga_request_put(request); + mutex_unlock(&request_manager->lock); + + rga_session_deinit(session); + + return ret; + +err_free_request_by_id: + mutex_lock(&request_manager->lock); + + request = rga_request_lookup(request_manager, request_id); + if (IS_ERR_OR_NULL(request)) { + pr_err("can not find request from id[%d]", request_id); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } + + rga_request_free(request); + + mutex_unlock(&request_manager->lock); + return ret; } EXPORT_SYMBOL_GPL(rga_kernel_commit); diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 88b1423732a0..91c06d9a5e01 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -848,6 +848,63 @@ err_put_request: return ERR_PTR(ret); } +struct rga_request *rga_request_kernel_config(struct rga_user_request *user_request) +{ + int ret = 0; + unsigned long flags; + struct rga_pending_request_manager *request_manager; + struct rga_request *request; + struct rga_req *task_list; + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { + pr_err("rga_pending_request_manager is null!\n"); + return ERR_PTR(-EFAULT); + } + + mutex_lock(&request_manager->lock); + + request = rga_request_lookup(request_manager, user_request->id); + if (IS_ERR_OR_NULL(request)) { + pr_err("can not find request from id[%d]", user_request->id); + mutex_unlock(&request_manager->lock); + return ERR_PTR(-EINVAL); + } + + rga_request_get(request); + mutex_unlock(&request_manager->lock); + + task_list = kmalloc_array(user_request->task_num, sizeof(struct rga_req), GFP_KERNEL); + if (task_list == NULL) { + pr_err("task_req list alloc error!\n"); + ret = -ENOMEM; + goto err_put_request; + } + + memcpy(task_list, u64_to_user_ptr(user_request->task_ptr), + sizeof(struct rga_req) * user_request->task_num); + + 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); + + return request; + +err_put_request: + mutex_lock(&request_manager->lock); + rga_request_put(request); + mutex_unlock(&request_manager->lock); + + return ERR_PTR(ret); +} + int rga_request_submit(struct rga_request *request) { int ret = 0;