From a9d7cb122c283c2199c3aba8fe77a91e6027172b Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Wed, 29 Jun 2022 17:37:14 +0800 Subject: [PATCH] video: rockchip: rga3: remove the binding of RGA2 and 'RGA_MMU' Since some RGA2 will use IOMMU, it is unreasonable to use RGA2_core for previous MMU-related judgments. Signed-off-by: Yu Qiaowei Change-Id: Ibd1f33cd57178fac9fa04ea752459307b7304d39 --- drivers/video/rockchip/rga3/include/rga_drv.h | 6 +- drivers/video/rockchip/rga3/include/rga_job.h | 2 +- drivers/video/rockchip/rga3/rga_debugger.c | 6 +- drivers/video/rockchip/rga3/rga_job.c | 6 +- drivers/video/rockchip/rga3/rga_mm.c | 211 +++++++++--------- drivers/video/rockchip/rga3/rga_policy.c | 4 +- 6 files changed, 113 insertions(+), 122 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h index 261a11aa3916..4d50b20cd45c 100644 --- a/drivers/video/rockchip/rga3/include/rga_drv.h +++ b/drivers/video/rockchip/rga3/include/rga_drv.h @@ -157,10 +157,8 @@ struct rga_dma_buffer { */ size_t offset; - /* The core of the mapping */ - int core; - - struct device *dev; + /* The scheduler of the mapping */ + struct rga_scheduler_t *scheduler; }; struct rga_virt_addr { diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h index d635f079598e..86bfca4217cd 100644 --- a/drivers/video/rockchip/rga3/include/rga_job.h +++ b/drivers/video/rockchip/rga3/include/rga_job.h @@ -18,7 +18,7 @@ enum job_flags { RGA_JOB_ASYNC = 1 << 1, RGA_JOB_SYNC = 1 << 2, RGA_JOB_USE_HANDLE = 1 << 3, - RGA_JOB_UNSUPPORT_RGA2 = 1 << 4, + RGA_JOB_UNSUPPORT_RGA_MMU = 1 << 4, }; struct rga_scheduler_t *rga_job_get_scheduler(struct rga_job *job); diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c index c27da0352cd8..20901a3e2961 100644 --- a/drivers/video/rockchip/rga3/rga_debugger.c +++ b/drivers/video/rockchip/rga3/rga_debugger.c @@ -257,7 +257,8 @@ static int rga_mm_session_show(struct seq_file *m, void *data) case RGA_DMA_BUFFER_PTR: seq_puts(m, "dma_buffer:\n"); for (i = 0; i < dump_buffer->dma_buffer_size; i++) { - seq_printf(m, "\t core %d:\n", dump_buffer->dma_buffer[i].core); + seq_printf(m, "\t core %d:\n", + dump_buffer->dma_buffer[i].scheduler->core); seq_printf(m, "\t\t dma_buf = %p, iova = 0x%lx\n", dump_buffer->dma_buffer[i].dma_buf, (unsigned long)dump_buffer->dma_buffer[i].iova); @@ -271,7 +272,8 @@ static int rga_mm_session_show(struct seq_file *m, void *data) dump_buffer->virt_addr->size); for (i = 0; i < dump_buffer->dma_buffer_size; i++) { - seq_printf(m, "\t core %d:\n", dump_buffer->dma_buffer[i].core); + seq_printf(m, "\t core %d:\n", + dump_buffer->dma_buffer[i].scheduler->core); seq_printf(m, "\t\t iova = 0x%lx, sgt = %p, size = %ld\n", (unsigned long)dump_buffer->dma_buffer[i].iova, dump_buffer->dma_buffer[i].sgt, diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c index d6eb80c76d8e..728192602dca 100644 --- a/drivers/video/rockchip/rga3/rga_job.c +++ b/drivers/video/rockchip/rga3/rga_job.c @@ -182,7 +182,7 @@ static int rga_job_judgment_support_core(struct rga_job *job) mm_flag = (uint32_t)ret; if (~mm_flag & RGA_MEM_UNDER_4G) { - job->flags |= RGA_JOB_UNSUPPORT_RGA2; + job->flags |= RGA_JOB_UNSUPPORT_RGA_MMU; goto out_finish; } } @@ -195,7 +195,7 @@ static int rga_job_judgment_support_core(struct rga_job *job) mm_flag = (uint32_t)ret; if (~mm_flag & RGA_MEM_UNDER_4G) { - job->flags |= RGA_JOB_UNSUPPORT_RGA2; + job->flags |= RGA_JOB_UNSUPPORT_RGA_MMU; goto out_finish; } } @@ -208,7 +208,7 @@ static int rga_job_judgment_support_core(struct rga_job *job) mm_flag = (uint32_t)ret; if (~mm_flag & RGA_MEM_UNDER_4G) { - job->flags |= RGA_JOB_UNSUPPORT_RGA2; + job->flags |= RGA_JOB_UNSUPPORT_RGA_MMU; goto out_finish; } } diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index 9e7c48859ccc..b31f8160c19a 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -13,6 +13,7 @@ #include "rga_dma_buf.h" #include "rga_common.h" #include "rga2_mmu_info.h" +#include "rga_hw_config.h" #include "rga_debugger.h" static void rga_current_mm_read_lock(struct mm_struct *mm) @@ -362,9 +363,9 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { scheduler = job ? job->scheduler : rga_drvdata->scheduler[i]; - /* If the physical address is greater than 4G, there is no need to map RGA2. */ - if ((scheduler->core == RGA2_SCHEDULER_CORE0) && - (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G) && + /* If the physical address is greater than 4G, there is no need to map RAG_MMU. */ + if (scheduler->data->mmu == RGA_MMU && + ~internal_buffer->mm_flag & RGA_MEM_UNDER_4G && i != 0) continue; @@ -387,15 +388,17 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer, goto FREE_RGA_DMA_BUF; } - internal_buffer->dma_buffer[i].core = scheduler->core; - internal_buffer->dma_buffer[i].dev = scheduler->dev; + internal_buffer->dma_buffer[i].scheduler = scheduler; /* At first, check whether the physical address. */ if (i == 0) { if (rga_mm_check_range_sgt(internal_buffer->dma_buffer[0].sgt)) internal_buffer->mm_flag |= RGA_MEM_UNDER_4G; - /* If it's physically contiguous, there is no need to continue dma_map. */ + /* + * If it's physically contiguous, then the RGA_MMU can + * directly use the physical address. + */ if (rga_mm_check_contiguous_sgt(internal_buffer->dma_buffer[0].sgt)) { internal_buffer->mm_flag |= RGA_MEM_PHYSICAL_CONTIGUOUS; internal_buffer->phys_addr = @@ -404,12 +407,6 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer, pr_err("%s get physical address error!", __func__); goto FREE_RGA_DMA_BUF; } - - /* - * Since RGA3 currently does not support physical addresses, - * it is necessary to continue to map sgt. - */ - // TODO: iommu supports phys_addr } } } @@ -429,14 +426,19 @@ static void rga_mm_unmap_virt_addr(struct rga_internal_buffer *internal_buffer) WARN_ON(internal_buffer->dma_buffer == NULL || internal_buffer->virt_addr == NULL); for (i = 0; i < internal_buffer->dma_buffer_size; i++) - if (internal_buffer->dma_buffer[i].core == RGA3_SCHEDULER_CORE0 || - internal_buffer->dma_buffer[i].core == RGA3_SCHEDULER_CORE1) + switch (internal_buffer->dma_buffer[i].scheduler->data->mmu) { + case RGA_IOMMU: rga_iommu_unmap(&internal_buffer->dma_buffer[i]); - else if (internal_buffer->dma_buffer[i].core != 0) - dma_unmap_sg(internal_buffer->dma_buffer[i].dev, + break; + case RGA_MMU: + dma_unmap_sg(internal_buffer->dma_buffer[i].scheduler->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, DMA_BIDIRECTIONAL); + break; + default: + break; + } for (i = 0; i < internal_buffer->dma_buffer_size; i++) rga_free_sgt(&internal_buffer->dma_buffer[i]); @@ -489,9 +491,9 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { scheduler = job ? job->scheduler : rga_drvdata->scheduler[i]; - /* If the physical address is greater than 4G, there is no need to map RGA2. */ - if ((scheduler->core == RGA2_SCHEDULER_CORE0) && - (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G) && + /* If the physical address is greater than 4G, there is no need to map RGA_MMU. */ + if (scheduler->data->mmu == RGA_MMU && + ~internal_buffer->mm_flag & RGA_MEM_UNDER_4G && i != 0) continue; @@ -511,12 +513,8 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { scheduler = job ? job->scheduler : rga_drvdata->scheduler[i]; - if ((scheduler->core == RGA2_SCHEDULER_CORE0) && - (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G)) - continue; - - if (scheduler->core == RGA3_SCHEDULER_CORE0 || - scheduler->core == RGA3_SCHEDULER_CORE1) { + switch (scheduler->data->mmu) { + case RGA_IOMMU: ret = rga_iommu_map_sgt(internal_buffer->dma_buffer[i].sgt, internal_buffer->dma_buffer[i].size, &internal_buffer->dma_buffer[i], @@ -526,7 +524,11 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, __func__, scheduler->core); goto unmap_virt_addr; } - } else { + break; + case RGA_MMU: + if (~internal_buffer->mm_flag & RGA_MEM_UNDER_4G) + continue; + ret = dma_map_sg(scheduler->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, @@ -539,24 +541,33 @@ static int rga_mm_map_virt_addr(struct rga_external_buffer *external_buffer, ret = -EINVAL; goto unmap_virt_addr; } + break; + default: + pr_err("Current RGA mmu[%d] cannot support virtual address!\n", + scheduler->data->mmu); + goto free_sgt_and_dma_buffer; } - internal_buffer->dma_buffer[i].core = scheduler->core; - internal_buffer->dma_buffer[i].dev = scheduler->dev; + internal_buffer->dma_buffer[i].scheduler = scheduler; } return 0; unmap_virt_addr: for (i = 0; i < internal_buffer->dma_buffer_size; i++) - if (internal_buffer->dma_buffer[i].core == RGA3_SCHEDULER_CORE0 || - internal_buffer->dma_buffer[i].core == RGA3_SCHEDULER_CORE1) + switch (internal_buffer->dma_buffer[i].scheduler->data->mmu) { + case RGA_IOMMU: rga_iommu_unmap(&internal_buffer->dma_buffer[i]); - else if (internal_buffer->dma_buffer[i].core != 0) - dma_unmap_sg(internal_buffer->dma_buffer[i].dev, + break; + case RGA_MMU: + dma_unmap_sg(internal_buffer->dma_buffer[i].scheduler->dev, internal_buffer->dma_buffer[i].sgt->sgl, internal_buffer->dma_buffer[i].sgt->orig_nents, DMA_BIDIRECTIONAL); + break; + default: + break; + } free_sgt_and_dma_buffer: for (i = 0; i < internal_buffer->dma_buffer_size; i++) rga_free_sgt(&internal_buffer->dma_buffer[i]); @@ -577,12 +588,9 @@ static void rga_mm_unmap_phys_addr(struct rga_internal_buffer *internal_buffer) WARN_ON(internal_buffer->dma_buffer == NULL); - for (i = 0; i < internal_buffer->dma_buffer_size; i++) { - if (internal_buffer->dma_buffer[i].core == RGA2_SCHEDULER_CORE0) - continue; - - rga_iommu_unmap(&internal_buffer->dma_buffer[i]); - } + for (i = 0; i < internal_buffer->dma_buffer_size; i++) + if (internal_buffer->dma_buffer[i].scheduler->data->mmu == RGA_IOMMU) + rga_iommu_unmap(&internal_buffer->dma_buffer[i]); internal_buffer->phys_addr = 0; @@ -624,22 +632,19 @@ static int rga_mm_map_phys_addr(struct rga_external_buffer *external_buffer, for (i = 0; i < internal_buffer->dma_buffer_size; i++) { scheduler = job ? job->scheduler : rga_drvdata->scheduler[i]; - /* RGA_MMU can directly access physical addresses. */ - if (scheduler->core == RGA2_SCHEDULER_CORE0) - continue; - - ret = rga_iommu_map(internal_buffer->phys_addr, - internal_buffer->size, - &internal_buffer->dma_buffer[i], - scheduler->dev); - if (ret < 0) { - pr_err("%s core[%d] map phys_addr error!\n", - __func__, scheduler->core); - goto UNMAP_PHYS_ADDR; + if (scheduler->data->mmu == RGA_IOMMU) { + ret = rga_iommu_map(internal_buffer->phys_addr, + internal_buffer->size, + &internal_buffer->dma_buffer[i], + scheduler->dev); + if (ret < 0) { + pr_err("%s core[%d] map phys_addr error!\n", + __func__, scheduler->core); + goto UNMAP_PHYS_ADDR; + } } - internal_buffer->dma_buffer[i].core = scheduler->core; - internal_buffer->dma_buffer[i].dev = scheduler->dev; + internal_buffer->dma_buffer[i].scheduler = scheduler; } return 0; @@ -852,7 +857,7 @@ dma_addr_t rga_mm_lookup_iova(struct rga_internal_buffer *buffer, int core) int i; for (i = 0; i < buffer->dma_buffer_size; i++) - if (buffer->dma_buffer[i].core == core) + if (buffer->dma_buffer[i].scheduler->core == core) return buffer->dma_buffer[i].iova + buffer->dma_buffer[i].offset; return 0; @@ -863,7 +868,7 @@ struct sg_table *rga_mm_lookup_sgt(struct rga_internal_buffer *buffer, int core) int i; for (i = 0; i < buffer->dma_buffer_size; i++) - if (buffer->dma_buffer[i].core == core) + if (buffer->dma_buffer[i].scheduler->core == core) return buffer->dma_buffer[i].sgt; return NULL; @@ -883,7 +888,7 @@ void rga_mm_dump_buffer(struct rga_internal_buffer *dump_buffer) pr_info("dma_buffer:\n"); for (i = 0; i < dump_buffer->dma_buffer_size; i++) { pr_info("core %d: dma_buf = %p, iova = 0x%lx\n", - dump_buffer->dma_buffer[i].core, + dump_buffer->dma_buffer[i].scheduler->core, dump_buffer->dma_buffer[i].dma_buf, (unsigned long)dump_buffer->dma_buffer[i].iova); } @@ -900,7 +905,7 @@ void rga_mm_dump_buffer(struct rga_internal_buffer *dump_buffer) for (i = 0; i < dump_buffer->dma_buffer_size; i++) { pr_info("core %d: iova = 0x%lx, sgt = %p, size = %ld\n", - dump_buffer->dma_buffer[i].core, + dump_buffer->dma_buffer[i].scheduler->core, (unsigned long)dump_buffer->dma_buffer[i].iova, dump_buffer->dma_buffer[i].sgt, dump_buffer->dma_buffer[i].size); @@ -934,13 +939,13 @@ void rga_mm_dump_info(struct rga_mm *mm_session) } } -static bool rga_mm_is_need_mmu(int core, struct rga_internal_buffer *buffer) +static bool rga_mm_is_need_mmu(struct rga_job *job, struct rga_internal_buffer *buffer) { - if (buffer == NULL) + if (buffer == NULL || job == NULL || job->scheduler == NULL) return false; if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS && - core == RGA2_SCHEDULER_CORE0) + job->scheduler->data->mmu == RGA_MMU) return false; else if (buffer->mm_flag & RGA_MEM_NEED_USE_IOMMU) return true; @@ -956,10 +961,10 @@ static int rga_mm_set_mmu_flag(struct rga_job *job) int dst_mmu_en; int els_mmu_en; - src_mmu_en = rga_mm_is_need_mmu(job->core, job->src_buffer.addr); - src1_mmu_en = rga_mm_is_need_mmu(job->core, job->src1_buffer.addr); - dst_mmu_en = rga_mm_is_need_mmu(job->core, job->dst_buffer.addr); - els_mmu_en = rga_mm_is_need_mmu(job->core, job->els_buffer.addr); + src_mmu_en = rga_mm_is_need_mmu(job, job->src_buffer.addr); + src1_mmu_en = rga_mm_is_need_mmu(job, job->src1_buffer.addr); + dst_mmu_en = rga_mm_is_need_mmu(job, job->dst_buffer.addr); + els_mmu_en = rga_mm_is_need_mmu(job, job->els_buffer.addr); mmu_info = &job->rga_command_base.mmu_info; memset(mmu_info, 0x0, sizeof(*mmu_info)); @@ -1226,52 +1231,38 @@ static int rga_mm_get_buffer_info(struct rga_job *job, { uint64_t addr; - switch (internal_buffer->type) { - case RGA_DMA_BUFFER: - case RGA_DMA_BUFFER_PTR: - if (job->core == RGA3_SCHEDULER_CORE0 || - job->core == RGA3_SCHEDULER_CORE1) { - addr = rga_mm_lookup_iova(internal_buffer, job->core); - if (addr == 0) { - pr_err("core[%d] lookup dma_buf iova error!\n", job->core); - return -EINVAL; - } - } else if (job->core == RGA2_SCHEDULER_CORE0 && - internal_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { - addr = internal_buffer->phys_addr; - } else { - addr = 0; - } - - break; - case RGA_VIRTUAL_ADDRESS: - if (job->core == RGA3_SCHEDULER_CORE0 || - job->core == RGA3_SCHEDULER_CORE1) { - addr = rga_mm_lookup_iova(internal_buffer, job->core); - if (addr == 0) { - pr_err("core[%d] lookup virt_addr iova error!\n", job->core); - return -EINVAL; - } - } else { - addr = internal_buffer->virt_addr->addr; - } - - break; - case RGA_PHYSICAL_ADDRESS: - if (job->core == RGA3_SCHEDULER_CORE0 || - job->core == RGA3_SCHEDULER_CORE1) { - addr = rga_mm_lookup_iova(internal_buffer, job->core); - if (addr == 0) { - pr_err("core[%d] lookup phys_addr iova error!\n", job->core); - return -EINVAL; - } - } else { - addr = internal_buffer->phys_addr; + switch (job->scheduler->data->mmu) { + case RGA_IOMMU: + addr = rga_mm_lookup_iova(internal_buffer, job->core); + if (addr == 0) { + pr_err("core[%d] lookup buffer_type[0x%x] iova error!\n", + job->core, internal_buffer->type); + return -EINVAL; } break; + case RGA_MMU: default: - pr_err("Illegal external buffer!\n"); - return -EFAULT; + if (internal_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { + addr = internal_buffer->phys_addr; + break; + } + + switch (internal_buffer->type) { + case RGA_DMA_BUFFER: + case RGA_DMA_BUFFER_PTR: + addr = 0; + break; + case RGA_VIRTUAL_ADDRESS: + addr = internal_buffer->virt_addr->addr; + break; + case RGA_PHYSICAL_ADDRESS: + addr = internal_buffer->phys_addr; + break; + default: + pr_err("Illegal external buffer!\n"); + return -EFAULT; + } + break; } *channel_addr = addr; @@ -1403,8 +1394,8 @@ static int rga_mm_get_channel_handle_info(struct rga_mm *mm, rga_convert_addr(img, false); } - if (job->core == RGA2_SCHEDULER_CORE0 && - rga_mm_is_need_mmu(job->core, job_buf->addr)) { + if (job->scheduler->data->mmu == RGA_MMU && + rga_mm_is_need_mmu(job, job_buf->addr)) { ret = rga_mm_set_mmu_base(job, img, job_buf); if (ret < 0) { pr_err("Can't set RGA2 MMU_BASE from handle!\n"); @@ -1556,8 +1547,8 @@ static int rga_mm_map_channel_job_buffer(struct rga_job *job, job_buffer->addr = buffer; - if (job->core == RGA2_SCHEDULER_CORE0 && - rga_mm_is_need_mmu(job->core, job_buffer->addr)) { + if (job->scheduler->data->mmu == RGA_MMU && + rga_mm_is_need_mmu(job, job_buffer->addr)) { ret = rga_mm_set_mmu_base(job, img, job_buffer); if (ret < 0) { pr_err("Can't set RGA2 MMU_BASE!\n"); diff --git a/drivers/video/rockchip/rga3/rga_policy.c b/drivers/video/rockchip/rga3/rga_policy.c index c85753524ac2..16564891e7d3 100644 --- a/drivers/video/rockchip/rga3/rga_policy.c +++ b/drivers/video/rockchip/rga3/rga_policy.c @@ -236,8 +236,8 @@ int rga_job_assign(struct rga_job *job) if (DEBUGGER_EN(MSG)) pr_info("start policy on core = %d", scheduler->core); - if (scheduler->core == RGA2_SCHEDULER_CORE0 && - job->flags & RGA_JOB_UNSUPPORT_RGA2) { + if (scheduler->data->mmu == RGA_MMU && + job->flags & RGA_JOB_UNSUPPORT_RGA_MMU) { if (DEBUGGER_EN(MSG)) pr_info("RGA2 only support under 4G memory!\n"); continue;