video: rockchip: rga3: mpi_job uses importbuffer

Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com>
Change-Id: I8170657fbab1da870b513f73b3e55bf80a870794
This commit is contained in:
Yu Qiaowei
2022-03-25 21:30:30 +08:00
committed by Tao Huang
parent af89acfb26
commit 66a65ee99d
7 changed files with 182 additions and 61 deletions

View File

@@ -73,7 +73,8 @@
enum rga_memory_type {
RGA_DMA_BUFFER = 0,
RGA_VIRTUAL_ADDRESS,
RGA_PHYSICAL_ADDRESS
RGA_PHYSICAL_ADDRESS,
RGA_DMA_BUFFER_PTR,
};
enum rga_scale_up_mode {
@@ -840,6 +841,7 @@ struct rga_mpi_job_t {
struct rga_video_frame_info *src;
struct rga_video_frame_info *pat;
struct rga_video_frame_info *dst;
struct rga_video_frame_info *output;
int ctx_id;
};

View File

@@ -24,9 +24,11 @@ int rga_iommu_map_virt_addr(struct rga_memory_parm *memory_parm,
struct mm_struct *mm);
void rga_iommu_unmap_virt_addr(struct rga_dma_buffer *virt_addr);
int rga_dma_map_buf(struct dma_buf *dma_buf, struct rga_dma_buffer *rga_dma_buffer,
enum dma_data_direction dir, struct device *rga_dev);
int rga_dma_map_fd(int fd, struct rga_dma_buffer *rga_dma_buffer,
enum dma_data_direction dir, struct device *rga_dev);
void rga_dma_unmap_fd(struct rga_dma_buffer *rga_dma_buffer);
void rga_dma_unmap_buf(struct rga_dma_buffer *rga_dma_buffer);
int rga_dma_get_info(struct rga_job *job);
void rga_dma_put_info(struct rga_job *job);

View File

@@ -226,6 +226,7 @@ static int rga_mm_session_show(struct seq_file *m, void *data)
switch (dump_buffer->type) {
case RGA_DMA_BUFFER:
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);

View File

@@ -737,6 +737,53 @@ static int rga_dma_memory_check(struct rga_dma_buffer_t *rga_dma_buffer,
return ret;
}
int rga_dma_map_buf(struct dma_buf *dma_buf, struct rga_dma_buffer *rga_dma_buffer,
enum dma_data_direction dir, struct device *rga_dev)
{
struct dma_buf_attachment *attach = NULL;
struct sg_table *sgt = NULL;
int ret = 0;
if (dma_buf != NULL) {
get_dma_buf(dma_buf);
} else {
pr_err("dma_buf is Invalid[%p]\n", dma_buf);
return -EINVAL;
}
attach = dma_buf_attach(dma_buf, rga_dev);
if (IS_ERR(attach)) {
pr_err("Failed to attach dma_buf\n");
ret = -EINVAL;
goto err_get_attach;
}
sgt = dma_buf_map_attachment(attach, dir);
if (IS_ERR(sgt)) {
pr_err("Failed to map src attachment\n");
ret = -EINVAL;
goto err_get_sgt;
}
rga_dma_buffer->dma_buf = dma_buf;
rga_dma_buffer->attach = attach;
rga_dma_buffer->sgt = sgt;
rga_dma_buffer->iova = sg_dma_address(sgt->sgl);
rga_dma_buffer->size = sg_dma_len(sgt->sgl);
rga_dma_buffer->dir = dir;
return ret;
err_get_sgt:
if (attach)
dma_buf_detach(dma_buf, attach);
err_get_attach:
if (dma_buf)
dma_buf_put(dma_buf);
return ret;
}
int rga_dma_map_fd(int fd, struct rga_dma_buffer *rga_dma_buffer,
enum dma_data_direction dir, struct device *rga_dev)
{
@@ -785,7 +832,7 @@ err_get_attach:
return ret;
}
void rga_dma_unmap_fd(struct rga_dma_buffer *rga_dma_buffer)
void rga_dma_unmap_buf(struct rga_dma_buffer *rga_dma_buffer)
{
if (rga_dma_buffer->attach && rga_dma_buffer->sgt)
dma_buf_unmap_attachment(rga_dma_buffer->attach,

View File

@@ -41,16 +41,33 @@ static const struct rga_backend_ops rga2_ops = {
.soft_reset = rga2_soft_reset
};
static int rga_mpi_set_channel_info(uint32_t flags_mask, uint32_t flags,
struct rga_video_frame_info *mpi_frame,
struct rga_img_info_t *channel_info,
struct rga_img_info_t *cache_info)
static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, struct rga_img_info_t *channel_info)
{
struct rga_external_buffer buffer;
buffer.memory = (unsigned long)dma_buf;
buffer.type = RGA_DMA_BUFFER_PTR;
buffer.memory_parm.width = channel_info->vir_w;
buffer.memory_parm.height = channel_info->vir_h;
buffer.memory_parm.format = channel_info->format;
buffer.handle = rga_mm_import_buffer(&buffer);
if (buffer.handle == 0) {
pr_err("can not import dma_buf %p\n", dma_buf);
return -EFAULT;
}
channel_info->yrgb_addr = buffer.handle;
return 0;
}
static void rga_mpi_set_channel_info(uint32_t flags_mask, uint32_t flags,
struct rga_video_frame_info *mpi_frame,
struct rga_img_info_t *channel_info,
struct rga_img_info_t *cache_info)
{
uint32_t fix_enable_flag, cache_info_flag;
if (mpi_frame == NULL)
return -EFAULT;
switch (flags_mask) {
case RGA_CONTEXT_SRC_MASK:
fix_enable_flag = RGA_CONTEXT_SRC_FIX_ENABLE;
@@ -65,7 +82,7 @@ static int rga_mpi_set_channel_info(uint32_t flags_mask, uint32_t flags,
cache_info_flag = RGA_CONTEXT_DST_CACHE_INFO;
break;
default:
return -EFAULT;
return;
}
if (flags & fix_enable_flag) {
@@ -91,8 +108,6 @@ static int rga_mpi_set_channel_info(uint32_t flags_mask, uint32_t flags,
}
}
return 0;
}
int rga_mpi_commit(struct rga_mpi_job_t *mpi_job)
@@ -114,8 +129,8 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job)
spin_lock_irqsave(&ctx->lock, flags);
ctx->sync_mode = RGA_BLIT_SYNC;
/* TODO: batch mode need mpi async mode */
ctx->sync_mode = RGA_BLIT_SYNC;
ctx->use_batch_mode = false;
cached_cmd = ctx->cached_cmd;
@@ -123,37 +138,58 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job)
spin_unlock_irqrestore(&ctx->lock, flags);
ret = rga_mpi_set_channel_info(RGA_CONTEXT_SRC_MASK,
ctx->mpi_config_flags,
mpi_job->src,
&mpi_cmd.src,
&cached_cmd->src);
if (ret < 0) {
pr_err("src channel set info error!\n");
return ret;
/* set channel info */
if ((mpi_job->src != NULL) && (ctx->flags & RGA_CONTEXT_SRC_MASK))
rga_mpi_set_channel_info(RGA_CONTEXT_SRC_MASK,
ctx->flags,
mpi_job->src,
&mpi_cmd.src,
&cached_cmd->src);
if ((mpi_job->pat != NULL) && (ctx->flags & RGA_CONTEXT_PAT_MASK))
rga_mpi_set_channel_info(RGA_CONTEXT_PAT_MASK,
ctx->flags,
mpi_job->pat,
&mpi_cmd.pat,
&cached_cmd->pat);
if ((mpi_job->dst != NULL) && (ctx->flags & RGA_CONTEXT_DST_MASK))
rga_mpi_set_channel_info(RGA_CONTEXT_DST_MASK,
ctx->flags,
mpi_job->dst,
&mpi_cmd.dst,
&cached_cmd->dst);
/* set buffer handle */
if (mpi_job->dma_buf_src0 != NULL) {
ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src0, &mpi_cmd.src);
if (ret < 0) {
pr_err("src channel set buffer handle failed!\n");
return ret;
}
}
ret = rga_mpi_set_channel_info(RGA_CONTEXT_PAT_MASK,
ctx->mpi_config_flags,
mpi_job->pat,
&mpi_cmd.pat,
&cached_cmd->pat);
if (ret < 0) {
pr_err("src1 channel set info error!\n");
return ret;
if (mpi_job->dma_buf_src1 != NULL) {
ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_src1, &mpi_cmd.pat);
if (ret < 0) {
pr_err("src1 channel set buffer handle failed!\n");
return ret;
}
}
ret = rga_mpi_set_channel_info(RGA_CONTEXT_DST_MASK,
ctx->mpi_config_flags,
mpi_job->dst,
&mpi_cmd.dst,
&cached_cmd->dst);
if (ret < 0) {
pr_err("dst channel set info error!\n");
return ret;
if (mpi_job->dma_buf_dst != NULL) {
ret = rga_mpi_set_channel_buffer(mpi_job->dma_buf_dst, &mpi_cmd.dst);
if (ret < 0) {
pr_err("dst channel set buffer handle failed!\n");
return ret;
}
}
mpi_cmd.handle_flag = 1;
mpi_cmd.mmu_info.mmu_en = 0;
mpi_cmd.mmu_info.mmu_flag = 0;
/* commit job */
if (ctx->cmd_num > 1) {
pr_err("Currently ctx does not support multiple tasks!");
/* TODO */
@@ -176,16 +212,23 @@ int rga_mpi_commit(struct rga_mpi_job_t *mpi_job)
return ret;
}
if ((mpi_job->dma_buf_src0 != NULL) && (mpi_cmd.src.yrgb_addr > 0))
rga_mm_release_buffer(mpi_cmd.src.yrgb_addr);
if ((mpi_job->dma_buf_src1 != NULL) && (mpi_cmd.pat.yrgb_addr > 0))
rga_mm_release_buffer(mpi_cmd.pat.yrgb_addr);
if ((mpi_job->dma_buf_dst != NULL) && (mpi_cmd.dst.yrgb_addr > 0))
rga_mm_release_buffer(mpi_cmd.dst.yrgb_addr);
/* copy dst info to mpi job for next node */
if (mpi_job->dst != NULL) {
mpi_job->dst->x_offset = mpi_cmd.dst.x_offset;
mpi_job->dst->y_offset = mpi_cmd.dst.y_offset;
mpi_job->dst->width = mpi_cmd.dst.act_w;
mpi_job->dst->height = mpi_cmd.dst.act_h;
mpi_job->dst->vir_w = mpi_cmd.dst.vir_w;
mpi_job->dst->vir_h = mpi_cmd.dst.vir_h;
mpi_job->dst->rd_mode = mpi_cmd.dst.rd_mode;
mpi_job->dst->format = mpi_cmd.dst.format;
if (mpi_job->output != NULL) {
mpi_job->output->x_offset = mpi_cmd.dst.x_offset;
mpi_job->output->y_offset = mpi_cmd.dst.y_offset;
mpi_job->output->width = mpi_cmd.dst.act_w;
mpi_job->output->height = mpi_cmd.dst.act_h;
mpi_job->output->vir_w = mpi_cmd.dst.vir_w;
mpi_job->output->vir_h = mpi_cmd.dst.vir_h;
mpi_job->output->rd_mode = mpi_cmd.dst.rd_mode;
mpi_job->output->format = mpi_cmd.dst.format;
}
return ret;
@@ -358,8 +401,10 @@ static long rga_ioctl_import_buffer(unsigned long arg)
for (i = 0; i < buffer_pool.size; i++) {
ret = rga_mm_import_buffer(&external_buffer[i]);
if (ret < 0) {
pr_err("buffer[%d] mm import buffer failed!\n", i);
if (ret == 0) {
pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = 0x%x\n",
i, (unsigned long)external_buffer[i].memory,
external_buffer[i].type);
goto err_free_external_buffer;
}

View File

@@ -1113,9 +1113,6 @@ int rga_job_mpi_commit(struct rga_req *rga_command_base,
job->dma_buf_dst = mpi_job->dma_buf_dst;
}
/* Increments the reference count on the dma-buf */
rga_get_dma_buf(job);
job->ctx_id = ctx->id;
if (ctx->sync_mode == RGA_BLIT_ASYNC) {

View File

@@ -317,7 +317,7 @@ static void rga_mm_unmap_dma_buffer(struct rga_internal_buffer *internal_buffer)
int i;
for (i = 0; i < internal_buffer->dma_buffer_size; i++) {
rga_dma_unmap_fd(&internal_buffer->dma_buffer[i]);
rga_dma_unmap_buf(&internal_buffer->dma_buffer[i]);
if (i == 0 &&
internal_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS &&
@@ -351,10 +351,19 @@ static int rga_mm_map_dma_buffer(struct rga_external_buffer *external_buffer,
i != 0)
continue;
ret = rga_dma_map_fd((int)external_buffer->memory,
&internal_buffer->dma_buffer[i],
DMA_BIDIRECTIONAL,
rga_drvdata->rga_scheduler[i]->dev);
if (external_buffer->type == RGA_DMA_BUFFER)
ret = rga_dma_map_fd((int)external_buffer->memory,
&internal_buffer->dma_buffer[i],
DMA_BIDIRECTIONAL,
rga_drvdata->rga_scheduler[i]->dev);
else if (external_buffer->type == RGA_DMA_BUFFER_PTR)
ret = rga_dma_map_buf((struct dma_buf *)
u64_to_user_ptr(external_buffer->memory),
&internal_buffer->dma_buffer[i],
DMA_BIDIRECTIONAL,
rga_drvdata->rga_scheduler[i]->dev);
else
ret = -EFAULT;
if (ret < 0) {
pr_err("%s core[%d] map dma buffer error!\n",
__func__, rga_drvdata->rga_scheduler[0]->core);
@@ -535,6 +544,7 @@ static int rga_mm_unmap_buffer(struct rga_internal_buffer *internal_buffer)
{
switch (internal_buffer->type) {
case RGA_DMA_BUFFER:
case RGA_DMA_BUFFER_PTR:
rga_mm_unmap_dma_buffer(internal_buffer);
break;
case RGA_VIRTUAL_ADDRESS:
@@ -561,7 +571,8 @@ static int rga_mm_map_buffer(struct rga_external_buffer *external_buffer,
switch (external_buffer->type) {
case RGA_DMA_BUFFER:
internal_buffer->type = RGA_DMA_BUFFER;
case RGA_DMA_BUFFER_PTR:
internal_buffer->type = external_buffer->type;
ret = rga_mm_map_dma_buffer(external_buffer, internal_buffer);
if (ret < 0) {
@@ -669,6 +680,20 @@ rga_mm_lookup_external(struct rga_mm *mm_session,
}
break;
case RGA_DMA_BUFFER_PTR:
idr_for_each_entry(&mm_session->memory_idr, temp_buffer, id) {
if (temp_buffer->dma_buffer == NULL)
continue;
if ((unsigned long)temp_buffer->dma_buffer[0].dma_buf ==
external_buffer->memory) {
output_buffer = temp_buffer;
break;
}
}
break;
default:
pr_err("Illegal external buffer!\n");
return NULL;
@@ -742,6 +767,7 @@ void rga_mm_dump_info(struct rga_mm *mm_session)
switch (dump_buffer->type) {
case RGA_DMA_BUFFER:
case RGA_DMA_BUFFER_PTR:
pr_info("dma_buffer:\n");
for (i = 0; i < dump_buffer->dma_buffer_size; i++) {
pr_info("\t core %d:\n", dump_buffer->dma_buffer[i].core);
@@ -904,6 +930,7 @@ static int rga_mm_get_channel_handle_info(struct rga_mm *mm,
switch (internal_buffer->type) {
case RGA_DMA_BUFFER:
case RGA_DMA_BUFFER_PTR:
if (job->core == RGA3_SCHEDULER_CORE0 ||
job->core == RGA3_SCHEDULER_CORE1) {
img->yrgb_addr = rga_mm_lookup_iova(internal_buffer, job->core);
@@ -1071,7 +1098,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer)
mm = rga_drvdata->mm;
if (mm == NULL) {
pr_err("rga mm is null!\n");
return -EFAULT;
return 0;
}
mutex_lock(&mm->lock);
@@ -1091,7 +1118,7 @@ uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer)
pr_err("%s alloc internal_buffer error!\n", __func__);
mutex_unlock(&mm->lock);
return -ENOMEM;
return 0;
}
ret = rga_mm_map_buffer(external_buffer, internal_buffer);
@@ -1117,7 +1144,7 @@ FREE_INTERNAL_BUFFER:
mutex_unlock(&mm->lock);
kfree(internal_buffer);
return ret;
return 0;
}
int rga_mm_release_buffer(uint32_t handle)