[PATCH v1 12/14] media: platform: mtk-mdp3: Reconfigure shared memory
roy-cw.yeh
roy-cw.yeh at mediatek.com
Sun Jan 16 21:52:52 PST 2022
From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>
MDP communicates with SCP through shared memory.
SCP is responsible for calculating information that MDP needed,
however SCP has poor performance.
In order to improve performance,
shared memory is reconfigured into three buffer
to make more logical sense.
The third buffer - path buffer
which allocated in scp before is used for scp calculation.
This buffer need to be clear when frame_change occurs,
but it costs lot of time for scp doing memset which decreases performance.
Thus we move this buffer to kernel,
do memset in ap side to accelerate frame processing.
Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
.../media/platform/mtk-mdp3/mtk-mdp3-vpu.c | 106 +++++++++---------
.../media/platform/mtk-mdp3/mtk-mdp3-vpu.h | 8 ++
2 files changed, 58 insertions(+), 56 deletions(-)
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
index 035fa3e55335..73da786b5270 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
@@ -10,7 +10,7 @@
#include "mtk-mdp3-core.h"
#define MDP_VPU_MESSAGE_TIMEOUT 500U
-#define vpu_alloc_size 0x7F8000
+#define MDP_VPU_PATH_SIZE 0x78000
static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
{
@@ -19,23 +19,46 @@ static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu)
{
- if (vpu->work && vpu->work_addr)
- return 0;
+ vpu->work = dma_alloc_wc(scp_get_device(vpu->scp), vpu->work_size,
+ &vpu->work_addr, GFP_KERNEL);
+ if (!vpu->work)
+ goto err_return;
- vpu->work = dma_alloc_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
- &vpu->work_addr, GFP_KERNEL);
+ vpu->config = dma_alloc_wc(scp_get_device(vpu->scp), vpu->config_size,
+ &vpu->config_addr, GFP_KERNEL);
+ if (!vpu->config)
+ goto err_free_work;
- if (!vpu->work)
- return -ENOMEM;
- else
- return 0;
+ vpu->path = dma_alloc_wc(scp_get_device(vpu->scp), vpu->path_size,
+ &vpu->path_addr, GFP_KERNEL);
+ if (!vpu->path)
+ goto err_free_config;
+
+ return 0;
+
+err_free_config:
+ dma_free_wc(scp_get_device(vpu->scp), vpu->config_size,
+ vpu->config, vpu->config_addr);
+err_free_work:
+ dma_free_wc(scp_get_device(vpu->scp), vpu->work_size,
+ vpu->work, vpu->work_addr);
+err_return:
+ return -ENOMEM;
}
void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu)
{
if (vpu->work && vpu->work_addr)
- dma_free_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
- vpu->work, vpu->work_addr);
+ dma_free_wc(scp_get_device(vpu->scp), vpu->work_size,
+ vpu->work, vpu->work_addr);
+
+ if (vpu->config && vpu->config_addr)
+ dma_free_wc(scp_get_device(vpu->scp), vpu->config_size,
+ vpu->config, vpu->config_addr);
+
+ if (vpu->path && vpu->path_addr)
+ dma_free_wc(scp_get_device(vpu->scp), vpu->path_size,
+ vpu->path, vpu->path_addr);
}
static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len,
@@ -156,9 +179,6 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
struct mdp_ipi_init_msg msg = {
.drv_data = (unsigned long)vpu,
};
- size_t mem_size;
- phys_addr_t pool;
- const size_t pool_size = sizeof(struct mdp_config_pool);
struct mdp_dev *mdp = vpu_to_mdp(vpu);
int err;
@@ -171,33 +191,20 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
goto err_work_size;
/* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */
- mem_size = vpu_alloc_size;
- if (mdp_vpu_shared_mem_alloc(vpu)) {
+ vpu->config_size = MDP_DUAL_PIPE * sizeof(struct img_config);
+ vpu->path_size = MDP_VPU_PATH_SIZE;
+ err = mdp_vpu_shared_mem_alloc(vpu);
+ if (err) {
dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
goto err_mem_alloc;
}
- pool = ALIGN((uintptr_t)vpu->work + vpu->work_size, 8);
- if (pool + pool_size - (uintptr_t)vpu->work > mem_size) {
- dev_err(&mdp->pdev->dev,
- "VPU memory insufficient: %zx + %zx > %zx",
- vpu->work_size, pool_size, mem_size);
- err = -ENOMEM;
- goto err_mem_size;
- }
-
- dev_dbg(&mdp->pdev->dev,
- "VPU work:%pK pa:%pad sz:%zx pool:%pa sz:%zx (mem sz:%zx)",
- vpu->work, &vpu->work_addr, vpu->work_size,
- &pool, pool_size, mem_size);
- vpu->pool = (struct mdp_config_pool *)(uintptr_t)pool;
msg.work_addr = vpu->work_addr;
msg.work_size = vpu->work_size;
err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
if (err)
goto err_work_size;
- memset(vpu->pool, 0, sizeof(*vpu->pool));
return 0;
err_work_size:
@@ -210,7 +217,6 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
break;
}
return err;
-err_mem_size:
err_mem_alloc:
return err;
}
@@ -233,11 +239,8 @@ static struct img_config *mdp_config_get(struct mdp_vpu_dev *vpu,
if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
return ERR_PTR(-EINVAL);
- mutex_lock(vpu->lock);
- vpu->pool->cfg_count[id]++;
- config = &vpu->pool->configs[id];
- *addr = vpu->work_addr + ((uintptr_t)config - (uintptr_t)vpu->work);
- mutex_unlock(vpu->lock);
+ config = vpu->config;
+ *addr = vpu->config_addr;
return config;
}
@@ -250,14 +253,7 @@ static int mdp_config_put(struct mdp_vpu_dev *vpu,
if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
return -EINVAL;
- if (vpu->lock)
- mutex_lock(vpu->lock);
- if (!vpu->pool->cfg_count[id] || config != &vpu->pool->configs[id])
- err = -EINVAL;
- else
- vpu->pool->cfg_count[id]--;
- if (vpu->lock)
- mutex_unlock(vpu->lock);
+
return err;
}
@@ -288,25 +284,23 @@ int mdp_vpu_ctx_deinit(struct mdp_vpu_ctx *ctx)
int mdp_vpu_process(struct mdp_vpu_ctx *ctx, struct img_ipi_frameparam *param)
{
- struct mdp_vpu_dev *vpu = ctx->vpu_dev;
- struct mdp_dev *mdp = vpu_to_mdp(vpu);
struct img_sw_addr addr;
- if (!ctx->vpu_dev->work || !ctx->vpu_dev->work_addr) {
- if (mdp_vpu_shared_mem_alloc(vpu)) {
- dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
- return -ENOMEM;
- }
- }
memset((void *)ctx->vpu_dev->work, 0, ctx->vpu_dev->work_size);
- memset(ctx->config, 0, sizeof(*ctx->config));
- param->config_data.va = (unsigned long)ctx->config;
+
+ if (param->frame_change)
+ memset((void *)ctx->vpu_dev->path, 0, ctx->vpu_dev->path_size);
+ param->self_data.pa = ctx->vpu_dev->path_addr;
+ param->self_data.va = (u64)ctx->vpu_dev->path;
+
+ memset(ctx->config, 0, ctx->vpu_dev->config_size);
+ param->config_data.va = (u64)ctx->config;
param->config_data.pa = ctx->inst_addr;
param->drv_data = (unsigned long)ctx;
memcpy((void *)ctx->vpu_dev->work, param, sizeof(*param));
addr.pa = ctx->vpu_dev->work_addr;
- addr.va = (uintptr_t)ctx->vpu_dev->work;
+ addr.va = (u64)ctx->vpu_dev->work;
return mdp_vpu_sendmsg(ctx->vpu_dev, SCP_IPI_MDP_FRAME,
&addr, sizeof(addr));
}
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
index 3140d2925a1a..597589c73266 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
@@ -58,6 +58,14 @@ struct mdp_vpu_dev {
size_t work_size;
struct mdp_config_pool *pool;
u32 status;
+
+ void *config;
+ dma_addr_t config_addr;
+ size_t config_size;
+
+ void *path;
+ dma_addr_t path_addr;
+ size_t path_size;
};
struct mdp_vpu_ctx {
--
2.18.0
More information about the Linux-mediatek
mailing list