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 <cerf.yu@rock-chips.com>
Change-Id: Ibd1f33cd57178fac9fa04ea752459307b7304d39
This commit is contained in:
Yu Qiaowei
2022-06-29 17:37:14 +08:00
parent da1523cb4e
commit a9d7cb122c
6 changed files with 113 additions and 122 deletions

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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");

View File

@@ -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;