diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index ed051e4621c4..bd0f908ab5a0 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -44,6 +44,7 @@ int rga_request_alloc(uint32_t flags, struct rga_session *session); struct rga_request *rga_request_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); int rga_request_manager_init(struct rga_pending_request_manager **request_manager_session); diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index 759c37aca3f9..2b7cc08b1e23 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -130,6 +130,17 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) return -EINVAL; } + if (request->task_count > 1) { + /* TODO */ + pr_err("Currently request does not support multiple tasks!"); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } + + /* + * The mpi commit will use the request repeatedly, so an additional + * get() is added here. + */ rga_request_get(request); mutex_unlock(&request_manager->lock); @@ -137,7 +148,6 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) /* TODO: batch mode need mpi async mode */ request->sync_mode = RGA_BLIT_SYNC; - request->use_batch_mode = false; cached_cmd = request->task_list; memcpy(&mpi_cmd, cached_cmd, sizeof(mpi_cmd)); @@ -173,7 +183,7 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) request->session); if (ret < 0) { pr_err("src channel set buffer handle failed!\n"); - return ret; + goto err_put_request; } } @@ -183,7 +193,7 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) request->session); if (ret < 0) { pr_err("src1 channel set buffer handle failed!\n"); - return ret; + goto err_put_request; } } @@ -193,7 +203,7 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) request->session); if (ret < 0) { pr_err("dst channel set buffer handle failed!\n"); - return ret; + goto err_put_request; } } @@ -201,17 +211,10 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) mpi_cmd.mmu_info.mmu_en = 0; mpi_cmd.mmu_info.mmu_flag = 0; - /* commit job */ - if (request->task_count > 1) { - pr_err("Currently request does not support multiple tasks!"); - /* TODO */ - return -EINVAL; - } - if (DEBUGGER_EN(MSG)) rga_cmd_print_debug_info(&mpi_cmd); - ret = rga_job_mpi_commit(&mpi_cmd, request); + ret = rga_request_mpi_submit(&mpi_cmd, request); if (ret < 0) { if (ret == -ERESTARTSYS) { if (DEBUGGER_EN(MSG)) @@ -221,7 +224,7 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) pr_err("%s, commit mpi job failed\n", __func__); } - return ret; + goto err_put_request; } if ((mpi_job->dma_buf_src0 != NULL) && (mpi_cmd.src.yrgb_addr > 0)) @@ -243,6 +246,9 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job) mpi_job->output->format = mpi_cmd.dst.format; } + return 0; + +err_put_request: mutex_lock(&request_manager->lock); rga_request_put(request); mutex_unlock(&request_manager->lock); diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 24bec21a1fa6..6c42319865b7 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -684,57 +684,6 @@ running_job_abort: return ERR_PTR(ret); } -int rga_job_mpi_commit(struct rga_req *rga_command_base, struct rga_request *request) -{ - struct rga_job *job = NULL; - struct rga_scheduler_t *scheduler = NULL; - int ret = 0; - - job = rga_job_alloc(rga_command_base); - if (!job) { - pr_err("failed to alloc rga job!\n"); - return -ENOMEM; - } - - job->request_id = request->id; - - if (request->sync_mode == RGA_BLIT_ASYNC) { - //TODO: mpi async mode - pr_err("rk-debug TODO\n"); - } else if (request->sync_mode == RGA_BLIT_SYNC) { - scheduler = rga_job_schedule(job); - if (scheduler == NULL) { - pr_err("failed to get scheduler, %s(%d)\n", __func__, - __LINE__); - ret = -EINVAL; - goto invalid_job; - } - - ret = job->ret; - if (ret < 0) { - pr_err("some error on job, %s(%d)\n", __func__, - __LINE__); - goto running_job_abort; - } - - ret = rga_job_wait(job); - if (ret < 0) { - goto running_job_abort; - } - rga_job_cleanup(job); - } - return ret; - -invalid_job: - rga_invalid_job_abort(job); - return ret; - -/* only used by SYNC mode */ -running_job_abort: - rga_running_job_abort(job, scheduler); - return ret; -} - int rga_request_check(struct rga_user_request *req) { if (req->id <= 0) { @@ -1017,6 +966,51 @@ error_release_fence_put: return ret; } +int rga_request_mpi_submit(struct rga_req *req, struct rga_request *request) +{ + int ret = 0; + struct rga_job *job = NULL; + unsigned long flags; + + if (request->sync_mode == RGA_BLIT_ASYNC) { + pr_err("mpi unsupported async mode!\n"); + return -EINVAL; + } + + spin_lock_irqsave(&request->lock, flags); + + if (request->is_running) { + pr_err("can not re-config when request is running"); + spin_unlock_irqrestore(&request->lock, flags); + return -EFAULT; + } + + /* Reset */ + request->finished_task_count = 0; + + if (request->task_list == NULL) { + pr_err("can not find task list from id[%d]", request->id); + spin_unlock_irqrestore(&request->lock, flags); + return -EINVAL; + } + + request->is_running = true; + + spin_unlock_irqrestore(&request->lock, flags); + + job = rga_job_commit(req, request); + if (IS_ERR_OR_NULL(job)) { + pr_err("failed to commit job!\n"); + return job ? PTR_ERR(job) : -EFAULT; + } + + ret = rga_request_wait(request); + if (ret < 0) + return ret; + + return 0; +} + int rga_request_free(struct rga_request *request) { struct rga_pending_request_manager *request_manager;