diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index 89c31f3fbf53..10b0a9253350 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -14,10 +14,11 @@ #include "rga_drv.h" enum job_flags { - RGA_JOB_DONE = 1 << 0, - RGA_JOB_ASYNC = 1 << 1, - RGA_JOB_SYNC = 1 << 2, - RGA_JOB_USE_HANDLE = 1 << 3, + RGA_JOB_DONE = 1 << 0, + RGA_JOB_ASYNC = 1 << 1, + RGA_JOB_SYNC = 1 << 2, + RGA_JOB_USE_HANDLE = 1 << 3, + RGA_JOB_UNSUPPORT_RGA2 = 1 << 4, }; struct rga_scheduler_t *rga_job_get_scheduler(int core); diff --git a/drivers/video/rockchip/rga3/include/rga_mm.h b/drivers/video/rockchip/rga3/include/rga_mm.h index 409efc022bc8..0683ecab30c0 100644 --- a/drivers/video/rockchip/rga3/include/rga_mm.h +++ b/drivers/video/rockchip/rga3/include/rga_mm.h @@ -34,6 +34,7 @@ struct rga_mm { }; struct rga_internal_buffer *rga_mm_lookup_handle(struct rga_mm *mm_session, uint32_t handle); +int rga_mm_lookup_flag(struct rga_mm *mm_session, uint64_t handle); dma_addr_t rga_mm_lookup_iova(struct rga_internal_buffer *buffer, int core); struct sg_table *rga_mm_lookup_sgt(struct rga_internal_buffer *buffer, int core); diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index 3d3421b7da64..08235681f247 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -141,6 +141,67 @@ static int rga_job_cleanup(struct rga_job *job) return 0; } +static int rga_job_judgment_support_core(struct rga_job *job) +{ + int ret = 0; + uint32_t mm_flag; + struct rga_req *req; + struct rga_mm *mm; + + req = &job->rga_command_base; + mm = rga_drvdata->mm; + if (mm == NULL) { + pr_err("rga mm is null!\n"); + return -EFAULT; + } + + mutex_lock(&mm->lock); + + if (likely(req->src.yrgb_addr > 0)) { + ret = rga_mm_lookup_flag(mm, req->src.yrgb_addr); + if (ret < 0) + goto out_finish; + else + mm_flag = (uint32_t)ret; + + if (~mm_flag & RGA_MM_UNDER_4G) { + job->flags |= RGA_JOB_UNSUPPORT_RGA2; + goto out_finish; + } + } + + if (likely(req->dst.yrgb_addr > 0)) { + ret = rga_mm_lookup_flag(mm, req->dst.yrgb_addr); + if (ret < 0) + goto out_finish; + else + mm_flag = (uint32_t)ret; + + if (~mm_flag & RGA_MM_UNDER_4G) { + job->flags |= RGA_JOB_UNSUPPORT_RGA2; + goto out_finish; + } + } + + if (req->pat.yrgb_addr > 0) { + ret = rga_mm_lookup_flag(mm, req->pat.yrgb_addr); + if (ret < 0) + goto out_finish; + else + mm_flag = (uint32_t)ret; + + if (~mm_flag & RGA_MM_UNDER_4G) { + job->flags |= RGA_JOB_UNSUPPORT_RGA2; + goto out_finish; + } + } + +out_finish: + mutex_unlock(&mm->lock); + + return ret; +} + static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base) { struct rga_job *job = NULL; @@ -164,10 +225,13 @@ static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base) job->priority = rga_command_base->priority; } - if (job->rga_command_base.handle_flag & 1) + if (job->rga_command_base.handle_flag & 1) { job->flags |= RGA_JOB_USE_HANDLE; - else + + rga_job_judgment_support_core(job); + } else { rga_job_get_current_mm(job); + } return job; } diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index 585153b7f719..4cc0ea0bd4a0 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -683,6 +683,19 @@ struct rga_internal_buffer *rga_mm_lookup_handle(struct rga_mm *mm_session, uint return output_buffer; } +int rga_mm_lookup_flag(struct rga_mm *mm_session, uint64_t handle) +{ + struct rga_internal_buffer *output_buffer; + + output_buffer = rga_mm_lookup_handle(mm_session, handle); + if (output_buffer == NULL) { + pr_err("This handle[%ld] is illegal.\n", (unsigned long)handle); + return -EINVAL; + } + + return output_buffer->mm_flag; +} + dma_addr_t rga_mm_lookup_iova(struct rga_internal_buffer *buffer, int core) { int i; diff --git a/drivers/video/rockchip/rga3/rga_policy.c b/drivers/video/rockchip/rga3/rga_policy.c index d2ec4ea39afe..a4da3d94cc40 100644 --- a/drivers/video/rockchip/rga3/rga_policy.c +++ b/drivers/video/rockchip/rga3/rga_policy.c @@ -205,6 +205,13 @@ int rga_job_assign(struct rga_job *job) if (RGA_DEBUG_MSG) pr_err("start policy on core = %d", scheduler->core); + if (scheduler->core == RGA2_SCHEDULER_CORE0 && + job->flags & RGA_JOB_UNSUPPORT_RGA2) { + if (RGA_DEBUG_MSG) + pr_debug("RGA2 only support under 4G memory!\n"); + continue; + } + if (feature > 0) { if (!(feature & data->feature)) { if (RGA_DEBUG_MSG)