From c93d87e863a95d5f022ca12558f17c8cd478ad12 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Mon, 11 Jul 2022 17:03:56 +0800 Subject: [PATCH] video: rockchip: rga3: blit-command adapted to batch mode Signed-off-by: Yu Qiaowei Change-Id: I1b5d25396cf26b10df8c4e62357ec0e203018b7b --- drivers/video/rockchip/rga3/include/rga_job.h | 3 +- drivers/video/rockchip/rga3/rga_drv.c | 129 ++++++++++++------ drivers/video/rockchip/rga3/rga_job.c | 46 ++----- 3 files changed, 100 insertions(+), 78 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index 86bfca4217cd..ed051e4621c4 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -39,7 +39,8 @@ struct rga_request *rga_request_lookup(struct rga_pending_request_manager *reque int rga_request_commit(struct rga_request *user_request); int rga_request_put(struct rga_request *request); void rga_request_get(struct rga_request *request); -uint32_t rga_request_alloc(uint32_t flags, struct rga_session *session); +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); int rga_request_submit(struct rga_request *request); diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index a7fe28e6c50b..759c37aca3f9 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -782,18 +782,98 @@ static long rga_ioctl_request_cancel(unsigned long arg) return 0; } +static long rga_ioctl_blit(unsigned long arg, uint32_t cmd, struct rga_session *session) +{ + int ret = 0; + int request_id; + struct rga_user_request user_request; + struct rga_req *rga_req; + struct rga_request *request = NULL; + struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; + + request_id = rga_request_alloc(0, session); + if (request_id < 0) { + pr_err("request alloc error!\n"); + ret = request_id; + return ret; + } + + memset(&user_request, 0, sizeof(user_request)); + user_request.id = request_id; + user_request.task_ptr = arg; + user_request.task_num = 1; + user_request.sync_mode = cmd; + + ret = rga_request_check(&user_request); + if (ret < 0) { + pr_err("user request check error!\n"); + goto err_free_request_by_id; + } + + request = rga_request_config(&user_request); + if (IS_ERR(request)) { + pr_err("request[%d] config failed!\n", user_request.id); + ret = -EFAULT; + goto err_free_request_by_id; + } + + rga_req = request->task_list; + /* In the BLIT_SYNC/BLIT_ASYNC command, in_fence_fd needs to be set. */ + request->acquire_fence_fd = rga_req->in_fence_fd; + + if (DEBUGGER_EN(MSG)) { + pr_info("Blit mode: request id = %d", user_request.id); + rga_cmd_print_debug_info(rga_req); + } + + ret = rga_request_submit(request); + if (ret < 0) { + pr_err("request[%d] submit failed!\n", user_request.id); + goto err_put_request; + } + + if (request->sync_mode == RGA_BLIT_ASYNC) { + rga_req->out_fence_fd = request->release_fence_fd; + if (copy_to_user((struct rga_req *)arg, rga_req, sizeof(struct rga_req))) { + pr_err("copy_to_user failed\n"); + ret = -EFAULT; + goto err_put_request; + } + } + +err_put_request: + mutex_lock(&request_manager->lock); + rga_request_put(request); + mutex_unlock(&request_manager->lock); + + 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; +} + static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) { - struct rga_drvdata_t *rga = rga_drvdata; - struct rga_req req_rga; int ret = 0; int i = 0; int major_version = 0, minor_version = 0; char version[16] = { 0 }; struct rga_version_t driver_version; struct rga_hw_versions_t hw_versions; - struct rga_request request; - + struct rga_drvdata_t *rga = rga_drvdata; struct rga_session *session = file->private_data; if (!rga) { @@ -807,46 +887,7 @@ static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg) switch (cmd) { case RGA_BLIT_SYNC: case RGA_BLIT_ASYNC: - if (unlikely(copy_from_user(&req_rga, - (struct rga_req *)arg, sizeof(struct rga_req)))) { - pr_err("copy_from_user failed\n"); - ret = -EFAULT; - break; - } - - if (DEBUGGER_EN(MSG)) - rga_cmd_print_debug_info(&req_rga); - - memset(&request, 0x0, sizeof(request)); - - spin_lock_init(&request.lock); - 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_submit(&request); - if (ret < 0) { - if (ret == -ERESTARTSYS) { - if (DEBUGGER_EN(MSG)) - pr_err("rga_request_commit failed, by a software interrupt.\n"); - } else { - pr_err("rga_request_commit failed\n"); - } - - 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"); - ret = -EFAULT; - break; - } + ret = rga_ioctl_blit(arg, cmd, session); break; case RGA_CACHE_FLUSH: diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 0a55cde509d8..24bec21a1fa6 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -777,10 +777,9 @@ static int rga_request_wait(struct rga_request *request) int left_time; int ret; - left_time = wait_event_interruptible_timeout(request->finished_wq, - request->finished_task_count == - request->task_count, - RGA_SYNC_TIMEOUT_DELAY * request->task_count); + left_time = wait_event_timeout(request->finished_wq, + request->finished_task_count == request->task_count, + RGA_SYNC_TIMEOUT_DELAY * request->task_count); switch (left_time) { case 0: @@ -804,37 +803,18 @@ int rga_request_commit(struct rga_request *request) int i = 0; struct rga_job *job = NULL; - if (request->use_batch_mode) { - for (i = 0; i < request->task_count; i++) { - job = rga_job_commit(&(request->task_list[i]), request); - if (IS_ERR_OR_NULL(job)) { - pr_err("failed to commit job!\n"); - return job ? PTR_ERR(job) : -EFAULT; - } - } - - if (request->sync_mode == RGA_BLIT_SYNC) { - ret = rga_request_wait(request); - if (ret < 0) { - return ret; - } - } - } else { - job = rga_job_commit(request->task_list, request); + for (i = 0; i < request->task_count; i++) { + job = rga_job_commit(&(request->task_list[i]), request); if (IS_ERR_OR_NULL(job)) { pr_err("failed to commit job!\n"); return job ? PTR_ERR(job) : -EFAULT; } + } - if (request->sync_mode == RGA_BLIT_SYNC) { - ret = rga_job_wait(job); - if (ret < 0) { - rga_running_job_abort(job, job->scheduler); - return ret; - } - - rga_job_cleanup(job); - } + if (request->sync_mode == RGA_BLIT_SYNC) { + ret = rga_request_wait(request); + if (ret < 0) + return ret; } return 0; @@ -1037,7 +1017,7 @@ error_release_fence_put: return ret; } -static int rga_request_free(struct rga_request *request) +int rga_request_free(struct rga_request *request) { struct rga_pending_request_manager *request_manager; struct rga_req *task_list; @@ -1142,7 +1122,7 @@ static int rga_request_free_cb(int id, void *ptr, void *data) return rga_request_free((struct rga_request *)ptr); } -uint32_t rga_request_alloc(uint32_t flags, struct rga_session *session) +int rga_request_alloc(uint32_t flags, struct rga_session *session) { struct rga_pending_request_manager *request_manager; struct rga_request *request; @@ -1189,7 +1169,7 @@ uint32_t rga_request_alloc(uint32_t flags, struct rga_session *session) mutex_unlock(&request_manager->lock); - return (uint32_t)request->id; + return request->id; } int rga_request_put(struct rga_request *request)