[PATCH v7 5/6] media: mediatek: encoder: Add support for VCP encode process
Irui Wang
irui.wang at mediatek.com
Fri Jun 5 02:35:17 PDT 2026
Adapt the encoder driver to support VCP firmware interface.
Use platform data fw_type to identify VCP firmware and perform
VCP-specific operations:
- Allocate RC buffers using the VCP device
- Send shared memory address to VCP firmware
- Map the encoder VSI address to the CPU address space using the
VCP shared memory address.
Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
.../mediatek/vcodec/common/mtk_vcodec_fw.c | 6 +++++
.../mediatek/vcodec/common/mtk_vcodec_fw.h | 1 +
.../vcodec/common/mtk_vcodec_fw_priv.h | 1 +
.../vcodec/common/mtk_vcodec_fw_vcp.c | 6 +++++
.../vcodec/encoder/venc/venc_common_if.c | 22 ++++++++++++++-----
.../mediatek/vcodec/encoder/venc_vpu_if.c | 16 ++++++++++++--
6 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
index 9df64200d933..7619ccd1f538 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
@@ -90,3 +90,9 @@ int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
return fw->type;
}
EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
+
+struct device *mtk_vcodec_fw_get_dev(struct mtk_vcodec_fw *fw)
+{
+ return fw->ops->get_fw_dev(fw);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_dev);
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
index 142e2e87905c..8ff6fcc114e3 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
@@ -42,5 +42,6 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
void *buf, unsigned int len, unsigned int wait);
int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
int mtk_vcodec_fw_get_ipi(enum mtk_vcodec_fw_type type, int hw_id);
+struct device *mtk_vcodec_fw_get_dev(struct mtk_vcodec_fw *fw);
#endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
index 0a2a9b010244..710c83c871f4 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_priv.h
@@ -29,6 +29,7 @@ struct mtk_vcodec_fw_ops {
int (*ipi_send)(struct mtk_vcodec_fw *fw, int id, void *buf,
unsigned int len, unsigned int wait);
void (*release)(struct mtk_vcodec_fw *fw);
+ struct device *(*get_fw_dev)(struct mtk_vcodec_fw *fw);
};
#if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU)
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
index 061a61bda33f..72627fef0ac5 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
@@ -494,6 +494,11 @@ static void mtk_vcodec_vcp_release(struct mtk_vcodec_fw *fw)
fw->vcp->is_register_done = false;
}
+static struct device *mtk_vcodec_vcp_get_fw_dev(struct mtk_vcodec_fw *fw)
+{
+ return fw->vcp->vcp_device->dev;
+}
+
static const struct mtk_vcodec_fw_ops mtk_vcodec_vcp_msg = {
.load_firmware = mtk_vcodec_vcp_load_firmware,
.get_vdec_capa = mtk_vcodec_vcp_get_vdec_capa,
@@ -501,6 +506,7 @@ static const struct mtk_vcodec_fw_ops mtk_vcodec_vcp_msg = {
.ipi_register = mtk_vcodec_vcp_set_ipi_register,
.ipi_send = mtk_vcodec_vcp_ipi_send,
.release = mtk_vcodec_vcp_release,
+ .get_fw_dev = mtk_vcodec_vcp_get_fw_dev,
};
struct mtk_vcodec_fw *mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use fw_use)
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
index 0efb13aef8d6..5ee138f0b2e7 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_common_if.c
@@ -481,7 +481,11 @@ static void venc_free_rc_buf(struct venc_inst *inst,
int i;
struct device *dev;
- dev = &inst->ctx->dev->plat_dev->dev;
+ if (inst->ctx->dev->venc_pdata->fw_type == VCP)
+ dev = mtk_vcodec_fw_get_dev(inst->ctx->dev->fw_handler);
+ else
+ dev = &inst->ctx->dev->plat_dev->dev;
+
mtk_venc_mem_free(inst, dev, &bufs->rc_code);
for (i = 0; i < core_num; i++)
@@ -530,12 +534,18 @@ static int venc_alloc_rc_buf(struct venc_inst *inst,
struct device *dev;
void *tmp_va;
- dev = &inst->ctx->dev->plat_dev->dev;
- if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
- return -ENOMEM;
+ if (inst->ctx->dev->venc_pdata->fw_type == VCP) {
+ dev = mtk_vcodec_fw_get_dev(fw);
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
+ return -ENOMEM;
+ } else {
+ dev = &inst->ctx->dev->plat_dev->dev;
+ if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_code))
+ return -ENOMEM;
- tmp_va = mtk_vcodec_fw_map_dm_addr(fw, bufs->rc_code.pa);
- memcpy(bufs->rc_code.va, tmp_va, bufs->rc_code.size);
+ tmp_va = mtk_vcodec_fw_map_dm_addr(fw, bufs->rc_code.pa);
+ memcpy(bufs->rc_code.va, tmp_va, bufs->rc_code.size);
+ }
for (i = 0; i < core_num; i++) {
if (mtk_venc_mem_alloc(inst, dev, &bufs->rc_info[i]))
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
index 7772b8442ebc..1da9043fd4f6 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
@@ -8,16 +8,26 @@
#include "venc_ipi_msg.h"
#include "venc_vpu_if.h"
+#define VSI_OFFSET_MASK 0x0FFFFFFF
+
static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
{
const struct venc_vpu_ipi_msg_init_comm *msg = data;
struct mtk_vcodec_fw *fw = vpu->ctx->dev->fw_handler;
+ u64 pa_start, vsi_offset;
vpu->inst_addr = msg->init_ack.vpu_inst_addr;
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, vpu->inst_addr);
+
+ if (vpu->ctx->dev->venc_pdata->fw_type == VCP) {
+ pa_start = (u64)fw->vcp->iova_addr;
+ vsi_offset = (msg->vpu_vsi_addr & VSI_OFFSET_MASK) - (pa_start & VSI_OFFSET_MASK);
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, ENCODER_MEM) + vsi_offset;
+ } else {
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(fw, msg->vpu_vsi_addr);
+ }
/* Firmware version field value is unspecified on MT8173. */
- if (mtk_vcodec_fw_get_type(fw) == VPU)
+ if (vpu->ctx->dev->venc_pdata->fw_type == VPU)
return;
/* Check firmware version. */
@@ -155,6 +165,8 @@ int vpu_enc_init(struct venc_vpu_inst *vpu)
out.base.venc_inst = (unsigned long)vpu;
if (MTK_ENC_DRV_IS_COMM(vpu->ctx)) {
out.codec_type = vpu->ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
+ if (vpu->ctx->dev->venc_pdata->fw_type == VCP)
+ out.shared_iova = vpu->ctx->dev->fw_handler->vcp->iova_addr;
msg_size = sizeof(struct venc_ap_ipi_msg_init_comm);
} else {
msg_size = sizeof(struct venc_ap_ipi_msg_init);
--
2.45.2
More information about the linux-arm-kernel
mailing list