mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user