* [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-19 9:01 ` Krzysztof Kozlowski
2025-08-15 8:52 ` [PATCH v2 02/14] media: mediatek: vcodec: add decoder compatible to support mt8196 Yunfei Dong
` (12 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Add decoder document in dt-bindings yaml file for mt8196 platform.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../bindings/media/mediatek,vcodec-subdev-decoder.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index bf8082d87ac0..74e1d88d3056 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -76,6 +76,7 @@ properties:
- mediatek,mt8186-vcodec-dec
- mediatek,mt8188-vcodec-dec
- mediatek,mt8195-vcodec-dec
+ - mediatek,mt8196-vcodec-dec
reg:
minItems: 1
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196
2025-08-15 8:52 ` [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196 Yunfei Dong
@ 2025-08-19 9:01 ` Krzysztof Kozlowski
2025-08-19 9:05 ` Krzysztof Kozlowski
0 siblings, 1 reply; 17+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-19 9:01 UTC (permalink / raw)
To: Yunfei Dong
Cc: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida, Hsin-Yi Wang,
Fritz Koenig, Daniel Vetter, Steve Cho, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
On Fri, Aug 15, 2025 at 04:52:14PM +0800, Yunfei Dong wrote:
> Add decoder document in dt-bindings yaml file for mt8196 platform.
Nothing improved.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196
2025-08-19 9:01 ` Krzysztof Kozlowski
@ 2025-08-19 9:05 ` Krzysztof Kozlowski
0 siblings, 0 replies; 17+ messages in thread
From: Krzysztof Kozlowski @ 2025-08-19 9:05 UTC (permalink / raw)
To: Yunfei Dong
Cc: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida, Hsin-Yi Wang,
Fritz Koenig, Daniel Vetter, Steve Cho, linux-media, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek,
Project_Global_Chrome_Upstream_Group
On 19/08/2025 11:01, Krzysztof Kozlowski wrote:
> On Fri, Aug 15, 2025 at 04:52:14PM +0800, Yunfei Dong wrote:
>> Add decoder document in dt-bindings yaml file for mt8196 platform.
>
> Nothing improved.
Although maybe I am mixing patchsets, but all other comments apply here
as well. Anyway, you did not bother to cc maintainers, so I will
actually ignore patchset as requested.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 02/14] media: mediatek: vcodec: add decoder compatible to support mt8196
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196 Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 03/14] media: mediatek: vcodec: add driver to support vcp Yunfei Dong
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
MT8196 is lat single core architecture. Support its compatible and
use `mtk_lat_sig_core_pdata` to initialize platform data.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 6 ++++++
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index 9247d92d431d..fa609343c168 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -346,6 +346,8 @@ static void mtk_vcodec_dec_get_chip_name(struct mtk_vcodec_dec_dev *vdec_dev)
vdec_dev->chip_name = MTK_VDEC_MT8186;
else if (of_device_is_compatible(dev->of_node, "mediatek,mt8188-vcodec-dec"))
vdec_dev->chip_name = MTK_VDEC_MT8188;
+ else if (of_device_is_compatible(dev->of_node, "mediatek,mt8196-vcodec-dec"))
+ vdec_dev->chip_name = MTK_VDEC_MT8196;
else
vdec_dev->chip_name = MTK_VDEC_INVAL;
}
@@ -559,6 +561,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
.compatible = "mediatek,mt8188-vcodec-dec",
.data = &mtk_lat_sig_core_pdata,
},
+ {
+ .compatible = "mediatek,mt8196-vcodec-dec",
+ .data = &mtk_lat_sig_core_pdata,
+ },
{},
};
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
index aececca7ecf8..6bdde600a167 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
@@ -27,6 +27,7 @@ enum mtk_vcodec_dec_chip_name {
MTK_VDEC_MT8188 = 8188,
MTK_VDEC_MT8192 = 8192,
MTK_VDEC_MT8195 = 8195,
+ MTK_VDEC_MT8196 = 8196,
};
/*
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 03/14] media: mediatek: vcodec: add driver to support vcp
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 01/14] dt-bindings: media: mediatek: vcodec: add decoder dt-bindings for mt8196 Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 02/14] media: mediatek: vcodec: add decoder compatible to support mt8196 Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 04/14] media: mediatek: vcodec: add driver to support vcp encoder Yunfei Dong
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The processor is changed from scp to vcp in mt8196 platform.
Adding new firmware interface to communicate kernel with vcp
for the communication method is changed.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../media/platform/mediatek/vcodec/Kconfig | 4 +
.../platform/mediatek/vcodec/common/Makefile | 4 +
.../mediatek/vcodec/common/mtk_vcodec_fw.c | 3 +
.../mediatek/vcodec/common/mtk_vcodec_fw.h | 1 +
.../vcodec/common/mtk_vcodec_fw_priv.h | 12 +
.../vcodec/common/mtk_vcodec_fw_vcp.c | 449 ++++++++++++++++++
.../vcodec/common/mtk_vcodec_fw_vcp.h | 137 ++++++
include/linux/remoteproc/mtk_vcp_public.h | 2 +-
8 files changed, 611 insertions(+), 1 deletion(-)
create mode 100644 drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
create mode 100644 drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig b/drivers/media/platform/mediatek/vcodec/Kconfig
index bc8292232530..d23dad5c78ce 100644
--- a/drivers/media/platform/mediatek/vcodec/Kconfig
+++ b/drivers/media/platform/mediatek/vcodec/Kconfig
@@ -1,4 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
+config VIDEO_MEDIATEK_VCODEC_VCP
+ bool
+
config VIDEO_MEDIATEK_VCODEC_SCP
bool
@@ -21,6 +24,7 @@ config VIDEO_MEDIATEK_VCODEC
select V4L2_MEM2MEM_DEV
select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU
select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP
+ select VIDEO_MEDIATEK_VCODEC_VCP if MTK_VCP_RPROC
select V4L2_H264
select V4L2_VP9
select MEDIA_CONTROLLER
diff --git a/drivers/media/platform/mediatek/vcodec/common/Makefile b/drivers/media/platform/mediatek/vcodec/common/Makefile
index d0479914dfb3..2f68692e8c98 100644
--- a/drivers/media/platform/mediatek/vcodec/common/Makefile
+++ b/drivers/media/platform/mediatek/vcodec/common/Makefile
@@ -14,6 +14,10 @@ ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP),)
mtk-vcodec-common-y += mtk_vcodec_fw_scp.o
endif
+ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_VCP),)
+mtk-vcodec-common-y += mtk_vcodec_fw_vcp.o
+endif
+
ifneq ($(CONFIG_DEBUG_FS),)
obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dbgfs.o
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 08949b08fbc6..fc547afa4ebf 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
@@ -3,6 +3,7 @@
#include "../decoder/mtk_vcodec_dec_drv.h"
#include "../encoder/mtk_vcodec_enc_drv.h"
#include "mtk_vcodec_fw_priv.h"
+#include "mtk_vcodec_fw_vcp.h"
struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type type,
enum mtk_vcodec_fw_use fw_use)
@@ -19,6 +20,8 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type t
return mtk_vcodec_fw_vpu_init(priv, fw_use);
case SCP:
return mtk_vcodec_fw_scp_init(priv, fw_use);
+ case VCP:
+ return mtk_vcodec_fw_vcp_init(priv, fw_use);
default:
dev_err(&plat_dev->dev, "Invalid vcodec fw type");
return ERR_PTR(-EINVAL);
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 300363a40158..c1642fb09b42 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_enc_dev;
enum mtk_vcodec_fw_type {
VPU,
SCP,
+ VCP,
};
enum mtk_vcodec_fw_use {
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 99603accd82e..0a2a9b010244 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
@@ -4,6 +4,7 @@
#define _MTK_VCODEC_FW_PRIV_H_
#include "mtk_vcodec_fw.h"
+#include "mtk_vcodec_fw_vcp.h"
struct mtk_vcodec_dec_dev;
struct mtk_vcodec_enc_dev;
@@ -13,6 +14,7 @@ struct mtk_vcodec_fw {
const struct mtk_vcodec_fw_ops *ops;
struct platform_device *pdev;
struct mtk_scp *scp;
+ struct mtk_vcp *vcp;
enum mtk_vcodec_fw_use fw_use;
};
@@ -49,4 +51,14 @@ mtk_vcodec_fw_scp_init(void *priv, enum mtk_vcodec_fw_use fw_use)
}
#endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_SCP */
+#if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VCP)
+struct mtk_vcodec_fw *mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use fw_use);
+#else
+static inline struct mtk_vcodec_fw *
+mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use fw_use)
+{
+ return ERR_PTR(-ENODEV);
+}
+#endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_VCP */
+
#endif /* _MTK_VCODEC_FW_PRIV_H_ */
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
new file mode 100644
index 000000000000..227310c116c6
--- /dev/null
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.c
@@ -0,0 +1,449 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+#include <linux/iommu.h>
+#include <linux/remoteproc/mtk_vcp_public.h>
+#include <linux/firmware/mediatek/mtk-vcp-ipc.h>
+
+#include "../decoder/mtk_vcodec_dec_drv.h"
+#include "../decoder/vdec_ipi_msg.h"
+#include "mtk_vcodec_fw_priv.h"
+
+#define IPI_SEND_TIMEOUT_MS 100U
+#define IPI_TIMEOUT_MS 100U
+
+static void mtk_vcodec_vcp_ipi_lock(struct mtk_vcp *vcp, u32 ipi_id)
+{
+ if (WARN_ON(ipi_id >= VCP_IPI_MAX))
+ return;
+
+ mutex_lock(&vcp->ipi_desc[ipi_id].lock);
+}
+
+static void mtk_vcodec_vcp_ipi_unlock(struct mtk_vcp *vcp, u32 ipi_id)
+{
+ if (WARN_ON(ipi_id >= VCP_IPI_MAX))
+ return;
+
+ mutex_unlock(&vcp->ipi_desc[ipi_id].lock);
+}
+
+static int mtk_vcodec_vcp_notifier(struct notifier_block *nb, unsigned long event, void *ptr)
+{
+ struct mtk_vcp *vcp = container_of(nb, struct mtk_vcp, vcp_notify);
+
+ switch (event) {
+ case VCP_EVENT_SUSPEND:
+ case VCP_EVENT_STOP:
+ dev_dbg(&vcp->pdev->dev, "vcp notifier suspend");
+ break;
+ case VCP_EVENT_READY:
+ case VCP_EVENT_RESUME:
+ dev_dbg(&vcp->pdev->dev, "vcp notifier ready");
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void mtk_vcodec_vcp_free_msg_node(struct mtk_vcodec_fw *fw,
+ struct mtk_vcp_msg_node *msg_node)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&fw->vcp->msg_queue.lock, flags);
+ list_add(&msg_node->list, &fw->vcp->msg_queue.node_list);
+ spin_unlock_irqrestore(&fw->vcp->msg_queue.lock, flags);
+}
+
+static int mtk_vcodec_vcp_ipi_register(struct mtk_vcp *vcp, u32 ipi_id, vcp_ipi_handler_t handler,
+ void *priv)
+{
+ if (!vcp)
+ return -EPROBE_DEFER;
+
+ if (WARN_ON(ipi_id >= VCP_IPI_MAX) || WARN_ON(!handler))
+ return -EINVAL;
+
+ mtk_vcodec_vcp_ipi_lock(vcp, ipi_id);
+ vcp->ipi_desc[ipi_id].handler = handler;
+ vcp->ipi_desc[ipi_id].priv = priv;
+ mtk_vcodec_vcp_ipi_unlock(vcp, ipi_id);
+
+ return 0;
+}
+
+static int mtk_vcodec_vcp_msg_process_thread(void *arg)
+{
+ struct mtk_vcodec_fw *fw = arg;
+ struct vdec_vpu_ipi_ack *msg = NULL;
+ struct mtk_vcp_share_obj *obj;
+ struct mtk_vcp_msg_node *msg_node;
+ unsigned long flags;
+ vcp_ipi_handler_t handler;
+ int ret = 0;
+
+ do {
+ ret = wait_event_interruptible(fw->vcp->msg_queue.wq,
+ atomic_read(&fw->vcp->msg_queue.cnt) > 0);
+ if (ret < 0) {
+ dev_err(&fw->pdev->dev, "wait msg queue ack timeout %d %d\n",
+ ret, atomic_read(&fw->vcp->msg_queue.cnt));
+ continue;
+ }
+
+ spin_lock_irqsave(&fw->vcp->msg_queue.lock, flags);
+ msg_node = list_entry(fw->vcp->msg_queue.msg_list.next,
+ struct mtk_vcp_msg_node, list);
+ list_del(&msg_node->list);
+ atomic_dec(&fw->vcp->msg_queue.cnt);
+ spin_unlock_irqrestore(&fw->vcp->msg_queue.lock, flags);
+
+ obj = &msg_node->ipi_data;
+ msg = (struct vdec_vpu_ipi_ack *)obj->share_buf;
+
+ if (!msg->ap_inst_addr) {
+ dev_err(&fw->pdev->dev, "invalid message address\n");
+ mtk_vcodec_vcp_free_msg_node(fw, msg_node);
+ continue;
+ }
+
+ dev_dbg(&fw->pdev->dev, "msg ack id %d len %d msg_id 0x%x\n", obj->id, obj->len,
+ msg->msg_id);
+
+ mtk_vcodec_vcp_ipi_lock(fw->vcp, obj->id);
+ handler = fw->vcp->ipi_desc[obj->id].handler;
+ if (!handler) {
+ dev_err(&fw->pdev->dev, "invalid ack ipi handler id = %d\n", obj->id);
+ mtk_vcodec_vcp_ipi_unlock(fw->vcp, obj->id);
+ mtk_vcodec_vcp_free_msg_node(fw, msg_node);
+ return -EINVAL;
+ }
+
+ handler(msg, obj->len, fw->vcp->ipi_desc[obj->id].priv);
+ mtk_vcodec_vcp_ipi_unlock(fw->vcp, obj->id);
+
+ fw->vcp->msg_signaled[obj->id] = true;
+ wake_up(&fw->vcp->msg_wq[obj->id]);
+
+ mtk_vcodec_vcp_free_msg_node(fw, msg_node);
+ } while (!kthread_should_stop());
+
+ return ret;
+}
+
+static int mtk_vcodec_vcp_msg_ack_isr(unsigned int id, void *prdata, void *data, unsigned int len)
+{
+ struct mtk_vcodec_fw *fw = prdata;
+ struct mtk_vcp_msg_queue *msg_queue = &fw->vcp->msg_queue;
+ struct mtk_vcp_msg_node *msg_node;
+ struct vdec_vpu_ipi_ack *msg = NULL;
+ struct mtk_vcp_share_obj *obj = data;
+ unsigned long flags;
+
+ msg = (struct vdec_vpu_ipi_ack *)obj->share_buf;
+
+ spin_lock_irqsave(&msg_queue->lock, flags);
+ if (!list_empty(&msg_queue->node_list)) {
+ msg_node = list_entry(msg_queue->node_list.next, struct mtk_vcp_msg_node, list);
+
+ memcpy(&msg_node->ipi_data, obj, sizeof(*obj));
+ list_move_tail(&msg_node->list, &msg_queue->msg_list);
+ atomic_inc(&msg_queue->cnt);
+ spin_unlock_irqrestore(&msg_queue->lock, flags);
+
+ dev_dbg(&fw->pdev->dev, "push ipi_id %x msg_id %x, msg cnt %d\n",
+ obj->id, msg->msg_id, atomic_read(&msg_queue->cnt));
+
+ wake_up(&msg_queue->wq);
+ } else {
+ spin_unlock_irqrestore(&msg_queue->lock, flags);
+ dev_err(&fw->pdev->dev, "no free nodes in msg queue\n");
+ }
+
+ return 0;
+}
+
+static int mtk_vcodec_vcp_msg_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
+ unsigned int len, unsigned int wait)
+{
+ struct mtk_vcp *vcp = fw->vcp;
+ struct mtk_vcp_device *vcp_device = vcp->vcp_device;
+ struct mutex *msg_mutex = &vcp->ipi_mutex;
+ bool *msg_signaled = &vcp->msg_signaled[id];
+ wait_queue_head_t *msg_wq = &vcp->msg_wq[id];
+ int ret, ipi_size, feature_id, mailbox_id, retry_cnt = 0;
+ unsigned long timeout_jiffies = 0;
+ struct mtk_vcp_share_obj obj = {0};
+ unsigned int *data;
+
+ if (!vcp_device) {
+ dev_dbg(&fw->pdev->dev, "vcp device is null\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(msg_mutex);
+ feature_id = VDEC_FEATURE_ID;
+ mailbox_id = IPI_OUT_VDEC_1;
+
+ timeout_jiffies = jiffies + msecs_to_jiffies(VCP_SYNC_TIMEOUT_MS);
+ while (!vcp_device->ops->vcp_is_ready(feature_id)) {
+ if (time_after(jiffies, timeout_jiffies)) {
+ vcp->ipi_id_ack[id] = -EINVAL;
+ ret = -EINVAL;
+ goto error;
+ }
+ mdelay(1);
+ }
+
+ if (len > VCP_SHARE_BUF_SIZE) {
+ vcp->ipi_id_ack[id] = -EINVAL;
+ ret = -EINVAL;
+ goto error;
+ }
+
+ obj.id = id;
+ obj.len = len;
+ memcpy(obj.share_buf, buf, len);
+
+ ipi_size = ((sizeof(u32) * 2) + len + 3) / 4;
+ data = (unsigned int *)obj.share_buf;
+ dev_dbg(&fw->pdev->dev, "vcp send message: id %d len %d data 0x%x\n",
+ obj.id, obj.len, data[0]);
+
+ ret = mtk_vcp_ipc_send(vcp_get_ipidev(vcp_device), mailbox_id, &obj, ipi_size);
+ if (ret != IPI_ACTION_DONE) {
+ vcp->ipi_id_ack[id] = -EIO;
+ ret = -EIO;
+ goto error;
+ }
+
+wait_ack:
+ /* wait for VCP's ACK */
+ ret = wait_event_timeout(*msg_wq, *msg_signaled, msecs_to_jiffies(IPI_TIMEOUT_MS));
+ if (!ret || retry_cnt > 5) {
+ vcp->ipi_id_ack[id] = VCODEC_IPI_MSG_STATUS_FAIL;
+ dev_err(&fw->pdev->dev, "wait ipi ack timeout! %d %d\n", ret, vcp->ipi_id_ack[id]);
+ } else if (ret == -ERESTARTSYS) {
+ dev_err(&fw->pdev->dev, "wait ipi ack err (%d)\n", vcp->ipi_id_ack[id]);
+ retry_cnt++;
+ goto wait_ack;
+ } else if (ret < 0) {
+ dev_err(&fw->pdev->dev, "wait ipi ack fail ret %d %d\n", ret, vcp->ipi_id_ack[id]);
+ vcp->ipi_id_ack[id] = VCODEC_IPI_MSG_STATUS_FAIL;
+ }
+
+ dev_dbg(&fw->pdev->dev, "receive message: id %d len %d data 0x%x\n",
+ obj.id, obj.len, data[0]);
+
+ *msg_signaled = false;
+ mutex_unlock(msg_mutex);
+
+ return vcp->ipi_id_ack[id];
+
+error:
+ mutex_unlock(msg_mutex);
+ dev_err(&fw->pdev->dev, "send msg error type:%d msg:%d > %d ret:%d\n", fw->type, len,
+ VCP_SHARE_BUF_SIZE, ret);
+
+ return ret;
+}
+
+static int mtk_vcodec_vcp_get_vcp_device(struct mtk_vcodec_fw *fw)
+{
+ struct device *dev = &fw->pdev->dev;
+ int retry = 0, retry_cnt = 10000;
+ phandle vcp_phandle;
+
+ while (request_module("mtk-vcp")) {
+ if (++retry > retry_cnt) {
+ dev_err(dev, "failed to load mtk-vcp module");
+ return -ENODEV;
+ }
+ msleep(1);
+ }
+
+ if (of_property_read_u32(dev->of_node, "mediatek,vcp", &vcp_phandle)) {
+ dev_err(dev, "can't get vcp handle.\n");
+ return -ENODEV;
+ }
+
+ fw->vcp->vcp_device = mtk_vcp_get_by_phandle(vcp_phandle);
+ if (!fw->vcp->vcp_device) {
+ dev_err(dev, "get vcp device failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int mtk_vcodec_vcp_load_firmware(struct mtk_vcodec_fw *fw)
+{
+ struct mtk_vcp_device *vcp_device;
+ int ret, feature_id, mem_id, mailbox_id, ipi_id;
+
+ if (fw->vcp->is_init_done) {
+ dev_dbg(&fw->pdev->dev, "vcp has already been initialized done.\n");
+ return 0;
+ }
+
+ if (mtk_vcodec_vcp_get_vcp_device(fw) < 0) {
+ dev_err(&fw->pdev->dev, "vcp device is null.\n");
+ return -EINVAL;
+ }
+
+ vcp_device = fw->vcp->vcp_device;
+
+ feature_id = VDEC_FEATURE_ID;
+ mem_id = VDEC_MEM_ID;
+ mailbox_id = IPI_IN_VDEC_1;
+ ipi_id = VCP_IPI_LAT_DECODER;
+
+ ret = mtk_vcp_mbox_ipc_register(vcp_get_ipidev(vcp_device), mailbox_id,
+ mtk_vcodec_vcp_msg_ack_isr, fw, &fw->vcp->share_data);
+ if (ret) {
+ dev_dbg(&fw->pdev->dev, "ipi register fail %d %d %d %d\n", ret, feature_id,
+ mem_id, mailbox_id);
+ return -EINVAL;
+ }
+
+ fw->vcp->vcp_notify.notifier_call = mtk_vcodec_vcp_notifier;
+ fw->vcp->vcp_notify.priority = 1;
+ vcp_device->ops->vcp_register_notify(feature_id, &fw->vcp->vcp_notify);
+
+ fw->vcp->is_init_done = true;
+
+ mutex_init(&fw->vcp->ipi_desc[ipi_id].lock);
+ mutex_init(&fw->vcp->ipi_mutex);
+
+ kthread_run(mtk_vcodec_vcp_msg_process_thread, fw, "vcp_vdec_msq_thread");
+
+ fw->vcp->vsi_addr = vcp_device->ops->vcp_get_mem_virt(mem_id);
+ fw->vcp->vsi_core_addr = fw->vcp->vsi_addr + VCODEC_VSI_LEN;
+ fw->vcp->vsi_size = vcp_device->ops->vcp_get_mem_size(mem_id);
+ fw->vcp->iova_addr = vcp_device->ops->vcp_get_mem_iova(mem_id);
+
+ init_waitqueue_head(&fw->vcp->msg_wq[VCP_IPI_LAT_DECODER]);
+ init_waitqueue_head(&fw->vcp->msg_wq[VCP_IPI_CORE_DECODER]);
+
+ dev_dbg(&fw->pdev->dev, "vdec vcp init done => va: %p size:0x%x iova:%p.\n",
+ fw->vcp->vsi_addr, fw->vcp->vsi_size, &fw->vcp->iova_addr);
+
+ return 0;
+}
+
+static unsigned int mtk_vcodec_vcp_get_vdec_capa(struct mtk_vcodec_fw *fw)
+{
+ return MTK_VDEC_FORMAT_MM21 | MTK_VDEC_FORMAT_H264_SLICE | MTK_VDEC_FORMAT_VP9_FRAME |
+ MTK_VDEC_FORMAT_AV1_FRAME | MTK_VDEC_FORMAT_HEVC_FRAME |
+ MTK_VDEC_IS_SUPPORT_10BIT | MTK_VDEC_IS_SUPPORT_EXT;
+}
+
+static void *mtk_vcodec_vcp_dm_addr(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr)
+{
+ return NULL;
+}
+
+static int mtk_vcodec_vcp_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
+ mtk_vcodec_ipi_handler handler,
+ const char *name, void *priv)
+{
+ return mtk_vcodec_vcp_ipi_register(fw->vcp, id, handler, priv);
+}
+
+static int mtk_vcodec_vcp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
+ unsigned int len, unsigned int wait)
+{
+ struct mtk_vcp_device *vcp_device = fw->vcp->vcp_device;
+ struct device *dev = &fw->pdev->dev;
+ int ret;
+
+ if (!fw->vcp->vcp_device) {
+ dev_err(dev, "vcp device is null\n");
+ return -ENODEV;
+ }
+
+ ret = vcp_device->ops->vcp_register_feature(vcp_device, VDEC_FEATURE_ID);
+ if (ret < 0)
+ goto error;
+
+ ret = mtk_vcodec_vcp_msg_ipi_send(fw, id, buf, len, wait);
+ if (ret < 0)
+ goto error;
+
+ ret = vcp_device->ops->vcp_deregister_feature(vcp_device, VDEC_FEATURE_ID);
+ if (ret < 0)
+ goto error;
+
+ return ret;
+
+error:
+ dev_err(dev, "vcp ipi send fail ret:%d\n", ret);
+
+ return ret;
+}
+
+static void mtk_vcodec_vcp_release(struct mtk_vcodec_fw *fw)
+{
+}
+
+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,
+ .map_dm_addr = mtk_vcodec_vcp_dm_addr,
+ .ipi_register = mtk_vcodec_vcp_set_ipi_register,
+ .ipi_send = mtk_vcodec_vcp_ipi_send,
+ .release = mtk_vcodec_vcp_release,
+};
+
+struct mtk_vcodec_fw *mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use fw_use)
+{
+ struct mtk_vcp_msg_node *msg_node;
+ struct platform_device *plat_dev;
+ struct mtk_vcodec_fw *fw;
+ int i;
+
+ if (fw_use == DECODER) {
+ struct mtk_vcodec_dec_dev *dec_dev = priv;
+
+ plat_dev = dec_dev->plat_dev;
+ } else {
+ pr_err("Invalid fw_use %d (use a reasonable fw id here)\n", fw_use);
+ return ERR_PTR(-EINVAL);
+ }
+
+ fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+ if (!fw)
+ return ERR_PTR(-ENOMEM);
+
+ fw->type = VCP;
+ fw->pdev = plat_dev;
+ fw->fw_use = fw_use;
+ fw->ops = &mtk_vcodec_vcp_msg;
+ fw->vcp = devm_kzalloc(&plat_dev->dev, sizeof(*fw->vcp), GFP_KERNEL);
+ if (!fw->vcp)
+ return ERR_PTR(-ENOMEM);
+
+ INIT_LIST_HEAD(&fw->vcp->msg_queue.msg_list);
+ INIT_LIST_HEAD(&fw->vcp->msg_queue.node_list);
+ spin_lock_init(&fw->vcp->msg_queue.lock);
+ init_waitqueue_head(&fw->vcp->msg_queue.wq);
+ atomic_set(&fw->vcp->msg_queue.cnt, 0);
+ fw->vcp->pdev = plat_dev;
+
+ for (i = 0; i < VCP_MAX_MQ_NODE_CNT; i++) {
+ msg_node = devm_kzalloc(&plat_dev->dev, sizeof(*msg_node), GFP_KERNEL);
+ if (!msg_node)
+ return ERR_PTR(-ENOMEM);
+
+ list_add(&msg_node->list, &fw->vcp->msg_queue.node_list);
+ }
+
+ return fw;
+}
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
new file mode 100644
index 000000000000..40f5481d1889
--- /dev/null
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong@mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_FW_VCP_H_
+#define _MTK_VCODEC_FW_VCP_H_
+
+typedef void (*vcp_ipi_handler_t) (void *data, unsigned int len, void *priv);
+
+#define VCP_MAX_MQ_NODE_CNT 6
+#define VCP_SHARE_BUF_SIZE 64
+
+#define VCODEC_VSI_LEN (0x2000)
+
+/* enum mtk_vcp_ipi_index - index used to separate different hardware */
+enum mtk_vcp_ipi_index {
+ VCP_IPI_LAT_DECODER,
+ VCP_IPI_CORE_DECODER,
+ VCP_IPI_MAX,
+};
+
+/**
+ * struct mtk_vcp_msg_queue - process the vcp message between kernel with vcp
+ *
+ * @msg_list: store share buffer list which from vcp to kernel
+ * @wq: waitqueue that can be used to wait for vcp message
+ * @lock: protect msg list
+ * @cnt: the count of share obj in msg list
+ * @node_list: share obj list
+ */
+struct mtk_vcp_msg_queue {
+ struct list_head msg_list;
+ wait_queue_head_t wq;
+ spinlock_t lock;
+ atomic_t cnt;
+ struct list_head node_list;
+};
+
+/**
+ * struct mtk_vcp_ipi_desc - store the ack handler
+ *
+ * @lock: protect ack handler data
+ * @handler: calling this handler when kernel receive ack
+ * @priv: private data when calling handler to process
+ */
+struct mtk_vcp_ipi_desc {
+ struct mutex lock;
+ vcp_ipi_handler_t handler;
+ void *priv;
+};
+
+/**
+ * struct mtk_vcp_share_obj - share buffer used to send data to vcp
+ *
+ * @id: message index
+ * @len: message size
+ * @share_buf: message data
+ */
+struct mtk_vcp_share_obj {
+ unsigned int id;
+ unsigned int len;
+ unsigned char share_buf[VCP_SHARE_BUF_SIZE];
+};
+
+/* enum mtk_vcp_ipi_msg_status - the status when send message to vcp */
+enum mtk_vcp_ipi_msg_status {
+ VCODEC_IPI_MSG_STATUS_OK = 0,
+ VCODEC_IPI_MSG_STATUS_FAIL = -1,
+ VCODEC_IPI_MSG_STATUS_MAX_INST = -2,
+ VCODEC_IPI_MSG_STATUS_ILSEQ = -3,
+ VCODEC_IPI_MSG_STATUS_INVALID_ID = -4,
+ VCODEC_IPI_MSG_STATUS_DMA_FAIL = -5,
+};
+
+/**
+ * struct mtk_vcp_msg_node - share buffer used to send data to vcp
+ *
+ * @ipi_data: share obj data
+ * @list: list to store msg node
+ */
+struct mtk_vcp_msg_node {
+ struct mtk_vcp_share_obj ipi_data;
+ struct list_head list;
+};
+
+/**
+ * struct mtk_vcp - vcp firmware private data
+ *
+ * @is_init_done: vcp is ready to use
+ *
+ * @ipi_mutex: used to protect ipi data
+ * @msg_signaled: whether receive ack from vcp
+ * @msg_wq: wake message queue
+ *
+ * @ipi_desc: store ack handler
+ * @ipi_id_ack: the ack handler status
+ *
+ * @msg_queue: process vcp message
+ * @share_data: temp share obj data
+ *
+ * @vcp_notify: register notifier to vcp
+ *
+ * @vsi_addr: vsi virtual data address
+ * @vsi_core_addr: vsi core virtual data address
+ * @iova_addr: vsi iova address
+ * @vsi_size: vsi size
+ *
+ * @pdev: platform device
+ * @vcp_device: vcp private data
+ */
+struct mtk_vcp {
+ bool is_init_done;
+
+ struct mutex ipi_mutex;
+ bool msg_signaled[VCP_IPI_MAX];
+ wait_queue_head_t msg_wq[VCP_IPI_MAX];
+
+ struct mtk_vcp_ipi_desc ipi_desc[VCP_IPI_MAX];
+ bool ipi_id_ack[VCP_IPI_MAX];
+
+ struct mtk_vcp_msg_queue msg_queue;
+ struct mtk_vcp_share_obj share_data;
+
+ struct notifier_block vcp_notify;
+
+ void *vsi_addr;
+ void *vsi_core_addr;
+ dma_addr_t iova_addr;
+ int vsi_size;
+
+ struct platform_device *pdev;
+ struct mtk_vcp_device *vcp_device;
+};
+
+#endif
diff --git a/include/linux/remoteproc/mtk_vcp_public.h b/include/linux/remoteproc/mtk_vcp_public.h
index 07b0b30ea964..0b7d1c3c28ca 100644
--- a/include/linux/remoteproc/mtk_vcp_public.h
+++ b/include/linux/remoteproc/mtk_vcp_public.h
@@ -10,7 +10,7 @@
#include <linux/firmware/mediatek/mtk-vcp-ipc.h>
#include <linux/remoteproc.h>
-#define VCP_SYNC_TIMEOUT_MS (999)
+#define VCP_SYNC_TIMEOUT_MS (50)
/* vcp notify event */
enum VCP_NOTIFY_EVENT {
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 04/14] media: mediatek: vcodec: add driver to support vcp encoder
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (2 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 03/14] media: mediatek: vcodec: add driver to support vcp Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 05/14] media: mediatek: vcodec: get different firmware ipi id Yunfei Dong
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Encoder also need to call vcp interface to communicate with vcp,
add driver to support encoder.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/common/mtk_vcodec_fw_vcp.c | 40 +++++++++++++++----
.../vcodec/common/mtk_vcodec_fw_vcp.h | 1 +
.../mediatek/vcodec/encoder/mtk_vcodec_enc.c | 1 -
.../mediatek/vcodec/encoder/mtk_vcodec_enc.h | 2 +
4 files changed, 36 insertions(+), 8 deletions(-)
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 227310c116c6..c9e5cde40aef 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
@@ -13,6 +13,8 @@
#include "../decoder/mtk_vcodec_dec_drv.h"
#include "../decoder/vdec_ipi_msg.h"
+#include "../encoder/mtk_vcodec_enc.h"
+#include "../encoder/mtk_vcodec_enc_drv.h"
#include "mtk_vcodec_fw_priv.h"
#define IPI_SEND_TIMEOUT_MS 100U
@@ -189,8 +191,8 @@ static int mtk_vcodec_vcp_msg_ipi_send(struct mtk_vcodec_fw *fw, int id, void *b
}
mutex_lock(msg_mutex);
- feature_id = VDEC_FEATURE_ID;
- mailbox_id = IPI_OUT_VDEC_1;
+ feature_id = (fw->fw_use == ENCODER) ? VENC_FEATURE_ID : VDEC_FEATURE_ID;
+ mailbox_id = (fw->fw_use == ENCODER) ? IPI_OUT_VENC_0 : IPI_OUT_VDEC_1;
timeout_jiffies = jiffies + msecs_to_jiffies(VCP_SYNC_TIMEOUT_MS);
while (!vcp_device->ops->vcp_is_ready(feature_id)) {
@@ -300,10 +302,10 @@ static int mtk_vcodec_vcp_load_firmware(struct mtk_vcodec_fw *fw)
vcp_device = fw->vcp->vcp_device;
- feature_id = VDEC_FEATURE_ID;
- mem_id = VDEC_MEM_ID;
- mailbox_id = IPI_IN_VDEC_1;
- ipi_id = VCP_IPI_LAT_DECODER;
+ feature_id = fw->fw_use == ENCODER ? VENC_FEATURE_ID : VDEC_FEATURE_ID;
+ mem_id = fw->fw_use == ENCODER ? VENC_MEM_ID : VDEC_MEM_ID;
+ mailbox_id = fw->fw_use == ENCODER ? IPI_IN_VENC_0 : IPI_IN_VDEC_1;
+ ipi_id = fw->fw_use == ENCODER ? VCP_IPI_ENCODER : VCP_IPI_LAT_DECODER;
ret = mtk_vcp_mbox_ipc_register(vcp_get_ipidev(vcp_device), mailbox_id,
mtk_vcodec_vcp_msg_ack_isr, fw, &fw->vcp->share_data);
@@ -322,6 +324,20 @@ static int mtk_vcodec_vcp_load_firmware(struct mtk_vcodec_fw *fw)
mutex_init(&fw->vcp->ipi_desc[ipi_id].lock);
mutex_init(&fw->vcp->ipi_mutex);
+ if (fw->fw_use == ENCODER) {
+ kthread_run(mtk_vcodec_vcp_msg_process_thread, fw, "vcp_enc_msq_thread");
+
+ fw->vcp->vsi_addr = vcp_device->ops->vcp_get_mem_virt(mem_id);
+ fw->vcp->vsi_size = vcp_device->ops->vcp_get_mem_size(mem_id);
+ fw->vcp->iova_addr = vcp_device->ops->vcp_get_mem_iova(mem_id);
+
+ dev_dbg(&fw->pdev->dev, "enc vcp init done => va: %p size:0x%x iova:%pad.\n",
+ fw->vcp->vsi_addr, fw->vcp->vsi_size, &fw->vcp->iova_addr);
+
+ init_waitqueue_head(&fw->vcp->msg_wq[VCP_IPI_ENCODER]);
+ return 0;
+ }
+
kthread_run(mtk_vcodec_vcp_msg_process_thread, fw, "vcp_vdec_msq_thread");
fw->vcp->vsi_addr = vcp_device->ops->vcp_get_mem_virt(mem_id);
@@ -345,6 +361,11 @@ static unsigned int mtk_vcodec_vcp_get_vdec_capa(struct mtk_vcodec_fw *fw)
MTK_VDEC_IS_SUPPORT_10BIT | MTK_VDEC_IS_SUPPORT_EXT;
}
+static unsigned int mtk_vcodec_vcp_get_venc_capa(struct mtk_vcodec_fw *fw)
+{
+ return MTK_VENC_4K_CAPABILITY_ENABLE;
+}
+
static void *mtk_vcodec_vcp_dm_addr(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr)
{
return NULL;
@@ -396,6 +417,7 @@ static void mtk_vcodec_vcp_release(struct mtk_vcodec_fw *fw)
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,
+ .get_venc_capa = mtk_vcodec_vcp_get_venc_capa,
.map_dm_addr = mtk_vcodec_vcp_dm_addr,
.ipi_register = mtk_vcodec_vcp_set_ipi_register,
.ipi_send = mtk_vcodec_vcp_ipi_send,
@@ -409,7 +431,11 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vcp_init(void *priv, enum mtk_vcodec_fw_use
struct mtk_vcodec_fw *fw;
int i;
- if (fw_use == DECODER) {
+ if (fw_use == ENCODER) {
+ struct mtk_vcodec_enc_dev *enc_dev = priv;
+
+ plat_dev = enc_dev->plat_dev;
+ } else if (fw_use == DECODER) {
struct mtk_vcodec_dec_dev *dec_dev = priv;
plat_dev = dec_dev->plat_dev;
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
index 40f5481d1889..53080ed12c69 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
@@ -16,6 +16,7 @@ typedef void (*vcp_ipi_handler_t) (void *data, unsigned int len, void *priv);
/* enum mtk_vcp_ipi_index - index used to separate different hardware */
enum mtk_vcp_ipi_index {
+ VCP_IPI_ENCODER,
VCP_IPI_LAT_DECODER,
VCP_IPI_CORE_DECODER,
VCP_IPI_MAX,
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
index a01dc25a7699..dcafb1303c29 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.c
@@ -26,7 +26,6 @@
#define MTK_DEFAULT_FRAMERATE_NUM 1001
#define MTK_DEFAULT_FRAMERATE_DENOM 30000
-#define MTK_VENC_4K_CAPABILITY_ENABLE BIT(0)
static void mtk_venc_worker(struct work_struct *work);
diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
index 908d8179b2d2..84156c102d8d 100644
--- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc.h
@@ -23,6 +23,8 @@
#define MTK_VENC_IRQ_STATUS_OFFSET 0x05C
#define MTK_VENC_IRQ_ACK_OFFSET 0x060
+#define MTK_VENC_4K_CAPABILITY_ENABLE BIT(0)
+
/**
* struct mtk_video_enc_buf - Private data related to each VB2 buffer.
* @m2m_buf: M2M buffer
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 05/14] media: mediatek: vcodec: get different firmware ipi id
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (3 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 04/14] media: mediatek: vcodec: add driver to support vcp encoder Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 06/14] media: mediatek: vcodec: get share memory address Yunfei Dong
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Getting ipi(inter-processor interrupt) id according to firmware
type and hardware index for different architecture.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/common/mtk_vcodec_fw.c | 13 +++++++++++++
.../platform/mediatek/vcodec/common/mtk_vcodec_fw.h | 1 +
.../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 4 ++--
.../vcodec/decoder/vdec/vdec_h264_req_multi_if.c | 4 ++--
.../vcodec/decoder/vdec/vdec_hevc_req_multi_if.c | 4 ++--
.../mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c | 4 ++--
.../vcodec/decoder/vdec/vdec_vp9_req_lat_if.c | 4 ++--
7 files changed, 24 insertions(+), 10 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 fc547afa4ebf..4ed7639dfa30 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.c
@@ -5,6 +5,19 @@
#include "mtk_vcodec_fw_priv.h"
#include "mtk_vcodec_fw_vcp.h"
+int mtk_vcodec_fw_get_ipi(enum mtk_vcodec_fw_type type, int hw_id)
+{
+ switch (type) {
+ case SCP:
+ return hw_id == MTK_VDEC_LAT0 ? SCP_IPI_VDEC_LAT : SCP_IPI_VDEC_CORE;
+ case VCP:
+ return hw_id == MTK_VDEC_LAT0 ? VCP_IPI_LAT_DECODER : VCP_IPI_CORE_DECODER;
+ default:
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_ipi);
+
struct mtk_vcodec_fw *mtk_vcodec_fw_select(void *priv, enum mtk_vcodec_fw_type type,
enum mtk_vcodec_fw_use fw_use)
{
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 c1642fb09b42..142e2e87905c 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw.h
@@ -41,5 +41,6 @@ int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
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);
#endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
index bf21f2467a0f..618064001883 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -1886,8 +1886,8 @@ static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx)
return -ENOMEM;
instance->ctx = ctx;
- instance->vpu.id = SCP_IPI_VDEC_LAT;
- instance->vpu.core_id = SCP_IPI_VDEC_CORE;
+ instance->vpu.id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_LAT0);
+ instance->vpu.core_id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_CORE);
instance->vpu.ctx = ctx;
instance->vpu.codec_type = ctx->current_codec;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index 5b25e1679b51..50f81f1cb616 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -1212,8 +1212,8 @@ static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
inst->ctx = ctx;
- inst->vpu.id = SCP_IPI_VDEC_LAT;
- inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+ inst->vpu.id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_LAT0);
+ inst->vpu.core_id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_CORE);
inst->vpu.ctx = ctx;
inst->vpu.codec_type = ctx->current_codec;
inst->vpu.capture_type = ctx->capture_fourcc;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
index 2725db882e5b..80fbd0309b9e 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
@@ -863,8 +863,8 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx)
inst->ctx = ctx;
- inst->vpu.id = SCP_IPI_VDEC_LAT;
- inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+ inst->vpu.id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_LAT0);
+ inst->vpu.core_id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_CORE);
inst->vpu.ctx = ctx;
inst->vpu.codec_type = ctx->current_codec;
inst->vpu.capture_type = ctx->capture_fourcc;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
index 232ef3bd246a..764f4d4054c0 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
@@ -281,8 +281,8 @@ static int vdec_vp8_slice_init(struct mtk_vcodec_dec_ctx *ctx)
inst->ctx = ctx;
- inst->vpu.id = SCP_IPI_VDEC_LAT;
- inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+ inst->vpu.id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_LAT0);
+ inst->vpu.core_id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_CORE);
inst->vpu.ctx = ctx;
inst->vpu.codec_type = ctx->current_codec;
inst->vpu.capture_type = ctx->capture_fourcc;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
index 47c302745c1d..0279f66efdf9 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
@@ -1855,8 +1855,8 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_dec_ctx *ctx)
return -ENOMEM;
instance->ctx = ctx;
- instance->vpu.id = SCP_IPI_VDEC_LAT;
- instance->vpu.core_id = SCP_IPI_VDEC_CORE;
+ instance->vpu.id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_LAT0);
+ instance->vpu.core_id = mtk_vcodec_fw_get_ipi(ctx->dev->fw_handler->type, MTK_VDEC_CORE);
instance->vpu.ctx = ctx;
instance->vpu.codec_type = ctx->current_codec;
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 06/14] media: mediatek: vcodec: get share memory address
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (4 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 05/14] media: mediatek: vcodec: get different firmware ipi id Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 07/14] media: mediatek: vcodec: define MT8196 vcodec levels Yunfei Dong
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
There is only one share memory for vcp architecture, need to
divide it into many different functions.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/common/mtk_vcodec_fw_vcp.c | 20 +++++++++++++++++-
.../vcodec/common/mtk_vcodec_fw_vcp.h | 13 ++++++++++++
.../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 21 ++++++++++++++-----
.../decoder/vdec/vdec_h264_req_multi_if.c | 6 +++++-
.../decoder/vdec/vdec_hevc_req_multi_if.c | 7 +++++--
.../vcodec/decoder/vdec/vdec_vp9_req_lat_if.c | 16 ++++++++++----
.../mediatek/vcodec/decoder/vdec_vpu_if.c | 7 +++++--
7 files changed, 75 insertions(+), 15 deletions(-)
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 c9e5cde40aef..f6b93e1bcbf3 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
@@ -366,8 +366,26 @@ static unsigned int mtk_vcodec_vcp_get_venc_capa(struct mtk_vcodec_fw *fw)
return MTK_VENC_4K_CAPABILITY_ENABLE;
}
-static void *mtk_vcodec_vcp_dm_addr(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr)
+static void *mtk_vcodec_vcp_dm_addr(struct mtk_vcodec_fw *fw, u32 mem_type)
{
+ unsigned char *vsi_core = fw->vcp->vsi_core_addr;
+
+ switch (mem_type) {
+ case ENCODER_MEM:
+ case VCODEC_LAT_MEM:
+ return fw->vcp->vsi_addr;
+ case VCODEC_CORE_MEM:
+ return vsi_core;
+ case VP9_FRAME_MEM:
+ return vsi_core + VCODEC_VSI_LEN;
+ case AV1_CDF_MEM:
+ return vsi_core + VCODEC_VSI_LEN + VP9_FRAME_SIZE;
+ case AV1_IQ_MEM:
+ return vsi_core + VCODEC_VSI_LEN + VP9_FRAME_SIZE + AV1_CDF_SIZE;
+ default:
+ break;
+ }
+
return NULL;
}
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
index 53080ed12c69..54df468f301b 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vcp.h
@@ -13,6 +13,19 @@ typedef void (*vcp_ipi_handler_t) (void *data, unsigned int len, void *priv);
#define VCP_SHARE_BUF_SIZE 64
#define VCODEC_VSI_LEN (0x2000)
+#define VP9_FRAME_SIZE (0x1000)
+#define AV1_CDF_SIZE (0xFE80)
+#define AV1_IQ_TABLE_SIZE (0x12200)
+
+/* enum mtk_vcp_mem_type - memory type for different hardware */
+enum mtk_vcp_mem_type {
+ ENCODER_MEM,
+ VCODEC_LAT_MEM,
+ VCODEC_CORE_MEM,
+ VP9_FRAME_MEM,
+ AV1_CDF_MEM,
+ AV1_IQ_MEM,
+};
/* enum mtk_vcp_ipi_index - index used to separate different hardware */
enum mtk_vcp_ipi_index {
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
index 618064001883..2b2173062cb0 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -774,8 +774,11 @@ static int vdec_av1_slice_init_cdf_table(struct vdec_av1_slice_instance *instanc
ctx = instance->ctx;
vsi = instance->vpu.vsi;
- remote_cdf_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
- (u32)vsi->cdf_table_addr);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ remote_cdf_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, AV1_CDF_MEM);
+ else
+ remote_cdf_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+ (u32)vsi->cdf_table_addr);
if (IS_ERR(remote_cdf_table)) {
mtk_vdec_err(ctx, "failed to map cdf table\n");
return PTR_ERR(remote_cdf_table);
@@ -805,8 +808,11 @@ static int vdec_av1_slice_init_iq_table(struct vdec_av1_slice_instance *instance
ctx = instance->ctx;
vsi = instance->vpu.vsi;
- remote_iq_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
- (u32)vsi->iq_table_addr);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ remote_iq_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, AV1_IQ_MEM);
+ else
+ remote_iq_table = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+ (u32)vsi->iq_table_addr);
if (IS_ERR(remote_iq_table)) {
mtk_vdec_err(ctx, "failed to map iq table\n");
return PTR_ERR(remote_iq_table);
@@ -1905,7 +1911,12 @@ static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx)
goto error_vsi;
}
instance->init_vsi = vsi;
- instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->core_vsi);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ instance->core_vsi =
+ mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, VCODEC_CORE_MEM);
+ else
+ instance->core_vsi =
+ mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, (u32)vsi->core_vsi);
if (!instance->core_vsi) {
mtk_vdec_err(ctx, "failed to get AV1 core vsi\n");
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
index 50f81f1cb616..6b354d30910c 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -1230,7 +1230,11 @@ static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx)
vsi_size = round_up(vsi_size, VCODEC_DEC_ALIGNED_64);
inst->vsi_ext = inst->vpu.vsi;
temp = (unsigned char *)inst->vsi_ext;
- inst->vsi_core_ext = (struct vdec_h264_slice_vsi_ext *)(temp + vsi_size);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ inst->vsi_core_ext =
+ mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, VCODEC_CORE_MEM);
+ else
+ inst->vsi_core_ext = (struct vdec_h264_slice_vsi_ext *)(temp + vsi_size);
if (inst->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE)
inst->decode = vdec_h264_slice_single_decode_ext;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
index 80fbd0309b9e..ac0deea0df4c 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
@@ -877,8 +877,11 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx)
vsi_size = round_up(sizeof(struct vdec_hevc_slice_vsi), VCODEC_DEC_ALIGNED_64);
inst->vsi = inst->vpu.vsi;
- inst->vsi_core =
- (struct vdec_hevc_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ inst->vsi_core = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, VCODEC_CORE_MEM);
+ else
+ inst->vsi_core =
+ (struct vdec_hevc_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
inst->resolution_changed = true;
inst->realloc_mv_buf = true;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
index 0279f66efdf9..fa0f406f7726 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c
@@ -513,8 +513,12 @@ static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance
if (!ctx || !vsi)
return -EINVAL;
- remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
- (u32)vsi->default_frame_ctx);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ remote_frame_ctx =
+ mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, VP9_FRAME_MEM);
+ else
+ remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+ (u32)vsi->default_frame_ctx);
if (!remote_frame_ctx) {
mtk_vdec_err(ctx, "failed to map default frame ctx\n");
return -EINVAL;
@@ -1875,8 +1879,12 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_dec_ctx *ctx)
goto error_vsi;
}
instance->init_vsi = vsi;
- instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
- (u32)vsi->core_vsi);
+ if (mtk_vcodec_fw_get_type(ctx->dev->fw_handler) == VCP)
+ instance->core_vsi =
+ mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler, VCODEC_CORE_MEM);
+ else
+ instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+ (u32)vsi->core_vsi);
if (!instance->core_vsi) {
mtk_vdec_err(ctx, "failed to get VP9 core vsi\n");
ret = -EINVAL;
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
index 145958206e38..ac10e0dfefb2 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -18,8 +18,11 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
/* mapping VPU address to kernel virtual address */
/* the content in vsi is initialized to 0 in VPU */
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
- msg->vpu_inst_addr);
+ if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VCP)
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler, VCODEC_LAT_MEM);
+ else
+ vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
+ msg->vpu_inst_addr);
vpu->inst_addr = msg->vpu_inst_addr;
mtk_vdec_debug(vpu->ctx, "- vpu_inst_addr = 0x%x", vpu->inst_addr);
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 07/14] media: mediatek: vcodec: define MT8196 vcodec levels.
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (5 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 06/14] media: mediatek: vcodec: get share memory address Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 08/14] media: mediatek: vcodec: support vcp architecture Yunfei Dong
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The supported level and profile are not the same for different
codecs and architecture. Select the correct one.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
index d873159b9b30..c1cef78471a9 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c
@@ -555,6 +555,7 @@ static void mtk_vcodec_dec_fill_h264_level(struct v4l2_ctrl_config *cfg,
cfg->max = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
break;
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_H264_LEVEL_6_0;
break;
case MTK_VDEC_MT8183:
@@ -573,6 +574,7 @@ static void mtk_vcodec_dec_fill_h264_profile(struct v4l2_ctrl_config *cfg,
switch (ctx->dev->chip_name) {
case MTK_VDEC_MT8188:
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10;
break;
default:
@@ -589,6 +591,7 @@ static void mtk_vcodec_dec_fill_h265_level(struct v4l2_ctrl_config *cfg,
cfg->max = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1;
break;
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2;
break;
default:
@@ -603,6 +606,7 @@ static void mtk_vcodec_dec_fill_h265_profile(struct v4l2_ctrl_config *cfg,
switch (ctx->dev->chip_name) {
case MTK_VDEC_MT8188:
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10;
break;
default:
@@ -620,6 +624,7 @@ static void mtk_vcodec_dec_fill_vp9_level(struct v4l2_ctrl_config *cfg,
cfg->max = V4L2_MPEG_VIDEO_VP9_LEVEL_5_1;
break;
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_VP9_LEVEL_5_2;
break;
case MTK_VDEC_MT8186:
@@ -637,6 +642,7 @@ static void mtk_vcodec_dec_fill_vp9_profile(struct v4l2_ctrl_config *cfg,
switch (ctx->dev->chip_name) {
case MTK_VDEC_MT8188:
case MTK_VDEC_MT8195:
+ case MTK_VDEC_MT8196:
cfg->max = V4L2_MPEG_VIDEO_VP9_PROFILE_2;
break;
default:
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 08/14] media: mediatek: vcodec: support vcp architecture
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (6 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 07/14] media: mediatek: vcodec: define MT8196 vcodec levels Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 09/14] media: mediatek: vcodec: support 36bit iova address Yunfei Dong
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Some platforms expose the video codec through the VCP coprocessor.
Use the VCP architecture when the VCP coprocessor is found.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index fa609343c168..5e312f86e652 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -380,6 +380,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
} else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
&rproc_phandle)) {
fw_type = SCP;
+ } else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vcp",
+ &rproc_phandle)) {
+ fw_type = VCP;
} else {
dev_dbg(&pdev->dev, "Could not get vdec IPI device");
return -ENODEV;
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 09/14] media: mediatek: vcodec: support 36bit iova address
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (7 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 08/14] media: mediatek: vcodec: support vcp architecture Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 10/14] media: mediatek: vcodec: clean xpc status Yunfei Dong
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Need to set dma mask to support 36bit iova address for decoder
hardware can use 36bit address to decode for mt8196.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
index 5e312f86e652..fabf969bc8a9 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -388,6 +388,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
return -ENODEV;
}
dma_set_max_seg_size(&pdev->dev, UINT_MAX);
+ if (dev->chip_name == MTK_VDEC_MT8196) {
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable 36-bit DMA: %d\n", ret);
+ return ret;
+ }
+ }
dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
if (IS_ERR(dev->fw_handler))
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 10/14] media: mediatek: vcodec: clean xpc status
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (8 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 09/14] media: mediatek: vcodec: support 36bit iova address Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 11/14] media: mediatek: vcodec: add debug information Yunfei Dong
` (3 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The driver need to clean xpc status when receive decoder hardware
interrupt for mt8196 platform.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/mtk_vcodec_dec_hw.c | 28 +++++++++++++++++++
.../vcodec/decoder/mtk_vcodec_dec_hw.h | 13 +++++++--
2 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
index 881d5de41e05..e4e527fe54dc 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.c
@@ -61,6 +61,31 @@ static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dec_dev *vdec_dev)
return 0;
}
+static void mtk_vdec_hw_write_reg_mask(void __iomem *reg_base, u32 reg_offset, u32 val, u32 mask)
+{
+ void __iomem *reg_addr = reg_base + reg_offset;
+ u32 reg_val;
+
+ reg_val = readl(reg_addr);
+ reg_val &= ~mask;
+ reg_val |= (val & mask);
+ writel(reg_val, reg_addr);
+}
+
+static void mtk_vdec_hw_clean_xpc(struct mtk_vdec_hw_dev *dev)
+{
+ u32 val, mask, addr = VDEC_XPC_CLEAN_ADDR;
+
+ if (dev->main_dev->chip_name != MTK_VDEC_MT8196)
+ return;
+
+ val = dev->hw_idx == MTK_VDEC_LAT0 ? VDEC_XPC_LAT_VAL : VDEC_XPC_CORE_VAL;
+ mask = dev->hw_idx == MTK_VDEC_LAT0 ? VDEC_XPC_LAT_MASK : VDEC_XPC_CORE_MASK;
+
+ mtk_vdec_hw_write_reg_mask(dev->reg_base[VDEC_HW_XPC], addr, val, mask);
+ mtk_vdec_hw_write_reg_mask(dev->reg_base[VDEC_HW_XPC], addr, 0, mask);
+}
+
static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
{
struct mtk_vdec_hw_dev *dev = priv;
@@ -88,6 +113,8 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+ mtk_vdec_hw_clean_xpc(dev);
+
wake_up_dec_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
mtk_v4l2_vdec_dbg(3, ctx, "wake up ctx %d, dec_done_status=%x",
@@ -166,6 +193,7 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
subdev_dev->hw_idx = hw_idx;
subdev_dev->main_dev = main_dev;
subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS];
+ subdev_dev->reg_base[VDEC_HW_XPC] = main_dev->reg_base[VDEC_HW_MISC];
set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) {
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h
index 83fe8b9428e6..50ce6c1d25a2 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_hw.h
@@ -18,17 +18,26 @@
#define VDEC_IRQ_CLR 0x10
#define VDEC_IRQ_CFG_REG 0xa4
+#define VDEC_XPC_CLEAN_ADDR 0xc
+#define VDEC_XPC_LAT_VAL BIT(0)
+#define VDEC_XPC_LAT_MASK BIT(0)
+
+#define VDEC_XPC_CORE_VAL BIT(4)
+#define VDEC_XPC_CORE_MASK BIT(4)
+
#define IS_SUPPORT_VDEC_HW_IRQ(hw_idx) ((hw_idx) != MTK_VDEC_LAT_SOC)
/**
* enum mtk_vdec_hw_reg_idx - subdev hardware register base index
- * @VDEC_HW_SYS : vdec soc register index
+ * @VDEC_HW_SYS: vdec soc register index
* @VDEC_HW_MISC: vdec misc register index
- * @VDEC_HW_MAX : vdec supported max register index
+ * @VDEC_HW_XPC: vdec xpc register index
+ * @VDEC_HW_MAX: vdec supported max register index
*/
enum mtk_vdec_hw_reg_idx {
VDEC_HW_SYS,
VDEC_HW_MISC,
+ VDEC_HW_XPC,
VDEC_HW_MAX
};
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 11/14] media: mediatek: vcodec: add debug information
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (9 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 10/14] media: mediatek: vcodec: clean xpc status Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 12/14] media: mediatek: vcodec: send share memory address to vcp Yunfei Dong
` (2 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Print hevc/av1 output format and 10bit capture format
information to debug.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../mediatek/vcodec/common/mtk_vcodec_dbgfs.c | 21 +++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c
index 5ad3797836db..79ccbe13735a 100644
--- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c
+++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c
@@ -29,6 +29,14 @@ static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_dec_ctx *ctx, char
curr_len = snprintf(buf + *used, total - *used,
"\toutput format: vp9 slice\n");
break;
+ case V4L2_PIX_FMT_HEVC_SLICE:
+ curr_len = snprintf(buf + *used, total - *used,
+ "\toutput format: hevc slice\n");
+ break;
+ case V4L2_PIX_FMT_AV1_FRAME:
+ curr_len = snprintf(buf + *used, total - *used,
+ "\toutput format: av1 slice\n");
+ break;
default:
curr_len = snprintf(buf + *used, total - *used,
"\tunsupported output format: 0x%x\n",
@@ -45,6 +53,14 @@ static void mtk_vdec_dbgfs_get_format_type(struct mtk_vcodec_dec_ctx *ctx, char
curr_len = snprintf(buf + *used, total - *used,
"\tcapture format: MT21C\n");
break;
+ case V4L2_PIX_FMT_MT2110T:
+ curr_len = snprintf(buf + *used, total - *used,
+ "\tcapture format: MT2110T (10bit tile mode)\n");
+ break;
+ case V4L2_PIX_FMT_MT2110R:
+ curr_len = snprintf(buf + *used, total - *used,
+ "\tcapture format: MT2110T (10bit raster mode)\n");
+ break;
default:
curr_len = snprintf(buf + *used, total - *used,
"\tunsupported capture format: 0x%x\n",
@@ -122,9 +138,10 @@ static ssize_t mtk_vdec_dbgfs_read(struct file *filp, char __user *ubuf,
if (dbgfs_index[MTK_VDEC_DBGFS_PICINFO]) {
curr_len = snprintf(buf + used_len, total_len - used_len,
- "\treal(%dx%d)=>align(%dx%d)\n",
+ "\treal(%dx%d)=>align(%dx%d) 10bit(%d)\n",
ctx->picinfo.pic_w, ctx->picinfo.pic_h,
- ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+ ctx->picinfo.buf_w, ctx->picinfo.buf_h,
+ ctx->is_10bit_bitstream);
used_len += curr_len;
}
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 12/14] media: mediatek: vcodec: send share memory address to vcp
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (10 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 11/14] media: mediatek: vcodec: add debug information Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 13/14] media: mediatek: decoder: fill av1 buffer size with picinfo Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 14/14] media: mediatek: decoder: support av1 extend vsi Yunfei Dong
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
Send share memory address to vcp for it is reserved in kernel
side.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h | 2 ++
drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h b/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h
index 47070be2a991..097561a1efdc 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_ipi_msg.h
@@ -67,11 +67,13 @@ struct vdec_vpu_ipi_ack {
* @msg_id : AP_IPIMSG_DEC_INIT
* @codec_type : codec fourcc
* @ap_inst_addr : AP video decoder instance address
+ * @shared_iova : reserved share memory address
*/
struct vdec_ap_ipi_init {
uint32_t msg_id;
u32 codec_type;
uint64_t ap_inst_addr;
+ u64 shared_iova;
};
/**
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
index ac10e0dfefb2..428ed9e5f2c3 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -232,6 +232,8 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
msg.msg_id = AP_IPIMSG_DEC_INIT;
msg.ap_inst_addr = (unsigned long)vpu;
msg.codec_type = vpu->codec_type;
+ if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VCP)
+ msg.shared_iova = vpu->ctx->dev->fw_handler->vcp->iova_addr;
mtk_vdec_debug(vpu->ctx, "vdec_inst=%p", vpu);
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 13/14] media: mediatek: decoder: fill av1 buffer size with picinfo
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (11 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 12/14] media: mediatek: vcodec: send share memory address to vcp Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
2025-08-15 8:52 ` [PATCH v2 14/14] media: mediatek: decoder: support av1 extend vsi Yunfei Dong
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The buffer size of y and c plane has been calculated in vcp/scp,
can fill each frame buffer size with picinfo directly.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
index 2b2173062cb0..6070485e26c4 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -1799,18 +1799,19 @@ static int vdec_av1_slice_setup_core_buffer(struct vdec_av1_slice_instance *inst
{
struct vb2_buffer *vb;
struct vb2_queue *vq;
- int w, h, plane, size;
+ int plane;
int i;
plane = instance->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
- w = vsi->frame.uh.upscaled_width;
- h = vsi->frame.uh.frame_height;
- size = ALIGN(w, VCODEC_DEC_ALIGNED_64) * ALIGN(h, VCODEC_DEC_ALIGNED_64);
/* frame buffer */
vsi->fb.y.dma_addr = fb->base_y.dma_addr;
+
+ vsi->fb.y.size = instance->ctx->picinfo.fb_sz[0];
+ vsi->fb.c.size = instance->ctx->picinfo.fb_sz[1];
+
if (plane == 1)
- vsi->fb.c.dma_addr = fb->base_y.dma_addr + size;
+ vsi->fb.c.dma_addr = fb->base_y.dma_addr + vsi->fb.y.size;
else
vsi->fb.c.dma_addr = fb->base_c.dma_addr;
@@ -1835,8 +1836,9 @@ static int vdec_av1_slice_setup_core_buffer(struct vdec_av1_slice_instance *inst
}
vref->y.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
+ vref->y.size = vsi->fb.y.size;
if (plane == 1)
- vref->c.dma_addr = vref->y.dma_addr + size;
+ vref->c.dma_addr = vref->y.dma_addr + vsi->fb.y.size;
else
vref->c.dma_addr = vb2_dma_contig_plane_dma_addr(vb, 1);
}
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 14/14] media: mediatek: decoder: support av1 extend vsi
2025-08-15 8:52 [PATCH v2 00/14] media: mediatek: vcodec: support video decoder in mt8196 Yunfei Dong
` (12 preceding siblings ...)
2025-08-15 8:52 ` [PATCH v2 13/14] media: mediatek: decoder: fill av1 buffer size with picinfo Yunfei Dong
@ 2025-08-15 8:52 ` Yunfei Dong
13 siblings, 0 replies; 17+ messages in thread
From: Yunfei Dong @ 2025-08-15 8:52 UTC (permalink / raw)
To: Nícolas F . R . A . Prado, Sebastian Fricke,
Nicolas Dufresne, Hans Verkuil, AngeloGioacchino Del Regno,
Benjamin Gaignard, Nathan Hebert, Daniel Almeida
Cc: Hsin-Yi Wang, Fritz Koenig, Daniel Vetter, Steve Cho, Yunfei Dong,
linux-media, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Project_Global_Chrome_Upstream_Group
The driver can't access tile buffer address for extend architecture,
set tile group information in vcp and share it with kernel.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 46 ++++++++++++++++---
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
index 6070485e26c4..43541faeea87 100644
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -25,6 +25,8 @@
#define AV1_INVALID_IDX -1
+#define AV1_NON_EXT_VSI_SIZE 0xD50
+
#define AV1_DIV_ROUND_UP_POW2(value, n) \
({ \
typeof(n) _n = n; \
@@ -641,6 +643,8 @@ struct vdec_av1_slice_fb {
* @frame: current frame info
* @state: status after decode done
* @cur_lst_tile_id: tile id for large scale
+ * @tile_group: tile group info
+ * @reserved: reserved
*/
struct vdec_av1_slice_vsi {
/* lat */
@@ -665,6 +669,8 @@ struct vdec_av1_slice_vsi {
struct vdec_av1_slice_frame frame;
struct vdec_av1_slice_state state;
u32 cur_lst_tile_id;
+ struct vdec_av1_slice_tile_group tile_group;
+ unsigned int reserved[4];
};
/**
@@ -1394,13 +1400,18 @@ static int vdec_av1_slice_setup_tile_group(struct vdec_av1_slice_instance *insta
struct vdec_av1_slice_vsi *vsi)
{
struct v4l2_ctrl_av1_tile_group_entry *ctrl_tge;
- struct vdec_av1_slice_tile_group *tile_group = &instance->tile_group;
+ struct vdec_av1_slice_tile_group *tile_group;
struct vdec_av1_slice_uncompressed_header *uh = &vsi->frame.uh;
struct vdec_av1_slice_tile *tile = &uh->tile;
struct v4l2_ctrl *ctrl;
u32 tge_size;
int i;
+ if (IS_VDEC_SUPPORT_EXT(instance->ctx->dev->dec_capability))
+ tile_group = &vsi->tile_group;
+ else
+ tile_group = &instance->tile_group;
+
ctrl = v4l2_ctrl_find(&instance->ctx->ctrl_hdl, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY);
if (!ctrl)
return -EINVAL;
@@ -1601,6 +1612,7 @@ static void vdec_av1_slice_setup_lat_buffer(struct vdec_av1_slice_instance *inst
struct vdec_lat_buf *lat_buf)
{
struct vdec_av1_slice_work_buffer *work_buffer;
+ u32 num_tiles;
int i;
vsi->bs.dma_addr = bs->dma_addr;
@@ -1635,12 +1647,18 @@ static void vdec_av1_slice_setup_lat_buffer(struct vdec_av1_slice_instance *inst
vsi->tile.buf = instance->tile.dma_addr;
vsi->tile.size = instance->tile.size;
- memcpy(lat_buf->tile_addr.va, instance->tile.va, 64 * instance->tile_group.num_tiles);
vsi->cdf_table.buf = instance->cdf_table.dma_addr;
vsi->cdf_table.size = instance->cdf_table.size;
vsi->iq_table.buf = instance->iq_table.dma_addr;
vsi->iq_table.size = instance->iq_table.size;
+
+ if (IS_VDEC_SUPPORT_EXT(instance->ctx->dev->dec_capability))
+ num_tiles = vsi->tile_group.num_tiles;
+ else
+ num_tiles = instance->tile_group.num_tiles;
+
+ memcpy(lat_buf->tile_addr.va, instance->tile.va, 64 * num_tiles);
}
static void vdec_av1_slice_setup_seg_buffer(struct vdec_av1_slice_instance *instance,
@@ -1663,7 +1681,7 @@ static void vdec_av1_slice_setup_tile_buffer(struct vdec_av1_slice_instance *ins
struct vdec_av1_slice_vsi *vsi,
struct mtk_vcodec_mem *bs)
{
- struct vdec_av1_slice_tile_group *tile_group = &instance->tile_group;
+ struct vdec_av1_slice_tile_group *tile_group;
struct vdec_av1_slice_uncompressed_header *uh = &vsi->frame.uh;
struct vdec_av1_slice_tile *tile = &uh->tile;
u32 tile_num, tile_row, tile_col;
@@ -1674,6 +1692,11 @@ static void vdec_av1_slice_setup_tile_buffer(struct vdec_av1_slice_instance *ins
u32 *tile_info_buf = instance->tile.va;
u64 pa = (u64)bs->dma_addr;
+ if (IS_VDEC_SUPPORT_EXT(instance->ctx->dev->dec_capability))
+ tile_group = &vsi->tile_group;
+ else
+ tile_group = &instance->tile_group;
+
if (uh->disable_cdf_update == 0)
allow_update_cdf = 1;
@@ -1887,7 +1910,7 @@ static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx)
{
struct vdec_av1_slice_instance *instance;
struct vdec_av1_slice_init_vsi *vsi;
- int ret;
+ int ret, vsi_size = AV1_NON_EXT_VSI_SIZE;
instance = kzalloc(sizeof(*instance), GFP_KERNEL);
if (!instance)
@@ -1926,9 +1949,18 @@ static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx)
goto error_vsi;
}
- if (vsi->vsi_size != sizeof(struct vdec_av1_slice_vsi))
- mtk_vdec_err(ctx, "remote vsi size 0x%x mismatch! expected: 0x%zx\n",
- vsi->vsi_size, sizeof(struct vdec_av1_slice_vsi));
+ if (IS_VDEC_SUPPORT_EXT(ctx->dev->dec_capability)) {
+ vsi_size = sizeof(struct vdec_av1_slice_vsi);
+ vsi->iq_table_size = AV1_IQ_TABLE_SIZE;
+ vsi->cdf_table_size = AV1_CDF_SIZE;
+ }
+
+ if (vsi->vsi_size != vsi_size) {
+ mtk_vdec_err(ctx, "remote vsi size 0x%x mismatch! expected: 0x%x\n",
+ vsi->vsi_size, vsi_size);
+ ret = -EINVAL;
+ goto error_vsi;
+ }
instance->irq_enabled = 1;
instance->inneracing_mode = IS_VDEC_INNER_RACING(instance->ctx->dev->dec_capability);
--
2.45.2
^ permalink raw reply related [flat|nested] 17+ messages in thread