From a06b16bc56a7746044d4b68535d215d49042532c Mon Sep 17 00:00:00 2001 From: Li Huang Date: Fri, 26 Nov 2021 15:28:10 +0800 Subject: [PATCH] video: rockchip: rga3: Update version to 1.1.3 1. Fixup timeout when running multi thread, because fd can not pass on other thread. 2. Tide some code Signed-off-by: Li Huang Change-Id: I68b0557138f583ab8bb341bf5bbe2ec145d2884c --- .../rockchip/rga3/include/rga2_mmu_info.h | 2 - drivers/video/rockchip/rga3/include/rga_drv.h | 3 +- drivers/video/rockchip/rga3/rga2_mmu_info.c | 4 +- drivers/video/rockchip/rga3/rga3_reg_info.c | 4 +- drivers/video/rockchip/rga3/rga_dma_buf.c | 151 ++++-------------- drivers/video/rockchip/rga3/rga_job.c | 34 ++-- 6 files changed, 61 insertions(+), 137 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga2_mmu_info.h b/drivers/video/rockchip/rga3/include/rga2_mmu_info.h index 9cf5d6c6904e..816caa0f5302 100644 --- a/drivers/video/rockchip/rga3/include/rga2_mmu_info.h +++ b/drivers/video/rockchip/rga3/include/rga2_mmu_info.h @@ -35,8 +35,6 @@ struct rga2_mmu_info_t { u8 pages_order; }; -void rga2_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler); -dma_addr_t rga2_dma_map_flush_page(struct page *page, int map, struct rga_scheduler_t *scheduler); void rga2_dma_flush_cache_for_virtual_address(struct rga2_mmu_other_t *reg, struct rga_scheduler_t *scheduler); diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 320710466013..4877eca9882e 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -62,11 +62,12 @@ /* Driver information */ #define DRIVER_DESC "RGA multicore Device Driver" #define DRIVER_NAME "rga_multicore" -#define DRIVER_VERSION "1.1.1" +#define DRIVER_VERSION "1.1.3" #define RGA3_VERSION "2.000" /* time limit */ #define RGA_ASYNC_TIMEOUT_DELAY HZ +#define RGA_SYNC_TIMEOUT_DELAY HZ #define RGA_RESET_TIMEOUT 1000 #define RGA_MAX_SCHEDULER 3 diff --git a/drivers/video/rockchip/rga3/rga2_mmu_info.c b/drivers/video/rockchip/rga3/rga2_mmu_info.c index aea6ac42b07e..c1e0774c670b 100644 --- a/drivers/video/rockchip/rga3/rga2_mmu_info.c +++ b/drivers/video/rockchip/rga3/rga2_mmu_info.c @@ -44,13 +44,13 @@ static struct rga_scheduler_t *get_scheduler(int core) return scheduler; } -void rga2_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler) +static void rga2_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler) { dma_sync_single_for_device(scheduler->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE); } -dma_addr_t rga2_dma_map_flush_page(struct page *page, int map, struct rga_scheduler_t *scheduler) +static dma_addr_t rga2_dma_map_flush_page(struct page *page, int map, struct rga_scheduler_t *scheduler) { dma_addr_t paddr = 0; diff --git a/drivers/video/rockchip/rga3/rga3_reg_info.c b/drivers/video/rockchip/rga3/rga3_reg_info.c index f72bc429b991..24288908d7ee 100644 --- a/drivers/video/rockchip/rga3/rga3_reg_info.c +++ b/drivers/video/rockchip/rga3/rga3_reg_info.c @@ -1978,7 +1978,7 @@ int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) p = job->cmd_reg; pr_info("CMD_REG\n"); - for (i = 0; i < 13; i++) + for (i = 0; i < 12; i++) pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, p[0 + i * 4], p[1 + i * 4], p[2 + i * 4], p[3 + i * 4]); @@ -2016,7 +2016,7 @@ int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) uint32_t i; pr_info("CMD_READ_BACK_REG\n"); - for (i = 0; i < 13; i++) + for (i = 0; i < 12; i++) pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, rga_read(0x100 + i * 16 + 0, scheduler), rga_read(0x100 + i * 16 + 4, scheduler), diff --git a/drivers/video/rockchip/rga3/rga_dma_buf.c b/drivers/video/rockchip/rga3/rga_dma_buf.c index 846a2ff6081d..1daac020a956 100644 --- a/drivers/video/rockchip/rga3/rga_dma_buf.c +++ b/drivers/video/rockchip/rga3/rga_dma_buf.c @@ -238,90 +238,6 @@ static void rga_dma_unmap_buffer(struct rga_dma_buffer_t *rga_dma_buffer) if (rga_dma_buffer->attach) dma_buf_detach(rga_dma_buffer->dma_buf, rga_dma_buffer->attach); - - if (rga_dma_buffer->dma_buf && (rga_dma_buffer->use_dma_buf == false)) - dma_buf_put(rga_dma_buffer->dma_buf); -} - -static int rga_dma_fd_get_channel_info(struct rga_img_info_t *channel_info, - struct rga_dma_buffer_t **rga_dma_buffer, - int mmu_flag, int fd, int core) -{ - int ret; - struct rga_dma_buffer_t *alloc_buffer; - struct rga_scheduler_t *scheduler = NULL; - - struct dma_buf *dma_buf = NULL; - - if (unlikely(!mmu_flag && fd)) { - pr_err("Fix it please enable mmu on dma fd channel\n"); - return -EINVAL; - } else if (mmu_flag && fd) { - /* else, perform a single mapping to dma buffer */ - alloc_buffer = kmalloc(sizeof(struct rga_dma_buffer_t), - GFP_KERNEL); - if (alloc_buffer == NULL) { - pr_err("rga2_dma_import_fd alloc error!\n"); - return -ENOMEM; - } - - dma_buf = dma_buf_get(fd); - if (IS_ERR(dma_buf)) { - ret = -EINVAL; - pr_err("dma_buf_get fail fd[%d]\n", fd); - kfree(alloc_buffer); - return ret; - } - - alloc_buffer->cached = false; - alloc_buffer->use_dma_buf = false; - - scheduler = get_scheduler(core); - if (scheduler == NULL) { - pr_err("failed to get scheduler, %s(%d)\n", __func__, - __LINE__); - kfree(alloc_buffer); - ret = -EINVAL; - return ret; - } - - ret = - rga_dma_map_buffer(dma_buf, alloc_buffer, - DMA_BIDIRECTIONAL, scheduler->dev); - if (ret < 0) { - pr_err("Can't map dma-buf\n"); - kfree(alloc_buffer); - return ret; - } - - *rga_dma_buffer = alloc_buffer; - } - -#if CONFIG_ROCKCHIP_RGA_DEBUGGER - if (RGA_DEBUG_CHECK_MODE) { - ret = rga_dma_memory_check(*rga_dma_buffer, - channel_info); - if (ret < 0) { - pr_err("Channel check memory error!\n"); - /* - * Note: This error is released by external - * rga_dma_put_channel_info(). - */ - return ret; - } - } -#endif - - if (core == RGA2_SCHEDULER_CORE0) - channel_info->yrgb_addr = channel_info->uv_addr; - else if (core == RGA3_SCHEDULER_CORE0 || core == RGA3_SCHEDULER_CORE1) { - if (fd) - channel_info->yrgb_addr = (*rga_dma_buffer)->iova; - } - - rga_convert_addr(channel_info); - - return 0; } static int rga_dma_buf_get_channel_info(struct rga_img_info_t *channel_info, @@ -345,7 +261,7 @@ static int rga_dma_buf_get_channel_info(struct rga_img_info_t *channel_info, return -ENOMEM; } - alloc_buffer->use_dma_buf = true; + alloc_buffer->use_dma_buf = false; scheduler = get_scheduler(core); if (scheduler == NULL) { @@ -386,14 +302,15 @@ static int rga_dma_buf_get_channel_info(struct rga_img_info_t *channel_info, if (core == RGA2_SCHEDULER_CORE0) channel_info->yrgb_addr = channel_info->uv_addr; else if (core == RGA3_SCHEDULER_CORE0 || core == RGA3_SCHEDULER_CORE1) - channel_info->yrgb_addr = (*rga_dma_buffer)->iova; + if (*rga_dma_buffer) + channel_info->yrgb_addr = (*rga_dma_buffer)->iova; rga_convert_addr(channel_info); return 0; } -static void rga_dma_put_channel_info(struct rga_dma_buffer_t **rga_dma_buffer) +static void rga_dma_put_channel_info(struct rga_dma_buffer_t **rga_dma_buffer, struct dma_buf **dma_buf) { struct rga_dma_buffer_t *buffer; @@ -402,9 +319,11 @@ static void rga_dma_put_channel_info(struct rga_dma_buffer_t **rga_dma_buffer) return; rga_dma_unmap_buffer(buffer); + dma_buf_put(*dma_buf); kfree(buffer); *rga_dma_buffer = NULL; + *dma_buf = NULL; } int rga_dma_buf_get(struct rga_job *job) @@ -498,93 +417,93 @@ int rga_dma_get_info(struct rga_job *job) /* src0 channel */ if (likely(src0 != NULL)) { mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 8) & 1); - if (job->dma_buf_src0 == NULL) { - ret = rga_dma_fd_get_channel_info(src0, - &job->rga_dma_buffer_src0, mmu_flag, - src0->yrgb_addr, job->core); - } else { + if (job->dma_buf_src0 != NULL) { ret = rga_dma_buf_get_channel_info(src0, &job->rga_dma_buffer_src0, mmu_flag, &job->dma_buf_src0, job->core); } + if (unlikely(ret < 0)) { pr_err("src0 channel get info error!\n"); goto src0_channel_err; } + + if (src0->yrgb_addr <= 0 && job->rga_dma_buffer_src0 != NULL) + job->rga_dma_buffer_src0->use_dma_buf = true; } /* dst channel */ if (likely(dst != NULL)) { - if (job->dma_buf_dst == NULL && dst != NULL) { - mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 10) & 1); - ret = rga_dma_fd_get_channel_info(dst, - &job->rga_dma_buffer_dst, mmu_flag, - dst->yrgb_addr, job->core); - } else if (dst != NULL) { + mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 10) & 1); + if (job->dma_buf_dst != NULL) { ret = rga_dma_buf_get_channel_info(dst, &job->rga_dma_buffer_dst, mmu_flag, &job->dma_buf_dst, job->core); } + if (unlikely(ret < 0)) { pr_err("dst channel get info error!\n"); goto dst_channel_err; } + + if (dst->yrgb_addr <= 0 && job->rga_dma_buffer_dst != NULL) + job->rga_dma_buffer_dst->use_dma_buf = true; } /* src1 channel */ if (src1 != NULL) { mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 9) & 1); - if (job->dma_buf_src1 == NULL) { - ret = rga_dma_fd_get_channel_info(src1, - &job->rga_dma_buffer_src1, mmu_flag, - src1->yrgb_addr, job->core); - } else { + if (job->dma_buf_src1 != NULL) { ret = rga_dma_buf_get_channel_info(src1, &job->rga_dma_buffer_src1, mmu_flag, &job->dma_buf_src1, job->core); } + if (unlikely(ret < 0)) { pr_err("src1 channel get info error!\n"); goto src1_channel_err; } + + if (src1->yrgb_addr <= 0 && job->rga_dma_buffer_src1 != NULL) + job->rga_dma_buffer_src1->use_dma_buf = true; } /* els channel */ if (els != NULL) { mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 11) & 1); - if (job->dma_buf_els == NULL && els != NULL) { - ret = rga_dma_fd_get_channel_info(els, - &job->rga_dma_buffer_els, mmu_flag, - els->yrgb_addr, job->core); - } else if (els != NULL) { + if (job->dma_buf_els != NULL) { ret = rga_dma_buf_get_channel_info(els, &job->rga_dma_buffer_els, mmu_flag, &job->dma_buf_els, job->core); } + if (unlikely(ret < 0)) { pr_err("els channel get info error!\n"); goto els_channel_err; } + + if (els->yrgb_addr <= 0 && job->rga_dma_buffer_els != NULL) + job->rga_dma_buffer_els->use_dma_buf = true; } return 0; els_channel_err: - rga_dma_put_channel_info(&job->rga_dma_buffer_els); + rga_dma_put_channel_info(&job->rga_dma_buffer_els, &job->dma_buf_els); dst_channel_err: - rga_dma_put_channel_info(&job->rga_dma_buffer_dst); + rga_dma_put_channel_info(&job->rga_dma_buffer_dst, &job->dma_buf_dst); src1_channel_err: - rga_dma_put_channel_info(&job->rga_dma_buffer_src1); + rga_dma_put_channel_info(&job->rga_dma_buffer_src1, &job->dma_buf_src1); src0_channel_err: - rga_dma_put_channel_info(&job->rga_dma_buffer_src0); + rga_dma_put_channel_info(&job->rga_dma_buffer_src0, &job->dma_buf_src0); return ret; } void rga_dma_put_info(struct rga_job *job) { - rga_dma_put_channel_info(&job->rga_dma_buffer_src0); - rga_dma_put_channel_info(&job->rga_dma_buffer_src1); - rga_dma_put_channel_info(&job->rga_dma_buffer_dst); - rga_dma_put_channel_info(&job->rga_dma_buffer_els); + rga_dma_put_channel_info(&job->rga_dma_buffer_src0, &job->dma_buf_src0); + rga_dma_put_channel_info(&job->rga_dma_buffer_src1, &job->dma_buf_src1); + rga_dma_put_channel_info(&job->rga_dma_buffer_dst, &job->dma_buf_dst); + rga_dma_put_channel_info(&job->rga_dma_buffer_els, &job->dma_buf_els); } diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index b6956e6a98e6..f090a75508dc 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -162,7 +162,7 @@ next_job: job->ret = rga_job_run(job, rga_scheduler); - /* If some error on ASYNC mode before hw run */ + /* If some error before hw run */ if (job->ret < 0) { pr_err("some error on rga_job_run, %s(%d)\n", __func__, __LINE__); @@ -178,6 +178,12 @@ next_job: if (job->flags & RGA_JOB_ASYNC) rga_job_cleanup(job); + else { + job->flags |= RGA_JOB_DONE; + wake_up(&rga_scheduler->job_done_wq); + } + + rga_dma_put_info(job); goto next_job; } @@ -635,7 +641,7 @@ static inline int rga_job_wait(struct rga_scheduler_t *rga_scheduler, int ret; left_time = wait_event_interruptible_timeout(rga_scheduler->job_done_wq, - job->flags & RGA_JOB_DONE, RGA_ASYNC_TIMEOUT_DELAY); + job->flags & RGA_JOB_DONE, RGA_SYNC_TIMEOUT_DELAY); if (left_time <= 0) { ret = left_time < 0 ? left_time : -ETIMEDOUT; @@ -689,6 +695,18 @@ int rga_commit(struct rga_req *rga_command_base, int flags) return -ENOMEM; } + /* + * because fd can not pass on other thread, + * so need to get dma_buf first. + */ + ret = rga_dma_buf_get(job); + if (ret < 0) { + pr_err("%s: failed to get dma buf from fd\n", + __func__); + rga_job_free(job); + return ret; + } + if (flags == RGA_BLIT_ASYNC) { ret = rga_out_fence_alloc(job); if (ret) { @@ -730,18 +748,6 @@ int rga_commit(struct rga_req *rga_command_base, int flags) } /* if input fence is valid */ } else if (ret == 0) { - /* - * because fd can not pass on dma_fence_callback, - * so need to get dma_buf first. - */ - ret = rga_dma_buf_get(job); - if (ret < 0) { - pr_err("%s: failed to get dma buf from fd\n", - __func__); - rga_job_free(job); - return ret; - } - ret = rga_add_dma_fence_callback(job, in_fence, rga_input_fence_signaled); if (ret < 0) {