summaryrefslogtreecommitdiff
path: root/drivers/media/platform/mtk-vcodec
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@kernel.org>2022-03-13 11:18:13 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-03-18 05:56:51 +0100
commit728dc4075accb2821b595f650b5a6a64f42a9abe (patch)
treec6c8498c366e7029b36177f36de1f7afd524d32b /drivers/media/platform/mtk-vcodec
parent1cb72963fa1e3667936d069333923787037e9ffb (diff)
media: platform: rename mtk-vcodec/ to mediatek/mtk-vcodec/
As the end goal is to have platform drivers split by vendor, rename mtk-vcodec/ to mediatek/mtk-vcodec/. Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/platform/mtk-vcodec')
-rw-r--r--drivers/media/platform/mtk-vcodec/Kconfig36
-rw-r--r--drivers/media/platform/mtk-vcodec/Makefile42
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c961
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h100
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c509
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c200
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h56
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c169
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h19
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c630
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c380
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h537
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c1451
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h50
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c479
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c90
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h17
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c67
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h43
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h52
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c73
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c112
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c43
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h19
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c135
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h63
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c503
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c774
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c616
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c1028
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_drv_base.h46
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_drv_if.c113
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_drv_if.h100
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h117
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_msg_queue.c290
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_msg_queue.h153
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_vpu_if.c243
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_vpu_if.h107
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c708
-rw-r--r--drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c468
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_drv_base.h53
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_drv_if.c100
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_drv_if.h170
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_ipi_msg.h220
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_vpu_if.c293
-rw-r--r--drivers/media/platform/mtk-vcodec/venc_vpu_if.h51
46 files changed, 0 insertions, 12486 deletions
diff --git a/drivers/media/platform/mtk-vcodec/Kconfig b/drivers/media/platform/mtk-vcodec/Kconfig
deleted file mode 100644
index 635801a19d55..000000000000
--- a/drivers/media/platform/mtk-vcodec/Kconfig
+++ /dev/null
@@ -1,36 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_MEDIATEK_VCODEC_SCP
- bool
-
-config VIDEO_MEDIATEK_VCODEC_VPU
- bool
-
-config VIDEO_MEDIATEK_VCODEC
- tristate "Mediatek Video Codec driver"
- depends on V4L_MEM2MEM_DRIVERS
- depends on MTK_IOMMU || COMPILE_TEST
- depends on VIDEO_DEV && VIDEO_V4L2
- depends on ARCH_MEDIATEK || COMPILE_TEST
- depends on VIDEO_MEDIATEK_VPU || MTK_SCP
- # The two following lines ensure we have the same state ("m" or "y") as
- # our dependencies, to avoid missing symbols during link.
- depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU
- depends on MTK_SCP || !MTK_SCP
- depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n)
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU
- select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP
- select V4L2_H264
- select MEDIA_CONTROLLER
- select MEDIA_CONTROLLER_REQUEST_API
- help
- Mediatek video codec driver provides HW capability to
- encode and decode in a range of video formats on MT8173
- and MT8183.
-
- Note that support for MT8173 requires VIDEO_MEDIATEK_VPU to
- also be selected. Support for MT8183 depends on MTK_SCP.
-
- To compile this driver as modules, choose M here: the
- modules will be called mtk-vcodec-dec and mtk-vcodec-enc.
diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
deleted file mode 100644
index 359619653a0e..000000000000
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
- mtk-vcodec-enc.o \
- mtk-vcodec-common.o \
- mtk-vcodec-dec-hw.o
-
-mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
- vdec/vdec_vp8_if.o \
- vdec/vdec_vp9_if.o \
- vdec/vdec_h264_req_if.o \
- mtk_vcodec_dec_drv.o \
- vdec_drv_if.o \
- vdec_vpu_if.o \
- vdec_msg_queue.o \
- mtk_vcodec_dec.o \
- mtk_vcodec_dec_stateful.o \
- mtk_vcodec_dec_stateless.o \
- mtk_vcodec_dec_pm.o \
-
-mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o
-
-mtk-vcodec-enc-y := venc/venc_vp8_if.o \
- venc/venc_h264_if.o \
- mtk_vcodec_enc.o \
- mtk_vcodec_enc_drv.o \
- mtk_vcodec_enc_pm.o \
- venc_drv_if.o \
- venc_vpu_if.o \
-
-
-mtk-vcodec-common-y := mtk_vcodec_intr.o \
- mtk_vcodec_util.o \
- mtk_vcodec_fw.o \
-
-ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU),)
-mtk-vcodec-common-y += mtk_vcodec_fw_vpu.o
-endif
-
-ifneq ($(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP),)
-mtk-vcodec-common-y += mtk_vcodec_fw_scp.o
-endif
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
deleted file mode 100644
index 130ecef2e766..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ /dev/null
@@ -1,961 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "vdec_drv_if.h"
-#include "mtk_vcodec_dec_pm.h"
-
-#define DFT_CFG_WIDTH MTK_VDEC_MIN_W
-#define DFT_CFG_HEIGHT MTK_VDEC_MIN_H
-
-static const struct mtk_video_fmt *
-mtk_vdec_find_format(struct v4l2_format *f,
- const struct mtk_vcodec_dec_pdata *dec_pdata)
-{
- const struct mtk_video_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < dec_pdata->num_formats; k++) {
- fmt = &dec_pdata->vdec_formats[k];
- if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
- return fmt;
- }
-
- return NULL;
-}
-
-static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
- enum v4l2_buf_type type)
-{
- if (V4L2_TYPE_IS_OUTPUT(type))
- return &ctx->q_data[MTK_Q_DATA_SRC];
-
- return &ctx->q_data[MTK_Q_DATA_DST];
-}
-
-static int vidioc_try_decoder_cmd(struct file *file, void *priv,
- struct v4l2_decoder_cmd *cmd)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- /* Use M2M stateless helper if relevant */
- if (ctx->dev->vdec_pdata->uses_stateless_api)
- return v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv,
- cmd);
- else
- return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd);
-}
-
-
-static int vidioc_decoder_cmd(struct file *file, void *priv,
- struct v4l2_decoder_cmd *cmd)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct vb2_queue *src_vq, *dst_vq;
- int ret;
-
- ret = vidioc_try_decoder_cmd(file, priv, cmd);
- if (ret)
- return ret;
-
- /* Use M2M stateless helper if relevant */
- if (ctx->dev->vdec_pdata->uses_stateless_api)
- return v4l2_m2m_ioctl_stateless_decoder_cmd(file, priv, cmd);
-
- mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd);
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- switch (cmd->cmd) {
- case V4L2_DEC_CMD_STOP:
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (!vb2_is_streaming(src_vq)) {
- mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
- return 0;
- }
- if (!vb2_is_streaming(dst_vq)) {
- mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
- return 0;
- }
- v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
- v4l2_m2m_try_schedule(ctx->m2m_ctx);
- break;
-
- case V4L2_DEC_CMD_START:
- vb2_clear_last_buffer_dequeued(dst_vq);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
-{
- mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
-}
-
-void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
-{
- mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
-}
-
-void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
-{
- vdec_if_deinit(ctx);
- ctx->state = MTK_STATE_FREE;
-}
-
-void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
-{
- struct mtk_q_data *q_data;
-
- ctx->dev->vdec_pdata->init_vdec_params(ctx);
-
- ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
- ctx->fh.m2m_ctx = ctx->m2m_ctx;
- ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
- INIT_WORK(&ctx->decode_work, ctx->dev->vdec_pdata->worker);
- ctx->colorspace = V4L2_COLORSPACE_REC709;
- ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
- ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
-
- q_data = &ctx->q_data[MTK_Q_DATA_SRC];
- memset(q_data, 0, sizeof(struct mtk_q_data));
- q_data->visible_width = DFT_CFG_WIDTH;
- q_data->visible_height = DFT_CFG_HEIGHT;
- q_data->fmt = ctx->dev->vdec_pdata->default_out_fmt;
- q_data->field = V4L2_FIELD_NONE;
-
- q_data->sizeimage[0] = DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
- q_data->bytesperline[0] = 0;
-
- q_data = &ctx->q_data[MTK_Q_DATA_DST];
- memset(q_data, 0, sizeof(struct mtk_q_data));
- q_data->visible_width = DFT_CFG_WIDTH;
- q_data->visible_height = DFT_CFG_HEIGHT;
- q_data->coded_width = DFT_CFG_WIDTH;
- q_data->coded_height = DFT_CFG_HEIGHT;
- q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
- q_data->field = V4L2_FIELD_NONE;
-
- v4l_bound_align_image(&q_data->coded_width,
- MTK_VDEC_MIN_W,
- MTK_VDEC_MAX_W, 4,
- &q_data->coded_height,
- MTK_VDEC_MIN_H,
- MTK_VDEC_MAX_H, 5, 6);
-
- q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
- q_data->bytesperline[0] = q_data->coded_width;
- q_data->sizeimage[1] = q_data->sizeimage[0] / 2;
- q_data->bytesperline[1] = q_data->coded_width;
-}
-
-static int vidioc_vdec_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MTK_STATE_ABORT) {
- mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
- ctx->id);
- return -EIO;
- }
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_vdec_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MTK_STATE_ABORT) {
- mtk_v4l2_err("[%d] Call on DQBUF after unrecoverable error",
- ctx->id);
- return -EIO;
- }
-
- return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_vdec_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strscpy(cap->driver, MTK_VCODEC_DEC_NAME, sizeof(cap->driver));
- strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
- strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
-
- return 0;
-}
-
-static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub)
-{
- switch (sub->type) {
- case V4L2_EVENT_EOS:
- return v4l2_event_subscribe(fh, sub, 2, NULL);
- case V4L2_EVENT_SOURCE_CHANGE:
- return v4l2_src_change_event_subscribe(fh, sub);
- default:
- return v4l2_ctrl_subscribe_event(fh, sub);
- }
-}
-
-static int vidioc_try_fmt(struct v4l2_format *f,
- const struct mtk_video_fmt *fmt)
-{
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
-
- pix_fmt_mp->field = V4L2_FIELD_NONE;
-
- pix_fmt_mp->width =
- clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
- pix_fmt_mp->height =
- clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- pix_fmt_mp->num_planes = 1;
- pix_fmt_mp->plane_fmt[0].bytesperline = 0;
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- int tmp_w, tmp_h;
-
- /*
- * Find next closer width align 64, heign align 64, size align
- * 64 rectangle
- * Note: This only get default value, the real HW needed value
- * only available when ctx in MTK_STATE_HEADER state
- */
- tmp_w = pix_fmt_mp->width;
- tmp_h = pix_fmt_mp->height;
- v4l_bound_align_image(&pix_fmt_mp->width,
- MTK_VDEC_MIN_W,
- MTK_VDEC_MAX_W, 6,
- &pix_fmt_mp->height,
- MTK_VDEC_MIN_H,
- MTK_VDEC_MAX_H, 6, 9);
-
- if (pix_fmt_mp->width < tmp_w &&
- (pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W)
- pix_fmt_mp->width += 64;
- if (pix_fmt_mp->height < tmp_h &&
- (pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H)
- pix_fmt_mp->height += 64;
-
- mtk_v4l2_debug(0,
- "before resize width=%d, height=%d, after resize width=%d, height=%d, sizeimage=%d",
- tmp_w, tmp_h, pix_fmt_mp->width,
- pix_fmt_mp->height,
- pix_fmt_mp->width * pix_fmt_mp->height);
-
- pix_fmt_mp->num_planes = fmt->num_planes;
- pix_fmt_mp->plane_fmt[0].sizeimage =
- pix_fmt_mp->width * pix_fmt_mp->height;
- pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
-
- if (pix_fmt_mp->num_planes == 2) {
- pix_fmt_mp->plane_fmt[1].sizeimage =
- (pix_fmt_mp->width * pix_fmt_mp->height) / 2;
- pix_fmt_mp->plane_fmt[1].bytesperline =
- pix_fmt_mp->width;
- }
- }
-
- pix_fmt_mp->flags = 0;
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
-
- fmt = mtk_vdec_find_format(f, dec_pdata);
- if (!fmt) {
- f->fmt.pix.pixelformat =
- ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc;
- fmt = mtk_vdec_find_format(f, dec_pdata);
- }
-
- return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
- const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
-
- fmt = mtk_vdec_find_format(f, dec_pdata);
- if (!fmt) {
- f->fmt.pix.pixelformat =
- ctx->q_data[MTK_Q_DATA_SRC].fmt->fourcc;
- fmt = mtk_vdec_find_format(f, dec_pdata);
- }
-
- if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
- mtk_v4l2_err("sizeimage of output format must be given");
- return -EINVAL;
- }
-
- return vidioc_try_fmt(f, fmt);
-}
-
-static int vidioc_vdec_g_selection(struct file *file, void *priv,
- struct v4l2_selection *s)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct mtk_q_data *q_data;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- q_data = &ctx->q_data[MTK_Q_DATA_DST];
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = ctx->picinfo.pic_w;
- s->r.height = ctx->picinfo.pic_h;
- break;
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = ctx->picinfo.buf_w;
- s->r.height = ctx->picinfo.buf_h;
- break;
- case V4L2_SEL_TGT_COMPOSE:
- if (vdec_if_get_param(ctx, GET_PARAM_CROP_INFO, &(s->r))) {
- /* set to default value if header info not ready yet*/
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = q_data->visible_width;
- s->r.height = q_data->visible_height;
- }
- break;
- default:
- return -EINVAL;
- }
-
- if (ctx->state < MTK_STATE_HEADER) {
- /* set to default value if header info not ready yet*/
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = q_data->visible_width;
- s->r.height = q_data->visible_height;
- return 0;
- }
-
- return 0;
-}
-
-static int vidioc_vdec_s_selection(struct file *file, void *priv,
- struct v4l2_selection *s)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = ctx->picinfo.pic_w;
- s->r.height = ctx->picinfo.pic_h;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_vdec_s_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_pix_format_mplane *pix_mp;
- struct mtk_q_data *q_data;
- int ret = 0;
- const struct mtk_video_fmt *fmt;
- const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
-
- mtk_v4l2_debug(3, "[%d]", ctx->id);
-
- q_data = mtk_vdec_get_q_data(ctx, f->type);
- if (!q_data)
- return -EINVAL;
-
- pix_mp = &f->fmt.pix_mp;
- /*
- * Setting OUTPUT format after OUTPUT buffers are allocated is invalid
- * if using the stateful API.
- */
- if (!dec_pdata->uses_stateless_api &&
- f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
- vb2_is_busy(&ctx->m2m_ctx->out_q_ctx.q)) {
- mtk_v4l2_err("out_q_ctx buffers already requested");
- ret = -EBUSY;
- }
-
- /*
- * Setting CAPTURE format after CAPTURE buffers are allocated is
- * invalid.
- */
- if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
- vb2_is_busy(&ctx->m2m_ctx->cap_q_ctx.q)) {
- mtk_v4l2_err("cap_q_ctx buffers already requested");
- ret = -EBUSY;
- }
-
- fmt = mtk_vdec_find_format(f, dec_pdata);
- if (fmt == NULL) {
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- f->fmt.pix.pixelformat =
- dec_pdata->default_out_fmt->fourcc;
- fmt = mtk_vdec_find_format(f, dec_pdata);
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- f->fmt.pix.pixelformat =
- dec_pdata->default_cap_fmt->fourcc;
- fmt = mtk_vdec_find_format(f, dec_pdata);
- }
- }
- if (fmt == NULL)
- return -EINVAL;
-
- q_data->fmt = fmt;
- vidioc_try_fmt(f, q_data->fmt);
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
- q_data->coded_width = pix_mp->width;
- q_data->coded_height = pix_mp->height;
-
- ctx->colorspace = pix_mp->colorspace;
- ctx->ycbcr_enc = pix_mp->ycbcr_enc;
- ctx->quantization = pix_mp->quantization;
- ctx->xfer_func = pix_mp->xfer_func;
-
- ctx->current_codec = fmt->fourcc;
- if (ctx->state == MTK_STATE_FREE) {
- ret = vdec_if_init(ctx, q_data->fmt->fourcc);
- if (ret) {
- mtk_v4l2_err("[%d]: vdec_if_init() fail ret=%d",
- ctx->id, ret);
- return -EINVAL;
- }
- ctx->state = MTK_STATE_INIT;
- }
- }
-
- /*
- * If using the stateless API, S_FMT should have the effect of setting
- * the CAPTURE queue resolution no matter which queue it was called on.
- */
- if (dec_pdata->uses_stateless_api) {
- ctx->picinfo.pic_w = pix_mp->width;
- ctx->picinfo.pic_h = pix_mp->height;
-
- ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
- if (ret) {
- mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
- ctx->id);
- return -EINVAL;
- }
-
- ctx->last_decoded_picinfo = ctx->picinfo;
-
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) {
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
- ctx->picinfo.fb_sz[0] +
- ctx->picinfo.fb_sz[1];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
- ctx->picinfo.buf_w;
- } else {
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
- ctx->picinfo.fb_sz[0];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] =
- ctx->picinfo.buf_w;
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[1] =
- ctx->picinfo.fb_sz[1];
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[1] =
- ctx->picinfo.buf_w;
- }
-
- ctx->q_data[MTK_Q_DATA_DST].coded_width = ctx->picinfo.buf_w;
- ctx->q_data[MTK_Q_DATA_DST].coded_height = ctx->picinfo.buf_h;
- mtk_v4l2_debug(2, "[%d] vdec_if_init() num_plane = %d wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
- ctx->id, pix_mp->num_planes, ctx->picinfo.buf_w, ctx->picinfo.buf_h,
- ctx->picinfo.pic_w, ctx->picinfo.pic_h,
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0],
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[1]);
- }
- return 0;
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *priv,
- struct v4l2_frmsizeenum *fsize)
-{
- int i = 0;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
-
- if (fsize->index != 0)
- return -EINVAL;
-
- for (i = 0; i < dec_pdata->num_framesizes; ++i) {
- if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
- continue;
-
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
- fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
- if (!(ctx->dev->dec_capability &
- VCODEC_CAPABILITY_4K_DISABLED)) {
- mtk_v4l2_debug(3, "4K is enabled");
- fsize->stepwise.max_width =
- VCODEC_DEC_4K_CODED_WIDTH;
- fsize->stepwise.max_height =
- VCODEC_DEC_4K_CODED_HEIGHT;
- }
- mtk_v4l2_debug(1, "%x, %d %d %d %d %d %d",
- ctx->dev->dec_capability,
- fsize->stepwise.min_width,
- fsize->stepwise.max_width,
- fsize->stepwise.step_width,
- fsize->stepwise.min_height,
- fsize->stepwise.max_height,
- fsize->stepwise.step_height);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
- bool output_queue)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
- const struct mtk_video_fmt *fmt;
- int i, j = 0;
-
- for (i = 0; i < dec_pdata->num_formats; i++) {
- if (output_queue &&
- dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
- continue;
- if (!output_queue &&
- dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
- continue;
-
- if (j == f->index)
- break;
- ++j;
- }
-
- if (i == dec_pdata->num_formats)
- return -EINVAL;
-
- fmt = &dec_pdata->vdec_formats[i];
- f->pixelformat = fmt->fourcc;
- f->flags = fmt->flags;
-
- return 0;
-}
-
-static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, priv, false);
-}
-
-static int vidioc_vdec_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- return vidioc_enum_fmt(f, priv, true);
-}
-
-static int vidioc_vdec_g_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
- struct vb2_queue *vq;
- struct mtk_q_data *q_data;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq) {
- mtk_v4l2_err("no vb2 queue for type=%d", f->type);
- return -EINVAL;
- }
-
- q_data = mtk_vdec_get_q_data(ctx, f->type);
-
- pix_mp->field = V4L2_FIELD_NONE;
- pix_mp->colorspace = ctx->colorspace;
- pix_mp->ycbcr_enc = ctx->ycbcr_enc;
- pix_mp->quantization = ctx->quantization;
- pix_mp->xfer_func = ctx->xfer_func;
-
- if ((f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
- (ctx->state >= MTK_STATE_HEADER)) {
- /* Until STREAMOFF is called on the CAPTURE queue
- * (acknowledging the event), the driver operates as if
- * the resolution hasn't changed yet.
- * So we just return picinfo yet, and update picinfo in
- * stop_streaming hook function
- */
- q_data->sizeimage[0] = ctx->picinfo.fb_sz[0];
- q_data->sizeimage[1] = ctx->picinfo.fb_sz[1];
- q_data->bytesperline[0] = ctx->last_decoded_picinfo.buf_w;
- q_data->bytesperline[1] = ctx->last_decoded_picinfo.buf_w;
- q_data->coded_width = ctx->picinfo.buf_w;
- q_data->coded_height = ctx->picinfo.buf_h;
- ctx->last_decoded_picinfo.cap_fourcc = q_data->fmt->fourcc;
-
- /*
- * Width and height are set to the dimensions
- * of the movie, the buffer is bigger and
- * further processing stages should crop to this
- * rectangle.
- */
- pix_mp->width = q_data->coded_width;
- pix_mp->height = q_data->coded_height;
-
- /*
- * Set pixelformat to the format in which mt vcodec
- * outputs the decoded frame
- */
- pix_mp->num_planes = q_data->fmt->num_planes;
- pix_mp->pixelformat = q_data->fmt->fourcc;
- pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
- pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
- pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
- pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
-
- } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- /*
- * This is run on OUTPUT
- * The buffer contains compressed image
- * so width and height have no meaning.
- * Assign value here to pass v4l2-compliance test
- */
- pix_mp->width = q_data->visible_width;
- pix_mp->height = q_data->visible_height;
- pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
- pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
- pix_mp->pixelformat = q_data->fmt->fourcc;
- pix_mp->num_planes = q_data->fmt->num_planes;
- } else {
- pix_mp->width = q_data->coded_width;
- pix_mp->height = q_data->coded_height;
- pix_mp->num_planes = q_data->fmt->num_planes;
- pix_mp->pixelformat = q_data->fmt->fourcc;
- pix_mp->plane_fmt[0].bytesperline = q_data->bytesperline[0];
- pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage[0];
- pix_mp->plane_fmt[1].bytesperline = q_data->bytesperline[1];
- pix_mp->plane_fmt[1].sizeimage = q_data->sizeimage[1];
-
- mtk_v4l2_debug(1, "[%d] type=%d state=%d Format information could not be read, not ready yet!",
- ctx->id, f->type, ctx->state);
- }
-
- return 0;
-}
-
-int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
- unsigned int *nplanes, unsigned int sizes[],
- struct device *alloc_devs[])
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
- struct mtk_q_data *q_data;
- unsigned int i;
-
- q_data = mtk_vdec_get_q_data(ctx, vq->type);
-
- if (q_data == NULL) {
- mtk_v4l2_err("vq->type=%d err\n", vq->type);
- return -EINVAL;
- }
-
- if (*nplanes) {
- for (i = 0; i < *nplanes; i++) {
- if (sizes[i] < q_data->sizeimage[i])
- return -EINVAL;
- }
- } else {
- if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- *nplanes = q_data->fmt->num_planes;
- else
- *nplanes = 1;
-
- for (i = 0; i < *nplanes; i++)
- sizes[i] = q_data->sizeimage[i];
- }
-
- mtk_v4l2_debug(1,
- "[%d]\t type = %d, get %d plane(s), %d buffer(s) of size 0x%x 0x%x ",
- ctx->id, vq->type, *nplanes, *nbuffers,
- sizes[0], sizes[1]);
-
- return 0;
-}
-
-int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct mtk_q_data *q_data;
- int i;
-
- mtk_v4l2_debug(3, "[%d] (%d) id=%d",
- ctx->id, vb->vb2_queue->type, vb->index);
-
- q_data = mtk_vdec_get_q_data(ctx, vb->vb2_queue->type);
-
- for (i = 0; i < q_data->fmt->num_planes; i++) {
- if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
- mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
- i, vb2_plane_size(vb, i),
- q_data->sizeimage[i]);
- }
- }
-
- return 0;
-}
-
-void vb2ops_vdec_buf_finish(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2;
- struct mtk_video_dec_buf *buf;
- bool buf_error;
-
- vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
- buf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
- mutex_lock(&ctx->lock);
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- buf->queued_in_v4l2 = false;
- buf->queued_in_vb2 = false;
- }
- buf_error = buf->error;
- mutex_unlock(&ctx->lock);
-
- if (buf_error) {
- mtk_v4l2_err("Unrecoverable error on buffer.");
- ctx->state = MTK_STATE_ABORT;
- }
-}
-
-int vb2ops_vdec_buf_init(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb,
- struct vb2_v4l2_buffer, vb2_buf);
- struct mtk_video_dec_buf *buf = container_of(vb2_v4l2,
- struct mtk_video_dec_buf, m2m_buf.vb);
-
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- buf->used = false;
- buf->queued_in_v4l2 = false;
- }
-
- return 0;
-}
-
-int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
-
- if (ctx->state == MTK_STATE_FLUSH)
- ctx->state = MTK_STATE_HEADER;
-
- return 0;
-}
-
-void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
-{
- struct vb2_v4l2_buffer *src_buf = NULL, *dst_buf = NULL;
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
- int ret;
-
- mtk_v4l2_debug(3, "[%d] (%d) state=(%x) ctx->decoded_frame_cnt=%d",
- ctx->id, q->type, ctx->state, ctx->decoded_frame_cnt);
-
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
- if (src_buf != &ctx->empty_flush_buf.vb) {
- struct media_request *req =
- src_buf->vb2_buf.req_obj.req;
- v4l2_m2m_buf_done(src_buf,
- VB2_BUF_STATE_ERROR);
- if (req)
- v4l2_ctrl_request_complete(req, &ctx->ctrl_hdl);
- }
- }
- return;
- }
-
- if (ctx->state >= MTK_STATE_HEADER) {
-
- /* Until STREAMOFF is called on the CAPTURE queue
- * (acknowledging the event), the driver operates
- * as if the resolution hasn't changed yet, i.e.
- * VIDIOC_G_FMT< etc. return previous resolution.
- * So we update picinfo here
- */
- ctx->picinfo = ctx->last_decoded_picinfo;
-
- mtk_v4l2_debug(2,
- "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)",
- ctx->id, ctx->last_decoded_picinfo.pic_w,
- ctx->last_decoded_picinfo.pic_h,
- ctx->picinfo.pic_w, ctx->picinfo.pic_h,
- ctx->last_decoded_picinfo.buf_w,
- ctx->last_decoded_picinfo.buf_h);
-
- ret = ctx->dev->vdec_pdata->flush_decoder(ctx);
- if (ret)
- mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
- }
- ctx->state = MTK_STATE_FLUSH;
-
- while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
- vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
- }
-
-}
-
-static void m2mops_vdec_device_run(void *priv)
-{
- struct mtk_vcodec_ctx *ctx = priv;
- struct mtk_vcodec_dev *dev = ctx->dev;
-
- queue_work(dev->decode_workqueue, &ctx->decode_work);
-}
-
-static int m2mops_vdec_job_ready(void *m2m_priv)
-{
- struct mtk_vcodec_ctx *ctx = m2m_priv;
-
- mtk_v4l2_debug(3, "[%d]", ctx->id);
-
- if (ctx->state == MTK_STATE_ABORT)
- return 0;
-
- if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
- (ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h))
- return 0;
-
- if (ctx->state != MTK_STATE_HEADER)
- return 0;
-
- return 1;
-}
-
-static void m2mops_vdec_job_abort(void *priv)
-{
- struct mtk_vcodec_ctx *ctx = priv;
-
- ctx->state = MTK_STATE_ABORT;
-}
-
-const struct v4l2_m2m_ops mtk_vdec_m2m_ops = {
- .device_run = m2mops_vdec_device_run,
- .job_ready = m2mops_vdec_job_ready,
- .job_abort = m2mops_vdec_job_abort,
-};
-
-const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = {
- .vidioc_streamon = v4l2_m2m_ioctl_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
- .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
- .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
- .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
-
- .vidioc_qbuf = vidioc_vdec_qbuf,
- .vidioc_dqbuf = vidioc_vdec_dqbuf,
-
- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
- .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
-
- .vidioc_s_fmt_vid_cap_mplane = vidioc_vdec_s_fmt,
- .vidioc_s_fmt_vid_out_mplane = vidioc_vdec_s_fmt,
- .vidioc_g_fmt_vid_cap_mplane = vidioc_vdec_g_fmt,
- .vidioc_g_fmt_vid_out_mplane = vidioc_vdec_g_fmt,
-
- .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
-
- .vidioc_enum_fmt_vid_cap = vidioc_vdec_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_out = vidioc_vdec_enum_fmt_vid_out,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
-
- .vidioc_querycap = vidioc_vdec_querycap,
- .vidioc_subscribe_event = vidioc_vdec_subscribe_evt,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_selection = vidioc_vdec_g_selection,
- .vidioc_s_selection = vidioc_vdec_s_selection,
-
- .vidioc_decoder_cmd = vidioc_decoder_cmd,
- .vidioc_try_decoder_cmd = vidioc_try_decoder_cmd,
-};
-
-int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct mtk_vcodec_ctx *ctx = priv;
- int ret = 0;
-
- mtk_v4l2_debug(3, "[%d]", ctx->id);
-
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_DMABUF | VB2_MMAP;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
- src_vq->ops = ctx->dev->vdec_pdata->vdec_vb2_ops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &ctx->dev->dev_mutex;
- src_vq->dev = &ctx->dev->plat_dev->dev;
-
- ret = vb2_queue_init(src_vq);
- if (ret) {
- mtk_v4l2_err("Failed to initialize videobuf2 queue(output)");
- return ret;
- }
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct mtk_video_dec_buf);
- dst_vq->ops = ctx->dev->vdec_pdata->vdec_vb2_ops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &ctx->dev->dev_mutex;
- dst_vq->dev = &ctx->dev->plat_dev->dev;
-
- ret = vb2_queue_init(dst_vq);
- if (ret)
- mtk_v4l2_err("Failed to initialize videobuf2 queue(capture)");
-
- return ret;
-}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
deleted file mode 100644
index 66cd6d2242c3..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _MTK_VCODEC_DEC_H_
-#define _MTK_VCODEC_DEC_H_
-
-#include <media/videobuf2-core.h>
-#include <media/v4l2-mem2mem.h>
-
-#define VCODEC_DEC_ALIGNED_64 64
-#define VCODEC_CAPABILITY_4K_DISABLED 0x10
-#define VCODEC_DEC_4K_CODED_WIDTH 4096U
-#define VCODEC_DEC_4K_CODED_HEIGHT 2304U
-#define MTK_VDEC_MAX_W 2048U
-#define MTK_VDEC_MAX_H 1088U
-#define MTK_VDEC_MIN_W 64U
-#define MTK_VDEC_MIN_H 64U
-
-#define MTK_VDEC_IRQ_STATUS_DEC_SUCCESS 0x10000
-
-/**
- * struct vdec_fb - decoder frame buffer
- * @base_y : Y plane memory info
- * @base_c : C plane memory info
- * @status : frame buffer status (vdec_fb_status)
- */
-struct vdec_fb {
- struct mtk_vcodec_mem base_y;
- struct mtk_vcodec_mem base_c;
- unsigned int status;
-};
-
-/**
- * struct mtk_video_dec_buf - Private data related to each VB2 buffer.
- * @m2m_buf: M2M buffer
- * @list: link list
- * @used: Capture buffer contain decoded frame data and keep in
- * codec data structure
- * @queued_in_vb2: Capture buffer is queue in vb2
- * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2
- * queue yet
- * @error: An unrecoverable error occurs on this buffer.
- * @frame_buffer: Decode status, and buffer information of Capture buffer
- * @bs_buffer: Output buffer info
- *
- * Note : These status information help us track and debug buffer state
- */
-struct mtk_video_dec_buf {
- struct v4l2_m2m_buffer m2m_buf;
-
- bool used;
- bool queued_in_vb2;
- bool queued_in_v4l2;
- bool error;
-
- union {
- struct vdec_fb frame_buffer;
- struct mtk_vcodec_mem bs_buffer;
- };
-};
-
-extern const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops;
-extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
-extern const struct media_device_ops mtk_vcodec_media_ops;
-extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
-extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
-extern const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata;
-
-
-/*
- * mtk_vdec_lock/mtk_vdec_unlock are for ctx instance to
- * get/release lock before/after access decoder hw.
- * mtk_vdec_lock get decoder hw lock and set curr_ctx
- * to ctx instance that get lock
- */
-void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx);
-void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx);
-int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq);
-void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx);
-void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx);
-
-/*
- * VB2 ops
- */
-int vb2ops_vdec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
- unsigned int *nplanes, unsigned int sizes[],
- struct device *alloc_devs[]);
-int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb);
-void vb2ops_vdec_buf_finish(struct vb2_buffer *vb);
-int vb2ops_vdec_buf_init(struct vb2_buffer *vb);
-int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count);
-void vb2ops_vdec_stop_streaming(struct vb2_queue *q);
-
-
-#endif /* _MTK_VCODEC_DEC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
deleted file mode 100644
index 48dad9bb13d2..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ /dev/null
@@ -1,509 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of.h>
-#include <linux/pm_runtime.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-device.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_dec_hw.h"
-#include "mtk_vcodec_dec_pm.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_fw.h"
-
-static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
-{
- switch (dev->vdec_pdata->hw_arch) {
- case MTK_VDEC_PURE_SINGLE_CORE:
- return MTK_VDEC_ONE_CORE;
- case MTK_VDEC_LAT_SINGLE_CORE:
- return MTK_VDEC_ONE_LAT_ONE_CORE;
- default:
- mtk_v4l2_err("hw arch %d not supported", dev->vdec_pdata->hw_arch);
- return MTK_VDEC_NO_HW;
- }
-}
-
-static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
-{
- struct mtk_vcodec_dev *dev = priv;
- struct mtk_vcodec_ctx *ctx;
- u32 cg_status = 0;
- unsigned int dec_done_status = 0;
- void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
- VDEC_IRQ_CFG_REG;
-
- ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
-
- /* check if HW active or not */
- cg_status = readl(dev->reg_base[0]);
- if ((cg_status & VDEC_HW_ACTIVE) != 0) {
- mtk_v4l2_err("DEC ISR, VDEC active is not 0x0 (0x%08x)",
- cg_status);
- return IRQ_HANDLED;
- }
-
- dec_done_status = readl(vdec_misc_addr);
- ctx->irq_status = dec_done_status;
- if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
- MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
- return IRQ_HANDLED;
-
- /* clear interrupt */
- writel((readl(vdec_misc_addr) | VDEC_IRQ_CFG),
- dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
- writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
- dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
-
- wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
-
- mtk_v4l2_debug(3,
- "mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
- ctx->id, dec_done_status);
-
- return IRQ_HANDLED;
-}
-
-static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
-{
- struct platform_device *pdev = dev->plat_dev;
- int reg_num, i;
-
- /* Sizeof(u32) * 4 bytes for each register base. */
- reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
- sizeof(u32) * 4);
- if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
- dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
- return -EINVAL;
- }
-
- for (i = 0; i < reg_num; i++) {
- dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
- if (IS_ERR(dev->reg_base[i]))
- return PTR_ERR(dev->reg_base[i]);
-
- mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
- }
-
- return 0;
-}
-
-static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
-{
- struct platform_device *pdev = dev->plat_dev;
- int ret;
-
- ret = mtk_vcodec_get_reg_bases(dev);
- if (ret)
- return ret;
-
- if (dev->vdec_pdata->is_subdev_supported)
- return 0;
-
- dev->dec_irq = platform_get_irq(pdev, 0);
- if (dev->dec_irq < 0) {
- dev_err(&pdev->dev, "failed to get irq number");
- return dev->dec_irq;
- }
-
- irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
- ret = devm_request_irq(&pdev->dev, dev->dec_irq,
- mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
- if (ret) {
- dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
- dev->dec_irq, ret);
- return ret;
- }
-
- ret = mtk_vcodec_init_dec_clk(pdev, &dev->pm);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to get mt vcodec clock source");
- return ret;
- }
-
- pm_runtime_enable(&pdev->dev);
- return 0;
-}
-
-static int fops_vcodec_open(struct file *file)
-{
- struct mtk_vcodec_dev *dev = video_drvdata(file);
- struct mtk_vcodec_ctx *ctx = NULL;
- int ret = 0, i, hw_count;
- struct vb2_queue *src_vq;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- mutex_lock(&dev->dev_mutex);
- ctx->id = dev->id_counter++;
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
- INIT_LIST_HEAD(&ctx->list);
- ctx->dev = dev;
- if (ctx->dev->vdec_pdata->is_subdev_supported) {
- hw_count = mtk_vcodec_get_hw_count(dev);
- if (!hw_count || !dev->subdev_prob_done) {
- ret = -EINVAL;
- goto err_ctrls_setup;
- }
-
- ret = dev->subdev_prob_done(dev);
- if (ret)
- goto err_ctrls_setup;
-
- for (i = 0; i < hw_count; i++)
- init_waitqueue_head(&ctx->queue[i]);
- } else {
- init_waitqueue_head(&ctx->queue[0]);
- }
- mutex_init(&ctx->lock);
-
- ctx->type = MTK_INST_DECODER;
- ret = dev->vdec_pdata->ctrls_setup(ctx);
- if (ret) {
- mtk_v4l2_err("Failed to setup mt vcodec controls");
- goto err_ctrls_setup;
- }
- ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_dec, ctx,
- &mtk_vcodec_dec_queue_init);
- if (IS_ERR((__force void *)ctx->m2m_ctx)) {
- ret = PTR_ERR((__force void *)ctx->m2m_ctx);
- mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
- ret);
- goto err_m2m_ctx_init;
- }
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- ctx->empty_flush_buf.vb.vb2_buf.vb2_queue = src_vq;
- mtk_vcodec_dec_set_default_params(ctx);
-
- if (v4l2_fh_is_singular(&ctx->fh)) {
- ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
- if (ret < 0)
- goto err_load_fw;
- /*
- * Does nothing if firmware was already loaded.
- */
- ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
- if (ret < 0) {
- /*
- * Return 0 if downloading firmware successfully,
- * otherwise it is failed
- */
- mtk_v4l2_err("failed to load firmware!");
- goto err_load_fw;
- }
-
- dev->dec_capability =
- mtk_vcodec_fw_get_vdec_capa(dev->fw_handler);
- mtk_v4l2_debug(0, "decoder capability %x", dev->dec_capability);
- }
-
- list_add(&ctx->list, &dev->ctx_list);
-
- mutex_unlock(&dev->dev_mutex);
- mtk_v4l2_debug(0, "%s decoder [%d]", dev_name(&dev->plat_dev->dev),
- ctx->id);
- return ret;
-
- /* Deinit when failure occurred */
-err_load_fw:
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
-err_m2m_ctx_init:
- v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-err_ctrls_setup:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- mutex_unlock(&dev->dev_mutex);
-
- return ret;
-}
-
-static int fops_vcodec_release(struct file *file)
-{
- struct mtk_vcodec_dev *dev = video_drvdata(file);
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
-
- mtk_v4l2_debug(0, "[%d] decoder", ctx->id);
- mutex_lock(&dev->dev_mutex);
-
- /*
- * Call v4l2_m2m_ctx_release before mtk_vcodec_dec_release. First, it
- * makes sure the worker thread is not running after vdec_if_deinit.
- * Second, the decoder will be flushed and all the buffers will be
- * returned in stop_streaming.
- */
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- mtk_vcodec_dec_release(ctx);
-
- if (v4l2_fh_is_singular(&ctx->fh))
- mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-
- list_del_init(&ctx->list);
- kfree(ctx);
- mutex_unlock(&dev->dev_mutex);
- return 0;
-}
-
-static const struct v4l2_file_operations mtk_vcodec_fops = {
- .owner = THIS_MODULE,
- .open = fops_vcodec_open,
- .release = fops_vcodec_release,
- .poll = v4l2_m2m_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = v4l2_m2m_fop_mmap,
-};
-
-static int mtk_vcodec_probe(struct platform_device *pdev)
-{
- struct mtk_vcodec_dev *dev;
- struct video_device *vfd_dec;
- phandle rproc_phandle;
- enum mtk_vcodec_fw_type fw_type;
- int i, ret;
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&dev->ctx_list);
- dev->plat_dev = pdev;
-
- dev->vdec_pdata = of_device_get_match_data(&pdev->dev);
- if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
- &rproc_phandle)) {
- fw_type = VPU;
- } else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
- &rproc_phandle)) {
- fw_type = SCP;
- } else {
- mtk_v4l2_err("Could not get vdec IPI device");
- return -ENODEV;
- }
- dma_set_max_seg_size(&pdev->dev, UINT_MAX);
-
- dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, DECODER);
- if (IS_ERR(dev->fw_handler))
- return PTR_ERR(dev->fw_handler);
-
- ret = mtk_vcodec_init_dec_resources(dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to init dec resources");
- goto err_dec_pm;
- }
-
- if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
- vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE);
- dev->core_workqueue =
- alloc_ordered_workqueue("core-decoder",
- WQ_MEM_RECLAIM | WQ_FREEZABLE);
- if (!dev->core_workqueue) {
- mtk_v4l2_err("Failed to create core workqueue");
- ret = -EINVAL;
- goto err_res;
- }
- }
-
- if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) {
- ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
- if (ret) {
- mtk_v4l2_err("Failed to set mask");
- goto err_core_workq;
- }
- }
-
- for (i = 0; i < MTK_VDEC_HW_MAX; i++)
- mutex_init(&dev->dec_mutex[i]);
- mutex_init(&dev->dev_mutex);
- spin_lock_init(&dev->irqlock);
-
- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
- "[/MTK_V4L2_VDEC]");
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret) {
- mtk_v4l2_err("v4l2_device_register err=%d", ret);
- goto err_core_workq;
- }
-
- init_waitqueue_head(&dev->queue);
-
- vfd_dec = video_device_alloc();
- if (!vfd_dec) {
- mtk_v4l2_err("Failed to allocate video device");
- ret = -ENOMEM;
- goto err_dec_alloc;
- }
- vfd_dec->fops = &mtk_vcodec_fops;
- vfd_dec->ioctl_ops = &mtk_vdec_ioctl_ops;
- vfd_dec->release = video_device_release;
- vfd_dec->lock = &dev->dev_mutex;
- vfd_dec->v4l2_dev = &dev->v4l2_dev;
- vfd_dec->vfl_dir = VFL_DIR_M2M;
- vfd_dec->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_STREAMING;
-
- snprintf(vfd_dec->name, sizeof(vfd_dec->name), "%s",
- MTK_VCODEC_DEC_NAME);
- video_set_drvdata(vfd_dec, dev);
- dev->vfd_dec = vfd_dec;
- platform_set_drvdata(pdev, dev);
-
- dev->m2m_dev_dec = v4l2_m2m_init(&mtk_vdec_m2m_ops);
- if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
- mtk_v4l2_err("Failed to init mem2mem dec device");
- ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
- goto err_dec_alloc;
- }
-
- dev->decode_workqueue =
- alloc_ordered_workqueue(MTK_VCODEC_DEC_NAME,
- WQ_MEM_RECLAIM | WQ_FREEZABLE);
- if (!dev->decode_workqueue) {
- mtk_v4l2_err("Failed to create decode workqueue");
- ret = -EINVAL;
- goto err_event_workq;
- }
-
- if (dev->vdec_pdata->is_subdev_supported) {
- ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
- &pdev->dev);
- if (ret) {
- mtk_v4l2_err("Main device of_platform_populate failed.");
- goto err_reg_cont;
- }
- }
-
- ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
- if (ret) {
- mtk_v4l2_err("Failed to register video device");
- goto err_reg_cont;
- }
-
- if (dev->vdec_pdata->uses_stateless_api) {
- dev->mdev_dec.dev = &pdev->dev;
- strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
- sizeof(dev->mdev_dec.model));
-
- media_device_init(&dev->mdev_dec);
- dev->mdev_dec.ops = &mtk_vcodec_media_ops;
- dev->v4l2_dev.mdev = &dev->mdev_dec;
-
- ret = v4l2_m2m_register_media_controller(dev->m2m_dev_dec, dev->vfd_dec,
- MEDIA_ENT_F_PROC_VIDEO_DECODER);
- if (ret) {
- mtk_v4l2_err("Failed to register media controller");
- goto err_dec_mem_init;
- }
-
- ret = media_device_register(&dev->mdev_dec);
- if (ret) {
- mtk_v4l2_err("Failed to register media device");
- goto err_media_reg;
- }
-
- mtk_v4l2_debug(0, "media registered as /dev/media%d", vfd_dec->minor);
- }
-
- mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor);
-
- return 0;
-
-err_media_reg:
- v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
-err_dec_mem_init:
- video_unregister_device(vfd_dec);
-err_reg_cont:
- if (dev->vdec_pdata->uses_stateless_api)
- media_device_cleanup(&dev->mdev_dec);
- destroy_workqueue(dev->decode_workqueue);
-err_event_workq:
- v4l2_m2m_release(dev->m2m_dev_dec);
-err_dec_alloc:
- v4l2_device_unregister(&dev->v4l2_dev);
-err_core_workq:
- if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
- destroy_workqueue(dev->core_workqueue);
-err_res:
- pm_runtime_disable(dev->pm.dev);
-err_dec_pm:
- mtk_vcodec_fw_release(dev->fw_handler);
- return ret;
-}
-
-static const struct of_device_id mtk_vcodec_match[] = {
- {
- .compatible = "mediatek,mt8173-vcodec-dec",
- .data = &mtk_vdec_8173_pdata,
- },
- {
- .compatible = "mediatek,mt8183-vcodec-dec",
- .data = &mtk_vdec_8183_pdata,
- },
- {
- .compatible = "mediatek,mt8192-vcodec-dec",
- .data = &mtk_lat_sig_core_pdata,
- },
- {},
-};
-
-MODULE_DEVICE_TABLE(of, mtk_vcodec_match);
-
-static int mtk_vcodec_dec_remove(struct platform_device *pdev)
-{
- struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
-
- destroy_workqueue(dev->decode_workqueue);
-
- if (media_devnode_is_registered(dev->mdev_dec.devnode)) {
- media_device_unregister(&dev->mdev_dec);
- v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
- media_device_cleanup(&dev->mdev_dec);
- }
-
- if (dev->m2m_dev_dec)
- v4l2_m2m_release(dev->m2m_dev_dec);
-
- if (dev->vfd_dec)
- video_unregister_device(dev->vfd_dec);
-
- v4l2_device_unregister(&dev->v4l2_dev);
- pm_runtime_disable(dev->pm.dev);
- mtk_vcodec_fw_release(dev->fw_handler);
- return 0;
-}
-
-static struct platform_driver mtk_vcodec_dec_driver = {
- .probe = mtk_vcodec_probe,
- .remove = mtk_vcodec_dec_remove,
- .driver = {
- .name = MTK_VCODEC_DEC_NAME,
- .of_match_table = mtk_vcodec_match,
- },
-};
-
-module_platform_driver(mtk_vcodec_dec_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mediatek video codec V4L2 decoder driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
deleted file mode 100644
index 8d2a641d92f1..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ /dev/null
@@ -1,200 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2021 MediaTek Inc.
- * Author: Yunfei Dong <yunfei.dong@mediatek.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_dec_hw.h"
-#include "mtk_vcodec_dec_pm.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-
-static const struct of_device_id mtk_vdec_hw_match[] = {
- {
- .compatible = "mediatek,mtk-vcodec-lat",
- .data = (void *)MTK_VDEC_LAT0,
- },
- {
- .compatible = "mediatek,mtk-vcodec-core",
- .data = (void *)MTK_VDEC_CORE,
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match);
-
-static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev)
-{
- struct platform_device *pdev = vdec_dev->plat_dev;
- struct device_node *subdev_node;
- enum mtk_vdec_hw_id hw_idx;
- const struct of_device_id *of_id;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mtk_vdec_hw_match); i++) {
- of_id = &mtk_vdec_hw_match[i];
- subdev_node = of_find_compatible_node(NULL, NULL,
- of_id->compatible);
- if (!subdev_node)
- continue;
-
- hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
- if (!test_bit(hw_idx, vdec_dev->subdev_bitmap)) {
- dev_err(&pdev->dev, "vdec %d is not ready", hw_idx);
- return -EAGAIN;
- }
- }
-
- return 0;
-}
-
-static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
-{
- struct mtk_vdec_hw_dev *dev = priv;
- struct mtk_vcodec_ctx *ctx;
- u32 cg_status;
- unsigned int dec_done_status;
- void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
- VDEC_IRQ_CFG_REG;
-
- ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx);
-
- /* check if HW active or not */
- cg_status = readl(dev->reg_base[VDEC_HW_SYS]);
- if (cg_status & VDEC_HW_ACTIVE) {
- mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
- cg_status);
- return IRQ_HANDLED;
- }
-
- dec_done_status = readl(vdec_misc_addr);
- if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
- MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
- return IRQ_HANDLED;
-
- /* clear interrupt */
- writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
- writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
-
- wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
-
- mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
- ctx->id, dec_done_status);
-
- return IRQ_HANDLED;
-}
-
-static int mtk_vdec_hw_init_irq(struct mtk_vdec_hw_dev *dev)
-{
- struct platform_device *pdev = dev->plat_dev;
- int ret;
-
- dev->dec_irq = platform_get_irq(pdev, 0);
- if (dev->dec_irq < 0) {
- dev_err(&pdev->dev, "Failed to get irq resource");
- return dev->dec_irq;
- }
-
- irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
- ret = devm_request_irq(&pdev->dev, dev->dec_irq,
- mtk_vdec_hw_irq_handler, 0, pdev->name, dev);
- if (ret) {
- dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
- dev->dec_irq, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int mtk_vdec_hw_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct mtk_vdec_hw_dev *subdev_dev;
- struct mtk_vcodec_dev *main_dev;
- const struct of_device_id *of_id;
- int hw_idx;
- int ret;
-
- if (!dev->parent) {
- dev_err(dev, "no parent for hardware devices.\n");
- return -ENODEV;
- }
-
- main_dev = dev_get_drvdata(dev->parent);
- if (!main_dev) {
- dev_err(dev, "failed to get parent driver data");
- return -EINVAL;
- }
-
- subdev_dev = devm_kzalloc(dev, sizeof(*subdev_dev), GFP_KERNEL);
- if (!subdev_dev)
- return -ENOMEM;
-
- subdev_dev->plat_dev = pdev;
- ret = mtk_vcodec_init_dec_clk(pdev, &subdev_dev->pm);
- if (ret)
- return ret;
- pm_runtime_enable(&pdev->dev);
-
- of_id = of_match_device(mtk_vdec_hw_match, dev);
- if (!of_id) {
- dev_err(dev, "Can't get vdec subdev id.\n");
- ret = -EINVAL;
- goto err;
- }
-
- hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
- if (hw_idx >= MTK_VDEC_HW_MAX) {
- dev_err(dev, "Hardware index %d not correct.\n", hw_idx);
- ret = -EINVAL;
- goto err;
- }
-
- main_dev->subdev_dev[hw_idx] = subdev_dev;
- 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];
- set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
-
- ret = mtk_vdec_hw_init_irq(subdev_dev);
- if (ret)
- goto err;
-
- subdev_dev->reg_base[VDEC_HW_MISC] =
- devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC])) {
- ret = PTR_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC]);
- goto err;
- }
-
- if (!main_dev->subdev_prob_done)
- main_dev->subdev_prob_done = mtk_vdec_hw_prob_done;
-
- platform_set_drvdata(pdev, subdev_dev);
- return 0;
-err:
- pm_runtime_disable(subdev_dev->pm.dev);
- return ret;
-}
-
-static struct platform_driver mtk_vdec_driver = {
- .probe = mtk_vdec_hw_probe,
- .driver = {
- .name = "mtk-vdec-comp",
- .of_match_table = mtk_vdec_hw_match,
- },
-};
-module_platform_driver(mtk_vdec_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mediatek video decoder hardware driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
deleted file mode 100644
index a63e4b1b81c3..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2021 MediaTek Inc.
- * Author: Yunfei Dong <yunfei.dong@mediatek.com>
- */
-
-#ifndef _MTK_VCODEC_DEC_HW_H_
-#define _MTK_VCODEC_DEC_HW_H_
-
-#include <linux/io.h>
-#include <linux/platform_device.h>
-
-#include "mtk_vcodec_drv.h"
-
-#define VDEC_HW_ACTIVE 0x10
-#define VDEC_IRQ_CFG 0x11
-#define VDEC_IRQ_CLR 0x10
-#define VDEC_IRQ_CFG_REG 0xa4
-
-/**
- * enum mtk_vdec_hw_reg_idx - subdev hardware register base index
- * @VDEC_HW_SYS : vdec soc register index
- * @VDEC_HW_MISC: vdec misc register index
- * @VDEC_HW_MAX : vdec supported max register index
- */
-enum mtk_vdec_hw_reg_idx {
- VDEC_HW_SYS,
- VDEC_HW_MISC,
- VDEC_HW_MAX
-};
-
-/**
- * struct mtk_vdec_hw_dev - vdec hardware driver data
- * @plat_dev: platform device
- * @main_dev: main device
- * @reg_base: mapped address of MTK Vcodec registers.
- *
- * @curr_ctx: the context that is waiting for codec hardware
- *
- * @dec_irq : decoder irq resource
- * @pm : power management control
- * @hw_idx : each hardware index
- */
-struct mtk_vdec_hw_dev {
- struct platform_device *plat_dev;
- struct mtk_vcodec_dev *main_dev;
- void __iomem *reg_base[VDEC_HW_MAX];
-
- struct mtk_vcodec_ctx *curr_ctx;
-
- int dec_irq;
- struct mtk_vcodec_pm pm;
- int hw_idx;
-};
-
-#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
deleted file mode 100644
index 7e0c2644bf7b..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/pm_runtime.h>
-
-#include "mtk_vcodec_dec_hw.h"
-#include "mtk_vcodec_dec_pm.h"
-#include "mtk_vcodec_util.h"
-
-int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm)
-{
- struct mtk_vcodec_clk *dec_clk;
- struct mtk_vcodec_clk_info *clk_info;
- int i = 0, ret;
-
- dec_clk = &pm->vdec_clk;
- pm->dev = &pdev->dev;
-
- dec_clk->clk_num =
- of_property_count_strings(pdev->dev.of_node, "clock-names");
- if (dec_clk->clk_num > 0) {
- dec_clk->clk_info = devm_kcalloc(&pdev->dev,
- dec_clk->clk_num, sizeof(*clk_info),
- GFP_KERNEL);
- if (!dec_clk->clk_info)
- return -ENOMEM;
- } else {
- mtk_v4l2_err("Failed to get vdec clock count");
- return -EINVAL;
- }
-
- for (i = 0; i < dec_clk->clk_num; i++) {
- clk_info = &dec_clk->clk_info[i];
- ret = of_property_read_string_index(pdev->dev.of_node,
- "clock-names", i, &clk_info->clk_name);
- if (ret) {
- mtk_v4l2_err("Failed to get clock name id = %d", i);
- return ret;
- }
- clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
- clk_info->clk_name);
- if (IS_ERR(clk_info->vcodec_clk)) {
- mtk_v4l2_err("devm_clk_get (%d)%s fail", i,
- clk_info->clk_name);
- return PTR_ERR(clk_info->vcodec_clk);
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
-
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
-{
- struct mtk_vdec_hw_dev *subdev_dev;
- struct mtk_vcodec_pm *pm;
- int ret;
-
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev\n");
- return -EINVAL;
- }
- pm = &subdev_dev->pm;
- } else {
- pm = &vdec_dev->pm;
- }
-
- ret = pm_runtime_resume_and_get(pm->dev);
- if (ret)
- mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
-
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
-{
- struct mtk_vdec_hw_dev *subdev_dev;
- struct mtk_vcodec_pm *pm;
- int ret;
-
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev\n");
- return;
- }
- pm = &subdev_dev->pm;
- } else {
- pm = &vdec_dev->pm;
- }
-
- ret = pm_runtime_put_sync(pm->dev);
- if (ret)
- mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
-
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
-{
- struct mtk_vdec_hw_dev *subdev_dev;
- struct mtk_vcodec_pm *pm;
- struct mtk_vcodec_clk *dec_clk;
- int ret, i;
-
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev\n");
- return;
- }
- pm = &subdev_dev->pm;
- enable_irq(subdev_dev->dec_irq);
- } else {
- pm = &vdec_dev->pm;
- enable_irq(vdec_dev->dec_irq);
- }
-
- dec_clk = &pm->vdec_clk;
- for (i = 0; i < dec_clk->clk_num; i++) {
- ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
- if (ret) {
- mtk_v4l2_err("clk_prepare_enable %d %s fail %d", i,
- dec_clk->clk_info[i].clk_name, ret);
- goto error;
- }
- }
-
- return;
-error:
- for (i -= 1; i >= 0; i--)
- clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
-
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
-{
- struct mtk_vdec_hw_dev *subdev_dev;
- struct mtk_vcodec_pm *pm;
- struct mtk_vcodec_clk *dec_clk;
- int i;
-
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev\n");
- return;
- }
- pm = &subdev_dev->pm;
- disable_irq(subdev_dev->dec_irq);
- } else {
- pm = &vdec_dev->pm;
- disable_irq(vdec_dev->dec_irq);
- }
-
- dec_clk = &pm->vdec_clk;
- for (i = dec_clk->clk_num - 1; i >= 0; i--)
- clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
deleted file mode 100644
index 3cc721bbfaf6..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _MTK_VCODEC_DEC_PM_H_
-#define _MTK_VCODEC_DEC_PM_H_
-
-#include "mtk_vcodec_drv.h"
-
-int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
-
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-
-#endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
deleted file mode 100644
index 04ca43c77e5f..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ /dev/null
@@ -1,630 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_dec_pm.h"
-#include "vdec_drv_if.h"
-
-static const struct mtk_video_fmt mtk_video_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_H264,
- .type = MTK_FMT_DEC,
- .num_planes = 1,
- .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- },
- {
- .fourcc = V4L2_PIX_FMT_VP8,
- .type = MTK_FMT_DEC,
- .num_planes = 1,
- .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- },
- {
- .fourcc = V4L2_PIX_FMT_VP9,
- .type = MTK_FMT_DEC,
- .num_planes = 1,
- .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
- },
- {
- .fourcc = V4L2_PIX_FMT_MT21C,
- .type = MTK_FMT_FRAME,
- .num_planes = 2,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX 0
-#define DEFAULT_CAP_FMT_IDX 3
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
- {
- .fourcc = V4L2_PIX_FMT_H264,
- .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
- MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
- },
- {
- .fourcc = V4L2_PIX_FMT_VP8,
- .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
- MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
- },
- {
- .fourcc = V4L2_PIX_FMT_VP9,
- .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
- MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
- },
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
-/*
- * This function tries to clean all display buffers, the buffers will return
- * in display order.
- * Note the buffers returned from codec driver may still be in driver's
- * reference list.
- */
-static struct vb2_buffer *get_display_buffer(struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_fb *disp_frame_buffer = NULL;
- struct mtk_video_dec_buf *dstbuf;
- struct vb2_v4l2_buffer *vb;
-
- mtk_v4l2_debug(3, "[%d]", ctx->id);
- if (vdec_if_get_param(ctx, GET_PARAM_DISP_FRAME_BUFFER,
- &disp_frame_buffer)) {
- mtk_v4l2_err("[%d]Cannot get param : GET_PARAM_DISP_FRAME_BUFFER", ctx->id);
- return NULL;
- }
-
- if (!disp_frame_buffer) {
- mtk_v4l2_debug(3, "No display frame buffer");
- return NULL;
- }
-
- dstbuf = container_of(disp_frame_buffer, struct mtk_video_dec_buf,
- frame_buffer);
- vb = &dstbuf->m2m_buf.vb;
- mutex_lock(&ctx->lock);
- if (dstbuf->used) {
- vb2_set_plane_payload(&vb->vb2_buf, 0, ctx->picinfo.fb_sz[0]);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
- vb2_set_plane_payload(&vb->vb2_buf, 1,
- ctx->picinfo.fb_sz[1]);
-
- mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to done_list %d",
- ctx->id, disp_frame_buffer->status,
- vb->vb2_buf.index, dstbuf->queued_in_vb2);
-
- v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
- ctx->decoded_frame_cnt++;
- }
- mutex_unlock(&ctx->lock);
- return &vb->vb2_buf;
-}
-
-/*
- * This function tries to clean all capture buffers that are not used as
- * reference buffers by codec driver any more
- * In this case, we need re-queue buffer to vb2 buffer if user space
- * already returns this buffer to v4l2 or this buffer is just the output of
- * previous sps/pps/resolution change decode, or do nothing if user
- * space still owns this buffer
- */
-static struct vb2_buffer *get_free_buffer(struct mtk_vcodec_ctx *ctx)
-{
- struct mtk_video_dec_buf *dstbuf;
- struct vdec_fb *free_frame_buffer = NULL;
- struct vb2_v4l2_buffer *vb;
-
- if (vdec_if_get_param(ctx, GET_PARAM_FREE_FRAME_BUFFER,
- &free_frame_buffer)) {
- mtk_v4l2_err("[%d] Error!! Cannot get param", ctx->id);
- return NULL;
- }
- if (!free_frame_buffer) {
- mtk_v4l2_debug(3, " No free frame buffer");
- return NULL;
- }
-
- mtk_v4l2_debug(3, "[%d] tmp_frame_addr = 0x%p", ctx->id,
- free_frame_buffer);
-
- dstbuf = container_of(free_frame_buffer, struct mtk_video_dec_buf,
- frame_buffer);
- vb = &dstbuf->m2m_buf.vb;
-
- mutex_lock(&ctx->lock);
- if (dstbuf->used) {
- if (dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2 &&
- free_frame_buffer->status == FB_ST_FREE) {
- /*
- * After decode sps/pps or non-display buffer, we don't
- * need to return capture buffer to user space, but
- * just re-queue this capture buffer to vb2 queue.
- * This reduce overheads that dq/q unused capture
- * buffer. In this case, queued_in_vb2 = true.
- */
- mtk_v4l2_debug(2, "[%d]status=%x queue id=%d to rdy_queue %d",
- ctx->id, free_frame_buffer->status,
- vb->vb2_buf.index, dstbuf->queued_in_vb2);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
- } else if (!dstbuf->queued_in_vb2 && dstbuf->queued_in_v4l2) {
- /*
- * If buffer in v4l2 driver but not in vb2 queue yet,
- * and we get this buffer from free_list, it means
- * that codec driver do not use this buffer as
- * reference buffer anymore. We should q buffer to vb2
- * queue, so later work thread could get this buffer
- * for decode. In this case, queued_in_vb2 = false
- * means this buffer is not from previous decode
- * output.
- */
- mtk_v4l2_debug(2,
- "[%d]status=%x queue id=%d to rdy_queue",
- ctx->id, free_frame_buffer->status,
- vb->vb2_buf.index);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
- dstbuf->queued_in_vb2 = true;
- } else {
- /*
- * Codec driver do not need to reference this capture
- * buffer and this buffer is not in v4l2 driver.
- * Then we don't need to do any thing, just add log when
- * we need to debug buffer flow.
- * When this buffer q from user space, it could
- * directly q to vb2 buffer
- */
- mtk_v4l2_debug(3, "[%d]status=%x err queue id=%d %d %d",
- ctx->id, free_frame_buffer->status,
- vb->vb2_buf.index, dstbuf->queued_in_vb2,
- dstbuf->queued_in_v4l2);
- }
- dstbuf->used = false;
- }
- mutex_unlock(&ctx->lock);
- return &vb->vb2_buf;
-}
-
-static void clean_display_buffer(struct mtk_vcodec_ctx *ctx)
-{
- while (get_display_buffer(ctx))
- ;
-}
-
-static void clean_free_buffer(struct mtk_vcodec_ctx *ctx)
-{
- while (get_free_buffer(ctx))
- ;
-}
-
-static void mtk_vdec_queue_res_chg_event(struct mtk_vcodec_ctx *ctx)
-{
- static const struct v4l2_event ev_src_ch = {
- .type = V4L2_EVENT_SOURCE_CHANGE,
- .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
- };
-
- mtk_v4l2_debug(1, "[%d]", ctx->id);
- v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
-}
-
-static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
-{
- bool res_chg;
- int ret;
-
- ret = vdec_if_decode(ctx, NULL, NULL, &res_chg);
- if (ret)
- mtk_v4l2_err("DecodeFinal failed, ret=%d", ret);
-
- clean_display_buffer(ctx);
- clean_free_buffer(ctx);
-
- return 0;
-}
-
-static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
- unsigned int pixelformat)
-{
- const struct mtk_video_fmt *fmt;
- struct mtk_q_data *dst_q_data;
- unsigned int k;
-
- dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
- for (k = 0; k < NUM_FORMATS; k++) {
- fmt = &mtk_video_formats[k];
- if (fmt->fourcc == pixelformat) {
- mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
- dst_q_data->fmt->fourcc, pixelformat);
- dst_q_data->fmt = fmt;
- return;
- }
- }
-
- mtk_v4l2_err("Cannot get fourcc(%d), using init value", pixelformat);
-}
-
-static int mtk_vdec_pic_info_update(struct mtk_vcodec_ctx *ctx)
-{
- unsigned int dpbsize = 0;
- int ret;
-
- if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO,
- &ctx->last_decoded_picinfo)) {
- mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
- return -EINVAL;
- }
-
- if (ctx->last_decoded_picinfo.pic_w == 0 ||
- ctx->last_decoded_picinfo.pic_h == 0 ||
- ctx->last_decoded_picinfo.buf_w == 0 ||
- ctx->last_decoded_picinfo.buf_h == 0) {
- mtk_v4l2_err("Cannot get correct pic info");
- return -EINVAL;
- }
-
- if (ctx->last_decoded_picinfo.cap_fourcc != ctx->picinfo.cap_fourcc &&
- ctx->picinfo.cap_fourcc != 0)
- mtk_vdec_update_fmt(ctx, ctx->picinfo.cap_fourcc);
-
- if (ctx->last_decoded_picinfo.pic_w == ctx->picinfo.pic_w ||
- ctx->last_decoded_picinfo.pic_h == ctx->picinfo.pic_h)
- return 0;
-
- mtk_v4l2_debug(1, "[%d]-> new(%d,%d), old(%d,%d), real(%d,%d)", ctx->id,
- ctx->last_decoded_picinfo.pic_w,
- ctx->last_decoded_picinfo.pic_h, ctx->picinfo.pic_w,
- ctx->picinfo.pic_h, ctx->last_decoded_picinfo.buf_w,
- ctx->last_decoded_picinfo.buf_h);
-
- ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
- if (dpbsize == 0)
- mtk_v4l2_err("Incorrect dpb size, ret=%d", ret);
-
- ctx->dpb_size = dpbsize;
-
- return ret;
-}
-
-static void mtk_vdec_worker(struct work_struct *work)
-{
- struct mtk_vcodec_ctx *ctx =
- container_of(work, struct mtk_vcodec_ctx, decode_work);
- struct mtk_vcodec_dev *dev = ctx->dev;
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
- struct mtk_vcodec_mem buf;
- struct vdec_fb *pfb;
- bool res_chg = false;
- int ret;
- struct mtk_video_dec_buf *dst_buf_info, *src_buf_info;
-
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- if (!src_buf) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_debug(1, "[%d] src_buf empty!!", ctx->id);
- return;
- }
-
- dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- if (!dst_buf) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
- return;
- }
-
- dst_buf_info =
- container_of(dst_buf, struct mtk_video_dec_buf, m2m_buf.vb);
-
- pfb = &dst_buf_info->frame_buffer;
- pfb->base_y.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
- pfb->base_y.dma_addr =
- vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
- pfb->base_y.size = ctx->picinfo.fb_sz[0];
-
- pfb->base_c.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 1);
- pfb->base_c.dma_addr =
- vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 1);
- pfb->base_c.size = ctx->picinfo.fb_sz[1];
- pfb->status = 0;
- mtk_v4l2_debug(3, "===>[%d] vdec_if_decode() ===>", ctx->id);
-
- mtk_v4l2_debug(3,
- "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx",
- dst_buf->vb2_buf.index, pfb, pfb->base_y.va,
- &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size);
-
- if (src_buf == &ctx->empty_flush_buf.vb) {
- mtk_v4l2_debug(1, "Got empty flush input buffer.");
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
- /* update dst buf status */
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
- mutex_lock(&ctx->lock);
- dst_buf_info->used = false;
- mutex_unlock(&ctx->lock);
-
- vdec_if_decode(ctx, NULL, NULL, &res_chg);
- clean_display_buffer(ctx);
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
- vb2_set_plane_payload(&dst_buf->vb2_buf, 1, 0);
- dst_buf->flags |= V4L2_BUF_FLAG_LAST;
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
- clean_free_buffer(ctx);
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- return;
- }
-
- src_buf_info =
- container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb);
-
- buf.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
- buf.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
- buf.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
- if (!buf.va) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_err("[%d] id=%d src_addr is NULL!!", ctx->id,
- src_buf->vb2_buf.index);
- return;
- }
- mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
- ctx->id, buf.va, &buf.dma_addr, buf.size, src_buf);
- dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
- dst_buf->timecode = src_buf->timecode;
- mutex_lock(&ctx->lock);
- dst_buf_info->used = true;
- mutex_unlock(&ctx->lock);
- src_buf_info->used = true;
-
- ret = vdec_if_decode(ctx, &buf, pfb, &res_chg);
-
- if (ret) {
- mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu dst_buf[%d] vdec_if_decode() ret=%d res_chg=%d===>",
- ctx->id, src_buf->vb2_buf.index, buf.size,
- src_buf->vb2_buf.timestamp, dst_buf->vb2_buf.index, ret, res_chg);
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ret == -EIO) {
- mutex_lock(&ctx->lock);
- src_buf_info->error = true;
- mutex_unlock(&ctx->lock);
- }
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- } else if (!res_chg) {
- /*
- * we only return src buffer with VB2_BUF_STATE_DONE
- * when decode success without resolution change
- */
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
- }
-
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
- clean_display_buffer(ctx);
- clean_free_buffer(ctx);
-
- if (!ret && res_chg) {
- mtk_vdec_pic_info_update(ctx);
- /*
- * On encountering a resolution change in the stream.
- * The driver must first process and decode all
- * remaining buffers from before the resolution change
- * point, so call flush decode here
- */
- mtk_vdec_flush_decoder(ctx);
- /*
- * After all buffers containing decoded frames from
- * before the resolution change point ready to be
- * dequeued on the CAPTURE queue, the driver sends a
- * V4L2_EVENT_SOURCE_CHANGE event for source change
- * type V4L2_EVENT_SRC_CH_RESOLUTION
- */
- mtk_vdec_queue_res_chg_event(ctx);
- }
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-}
-
-static void vb2ops_vdec_stateful_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *src_buf;
- struct mtk_vcodec_mem src_mem;
- bool res_chg = false;
- int ret;
- unsigned int dpbsize = 1, i;
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2;
- struct mtk_q_data *dst_q_data;
-
- mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
- vb->vb2_queue->type, vb->index, vb);
- /*
- * check if this buffer is ready to be used after decode
- */
- if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- struct mtk_video_dec_buf *buf;
-
- vb2_v4l2 = to_vb2_v4l2_buffer(vb);
- buf = container_of(vb2_v4l2, struct mtk_video_dec_buf,
- m2m_buf.vb);
- mutex_lock(&ctx->lock);
- if (!buf->used) {
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
- buf->queued_in_vb2 = true;
- buf->queued_in_v4l2 = true;
- } else {
- buf->queued_in_vb2 = false;
- buf->queued_in_v4l2 = true;
- }
- mutex_unlock(&ctx->lock);
- return;
- }
-
- v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
-
- if (ctx->state != MTK_STATE_INIT) {
- mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id,
- ctx->state);
- return;
- }
-
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- if (!src_buf) {
- mtk_v4l2_err("No src buffer");
- return;
- }
-
- if (src_buf == &ctx->empty_flush_buf.vb) {
- /* This shouldn't happen. Just in case. */
- mtk_v4l2_err("Invalid flush buffer.");
- v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- return;
- }
-
- src_mem.va = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
- src_mem.dma_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
- src_mem.size = (size_t)src_buf->vb2_buf.planes[0].bytesused;
- mtk_v4l2_debug(2, "[%d] buf id=%d va=%p dma=%pad size=%zx", ctx->id,
- src_buf->vb2_buf.index, src_mem.va, &src_mem.dma_addr,
- src_mem.size);
-
- ret = vdec_if_decode(ctx, &src_mem, NULL, &res_chg);
- if (ret || !res_chg) {
- /*
- * fb == NULL means to parse SPS/PPS header or
- * resolution info in src_mem. Decode can fail
- * if there is no SPS header or picture info
- * in bs
- */
-
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- if (ret == -EIO) {
- mtk_v4l2_err("[%d] Unrecoverable error in vdec_if_decode.", ctx->id);
- ctx->state = MTK_STATE_ABORT;
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- } else {
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
- }
- mtk_v4l2_debug(ret ? 0 : 1,
- "[%d] vdec_if_decode() src_buf=%d, size=%zu, fail=%d, res_chg=%d",
- ctx->id, src_buf->vb2_buf.index, src_mem.size, ret, res_chg);
- return;
- }
-
- if (vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo)) {
- mtk_v4l2_err("[%d]Error!! Cannot get param : GET_PARAM_PICTURE_INFO ERR", ctx->id);
- return;
- }
-
- ctx->last_decoded_picinfo = ctx->picinfo;
- dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
- for (i = 0; i < dst_q_data->fmt->num_planes; i++) {
- dst_q_data->sizeimage[i] = ctx->picinfo.fb_sz[i];
- dst_q_data->bytesperline[i] = ctx->picinfo.buf_w;
- }
-
- mtk_v4l2_debug(2, "[%d] vdec_if_init() OK wxh=%dx%d pic wxh=%dx%d sz[0]=0x%x sz[1]=0x%x",
- ctx->id, ctx->picinfo.buf_w, ctx->picinfo.buf_h, ctx->picinfo.pic_w,
- ctx->picinfo.pic_h, dst_q_data->sizeimage[0], dst_q_data->sizeimage[1]);
-
- ret = vdec_if_get_param(ctx, GET_PARAM_DPB_SIZE, &dpbsize);
- if (dpbsize == 0)
- mtk_v4l2_err("[%d] GET_PARAM_DPB_SIZE fail=%d", ctx->id, ret);
-
- ctx->dpb_size = dpbsize;
- ctx->state = MTK_STATE_HEADER;
- mtk_v4l2_debug(1, "[%d] dpbsize=%d", ctx->id, ctx->dpb_size);
-
- mtk_vdec_queue_res_chg_event(ctx);
-}
-
-static int mtk_vdec_g_v_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
- if (ctx->state >= MTK_STATE_HEADER) {
- ctrl->val = ctx->dpb_size;
- } else {
- mtk_v4l2_debug(0, "Seqinfo not ready");
- ctrl->val = 0;
- }
- break;
- default:
- ret = -EINVAL;
- }
- return ret;
-}
-
-static const struct v4l2_ctrl_ops mtk_vcodec_dec_ctrl_ops = {
- .g_volatile_ctrl = mtk_vdec_g_v_ctrl,
-};
-
-static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
-{
- struct v4l2_ctrl *ctrl;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 1);
-
- ctrl = v4l2_ctrl_new_std(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
- V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 0, 32, 1, 1);
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
- v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
- V4L2_MPEG_VIDEO_VP9_PROFILE_0, 0,
- V4L2_MPEG_VIDEO_VP9_PROFILE_0);
- /*
- * H264. Baseline / Extended decoding is not supported.
- */
- v4l2_ctrl_new_std_menu(&ctx->ctrl_hdl, &mtk_vcodec_dec_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
- V4L2_MPEG_VIDEO_H264_PROFILE_MAIN);
-
- if (ctx->ctrl_hdl.error) {
- mtk_v4l2_err("Adding control failed %d", ctx->ctrl_hdl.error);
- return ctx->ctrl_hdl.error;
- }
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
- return 0;
-}
-
-static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
-{
-}
-
-static struct vb2_ops mtk_vdec_frame_vb2_ops = {
- .queue_setup = vb2ops_vdec_queue_setup,
- .buf_prepare = vb2ops_vdec_buf_prepare,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = vb2ops_vdec_start_streaming,
-
- .buf_queue = vb2ops_vdec_stateful_buf_queue,
- .buf_init = vb2ops_vdec_buf_init,
- .buf_finish = vb2ops_vdec_buf_finish,
- .stop_streaming = vb2ops_vdec_stop_streaming,
-};
-
-const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
- .chip = MTK_MT8173,
- .init_vdec_params = mtk_init_vdec_params,
- .ctrls_setup = mtk_vcodec_dec_ctrls_setup,
- .vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
- .vdec_formats = mtk_video_formats,
- .num_formats = NUM_FORMATS,
- .default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
- .default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
- .vdec_framesizes = mtk_vdec_framesizes,
- .num_framesizes = NUM_SUPPORTED_FRAMESIZE,
- .worker = mtk_vdec_worker,
- .flush_decoder = mtk_vdec_flush_decoder,
- .is_subdev_supported = false,
- .hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
-};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
deleted file mode 100644
index 23d997ac114d..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ /dev/null
@@ -1,380 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <linux/module.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_dec_pm.h"
-#include "vdec_drv_if.h"
-
-/**
- * struct mtk_stateless_control - CID control type
- * @cfg: control configuration
- * @codec_type: codec type (V4L2 pixel format) for CID control type
- */
-struct mtk_stateless_control {
- struct v4l2_ctrl_config cfg;
- int codec_type;
-};
-
-static const struct mtk_stateless_control mtk_stateless_controls[] = {
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_SPS,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_PPS,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
- .def = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN,
- .max = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
- .menu_skip_mask =
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
- BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_DECODE_MODE,
- .min = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
- .def = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
- .max = V4L2_STATELESS_H264_DECODE_MODE_FRAME_BASED,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- },
- {
- .cfg = {
- .id = V4L2_CID_STATELESS_H264_START_CODE,
- .min = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
- .def = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
- .max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
- },
- .codec_type = V4L2_PIX_FMT_H264_SLICE,
- }
-};
-
-#define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
-
-static const struct mtk_video_fmt mtk_video_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_H264_SLICE,
- .type = MTK_FMT_DEC,
- .num_planes = 1,
- },
- {
- .fourcc = V4L2_PIX_FMT_MM21,
- .type = MTK_FMT_FRAME,
- .num_planes = 2,
- },
-};
-
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX 0
-#define DEFAULT_CAP_FMT_IDX 1
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
- {
- .fourcc = V4L2_PIX_FMT_H264_SLICE,
- .stepwise = { MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
- MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
- },
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
-static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
- struct vdec_fb *fb)
-{
- struct mtk_video_dec_buf *vdec_frame_buf =
- container_of(fb, struct mtk_video_dec_buf, frame_buffer);
- struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
- unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
-
- vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
- unsigned int cap_c_size =
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
-
- vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
- }
-}
-
-static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
- struct vb2_v4l2_buffer *vb2_v4l2)
-{
- struct mtk_video_dec_buf *framebuf =
- container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
- struct vdec_fb *pfb = &framebuf->frame_buffer;
- struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
-
- pfb->base_y.va = NULL;
- pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
- pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
-
- if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
- pfb->base_c.va = NULL;
- pfb->base_c.dma_addr =
- vb2_dma_contig_plane_dma_addr(dst_buf, 1);
- pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
- }
- mtk_v4l2_debug(1, "id=%d Framebuf pfb=%p VA=%p Y_DMA=%pad C_DMA=%pad Size=%zx frame_count = %d",
- dst_buf->index, pfb, pfb->base_y.va, &pfb->base_y.dma_addr,
- &pfb->base_c.dma_addr, pfb->base_y.size, ctx->decoded_frame_cnt);
-
- return pfb;
-}
-
-static void vb2ops_vdec_buf_request_complete(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
- v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_hdl);
-}
-
-static void mtk_vdec_worker(struct work_struct *work)
-{
- struct mtk_vcodec_ctx *ctx =
- container_of(work, struct mtk_vcodec_ctx, decode_work);
- struct mtk_vcodec_dev *dev = ctx->dev;
- struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
- struct vb2_buffer *vb2_src;
- struct mtk_vcodec_mem *bs_src;
- struct mtk_video_dec_buf *dec_buf_src;
- struct media_request *src_buf_req;
- struct vdec_fb *dst_buf;
- bool res_chg = false;
- int ret;
-
- vb2_v4l2_src = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- if (!vb2_v4l2_src) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_debug(1, "[%d] no available source buffer", ctx->id);
- return;
- }
-
- vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- if (!vb2_v4l2_dst) {
- v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
- mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
- return;
- }
-
- vb2_src = &vb2_v4l2_src->vb2_buf;
- dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
- m2m_buf.vb);
- bs_src = &dec_buf_src->bs_buffer;
-
- mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
- vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
-
- bs_src->va = NULL;
- bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
- bs_src->size = (size_t)vb2_src->planes[0].bytesused;
-
- mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
- ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
- /* Apply request controls. */
- src_buf_req = vb2_src->req_obj.req;
- if (src_buf_req)
- v4l2_ctrl_request_setup(src_buf_req, &ctx->ctrl_hdl);
- else
- mtk_v4l2_err("vb2 buffer media request is NULL");
-
- dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
- v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
- ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
- if (ret) {
- mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
- ctx->id, vb2_src->index, bs_src->size,
- vb2_src->timestamp, ret, res_chg);
- if (ret == -EIO) {
- mutex_lock(&ctx->lock);
- dec_buf_src->error = true;
- mutex_unlock(&ctx->lock);
- }
- }
-
- mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
-
- v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
- ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
- v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
-}
-
-static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2 = to_vb2_v4l2_buffer(vb);
-
- mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id, vb->vb2_queue->type, vb->index, vb);
-
- mutex_lock(&ctx->lock);
- v4l2_m2m_buf_queue(ctx->m2m_ctx, vb2_v4l2);
- mutex_unlock(&ctx->lock);
- if (vb->vb2_queue->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return;
-
- /* If an OUTPUT buffer, we may need to update the state */
- if (ctx->state == MTK_STATE_INIT) {
- ctx->state = MTK_STATE_HEADER;
- mtk_v4l2_debug(1, "Init driver from init to header.");
- } else {
- mtk_v4l2_debug(3, "[%d] already init driver %d", ctx->id, ctx->state);
- }
-}
-
-static int mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx)
-{
- bool res_chg;
-
- return vdec_if_decode(ctx, NULL, NULL, &res_chg);
-}
-
-static int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx)
-{
- unsigned int i;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_hdl, NUM_CTRLS);
- if (ctx->ctrl_hdl.error) {
- mtk_v4l2_err("v4l2_ctrl_handler_init failed\n");
- return ctx->ctrl_hdl.error;
- }
-
- for (i = 0; i < NUM_CTRLS; i++) {
- struct v4l2_ctrl_config cfg = mtk_stateless_controls[i].cfg;
-
- v4l2_ctrl_new_custom(&ctx->ctrl_hdl, &cfg, NULL);
- if (ctx->ctrl_hdl.error) {
- mtk_v4l2_err("Adding control %d failed %d", i, ctx->ctrl_hdl.error);
- return ctx->ctrl_hdl.error;
- }
- }
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
-
- return 0;
-}
-
-static int fops_media_request_validate(struct media_request *mreq)
-{
- const unsigned int buffer_cnt = vb2_request_buffer_cnt(mreq);
-
- switch (buffer_cnt) {
- case 1:
- /* We expect exactly one buffer with the request */
- break;
- case 0:
- mtk_v4l2_debug(1, "No buffer provided with the request");
- return -ENOENT;
- default:
- mtk_v4l2_debug(1, "Too many buffers (%d) provided with the request",
- buffer_cnt);
- return -EINVAL;
- }
-
- return vb2_request_validate(mreq);
-}
-
-const struct media_device_ops mtk_vcodec_media_ops = {
- .req_validate = fops_media_request_validate,
- .req_queue = v4l2_m2m_request_queue,
-};
-
-static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
-{
- struct vb2_queue *src_vq;
-
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
-
- /* Support request api for output plane */
- src_vq->supports_requests = true;
- src_vq->requires_requests = true;
-}
-
-static int vb2ops_vdec_out_buf_validate(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
- vbuf->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static struct vb2_ops mtk_vdec_request_vb2_ops = {
- .queue_setup = vb2ops_vdec_queue_setup,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = vb2ops_vdec_start_streaming,
- .stop_streaming = vb2ops_vdec_stop_streaming,
-
- .buf_queue = vb2ops_vdec_stateless_buf_queue,
- .buf_out_validate = vb2ops_vdec_out_buf_validate,
- .buf_init = vb2ops_vdec_buf_init,
- .buf_prepare = vb2ops_vdec_buf_prepare,
- .buf_finish = vb2ops_vdec_buf_finish,
- .buf_request_complete = vb2ops_vdec_buf_request_complete,
-};
-
-const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
- .chip = MTK_MT8183,
- .init_vdec_params = mtk_init_vdec_params,
- .ctrls_setup = mtk_vcodec_dec_ctrls_setup,
- .vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
- .vdec_formats = mtk_video_formats,
- .num_formats = NUM_FORMATS,
- .default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
- .default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
- .vdec_framesizes = mtk_vdec_framesizes,
- .num_framesizes = NUM_SUPPORTED_FRAMESIZE,
- .uses_stateless_api = true,
- .worker = mtk_vdec_worker,
- .flush_decoder = mtk_vdec_flush_decoder,
- .is_subdev_supported = false,
- .hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
-};
-
-/* This platform data is used for one lat and one core architecture. */
-const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
- .chip = MTK_MT8192,
- .init_vdec_params = mtk_init_vdec_params,
- .ctrls_setup = mtk_vcodec_dec_ctrls_setup,
- .vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
- .vdec_formats = mtk_video_formats,
- .num_formats = NUM_FORMATS,
- .default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
- .default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
- .vdec_framesizes = mtk_vdec_framesizes,
- .num_framesizes = NUM_SUPPORTED_FRAMESIZE,
- .uses_stateless_api = true,
- .worker = mtk_vdec_worker,
- .flush_decoder = mtk_vdec_flush_decoder,
- .is_subdev_supported = true,
- .hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
-};
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
deleted file mode 100644
index 813901c4be5e..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ /dev/null
@@ -1,537 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#ifndef _MTK_VCODEC_DRV_H_
-#define _MTK_VCODEC_DRV_H_
-
-#include <linux/platform_device.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-core.h>
-
-#include "mtk_vcodec_util.h"
-#include "vdec_msg_queue.h"
-
-#define MTK_VCODEC_DRV_NAME "mtk_vcodec_drv"
-#define MTK_VCODEC_DEC_NAME "mtk-vcodec-dec"
-#define MTK_VCODEC_ENC_NAME "mtk-vcodec-enc"
-#define MTK_PLATFORM_STR "platform:mt8173"
-
-#define MTK_VCODEC_MAX_PLANES 3
-#define MTK_V4L2_BENCHMARK 0
-#define WAIT_INTR_TIMEOUT_MS 1000
-#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
-
-/*
- * enum mtk_hw_reg_idx - MTK hw register base index
- */
-enum mtk_hw_reg_idx {
- VDEC_SYS,
- VDEC_MISC,
- VDEC_LD,
- VDEC_TOP,
- VDEC_CM,
- VDEC_AD,
- VDEC_AV,
- VDEC_PP,
- VDEC_HWD,
- VDEC_HWQ,
- VDEC_HWB,
- VDEC_HWG,
- NUM_MAX_VDEC_REG_BASE,
- /* h264 encoder */
- VENC_SYS = NUM_MAX_VDEC_REG_BASE,
- /* vp8 encoder */
- VENC_LT_SYS,
- NUM_MAX_VCODEC_REG_BASE
-};
-
-/*
- * enum mtk_instance_type - The type of an MTK Vcodec instance.
- */
-enum mtk_instance_type {
- MTK_INST_DECODER = 0,
- MTK_INST_ENCODER = 1,
-};
-
-/**
- * enum mtk_instance_state - The state of an MTK Vcodec instance.
- * @MTK_STATE_FREE: default state when instance is created
- * @MTK_STATE_INIT: vcodec instance is initialized
- * @MTK_STATE_HEADER: vdec had sps/pps header parsed or venc
- * had sps/pps header encoded
- * @MTK_STATE_FLUSH: vdec is flushing. Only used by decoder
- * @MTK_STATE_ABORT: vcodec should be aborted
- */
-enum mtk_instance_state {
- MTK_STATE_FREE = 0,
- MTK_STATE_INIT = 1,
- MTK_STATE_HEADER = 2,
- MTK_STATE_FLUSH = 3,
- MTK_STATE_ABORT = 4,
-};
-
-/*
- * enum mtk_encode_param - General encoding parameters type
- */
-enum mtk_encode_param {
- MTK_ENCODE_PARAM_NONE = 0,
- MTK_ENCODE_PARAM_BITRATE = (1 << 0),
- MTK_ENCODE_PARAM_FRAMERATE = (1 << 1),
- MTK_ENCODE_PARAM_INTRA_PERIOD = (1 << 2),
- MTK_ENCODE_PARAM_FORCE_INTRA = (1 << 3),
- MTK_ENCODE_PARAM_GOP_SIZE = (1 << 4),
-};
-
-enum mtk_fmt_type {
- MTK_FMT_DEC = 0,
- MTK_FMT_ENC = 1,
- MTK_FMT_FRAME = 2,
-};
-
-/*
- * enum mtk_vdec_hw_id - Hardware index used to separate
- * different hardware
- */
-enum mtk_vdec_hw_id {
- MTK_VDEC_CORE,
- MTK_VDEC_LAT0,
- MTK_VDEC_LAT1,
- MTK_VDEC_HW_MAX,
-};
-
-/*
- * enum mtk_vdec_hw_count - Supported hardware count
- */
-enum mtk_vdec_hw_count {
- MTK_VDEC_NO_HW = 0,
- MTK_VDEC_ONE_CORE,
- MTK_VDEC_ONE_LAT_ONE_CORE,
- MTK_VDEC_MAX_HW_COUNT,
-};
-
-/*
- * struct mtk_video_fmt - Structure used to store information about pixelformats
- */
-struct mtk_video_fmt {
- u32 fourcc;
- enum mtk_fmt_type type;
- u32 num_planes;
- u32 flags;
-};
-
-/*
- * struct mtk_codec_framesizes - Structure used to store information about
- * framesizes
- */
-struct mtk_codec_framesizes {
- u32 fourcc;
- struct v4l2_frmsize_stepwise stepwise;
-};
-
-/*
- * enum mtk_q_type - Type of queue
- */
-enum mtk_q_type {
- MTK_Q_DATA_SRC = 0,
- MTK_Q_DATA_DST = 1,
-};
-
-/*
- * struct mtk_q_data - Structure used to store information about queue
- */
-struct mtk_q_data {
- unsigned int visible_width;
- unsigned int visible_height;
- unsigned int coded_width;
- unsigned int coded_height;
- enum v4l2_field field;
- unsigned int bytesperline[MTK_VCODEC_MAX_PLANES];
- unsigned int sizeimage[MTK_VCODEC_MAX_PLANES];
- const struct mtk_video_fmt *fmt;
-};
-
-/**
- * struct mtk_enc_params - General encoding parameters
- * @bitrate: target bitrate in bits per second
- * @num_b_frame: number of b frames between p-frame
- * @rc_frame: frame based rate control
- * @rc_mb: macroblock based rate control
- * @seq_hdr_mode: H.264 sequence header is encoded separately or joined
- * with the first frame
- * @intra_period: I frame period
- * @gop_size: group of picture size, it's used as the intra frame period
- * @framerate_num: frame rate numerator. ex: framerate_num=30 and
- * framerate_denom=1 means FPS is 30
- * @framerate_denom: frame rate denominator. ex: framerate_num=30 and
- * framerate_denom=1 means FPS is 30
- * @h264_max_qp: Max value for H.264 quantization parameter
- * @h264_profile: V4L2 defined H.264 profile
- * @h264_level: V4L2 defined H.264 level
- * @force_intra: force/insert intra frame
- */
-struct mtk_enc_params {
- unsigned int bitrate;
- unsigned int num_b_frame;
- unsigned int rc_frame;
- unsigned int rc_mb;
- unsigned int seq_hdr_mode;
- unsigned int intra_period;
- unsigned int gop_size;
- unsigned int framerate_num;
- unsigned int framerate_denom;
- unsigned int h264_max_qp;
- unsigned int h264_profile;
- unsigned int h264_level;
- unsigned int force_intra;
-};
-
-/*
- * struct mtk_vcodec_clk_info - Structure used to store clock name
- */
-struct mtk_vcodec_clk_info {
- const char *clk_name;
- struct clk *vcodec_clk;
-};
-
-/*
- * struct mtk_vcodec_clk - Structure used to store vcodec clock information
- */
-struct mtk_vcodec_clk {
- struct mtk_vcodec_clk_info *clk_info;
- int clk_num;
-};
-
-/*
- * struct mtk_vcodec_pm - Power management data structure
- */
-struct mtk_vcodec_pm {
- struct mtk_vcodec_clk vdec_clk;
- struct mtk_vcodec_clk venc_clk;
- struct device *dev;
-};
-
-/**
- * struct vdec_pic_info - picture size information
- * @pic_w: picture width
- * @pic_h: picture height
- * @buf_w: picture buffer width (64 aligned up from pic_w)
- * @buf_h: picture buffer heiht (64 aligned up from pic_h)
- * @fb_sz: bitstream size of each plane
- * E.g. suppose picture size is 176x144,
- * buffer size will be aligned to 176x160.
- * @cap_fourcc: fourcc number(may changed when resolution change)
- * @reserved: align struct to 64-bit in order to adjust 32-bit and 64-bit os.
- */
-struct vdec_pic_info {
- unsigned int pic_w;
- unsigned int pic_h;
- unsigned int buf_w;
- unsigned int buf_h;
- unsigned int fb_sz[VIDEO_MAX_PLANES];
- unsigned int cap_fourcc;
- unsigned int reserved;
-};
-
-/**
- * struct mtk_vcodec_ctx - Context (instance) private data.
- *
- * @type: type of the instance - decoder or encoder
- * @dev: pointer to the mtk_vcodec_dev of the device
- * @list: link to ctx_list of mtk_vcodec_dev
- * @fh: struct v4l2_fh
- * @m2m_ctx: pointer to the v4l2_m2m_ctx of the context
- * @q_data: store information of input and output queue
- * of the context
- * @id: index of the context that this structure describes
- * @state: state of the context
- * @param_change: indicate encode parameter type
- * @enc_params: encoding parameters
- * @dec_if: hooked decoder driver interface
- * @enc_if: hoooked encoder driver interface
- * @drv_handle: driver handle for specific decode/encode instance
- *
- * @picinfo: store picture info after header parsing
- * @dpb_size: store dpb count after header parsing
- * @int_cond: variable used by the waitqueue
- * @int_type: type of the last interrupt
- * @queue: waitqueue that can be used to wait for this context to
- * finish
- * @irq_status: irq status
- *
- * @ctrl_hdl: handler for v4l2 framework
- * @decode_work: worker for the decoding
- * @encode_work: worker for the encoding
- * @last_decoded_picinfo: pic information get from latest decode
- * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only
- * to be used with encoder and stateful decoder.
- * @is_flushing: set to true if flushing is in progress.
- * @current_codec: current set input codec, in V4L2 pixel format
- *
- * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
- * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
- * @quantization: enum v4l2_quantization, colorspace quantization
- * @xfer_func: enum v4l2_xfer_func, colorspace transfer function
- * @decoded_frame_cnt: number of decoded frames
- * @lock: protect variables accessed by V4L2 threads and worker thread such as
- * mtk_video_dec_buf.
- * @hw_id: hardware index used to identify different hardware.
- *
- * @msg_queue: msg queue used to store lat buffer information.
- */
-struct mtk_vcodec_ctx {
- enum mtk_instance_type type;
- struct mtk_vcodec_dev *dev;
- struct list_head list;
-
- struct v4l2_fh fh;
- struct v4l2_m2m_ctx *m2m_ctx;
- struct mtk_q_data q_data[2];
- int id;
- enum mtk_instance_state state;
- enum mtk_encode_param param_change;
- struct mtk_enc_params enc_params;
-
- const struct vdec_common_if *dec_if;
- const struct venc_common_if *enc_if;
- void *drv_handle;
-
- struct vdec_pic_info picinfo;
- int dpb_size;
-
- int int_cond[MTK_VDEC_HW_MAX];
- int int_type[MTK_VDEC_HW_MAX];
- wait_queue_head_t queue[MTK_VDEC_HW_MAX];
- unsigned int irq_status;
-
- struct v4l2_ctrl_handler ctrl_hdl;
- struct work_struct decode_work;
- struct work_struct encode_work;
- struct vdec_pic_info last_decoded_picinfo;
- struct v4l2_m2m_buffer empty_flush_buf;
- bool is_flushing;
-
- u32 current_codec;
-
- enum v4l2_colorspace colorspace;
- enum v4l2_ycbcr_encoding ycbcr_enc;
- enum v4l2_quantization quantization;
- enum v4l2_xfer_func xfer_func;
-
- int decoded_frame_cnt;
- struct mutex lock;
- int hw_id;
-
- struct vdec_msg_queue msg_queue;
-};
-
-enum mtk_chip {
- MTK_MT8173,
- MTK_MT8183,
- MTK_MT8192,
- MTK_MT8195,
-};
-
-/*
- * enum mtk_vdec_hw_arch - Used to separate different hardware architecture
- */
-enum mtk_vdec_hw_arch {
- MTK_VDEC_PURE_SINGLE_CORE,
- MTK_VDEC_LAT_SINGLE_CORE,
-};
-
-/**
- * struct mtk_vcodec_dec_pdata - compatible data for each IC
- * @init_vdec_params: init vdec params
- * @ctrls_setup: init vcodec dec ctrls
- * @worker: worker to start a decode job
- * @flush_decoder: function that flushes the decoder
- *
- * @vdec_vb2_ops: struct vb2_ops
- *
- * @vdec_formats: supported video decoder formats
- * @num_formats: count of video decoder formats
- * @default_out_fmt: default output buffer format
- * @default_cap_fmt: default capture buffer format
- *
- * @vdec_framesizes: supported video decoder frame sizes
- * @num_framesizes: count of video decoder frame sizes
- *
- * @chip: chip this decoder is compatible with
- * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
- *
- * @is_subdev_supported: whether support parent-node architecture(subdev)
- * @uses_stateless_api: whether the decoder uses the stateless API with requests
- */
-
-struct mtk_vcodec_dec_pdata {
- void (*init_vdec_params)(struct mtk_vcodec_ctx *ctx);
- int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
- void (*worker)(struct work_struct *work);
- int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
-
- struct vb2_ops *vdec_vb2_ops;
-
- const struct mtk_video_fmt *vdec_formats;
- const int num_formats;
- const struct mtk_video_fmt *default_out_fmt;
- const struct mtk_video_fmt *default_cap_fmt;
-
- const struct mtk_codec_framesizes *vdec_framesizes;
- const int num_framesizes;
-
- enum mtk_chip chip;
- enum mtk_vdec_hw_arch hw_arch;
-
- bool is_subdev_supported;
- bool uses_stateless_api;
-};
-
-/**
- * struct mtk_vcodec_enc_pdata - compatible data for each IC
- *
- * @chip: chip this encoder is compatible with
- *
- * @uses_ext: whether the encoder uses the extended firmware messaging format
- * @min_bitrate: minimum supported encoding bitrate
- * @max_bitrate: maximum supported encoding bitrate
- * @capture_formats: array of supported capture formats
- * @num_capture_formats: number of entries in capture_formats
- * @output_formats: array of supported output formats
- * @num_output_formats: number of entries in output_formats
- * @core_id: stand for h264 or vp8 encode index
- */
-struct mtk_vcodec_enc_pdata {
- enum mtk_chip chip;
-
- bool uses_ext;
- unsigned long min_bitrate;
- unsigned long max_bitrate;
- const struct mtk_video_fmt *capture_formats;
- size_t num_capture_formats;
- const struct mtk_video_fmt *output_formats;
- size_t num_output_formats;
- int core_id;
-};
-
-#define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
-
-/**
- * struct mtk_vcodec_dev - driver data
- * @v4l2_dev: V4L2 device to register video devices for.
- * @vfd_dec: Video device for decoder
- * @mdev_dec: Media device for decoder
- * @vfd_enc: Video device for encoder.
- *
- * @m2m_dev_dec: m2m device for decoder
- * @m2m_dev_enc: m2m device for encoder.
- * @plat_dev: platform device
- * @ctx_list: list of struct mtk_vcodec_ctx
- * @irqlock: protect data access by irq handler and work thread
- * @curr_ctx: The context that is waiting for codec hardware
- *
- * @reg_base: Mapped address of MTK Vcodec registers.
- * @vdec_pdata: decoder IC-specific data
- * @venc_pdata: encoder IC-specific data
- *
- * @fw_handler: used to communicate with the firmware.
- * @id_counter: used to identify current opened instance
- *
- * @decode_workqueue: decode work queue
- * @encode_workqueue: encode work queue
- *
- * @int_cond: used to identify interrupt condition happen
- * @int_type: used to identify what kind of interrupt condition happen
- * @dev_mutex: video_device lock
- * @queue: waitqueue for waiting for completion of device commands
- *
- * @dec_irq: decoder irq resource
- * @enc_irq: h264 encoder irq resource
- *
- * @dec_mutex: decoder hardware lock
- * @enc_mutex: encoder hardware lock.
- *
- * @pm: power management control
- * @dec_capability: used to identify decode capability, ex: 4k
- * @enc_capability: used to identify encode capability
- *
- * @core_workqueue: queue used for core hardware decode
- * @msg_queue_core_ctx: msg queue context used for core workqueue
- *
- * @subdev_dev: subdev hardware device
- * @subdev_prob_done: check whether all used hw device is prob done
- * @subdev_bitmap: used to record hardware is ready or not
- */
-struct mtk_vcodec_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vfd_dec;
- struct media_device mdev_dec;
- struct video_device *vfd_enc;
-
- struct v4l2_m2m_dev *m2m_dev_dec;
- struct v4l2_m2m_dev *m2m_dev_enc;
- struct platform_device *plat_dev;
- struct list_head ctx_list;
- spinlock_t irqlock;
- struct mtk_vcodec_ctx *curr_ctx;
- void __iomem *reg_base[NUM_MAX_VCODEC_REG_BASE];
- const struct mtk_vcodec_dec_pdata *vdec_pdata;
- const struct mtk_vcodec_enc_pdata *venc_pdata;
-
- struct mtk_vcodec_fw *fw_handler;
-
- unsigned long id_counter;
-
- struct workqueue_struct *decode_workqueue;
- struct workqueue_struct *encode_workqueue;
- int int_cond;
- int int_type;
- struct mutex dev_mutex;
- wait_queue_head_t queue;
-
- int dec_irq;
- int enc_irq;
-
- /* decoder hardware mutex lock */
- struct mutex dec_mutex[MTK_VDEC_HW_MAX];
- struct mutex enc_mutex;
-
- struct mtk_vcodec_pm pm;
- unsigned int dec_capability;
- unsigned int enc_capability;
-
- struct workqueue_struct *core_workqueue;
- struct vdec_msg_queue_ctx msg_queue_core_ctx;
-
- void *subdev_dev[MTK_VDEC_HW_MAX];
- int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
- DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
-};
-
-static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-{
- return container_of(fh, struct mtk_vcodec_ctx, fh);
-}
-
-static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
-{
- return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
-}
-
-/* Wake up context wait_queue */
-static inline void
-wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason, unsigned int hw_id)
-{
- ctx->int_cond[hw_id] = 1;
- ctx->int_type[hw_id] = reason;
- wake_up_interruptible(&ctx->queue[hw_id]);
-}
-
-#endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
deleted file mode 100644
index c21367038c34..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ /dev/null
@@ -1,1451 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-dma-contig.h>
-#include <linux/pm_runtime.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_enc.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "venc_drv_if.h"
-
-#define MTK_VENC_MIN_W 160U
-#define MTK_VENC_MIN_H 128U
-#define MTK_VENC_HD_MAX_W 1920U
-#define MTK_VENC_HD_MAX_H 1088U
-#define MTK_VENC_4K_MAX_W 3840U
-#define MTK_VENC_4K_MAX_H 2176U
-
-#define DFT_CFG_WIDTH MTK_VENC_MIN_W
-#define DFT_CFG_HEIGHT MTK_VENC_MIN_H
-#define MTK_MAX_CTRLS_HINT 20
-
-#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);
-
-static const struct v4l2_frmsize_stepwise mtk_venc_hd_framesizes = {
- MTK_VENC_MIN_W, MTK_VENC_HD_MAX_W, 16,
- MTK_VENC_MIN_H, MTK_VENC_HD_MAX_H, 16,
-};
-
-static const struct v4l2_frmsize_stepwise mtk_venc_4k_framesizes = {
- MTK_VENC_MIN_W, MTK_VENC_4K_MAX_W, 16,
- MTK_VENC_MIN_H, MTK_VENC_4K_MAX_H, 16,
-};
-
-static int vidioc_venc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct mtk_vcodec_ctx *ctx = ctrl_to_ctx(ctrl);
- struct mtk_enc_params *p = &ctx->enc_params;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_BITRATE val = %d",
- ctrl->val);
- p->bitrate = ctrl->val;
- ctx->param_change |= MTK_ENCODE_PARAM_BITRATE;
- break;
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_B_FRAMES val = %d",
- ctrl->val);
- p->num_b_frame = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE val = %d",
- ctrl->val);
- p->rc_frame = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_MAX_QP val = %d",
- ctrl->val);
- p->h264_max_qp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_HEADER_MODE val = %d",
- ctrl->val);
- p->seq_hdr_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE val = %d",
- ctrl->val);
- p->rc_mb = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_PROFILE val = %d",
- ctrl->val);
- p->h264_profile = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_LEVEL val = %d",
- ctrl->val);
- p->h264_level = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_H264_I_PERIOD val = %d",
- ctrl->val);
- p->intra_period = ctrl->val;
- ctx->param_change |= MTK_ENCODE_PARAM_INTRA_PERIOD;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_GOP_SIZE val = %d",
- ctrl->val);
- p->gop_size = ctrl->val;
- ctx->param_change |= MTK_ENCODE_PARAM_GOP_SIZE;
- break;
- case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
- /*
- * FIXME - what vp8 profiles are actually supported?
- * The ctrl is added (with only profile 0 supported) for now.
- */
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_VP8_PROFILE val = %d", ctrl->val);
- break;
- case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
- mtk_v4l2_debug(2, "V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME");
- p->force_intra = 1;
- ctx->param_change |= MTK_ENCODE_PARAM_FORCE_INTRA;
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops mtk_vcodec_enc_ctrl_ops = {
- .s_ctrl = vidioc_venc_s_ctrl,
-};
-
-static int vidioc_enum_fmt(struct v4l2_fmtdesc *f,
- const struct mtk_video_fmt *formats,
- size_t num_formats)
-{
- if (f->index >= num_formats)
- return -EINVAL;
-
- f->pixelformat = formats[f->index].fourcc;
-
- return 0;
-}
-
-static const struct mtk_video_fmt *
-mtk_venc_find_format(u32 fourcc, const struct mtk_vcodec_enc_pdata *pdata)
-{
- const struct mtk_video_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < pdata->num_capture_formats; k++) {
- fmt = &pdata->capture_formats[k];
- if (fmt->fourcc == fourcc)
- return fmt;
- }
-
- for (k = 0; k < pdata->num_output_formats; k++) {
- fmt = &pdata->output_formats[k];
- if (fmt->fourcc == fourcc)
- return fmt;
- }
-
- return NULL;
-}
-
-static int vidioc_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(fh);
-
- if (fsize->index != 0)
- return -EINVAL;
-
- fmt = mtk_venc_find_format(fsize->pixel_format,
- ctx->dev->venc_pdata);
- if (!fmt)
- return -EINVAL;
-
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-
- if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE)
- fsize->stepwise = mtk_venc_4k_framesizes;
- else
- fsize->stepwise = mtk_venc_hd_framesizes;
-
- return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct mtk_vcodec_enc_pdata *pdata =
- fh_to_ctx(priv)->dev->venc_pdata;
-
- return vidioc_enum_fmt(f, pdata->capture_formats,
- pdata->num_capture_formats);
-}
-
-static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct mtk_vcodec_enc_pdata *pdata =
- fh_to_ctx(priv)->dev->venc_pdata;
-
- return vidioc_enum_fmt(f, pdata->output_formats,
- pdata->num_output_formats);
-}
-
-static int vidioc_venc_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strscpy(cap->driver, MTK_VCODEC_ENC_NAME, sizeof(cap->driver));
- strscpy(cap->bus_info, MTK_PLATFORM_STR, sizeof(cap->bus_info));
- strscpy(cap->card, MTK_PLATFORM_STR, sizeof(cap->card));
-
- return 0;
-}
-
-static int vidioc_venc_s_parm(struct file *file, void *priv,
- struct v4l2_streamparm *a)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct v4l2_fract *timeperframe = &a->parm.output.timeperframe;
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return -EINVAL;
-
- if (timeperframe->numerator == 0 || timeperframe->denominator == 0) {
- timeperframe->numerator = MTK_DEFAULT_FRAMERATE_NUM;
- timeperframe->denominator = MTK_DEFAULT_FRAMERATE_DENOM;
- }
-
- ctx->enc_params.framerate_num = timeperframe->denominator;
- ctx->enc_params.framerate_denom = timeperframe->numerator;
- ctx->param_change |= MTK_ENCODE_PARAM_FRAMERATE;
-
- a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
-
- return 0;
-}
-
-static int vidioc_venc_g_parm(struct file *file, void *priv,
- struct v4l2_streamparm *a)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return -EINVAL;
-
- a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
- a->parm.output.timeperframe.denominator =
- ctx->enc_params.framerate_num;
- a->parm.output.timeperframe.numerator =
- ctx->enc_params.framerate_denom;
-
- return 0;
-}
-
-static struct mtk_q_data *mtk_venc_get_q_data(struct mtk_vcodec_ctx *ctx,
- enum v4l2_buf_type type)
-{
- if (V4L2_TYPE_IS_OUTPUT(type))
- return &ctx->q_data[MTK_Q_DATA_SRC];
-
- return &ctx->q_data[MTK_Q_DATA_DST];
-}
-
-static void vidioc_try_fmt_cap(struct v4l2_format *f)
-{
- f->fmt.pix_mp.field = V4L2_FIELD_NONE;
- f->fmt.pix_mp.num_planes = 1;
- f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
- f->fmt.pix_mp.flags = 0;
-}
-
-/* V4L2 specification suggests the driver corrects the format struct if any of
- * the dimensions is unsupported
- */
-static int vidioc_try_fmt_out(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
- const struct mtk_video_fmt *fmt)
-{
- struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
- int tmp_w, tmp_h;
- unsigned int max_width, max_height;
-
- pix_fmt_mp->field = V4L2_FIELD_NONE;
-
- if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE) {
- max_width = MTK_VENC_4K_MAX_W;
- max_height = MTK_VENC_4K_MAX_H;
- } else {
- max_width = MTK_VENC_HD_MAX_W;
- max_height = MTK_VENC_HD_MAX_H;
- }
-
- pix_fmt_mp->height = clamp(pix_fmt_mp->height, MTK_VENC_MIN_H, max_height);
- pix_fmt_mp->width = clamp(pix_fmt_mp->width, MTK_VENC_MIN_W, max_width);
-
- /* find next closer width align 16, heign align 32, size align
- * 64 rectangle
- */
- tmp_w = pix_fmt_mp->width;
- tmp_h = pix_fmt_mp->height;
- v4l_bound_align_image(&pix_fmt_mp->width,
- MTK_VENC_MIN_W,
- max_width, 4,
- &pix_fmt_mp->height,
- MTK_VENC_MIN_H,
- max_height, 5, 6);
-
- if (pix_fmt_mp->width < tmp_w && (pix_fmt_mp->width + 16) <= max_width)
- pix_fmt_mp->width += 16;
- if (pix_fmt_mp->height < tmp_h && (pix_fmt_mp->height + 32) <= max_height)
- pix_fmt_mp->height += 32;
-
- mtk_v4l2_debug(0, "before resize w=%d, h=%d, after resize w=%d, h=%d, sizeimage=%d %d",
- tmp_w, tmp_h, pix_fmt_mp->width,
- pix_fmt_mp->height,
- pix_fmt_mp->plane_fmt[0].sizeimage,
- pix_fmt_mp->plane_fmt[1].sizeimage);
-
- pix_fmt_mp->num_planes = fmt->num_planes;
- pix_fmt_mp->plane_fmt[0].sizeimage =
- pix_fmt_mp->width * pix_fmt_mp->height +
- ((ALIGN(pix_fmt_mp->width, 16) * 2) * 16);
- pix_fmt_mp->plane_fmt[0].bytesperline = pix_fmt_mp->width;
-
- if (pix_fmt_mp->num_planes == 2) {
- pix_fmt_mp->plane_fmt[1].sizeimage =
- (pix_fmt_mp->width * pix_fmt_mp->height) / 2 +
- (ALIGN(pix_fmt_mp->width, 16) * 16);
- pix_fmt_mp->plane_fmt[2].sizeimage = 0;
- pix_fmt_mp->plane_fmt[1].bytesperline =
- pix_fmt_mp->width;
- pix_fmt_mp->plane_fmt[2].bytesperline = 0;
- } else if (pix_fmt_mp->num_planes == 3) {
- pix_fmt_mp->plane_fmt[1].sizeimage =
- pix_fmt_mp->plane_fmt[2].sizeimage =
- (pix_fmt_mp->width * pix_fmt_mp->height) / 4 +
- ((ALIGN(pix_fmt_mp->width, 16) / 2) * 16);
- pix_fmt_mp->plane_fmt[1].bytesperline =
- pix_fmt_mp->plane_fmt[2].bytesperline =
- pix_fmt_mp->width / 2;
- }
-
- pix_fmt_mp->flags = 0;
-
- return 0;
-}
-
-static void mtk_venc_set_param(struct mtk_vcodec_ctx *ctx,
- struct venc_enc_param *param)
-{
- struct mtk_q_data *q_data_src = &ctx->q_data[MTK_Q_DATA_SRC];
- struct mtk_enc_params *enc_params = &ctx->enc_params;
-
- switch (q_data_src->fmt->fourcc) {
- case V4L2_PIX_FMT_YUV420M:
- param->input_yuv_fmt = VENC_YUV_FORMAT_I420;
- break;
- case V4L2_PIX_FMT_YVU420M:
- param->input_yuv_fmt = VENC_YUV_FORMAT_YV12;
- break;
- case V4L2_PIX_FMT_NV12M:
- param->input_yuv_fmt = VENC_YUV_FORMAT_NV12;
- break;
- case V4L2_PIX_FMT_NV21M:
- param->input_yuv_fmt = VENC_YUV_FORMAT_NV21;
- break;
- default:
- mtk_v4l2_err("Unsupported fourcc =%d", q_data_src->fmt->fourcc);
- break;
- }
- param->h264_profile = enc_params->h264_profile;
- param->h264_level = enc_params->h264_level;
-
- /* Config visible resolution */
- param->width = q_data_src->visible_width;
- param->height = q_data_src->visible_height;
- /* Config coded resolution */
- param->buf_width = q_data_src->coded_width;
- param->buf_height = q_data_src->coded_height;
- param->frm_rate = enc_params->framerate_num /
- enc_params->framerate_denom;
- param->intra_period = enc_params->intra_period;
- param->gop_size = enc_params->gop_size;
- param->bitrate = enc_params->bitrate;
-
- mtk_v4l2_debug(0,
- "fmt 0x%x, P/L %d/%d, w/h %d/%d, buf %d/%d, fps/bps %d/%d, gop %d, i_period %d",
- param->input_yuv_fmt, param->h264_profile,
- param->h264_level, param->width, param->height,
- param->buf_width, param->buf_height,
- param->frm_rate, param->bitrate,
- param->gop_size, param->intra_period);
-}
-
-static int vidioc_venc_s_fmt_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
- struct vb2_queue *vq;
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
- int i, ret;
- const struct mtk_video_fmt *fmt;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq) {
- mtk_v4l2_err("fail to get vq");
- return -EINVAL;
- }
-
- if (vb2_is_busy(vq)) {
- mtk_v4l2_err("queue busy");
- return -EBUSY;
- }
-
- fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
- if (!fmt) {
- fmt = &ctx->dev->venc_pdata->capture_formats[0];
- f->fmt.pix.pixelformat = fmt->fourcc;
- }
-
- q_data->fmt = fmt;
- vidioc_try_fmt_cap(f);
-
- q_data->coded_width = f->fmt.pix_mp.width;
- q_data->coded_height = f->fmt.pix_mp.height;
- q_data->field = f->fmt.pix_mp.field;
-
- for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
- struct v4l2_plane_pix_format *plane_fmt;
-
- plane_fmt = &f->fmt.pix_mp.plane_fmt[i];
- q_data->bytesperline[i] = plane_fmt->bytesperline;
- q_data->sizeimage[i] = plane_fmt->sizeimage;
- }
-
- if (ctx->state == MTK_STATE_FREE) {
- ret = venc_if_init(ctx, q_data->fmt->fourcc);
- if (ret) {
- mtk_v4l2_err("venc_if_init failed=%d, codec type=%x",
- ret, q_data->fmt->fourcc);
- return -EBUSY;
- }
- ctx->state = MTK_STATE_INIT;
- }
-
- return 0;
-}
-
-static int vidioc_venc_s_fmt_out(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
- struct vb2_queue *vq;
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
- int ret, i;
- const struct mtk_video_fmt *fmt;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq) {
- mtk_v4l2_err("fail to get vq");
- return -EINVAL;
- }
-
- if (vb2_is_busy(vq)) {
- mtk_v4l2_err("queue busy");
- return -EBUSY;
- }
-
- fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
- if (!fmt) {
- fmt = &ctx->dev->venc_pdata->output_formats[0];
- f->fmt.pix.pixelformat = fmt->fourcc;
- }
-
- ret = vidioc_try_fmt_out(ctx, f, fmt);
- if (ret)
- return ret;
-
- q_data->fmt = fmt;
- q_data->visible_width = f->fmt.pix_mp.width;
- q_data->visible_height = f->fmt.pix_mp.height;
- q_data->coded_width = f->fmt.pix_mp.width;
- q_data->coded_height = f->fmt.pix_mp.height;
-
- q_data->field = f->fmt.pix_mp.field;
- ctx->colorspace = f->fmt.pix_mp.colorspace;
- ctx->ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
- ctx->quantization = f->fmt.pix_mp.quantization;
- ctx->xfer_func = f->fmt.pix_mp.xfer_func;
-
- for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
- struct v4l2_plane_pix_format *plane_fmt;
-
- plane_fmt = &f->fmt.pix_mp.plane_fmt[i];
- q_data->bytesperline[i] = plane_fmt->bytesperline;
- q_data->sizeimage[i] = plane_fmt->sizeimage;
- }
-
- return 0;
-}
-
-static int vidioc_venc_g_fmt(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct vb2_queue *vq;
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, f->type);
- int i;
-
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
-
- pix->width = q_data->coded_width;
- pix->height = q_data->coded_height;
- pix->pixelformat = q_data->fmt->fourcc;
- pix->field = q_data->field;
- pix->num_planes = q_data->fmt->num_planes;
- for (i = 0; i < pix->num_planes; i++) {
- pix->plane_fmt[i].bytesperline = q_data->bytesperline[i];
- pix->plane_fmt[i].sizeimage = q_data->sizeimage[i];
- }
-
- pix->flags = 0;
- pix->colorspace = ctx->colorspace;
- pix->ycbcr_enc = ctx->ycbcr_enc;
- pix->quantization = ctx->quantization;
- pix->xfer_func = ctx->xfer_func;
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
-
- fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
- if (!fmt) {
- fmt = &ctx->dev->venc_pdata->capture_formats[0];
- f->fmt.pix.pixelformat = fmt->fourcc;
- }
- f->fmt.pix_mp.colorspace = ctx->colorspace;
- f->fmt.pix_mp.ycbcr_enc = ctx->ycbcr_enc;
- f->fmt.pix_mp.quantization = ctx->quantization;
- f->fmt.pix_mp.xfer_func = ctx->xfer_func;
-
- vidioc_try_fmt_cap(f);
-
- return 0;
-}
-
-static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- const struct mtk_video_fmt *fmt;
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- const struct mtk_vcodec_enc_pdata *pdata = ctx->dev->venc_pdata;
-
- fmt = mtk_venc_find_format(f->fmt.pix.pixelformat, pdata);
- if (!fmt) {
- fmt = &ctx->dev->venc_pdata->output_formats[0];
- f->fmt.pix.pixelformat = fmt->fourcc;
- }
- if (!f->fmt.pix_mp.colorspace) {
- f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
- f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
- f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
- }
-
- return vidioc_try_fmt_out(ctx, f, fmt);
-}
-
-static int vidioc_venc_g_selection(struct file *file, void *priv,
- struct v4l2_selection *s)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- s->r.top = 0;
- s->r.left = 0;
- s->r.width = q_data->coded_width;
- s->r.height = q_data->coded_height;
- break;
- case V4L2_SEL_TGT_CROP:
- s->r.top = 0;
- s->r.left = 0;
- s->r.width = q_data->visible_width;
- s->r.height = q_data->visible_height;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int vidioc_venc_s_selection(struct file *file, void *priv,
- struct v4l2_selection *s)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, s->type);
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_CROP:
- /* Only support crop from (0,0) */
- s->r.top = 0;
- s->r.left = 0;
- s->r.width = min(s->r.width, q_data->coded_width);
- s->r.height = min(s->r.height, q_data->coded_height);
- q_data->visible_width = s->r.width;
- q_data->visible_height = s->r.height;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int vidioc_venc_qbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
-
- if (ctx->state == MTK_STATE_ABORT) {
- mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
- ctx->id);
- return -EIO;
- }
-
- return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_venc_dqbuf(struct file *file, void *priv,
- struct v4l2_buffer *buf)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- int ret;
-
- if (ctx->state == MTK_STATE_ABORT) {
- mtk_v4l2_err("[%d] Call on QBUF after unrecoverable error",
- ctx->id);
- return -EIO;
- }
-
- ret = v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
- if (ret)
- return ret;
-
- /*
- * Complete flush if the user dequeued the 0-payload LAST buffer.
- * We check the payload because a buffer with the LAST flag can also
- * be seen during resolution changes. If we happen to be flushing at
- * that time, the last buffer before the resolution changes could be
- * misinterpreted for the buffer generated by the flush and terminate
- * it earlier than we want.
- */
- if (!V4L2_TYPE_IS_OUTPUT(buf->type) &&
- buf->flags & V4L2_BUF_FLAG_LAST &&
- buf->m.planes[0].bytesused == 0 &&
- ctx->is_flushing) {
- /*
- * Last CAPTURE buffer is dequeued, we can allow another flush
- * to take place.
- */
- ctx->is_flushing = false;
- }
-
- return 0;
-}
-
-static int vidioc_encoder_cmd(struct file *file, void *priv,
- struct v4l2_encoder_cmd *cmd)
-{
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv);
- struct vb2_queue *src_vq, *dst_vq;
- int ret;
-
- if (ctx->state == MTK_STATE_ABORT) {
- mtk_v4l2_err("[%d] Call to CMD after unrecoverable error",
- ctx->id);
- return -EIO;
- }
-
- ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, cmd);
- if (ret)
- return ret;
-
- /* Calling START or STOP is invalid if a flush is in progress */
- if (ctx->is_flushing)
- return -EBUSY;
-
- mtk_v4l2_debug(1, "encoder cmd=%u", cmd->cmd);
-
- dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- switch (cmd->cmd) {
- case V4L2_ENC_CMD_STOP:
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- if (!vb2_is_streaming(src_vq)) {
- mtk_v4l2_debug(1, "Output stream is off. No need to flush.");
- return 0;
- }
- if (!vb2_is_streaming(dst_vq)) {
- mtk_v4l2_debug(1, "Capture stream is off. No need to flush.");
- return 0;
- }
- ctx->is_flushing = true;
- v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb);
- v4l2_m2m_try_schedule(ctx->m2m_ctx);
- break;
-
- case V4L2_ENC_CMD_START:
- vb2_clear_last_buffer_dequeued(dst_vq);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = {
- .vidioc_streamon = v4l2_m2m_ioctl_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
-
- .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
- .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
- .vidioc_qbuf = vidioc_venc_qbuf,
- .vidioc_dqbuf = vidioc_venc_dqbuf,
-
- .vidioc_querycap = vidioc_venc_querycap,
- .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
- .vidioc_enum_framesizes = vidioc_enum_framesizes,
-
- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
- .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_vid_out_mplane,
- .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-
- .vidioc_s_parm = vidioc_venc_s_parm,
- .vidioc_g_parm = vidioc_venc_g_parm,
- .vidioc_s_fmt_vid_cap_mplane = vidioc_venc_s_fmt_cap,
- .vidioc_s_fmt_vid_out_mplane = vidioc_venc_s_fmt_out,
-
- .vidioc_g_fmt_vid_cap_mplane = vidioc_venc_g_fmt,
- .vidioc_g_fmt_vid_out_mplane = vidioc_venc_g_fmt,
-
- .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
- .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
-
- .vidioc_g_selection = vidioc_venc_g_selection,
- .vidioc_s_selection = vidioc_venc_s_selection,
-
- .vidioc_encoder_cmd = vidioc_encoder_cmd,
- .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
-};
-
-static int vb2ops_venc_queue_setup(struct vb2_queue *vq,
- unsigned int *nbuffers,
- unsigned int *nplanes,
- unsigned int sizes[],
- struct device *alloc_devs[])
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vq);
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vq->type);
- unsigned int i;
-
- if (q_data == NULL)
- return -EINVAL;
-
- if (*nplanes) {
- for (i = 0; i < *nplanes; i++)
- if (sizes[i] < q_data->sizeimage[i])
- return -EINVAL;
- } else {
- *nplanes = q_data->fmt->num_planes;
- for (i = 0; i < *nplanes; i++)
- sizes[i] = q_data->sizeimage[i];
- }
-
- return 0;
-}
-
-static int vb2ops_venc_buf_prepare(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct mtk_q_data *q_data = mtk_venc_get_q_data(ctx, vb->vb2_queue->type);
- int i;
-
- for (i = 0; i < q_data->fmt->num_planes; i++) {
- if (vb2_plane_size(vb, i) < q_data->sizeimage[i]) {
- mtk_v4l2_err("data will not fit into plane %d (%lu < %d)",
- i, vb2_plane_size(vb, i),
- q_data->sizeimage[i]);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static void vb2ops_venc_buf_queue(struct vb2_buffer *vb)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vb2_v4l2 =
- container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-
- struct mtk_video_enc_buf *mtk_buf =
- container_of(vb2_v4l2, struct mtk_video_enc_buf,
- m2m_buf.vb);
-
- if ((vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) &&
- (ctx->param_change != MTK_ENCODE_PARAM_NONE)) {
- mtk_v4l2_debug(1, "[%d] Before id=%d encode parameter change %x",
- ctx->id,
- vb2_v4l2->vb2_buf.index,
- ctx->param_change);
- mtk_buf->param_change = ctx->param_change;
- mtk_buf->enc_params = ctx->enc_params;
- ctx->param_change = MTK_ENCODE_PARAM_NONE;
- }
-
- v4l2_m2m_buf_queue(ctx->m2m_ctx, to_vb2_v4l2_buffer(vb));
-}
-
-static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
- struct venc_enc_param param;
- int ret, pm_ret;
- int i;
-
- /* Once state turn into MTK_STATE_ABORT, we need stop_streaming
- * to clear it
- */
- if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) {
- ret = -EIO;
- goto err_start_stream;
- }
-
- /* Do the initialization when both start_streaming have been called */
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- if (!vb2_start_streaming_called(&ctx->m2m_ctx->cap_q_ctx.q))
- return 0;
- } else {
- if (!vb2_start_streaming_called(&ctx->m2m_ctx->out_q_ctx.q))
- return 0;
- }
-
- ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev);
- if (ret < 0) {
- mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
- goto err_start_stream;
- }
-
- mtk_venc_set_param(ctx, &param);
- ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param);
- if (ret) {
- mtk_v4l2_err("venc_if_set_param failed=%d", ret);
- ctx->state = MTK_STATE_ABORT;
- goto err_set_param;
- }
- ctx->param_change = MTK_ENCODE_PARAM_NONE;
-
- if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
- (ctx->enc_params.seq_hdr_mode !=
- V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE)) {
- ret = venc_if_set_param(ctx,
- VENC_SET_PARAM_PREPEND_HEADER,
- NULL);
- if (ret) {
- mtk_v4l2_err("venc_if_set_param failed=%d", ret);
- ctx->state = MTK_STATE_ABORT;
- goto err_set_param;
- }
- ctx->state = MTK_STATE_HEADER;
- }
-
- return 0;
-
-err_set_param:
- pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
- if (pm_ret < 0)
- mtk_v4l2_err("pm_runtime_put fail %d", pm_ret);
-
-err_start_stream:
- for (i = 0; i < q->num_buffers; ++i) {
- struct vb2_buffer *buf = vb2_get_buffer(q, i);
-
- /*
- * FIXME: This check is not needed as only active buffers
- * can be marked as done.
- */
- if (buf->state == VB2_BUF_STATE_ACTIVE) {
- mtk_v4l2_debug(0, "[%d] id=%d, type=%d, %d -> VB2_BUF_STATE_QUEUED",
- ctx->id, i, q->type,
- (int)buf->state);
- v4l2_m2m_buf_done(to_vb2_v4l2_buffer(buf),
- VB2_BUF_STATE_QUEUED);
- }
- }
-
- return ret;
-}
-
-static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
-{
- struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
- int ret;
-
- mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type);
-
- if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
- while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
- }
- /* STREAMOFF on the CAPTURE queue completes any ongoing flush */
- if (ctx->is_flushing) {
- struct v4l2_m2m_buffer *b, *n;
-
- mtk_v4l2_debug(1, "STREAMOFF called while flushing");
- /*
- * STREAMOFF could be called before the flush buffer is
- * dequeued. Check whether empty flush buf is still in
- * queue before removing it.
- */
- v4l2_m2m_for_each_src_buf_safe(ctx->m2m_ctx, b, n) {
- if (b == &ctx->empty_flush_buf) {
- v4l2_m2m_src_buf_remove_by_buf(ctx->m2m_ctx, &b->vb);
- break;
- }
- }
- ctx->is_flushing = false;
- }
- } else {
- while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) {
- if (src_buf != &ctx->empty_flush_buf.vb)
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- }
- if (ctx->is_flushing) {
- /*
- * If we are in the middle of a flush, put the flush
- * buffer back into the queue so the next CAPTURE
- * buffer gets returned with the LAST flag set.
- */
- v4l2_m2m_buf_queue(ctx->m2m_ctx,
- &ctx->empty_flush_buf.vb);
- }
- }
-
- if ((q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
- vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q)) ||
- (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
- vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q))) {
- mtk_v4l2_debug(1, "[%d]-> q type %d out=%d cap=%d",
- ctx->id, q->type,
- vb2_is_streaming(&ctx->m2m_ctx->out_q_ctx.q),
- vb2_is_streaming(&ctx->m2m_ctx->cap_q_ctx.q));
- return;
- }
-
- /* Release the encoder if both streams are stopped. */
- ret = venc_if_deinit(ctx);
- if (ret)
- mtk_v4l2_err("venc_if_deinit failed=%d", ret);
-
- ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
- if (ret < 0)
- mtk_v4l2_err("pm_runtime_put fail %d", ret);
-
- ctx->state = MTK_STATE_FREE;
-}
-
-static int vb2ops_venc_buf_out_validate(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
- vbuf->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static const struct vb2_ops mtk_venc_vb2_ops = {
- .queue_setup = vb2ops_venc_queue_setup,
- .buf_out_validate = vb2ops_venc_buf_out_validate,
- .buf_prepare = vb2ops_venc_buf_prepare,
- .buf_queue = vb2ops_venc_buf_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = vb2ops_venc_start_streaming,
- .stop_streaming = vb2ops_venc_stop_streaming,
-};
-
-static int mtk_venc_encode_header(void *priv)
-{
- struct mtk_vcodec_ctx *ctx = priv;
- int ret;
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
- struct mtk_vcodec_mem bs_buf;
- struct venc_done_result enc_result;
-
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
- if (!dst_buf) {
- mtk_v4l2_debug(1, "No dst buffer");
- return -EINVAL;
- }
-
- bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
- bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
- bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
-
- mtk_v4l2_debug(1,
- "[%d] buf id=%d va=0x%p dma_addr=0x%llx size=%zu",
- ctx->id,
- dst_buf->vb2_buf.index, bs_buf.va,
- (u64)bs_buf.dma_addr,
- bs_buf.size);
-
- ret = venc_if_encode(ctx,
- VENC_START_OPT_ENCODE_SEQUENCE_HEADER,
- NULL, &bs_buf, &enc_result);
-
- if (ret) {
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- ctx->state = MTK_STATE_ABORT;
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
- mtk_v4l2_err("venc_if_encode failed=%d", ret);
- return -EINVAL;
- }
- src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- if (src_buf) {
- dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
- dst_buf->timecode = src_buf->timecode;
- } else {
- mtk_v4l2_err("No timestamp for the header buffer.");
- }
-
- ctx->state = MTK_STATE_HEADER;
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
-
- return 0;
-}
-
-static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
-{
- struct venc_enc_param enc_prm;
- struct vb2_v4l2_buffer *vb2_v4l2 = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
- struct mtk_video_enc_buf *mtk_buf;
- int ret = 0;
-
- /* Don't upcast the empty flush buffer */
- if (vb2_v4l2 == &ctx->empty_flush_buf.vb)
- return 0;
-
- mtk_buf = container_of(vb2_v4l2, struct mtk_video_enc_buf, m2m_buf.vb);
-
- memset(&enc_prm, 0, sizeof(enc_prm));
- if (mtk_buf->param_change == MTK_ENCODE_PARAM_NONE)
- return 0;
-
- if (mtk_buf->param_change & MTK_ENCODE_PARAM_BITRATE) {
- enc_prm.bitrate = mtk_buf->enc_params.bitrate;
- mtk_v4l2_debug(1, "[%d] id=%d, change param br=%d",
- ctx->id,
- vb2_v4l2->vb2_buf.index,
- enc_prm.bitrate);
- ret |= venc_if_set_param(ctx,
- VENC_SET_PARAM_ADJUST_BITRATE,
- &enc_prm);
- }
- if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FRAMERATE) {
- enc_prm.frm_rate = mtk_buf->enc_params.framerate_num /
- mtk_buf->enc_params.framerate_denom;
- mtk_v4l2_debug(1, "[%d] id=%d, change param fr=%d",
- ctx->id,
- vb2_v4l2->vb2_buf.index,
- enc_prm.frm_rate);
- ret |= venc_if_set_param(ctx,
- VENC_SET_PARAM_ADJUST_FRAMERATE,
- &enc_prm);
- }
- if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_GOP_SIZE) {
- enc_prm.gop_size = mtk_buf->enc_params.gop_size;
- mtk_v4l2_debug(1, "change param intra period=%d",
- enc_prm.gop_size);
- ret |= venc_if_set_param(ctx,
- VENC_SET_PARAM_GOP_SIZE,
- &enc_prm);
- }
- if (!ret && mtk_buf->param_change & MTK_ENCODE_PARAM_FORCE_INTRA) {
- mtk_v4l2_debug(1, "[%d] id=%d, change param force I=%d",
- ctx->id,
- vb2_v4l2->vb2_buf.index,
- mtk_buf->enc_params.force_intra);
- if (mtk_buf->enc_params.force_intra)
- ret |= venc_if_set_param(ctx,
- VENC_SET_PARAM_FORCE_INTRA,
- NULL);
- }
-
- mtk_buf->param_change = MTK_ENCODE_PARAM_NONE;
-
- if (ret) {
- ctx->state = MTK_STATE_ABORT;
- mtk_v4l2_err("venc_if_set_param %d failed=%d",
- mtk_buf->param_change, ret);
- return -1;
- }
-
- return 0;
-}
-
-/*
- * v4l2_m2m_streamoff() holds dev_mutex and waits mtk_venc_worker()
- * to call v4l2_m2m_job_finish().
- * If mtk_venc_worker() tries to acquire dev_mutex, it will deadlock.
- * So this function must not try to acquire dev->dev_mutex.
- * This means v4l2 ioctls and mtk_venc_worker() can run at the same time.
- * mtk_venc_worker() should be carefully implemented to avoid bugs.
- */
-static void mtk_venc_worker(struct work_struct *work)
-{
- struct mtk_vcodec_ctx *ctx = container_of(work, struct mtk_vcodec_ctx,
- encode_work);
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
- struct venc_frm_buf frm_buf;
- struct mtk_vcodec_mem bs_buf;
- struct venc_done_result enc_result;
- int ret, i;
-
- /* check dst_buf, dst_buf may be removed in device_run
- * to stored encdoe header so we need check dst_buf and
- * call job_finish here to prevent recursion
- */
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
- if (!dst_buf) {
- v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
- return;
- }
-
- src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
-
- /*
- * If we see the flush buffer, send an empty buffer with the LAST flag
- * to the client. is_flushing will be reset at the time the buffer
- * is dequeued.
- */
- if (src_buf == &ctx->empty_flush_buf.vb) {
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- dst_buf->flags |= V4L2_BUF_FLAG_LAST;
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
- v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
- return;
- }
-
- memset(&frm_buf, 0, sizeof(frm_buf));
- for (i = 0; i < src_buf->vb2_buf.num_planes ; i++) {
- frm_buf.fb_addr[i].dma_addr =
- vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, i);
- frm_buf.fb_addr[i].size =
- (size_t)src_buf->vb2_buf.planes[i].length;
- }
- bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
- bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
- bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
-
- mtk_v4l2_debug(2,
- "Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
- (u64)frm_buf.fb_addr[0].dma_addr,
- frm_buf.fb_addr[0].size,
- (u64)frm_buf.fb_addr[1].dma_addr,
- frm_buf.fb_addr[1].size,
- (u64)frm_buf.fb_addr[2].dma_addr,
- frm_buf.fb_addr[2].size);
-
- ret = venc_if_encode(ctx, VENC_START_OPT_ENCODE_FRAME,
- &frm_buf, &bs_buf, &enc_result);
-
- dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
- dst_buf->timecode = src_buf->timecode;
-
- if (enc_result.is_key_frm)
- dst_buf->flags |= V4L2_BUF_FLAG_KEYFRAME;
-
- if (ret) {
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
- mtk_v4l2_err("venc_if_encode failed=%d", ret);
- } else {
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
- mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
- enc_result.bs_size);
- }
-
- v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
-
- mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
- src_buf->vb2_buf.index, dst_buf->vb2_buf.index, ret,
- enc_result.bs_size);
-}
-
-static void m2mops_venc_device_run(void *priv)
-{
- struct mtk_vcodec_ctx *ctx = priv;
-
- if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
- (ctx->state != MTK_STATE_HEADER)) {
- /* encode h264 sps/pps header */
- mtk_venc_encode_header(ctx);
- queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
- return;
- }
-
- mtk_venc_param_change(ctx);
- queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
-}
-
-static int m2mops_venc_job_ready(void *m2m_priv)
-{
- struct mtk_vcodec_ctx *ctx = m2m_priv;
-
- if (ctx->state == MTK_STATE_ABORT || ctx->state == MTK_STATE_FREE) {
- mtk_v4l2_debug(3, "[%d]Not ready: state=0x%x.",
- ctx->id, ctx->state);
- return 0;
- }
-
- return 1;
-}
-
-static void m2mops_venc_job_abort(void *priv)
-{
- struct mtk_vcodec_ctx *ctx = priv;
-
- ctx->state = MTK_STATE_ABORT;
-}
-
-const struct v4l2_m2m_ops mtk_venc_m2m_ops = {
- .device_run = m2mops_venc_device_run,
- .job_ready = m2mops_venc_job_ready,
- .job_abort = m2mops_venc_job_abort,
-};
-
-void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
-{
- struct mtk_q_data *q_data;
-
- ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
- ctx->fh.m2m_ctx = ctx->m2m_ctx;
- ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
- INIT_WORK(&ctx->encode_work, mtk_venc_worker);
-
- ctx->colorspace = V4L2_COLORSPACE_REC709;
- ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
- ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
-
- q_data = &ctx->q_data[MTK_Q_DATA_SRC];
- memset(q_data, 0, sizeof(struct mtk_q_data));
- q_data->visible_width = DFT_CFG_WIDTH;
- q_data->visible_height = DFT_CFG_HEIGHT;
- q_data->coded_width = DFT_CFG_WIDTH;
- q_data->coded_height = DFT_CFG_HEIGHT;
- q_data->field = V4L2_FIELD_NONE;
-
- q_data->fmt = &ctx->dev->venc_pdata->output_formats[0];
-
- v4l_bound_align_image(&q_data->coded_width,
- MTK_VENC_MIN_W,
- MTK_VENC_HD_MAX_W, 4,
- &q_data->coded_height,
- MTK_VENC_MIN_H,
- MTK_VENC_HD_MAX_H, 5, 6);
-
- if (q_data->coded_width < DFT_CFG_WIDTH &&
- (q_data->coded_width + 16) <= MTK_VENC_HD_MAX_W)
- q_data->coded_width += 16;
- if (q_data->coded_height < DFT_CFG_HEIGHT &&
- (q_data->coded_height + 32) <= MTK_VENC_HD_MAX_H)
- q_data->coded_height += 32;
-
- q_data->sizeimage[0] =
- q_data->coded_width * q_data->coded_height+
- ((ALIGN(q_data->coded_width, 16) * 2) * 16);
- q_data->bytesperline[0] = q_data->coded_width;
- q_data->sizeimage[1] =
- (q_data->coded_width * q_data->coded_height) / 2 +
- (ALIGN(q_data->coded_width, 16) * 16);
- q_data->bytesperline[1] = q_data->coded_width;
-
- q_data = &ctx->q_data[MTK_Q_DATA_DST];
- memset(q_data, 0, sizeof(struct mtk_q_data));
- q_data->coded_width = DFT_CFG_WIDTH;
- q_data->coded_height = DFT_CFG_HEIGHT;
- q_data->fmt = &ctx->dev->venc_pdata->capture_formats[0];
- q_data->field = V4L2_FIELD_NONE;
- ctx->q_data[MTK_Q_DATA_DST].sizeimage[0] =
- DFT_CFG_WIDTH * DFT_CFG_HEIGHT;
- ctx->q_data[MTK_Q_DATA_DST].bytesperline[0] = 0;
-
- ctx->enc_params.framerate_num = MTK_DEFAULT_FRAMERATE_NUM;
- ctx->enc_params.framerate_denom = MTK_DEFAULT_FRAMERATE_DENOM;
-}
-
-int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
-{
- const struct v4l2_ctrl_ops *ops = &mtk_vcodec_enc_ctrl_ops;
- struct v4l2_ctrl_handler *handler = &ctx->ctrl_hdl;
- u8 h264_max_level;
-
- if (ctx->dev->enc_capability & MTK_VENC_4K_CAPABILITY_ENABLE)
- h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
- else
- h264_max_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
-
- v4l2_ctrl_handler_init(handler, MTK_MAX_CTRLS_HINT);
-
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT,
- 1, 1, 1, 1);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE,
- ctx->dev->venc_pdata->min_bitrate,
- ctx->dev->venc_pdata->max_bitrate, 1, 4000000);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_B_FRAMES,
- 0, 2, 1, 0);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
- 0, 1, 1, 1);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
- 0, 51, 1, 51);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
- 0, 65535, 1, 0);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- 0, 65535, 1, 0);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
- 0, 1, 1, 0);
- v4l2_ctrl_new_std(handler, ops, V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
- 0, 0, 0, 0);
- v4l2_ctrl_new_std_menu(handler, ops,
- V4L2_CID_MPEG_VIDEO_HEADER_MODE,
- V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
- 0, V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE);
- v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
- 0, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
- v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL,
- h264_max_level,
- 0, V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
- v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
- V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
-
-
- if (handler->error) {
- mtk_v4l2_err("Init control handler fail %d",
- handler->error);
- return handler->error;
- }
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_hdl);
-
- return 0;
-}
-
-int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct mtk_vcodec_ctx *ctx = priv;
- int ret;
-
- /* Note: VB2_USERPTR works with dma-contig because mt8173
- * support iommu
- * https://patchwork.kernel.org/patch/8335461/
- * https://patchwork.kernel.org/patch/7596181/
- */
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct mtk_video_enc_buf);
- src_vq->ops = &mtk_venc_vb2_ops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &ctx->dev->dev_mutex;
- src_vq->dev = &ctx->dev->plat_dev->dev;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->ops = &mtk_venc_vb2_ops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &ctx->dev->dev_mutex;
- dst_vq->dev = &ctx->dev->plat_dev->dev;
-
- return vb2_queue_init(dst_vq);
-}
-
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
-{
- struct mtk_vcodec_dev *dev = ctx->dev;
-
- mutex_unlock(&dev->enc_mutex);
- return 0;
-}
-
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
-{
- struct mtk_vcodec_dev *dev = ctx->dev;
-
- mutex_lock(&dev->enc_mutex);
- return 0;
-}
-
-void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
-{
- int ret = venc_if_deinit(ctx);
-
- if (ret)
- mtk_v4l2_err("venc_if_deinit failed=%d", ret);
-
- ctx->state = MTK_STATE_FREE;
-}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
deleted file mode 100644
index 513ee7993e34..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#ifndef _MTK_VCODEC_ENC_H_
-#define _MTK_VCODEC_ENC_H_
-
-#include <media/videobuf2-core.h>
-#include <media/v4l2-mem2mem.h>
-
-#define MTK_VENC_IRQ_STATUS_SPS 0x1
-#define MTK_VENC_IRQ_STATUS_PPS 0x2
-#define MTK_VENC_IRQ_STATUS_FRM 0x4
-#define MTK_VENC_IRQ_STATUS_DRAM 0x8
-#define MTK_VENC_IRQ_STATUS_PAUSE 0x10
-#define MTK_VENC_IRQ_STATUS_SWITCH 0x20
-
-#define MTK_VENC_IRQ_STATUS_OFFSET 0x05C
-#define MTK_VENC_IRQ_ACK_OFFSET 0x060
-
-/**
- * struct mtk_video_enc_buf - Private data related to each VB2 buffer.
- * @m2m_buf: M2M buffer
- * @list: list that buffer link to
- * @param_change: Types of encode parameter change before encoding this
- * buffer
- * @enc_params: Encode parameters changed before encode this buffer
- */
-struct mtk_video_enc_buf {
- struct v4l2_m2m_buffer m2m_buf;
-
- u32 param_change;
- struct mtk_enc_params enc_params;
-};
-
-extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops;
-extern const struct v4l2_m2m_ops mtk_venc_m2m_ops;
-
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx);
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx);
-int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq);
-void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
-int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx);
-void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx);
-
-#endif /* _MTK_VCODEC_ENC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
deleted file mode 100644
index 5172cfe0db4a..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ /dev/null
@@ -1,479 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/of.h>
-#include <linux/pm_runtime.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_enc.h"
-#include "mtk_vcodec_enc_pm.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_fw.h"
-
-static const struct mtk_video_fmt mtk_video_formats_output[] = {
- {
- .fourcc = V4L2_PIX_FMT_NV12M,
- .type = MTK_FMT_FRAME,
- .num_planes = 2,
- },
- {
- .fourcc = V4L2_PIX_FMT_NV21M,
- .type = MTK_FMT_FRAME,
- .num_planes = 2,
- },
- {
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .type = MTK_FMT_FRAME,
- .num_planes = 3,
- },
- {
- .fourcc = V4L2_PIX_FMT_YVU420M,
- .type = MTK_FMT_FRAME,
- .num_planes = 3,
- },
-};
-
-static const struct mtk_video_fmt mtk_video_formats_capture_h264[] = {
- {
- .fourcc = V4L2_PIX_FMT_H264,
- .type = MTK_FMT_ENC,
- .num_planes = 1,
- },
-};
-
-static const struct mtk_video_fmt mtk_video_formats_capture_vp8[] = {
- {
- .fourcc = V4L2_PIX_FMT_VP8,
- .type = MTK_FMT_ENC,
- .num_planes = 1,
- },
-};
-
-static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
-{
- if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
- writel(MTK_VENC_IRQ_STATUS_PAUSE, addr);
-
- if (irq_status & MTK_VENC_IRQ_STATUS_SWITCH)
- writel(MTK_VENC_IRQ_STATUS_SWITCH, addr);
-
- if (irq_status & MTK_VENC_IRQ_STATUS_DRAM)
- writel(MTK_VENC_IRQ_STATUS_DRAM, addr);
-
- if (irq_status & MTK_VENC_IRQ_STATUS_SPS)
- writel(MTK_VENC_IRQ_STATUS_SPS, addr);
-
- if (irq_status & MTK_VENC_IRQ_STATUS_PPS)
- writel(MTK_VENC_IRQ_STATUS_PPS, addr);
-
- if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
- writel(MTK_VENC_IRQ_STATUS_FRM, addr);
-
-}
-static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
-{
- struct mtk_vcodec_dev *dev = priv;
- struct mtk_vcodec_ctx *ctx;
- unsigned long flags;
- void __iomem *addr;
-
- spin_lock_irqsave(&dev->irqlock, flags);
- ctx = dev->curr_ctx;
- spin_unlock_irqrestore(&dev->irqlock, flags);
-
- mtk_v4l2_debug(1, "id=%d coreid:%d", ctx->id, dev->venc_pdata->core_id);
- addr = dev->reg_base[dev->venc_pdata->core_id] +
- MTK_VENC_IRQ_ACK_OFFSET;
-
- ctx->irq_status = readl(dev->reg_base[dev->venc_pdata->core_id] +
- (MTK_VENC_IRQ_STATUS_OFFSET));
-
- clean_irq_status(ctx->irq_status, addr);
-
- wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
- return IRQ_HANDLED;
-}
-
-static int fops_vcodec_open(struct file *file)
-{
- struct mtk_vcodec_dev *dev = video_drvdata(file);
- struct mtk_vcodec_ctx *ctx = NULL;
- int ret = 0;
- struct vb2_queue *src_vq;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- mutex_lock(&dev->dev_mutex);
- /*
- * Use simple counter to uniquely identify this context. Only
- * used for logging.
- */
- ctx->id = dev->id_counter++;
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
- INIT_LIST_HEAD(&ctx->list);
- ctx->dev = dev;
- init_waitqueue_head(&ctx->queue[0]);
-
- ctx->type = MTK_INST_ENCODER;
- ret = mtk_vcodec_enc_ctrls_setup(ctx);
- if (ret) {
- mtk_v4l2_err("Failed to setup controls() (%d)",
- ret);
- goto err_ctrls_setup;
- }
- ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_enc, ctx,
- &mtk_vcodec_enc_queue_init);
- if (IS_ERR((__force void *)ctx->m2m_ctx)) {
- ret = PTR_ERR((__force void *)ctx->m2m_ctx);
- mtk_v4l2_err("Failed to v4l2_m2m_ctx_init() (%d)",
- ret);
- goto err_m2m_ctx_init;
- }
- src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- ctx->empty_flush_buf.vb.vb2_buf.vb2_queue = src_vq;
- mtk_vcodec_enc_set_default_params(ctx);
-
- if (v4l2_fh_is_singular(&ctx->fh)) {
- /*
- * load fireware to checks if it was loaded already and
- * does nothing in that case
- */
- ret = mtk_vcodec_fw_load_firmware(dev->fw_handler);
- if (ret < 0) {
- /*
- * Return 0 if downloading firmware successfully,
- * otherwise it is failed
- */
- mtk_v4l2_err("vpu_load_firmware failed!");
- goto err_load_fw;
- }
-
- dev->enc_capability =
- mtk_vcodec_fw_get_venc_capa(dev->fw_handler);
- mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
- }
-
- mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ",
- ctx->id, ctx, ctx->m2m_ctx);
-
- list_add(&ctx->list, &dev->ctx_list);
-
- mutex_unlock(&dev->dev_mutex);
- mtk_v4l2_debug(0, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
- ctx->id);
- return ret;
-
- /* Deinit when failure occurred */
-err_load_fw:
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
-err_m2m_ctx_init:
- v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-err_ctrls_setup:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
- mutex_unlock(&dev->dev_mutex);
-
- return ret;
-}
-
-static int fops_vcodec_release(struct file *file)
-{
- struct mtk_vcodec_dev *dev = video_drvdata(file);
- struct mtk_vcodec_ctx *ctx = fh_to_ctx(file->private_data);
-
- mtk_v4l2_debug(1, "[%d] encoder", ctx->id);
- mutex_lock(&dev->dev_mutex);
-
- v4l2_m2m_ctx_release(ctx->m2m_ctx);
- mtk_vcodec_enc_release(ctx);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
-
- list_del_init(&ctx->list);
- kfree(ctx);
- mutex_unlock(&dev->dev_mutex);
- return 0;
-}
-
-static const struct v4l2_file_operations mtk_vcodec_fops = {
- .owner = THIS_MODULE,
- .open = fops_vcodec_open,
- .release = fops_vcodec_release,
- .poll = v4l2_m2m_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = v4l2_m2m_fop_mmap,
-};
-
-static int mtk_vcodec_probe(struct platform_device *pdev)
-{
- struct mtk_vcodec_dev *dev;
- struct video_device *vfd_enc;
- struct resource *res;
- phandle rproc_phandle;
- enum mtk_vcodec_fw_type fw_type;
- int ret;
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&dev->ctx_list);
- dev->plat_dev = pdev;
-
- if (!of_property_read_u32(pdev->dev.of_node, "mediatek,vpu",
- &rproc_phandle)) {
- fw_type = VPU;
- } else if (!of_property_read_u32(pdev->dev.of_node, "mediatek,scp",
- &rproc_phandle)) {
- fw_type = SCP;
- } else {
- mtk_v4l2_err("Could not get venc IPI device");
- return -ENODEV;
- }
- dma_set_max_seg_size(&pdev->dev, UINT_MAX);
-
- dev->fw_handler = mtk_vcodec_fw_select(dev, fw_type, ENCODER);
- if (IS_ERR(dev->fw_handler))
- return PTR_ERR(dev->fw_handler);
-
- dev->venc_pdata = of_device_get_match_data(&pdev->dev);
- ret = mtk_vcodec_init_enc_clk(dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
- goto err_enc_pm;
- }
-
- pm_runtime_enable(&pdev->dev);
-
- dev->reg_base[dev->venc_pdata->core_id] =
- devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(dev->reg_base[dev->venc_pdata->core_id])) {
- ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_id]);
- goto err_res;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "failed to get irq resource");
- ret = -ENOENT;
- goto err_res;
- }
-
- dev->enc_irq = platform_get_irq(pdev, 0);
- irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
- ret = devm_request_irq(&pdev->dev, dev->enc_irq,
- mtk_vcodec_enc_irq_handler,
- 0, pdev->name, dev);
- if (ret) {
- dev_err(&pdev->dev,
- "Failed to install dev->enc_irq %d (%d) core_id (%d)",
- dev->enc_irq, ret, dev->venc_pdata->core_id);
- ret = -EINVAL;
- goto err_res;
- }
-
- mutex_init(&dev->enc_mutex);
- mutex_init(&dev->dev_mutex);
- spin_lock_init(&dev->irqlock);
-
- snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
- "[MTK_V4L2_VENC]");
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret) {
- mtk_v4l2_err("v4l2_device_register err=%d", ret);
- goto err_res;
- }
-
- init_waitqueue_head(&dev->queue);
-
- /* allocate video device for encoder and register it */
- vfd_enc = video_device_alloc();
- if (!vfd_enc) {
- mtk_v4l2_err("Failed to allocate video device");
- ret = -ENOMEM;
- goto err_enc_alloc;
- }
- vfd_enc->fops = &mtk_vcodec_fops;
- vfd_enc->ioctl_ops = &mtk_venc_ioctl_ops;
- vfd_enc->release = video_device_release;
- vfd_enc->lock = &dev->dev_mutex;
- vfd_enc->v4l2_dev = &dev->v4l2_dev;
- vfd_enc->vfl_dir = VFL_DIR_M2M;
- vfd_enc->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_STREAMING;
-
- snprintf(vfd_enc->name, sizeof(vfd_enc->name), "%s",
- MTK_VCODEC_ENC_NAME);
- video_set_drvdata(vfd_enc, dev);
- dev->vfd_enc = vfd_enc;
- platform_set_drvdata(pdev, dev);
-
- dev->m2m_dev_enc = v4l2_m2m_init(&mtk_venc_m2m_ops);
- if (IS_ERR((__force void *)dev->m2m_dev_enc)) {
- mtk_v4l2_err("Failed to init mem2mem enc device");
- ret = PTR_ERR((__force void *)dev->m2m_dev_enc);
- goto err_enc_mem_init;
- }
-
- dev->encode_workqueue =
- alloc_ordered_workqueue(MTK_VCODEC_ENC_NAME,
- WQ_MEM_RECLAIM |
- WQ_FREEZABLE);
- if (!dev->encode_workqueue) {
- mtk_v4l2_err("Failed to create encode workqueue");
- ret = -EINVAL;
- goto err_event_workq;
- }
-
- if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
- dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
-
- ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, -1);
- if (ret) {
- mtk_v4l2_err("Failed to register video device");
- goto err_enc_reg;
- }
-
- mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
- dev->venc_pdata->core_id, vfd_enc->num);
-
- return 0;
-
-err_enc_reg:
- destroy_workqueue(dev->encode_workqueue);
-err_event_workq:
- v4l2_m2m_release(dev->m2m_dev_enc);
-err_enc_mem_init:
- video_unregister_device(vfd_enc);
-err_enc_alloc:
- v4l2_device_unregister(&dev->v4l2_dev);
-err_res:
- pm_runtime_disable(dev->pm.dev);
-err_enc_pm:
- mtk_vcodec_fw_release(dev->fw_handler);
- return ret;
-}
-
-static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
- .chip = MTK_MT8173,
- .capture_formats = mtk_video_formats_capture_h264,
- .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
- .output_formats = mtk_video_formats_output,
- .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
- .min_bitrate = 64,
- .max_bitrate = 60000000,
- .core_id = VENC_SYS,
-};
-
-static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
- .chip = MTK_MT8173,
- .capture_formats = mtk_video_formats_capture_vp8,
- .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_vp8),
- .output_formats = mtk_video_formats_output,
- .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
- .min_bitrate = 64,
- .max_bitrate = 9000000,
- .core_id = VENC_LT_SYS,
-};
-
-static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
- .chip = MTK_MT8183,
- .uses_ext = true,
- .capture_formats = mtk_video_formats_capture_h264,
- .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
- .output_formats = mtk_video_formats_output,
- .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
- .min_bitrate = 64,
- .max_bitrate = 40000000,
- .core_id = VENC_SYS,
-};
-
-static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
- .chip = MTK_MT8192,
- .uses_ext = true,
- .capture_formats = mtk_video_formats_capture_h264,
- .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
- .output_formats = mtk_video_formats_output,
- .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
- .min_bitrate = 64,
- .max_bitrate = 100000000,
- .core_id = VENC_SYS,
-};
-
-static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
- .chip = MTK_MT8195,
- .uses_ext = true,
- .capture_formats = mtk_video_formats_capture_h264,
- .num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
- .output_formats = mtk_video_formats_output,
- .num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
- .min_bitrate = 64,
- .max_bitrate = 100000000,
- .core_id = VENC_SYS,
-};
-
-static const struct of_device_id mtk_vcodec_enc_match[] = {
- {.compatible = "mediatek,mt8173-vcodec-enc",
- .data = &mt8173_avc_pdata},
- {.compatible = "mediatek,mt8173-vcodec-enc-vp8",
- .data = &mt8173_vp8_pdata},
- {.compatible = "mediatek,mt8183-vcodec-enc", .data = &mt8183_pdata},
- {.compatible = "mediatek,mt8192-vcodec-enc", .data = &mt8192_pdata},
- {.compatible = "mediatek,mt8195-vcodec-enc", .data = &mt8195_pdata},
- {},
-};
-MODULE_DEVICE_TABLE(of, mtk_vcodec_enc_match);
-
-static int mtk_vcodec_enc_remove(struct platform_device *pdev)
-{
- struct mtk_vcodec_dev *dev = platform_get_drvdata(pdev);
-
- mtk_v4l2_debug_enter();
- destroy_workqueue(dev->encode_workqueue);
- if (dev->m2m_dev_enc)
- v4l2_m2m_release(dev->m2m_dev_enc);
-
- if (dev->vfd_enc)
- video_unregister_device(dev->vfd_enc);
-
- v4l2_device_unregister(&dev->v4l2_dev);
- pm_runtime_disable(dev->pm.dev);
- mtk_vcodec_fw_release(dev->fw_handler);
- return 0;
-}
-
-static struct platform_driver mtk_vcodec_enc_driver = {
- .probe = mtk_vcodec_probe,
- .remove = mtk_vcodec_enc_remove,
- .driver = {
- .name = MTK_VCODEC_ENC_NAME,
- .of_match_table = mtk_vcodec_enc_match,
- },
-};
-
-module_platform_driver(mtk_vcodec_enc_driver);
-
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mediatek video codec V4L2 encoder driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
deleted file mode 100644
index 7055954eb2af..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#include <linux/clk.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/pm_runtime.h>
-
-#include "mtk_vcodec_enc_pm.h"
-#include "mtk_vcodec_util.h"
-
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
-{
- struct platform_device *pdev;
- struct mtk_vcodec_pm *pm;
- struct mtk_vcodec_clk *enc_clk;
- struct mtk_vcodec_clk_info *clk_info;
- int ret, i;
-
- pdev = mtkdev->plat_dev;
- pm = &mtkdev->pm;
- memset(pm, 0, sizeof(struct mtk_vcodec_pm));
- pm->dev = &pdev->dev;
- enc_clk = &pm->venc_clk;
-
- enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
- "clock-names");
- if (enc_clk->clk_num > 0) {
- enc_clk->clk_info = devm_kcalloc(&pdev->dev,
- enc_clk->clk_num, sizeof(*clk_info),
- GFP_KERNEL);
- if (!enc_clk->clk_info)
- return -ENOMEM;
- } else {
- mtk_v4l2_err("Failed to get venc clock count");
- return -EINVAL;
- }
-
- for (i = 0; i < enc_clk->clk_num; i++) {
- clk_info = &enc_clk->clk_info[i];
- ret = of_property_read_string_index(pdev->dev.of_node,
- "clock-names", i, &clk_info->clk_name);
- if (ret) {
- mtk_v4l2_err("venc failed to get clk name %d", i);
- return ret;
- }
- clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
- clk_info->clk_name);
- if (IS_ERR(clk_info->vcodec_clk)) {
- mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
- clk_info->clk_name);
- return PTR_ERR(clk_info->vcodec_clk);
- }
- }
-
- return 0;
-}
-
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
-{
- struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
- int ret, i = 0;
-
- for (i = 0; i < enc_clk->clk_num; i++) {
- ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
- if (ret) {
- mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
- enc_clk->clk_info[i].clk_name, ret);
- goto clkerr;
- }
- }
-
- return;
-
-clkerr:
- for (i -= 1; i >= 0; i--)
- clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
-}
-
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
-{
- struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
- int i = 0;
-
- for (i = enc_clk->clk_num - 1; i >= 0; i--)
- clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
-}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
deleted file mode 100644
index bc455cefc0cd..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#ifndef _MTK_VCODEC_ENC_PM_H_
-#define _MTK_VCODEC_ENC_PM_H_
-
-#include "mtk_vcodec_drv.h"
-
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev);
-
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
-
-#endif /* _MTK_VCODEC_ENC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
deleted file mode 100644
index 94b39ae5c2e1..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include "mtk_vcodec_fw.h"
-#include "mtk_vcodec_fw_priv.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_drv.h"
-
-struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev,
- enum mtk_vcodec_fw_type type,
- enum mtk_vcodec_fw_use fw_use)
-{
- switch (type) {
- case VPU:
- return mtk_vcodec_fw_vpu_init(dev, fw_use);
- case SCP:
- return mtk_vcodec_fw_scp_init(dev);
- default:
- mtk_v4l2_err("invalid vcodec fw type");
- return ERR_PTR(-EINVAL);
- }
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_select);
-
-void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw)
-{
- fw->ops->release(fw);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_release);
-
-int mtk_vcodec_fw_load_firmware(struct mtk_vcodec_fw *fw)
-{
- return fw->ops->load_firmware(fw);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_load_firmware);
-
-unsigned int mtk_vcodec_fw_get_vdec_capa(struct mtk_vcodec_fw *fw)
-{
- return fw->ops->get_vdec_capa(fw);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_vdec_capa);
-
-unsigned int mtk_vcodec_fw_get_venc_capa(struct mtk_vcodec_fw *fw)
-{
- return fw->ops->get_venc_capa(fw);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_venc_capa);
-
-void *mtk_vcodec_fw_map_dm_addr(struct mtk_vcodec_fw *fw, u32 mem_addr)
-{
- return fw->ops->map_dm_addr(fw, mem_addr);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_map_dm_addr);
-
-int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
- mtk_vcodec_ipi_handler handler,
- const char *name, void *priv)
-{
- return fw->ops->ipi_register(fw, id, handler, name, priv);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_register);
-
-int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
- unsigned int len, unsigned int wait)
-{
- return fw->ops->ipi_send(fw, id, buf, len, wait);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_send);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
deleted file mode 100644
index 539bb626772c..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _MTK_VCODEC_FW_H_
-#define _MTK_VCODEC_FW_H_
-
-#include <linux/remoteproc.h>
-#include <linux/remoteproc/mtk_scp.h>
-
-#include "../mtk-vpu/mtk_vpu.h"
-
-struct mtk_vcodec_dev;
-
-enum mtk_vcodec_fw_type {
- VPU,
- SCP,
-};
-
-enum mtk_vcodec_fw_use {
- DECODER,
- ENCODER,
-};
-
-struct mtk_vcodec_fw;
-
-typedef void (*mtk_vcodec_ipi_handler) (void *data,
- unsigned int len, void *priv);
-
-struct mtk_vcodec_fw *mtk_vcodec_fw_select(struct mtk_vcodec_dev *dev,
- enum mtk_vcodec_fw_type type,
- enum mtk_vcodec_fw_use fw_use);
-void mtk_vcodec_fw_release(struct mtk_vcodec_fw *fw);
-
-int mtk_vcodec_fw_load_firmware(struct mtk_vcodec_fw *fw);
-unsigned int mtk_vcodec_fw_get_vdec_capa(struct mtk_vcodec_fw *fw);
-unsigned int mtk_vcodec_fw_get_venc_capa(struct mtk_vcodec_fw *fw);
-void *mtk_vcodec_fw_map_dm_addr(struct mtk_vcodec_fw *fw, u32 mem_addr);
-int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
- mtk_vcodec_ipi_handler handler,
- const char *name, void *priv);
-int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
- void *buf, unsigned int len, unsigned int wait);
-
-#endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h
deleted file mode 100644
index b41e66185cec..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_priv.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _MTK_VCODEC_FW_PRIV_H_
-#define _MTK_VCODEC_FW_PRIV_H_
-
-#include "mtk_vcodec_fw.h"
-
-struct mtk_vcodec_dev;
-
-struct mtk_vcodec_fw {
- enum mtk_vcodec_fw_type type;
- const struct mtk_vcodec_fw_ops *ops;
- struct platform_device *pdev;
- struct mtk_scp *scp;
-};
-
-struct mtk_vcodec_fw_ops {
- int (*load_firmware)(struct mtk_vcodec_fw *fw);
- unsigned int (*get_vdec_capa)(struct mtk_vcodec_fw *fw);
- unsigned int (*get_venc_capa)(struct mtk_vcodec_fw *fw);
- void *(*map_dm_addr)(struct mtk_vcodec_fw *fw, u32 dtcm_dmem_addr);
- int (*ipi_register)(struct mtk_vcodec_fw *fw, int id,
- mtk_vcodec_ipi_handler handler, const char *name,
- void *priv);
- 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);
-};
-
-#if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_VPU)
-struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
- enum mtk_vcodec_fw_use fw_use);
-#else
-static inline struct mtk_vcodec_fw *
-mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
- enum mtk_vcodec_fw_use fw_use)
-{
- return ERR_PTR(-ENODEV);
-}
-#endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_VPU */
-
-#if IS_ENABLED(CONFIG_VIDEO_MEDIATEK_VCODEC_SCP)
-struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev);
-#else
-static inline struct mtk_vcodec_fw *
-mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
-{
- return ERR_PTR(-ENODEV);
-}
-#endif /* CONFIG_VIDEO_MEDIATEK_VCODEC_SCP */
-
-#endif /* _MTK_VCODEC_FW_PRIV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
deleted file mode 100644
index d8e66b645bd8..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include "mtk_vcodec_fw_priv.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_drv.h"
-
-static int mtk_vcodec_scp_load_firmware(struct mtk_vcodec_fw *fw)
-{
- return rproc_boot(scp_get_rproc(fw->scp));
-}
-
-static unsigned int mtk_vcodec_scp_get_vdec_capa(struct mtk_vcodec_fw *fw)
-{
- return scp_get_vdec_hw_capa(fw->scp);
-}
-
-static unsigned int mtk_vcodec_scp_get_venc_capa(struct mtk_vcodec_fw *fw)
-{
- return scp_get_venc_hw_capa(fw->scp);
-}
-
-static void *mtk_vcodec_vpu_scp_dm_addr(struct mtk_vcodec_fw *fw,
- u32 dtcm_dmem_addr)
-{
- return scp_mapping_dm_addr(fw->scp, dtcm_dmem_addr);
-}
-
-static int mtk_vcodec_scp_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
- mtk_vcodec_ipi_handler handler,
- const char *name, void *priv)
-{
- return scp_ipi_register(fw->scp, id, handler, priv);
-}
-
-static int mtk_vcodec_scp_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
- unsigned int len, unsigned int wait)
-{
- return scp_ipi_send(fw->scp, id, buf, len, wait);
-}
-
-static void mtk_vcodec_scp_release(struct mtk_vcodec_fw *fw)
-{
- scp_put(fw->scp);
-}
-
-static const struct mtk_vcodec_fw_ops mtk_vcodec_rproc_msg = {
- .load_firmware = mtk_vcodec_scp_load_firmware,
- .get_vdec_capa = mtk_vcodec_scp_get_vdec_capa,
- .get_venc_capa = mtk_vcodec_scp_get_venc_capa,
- .map_dm_addr = mtk_vcodec_vpu_scp_dm_addr,
- .ipi_register = mtk_vcodec_scp_set_ipi_register,
- .ipi_send = mtk_vcodec_scp_ipi_send,
- .release = mtk_vcodec_scp_release,
-};
-
-struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
-{
- struct mtk_vcodec_fw *fw;
- struct mtk_scp *scp;
-
- scp = scp_get(dev->plat_dev);
- if (!scp) {
- mtk_v4l2_err("could not get vdec scp handle");
- return ERR_PTR(-EPROBE_DEFER);
- }
-
- fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
- fw->type = SCP;
- fw->ops = &mtk_vcodec_rproc_msg;
- fw->scp = scp;
-
- return fw;
-}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
deleted file mode 100644
index cfc7ebed8fb7..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include "mtk_vcodec_fw_priv.h"
-#include "mtk_vcodec_util.h"
-#include "mtk_vcodec_drv.h"
-
-static int mtk_vcodec_vpu_load_firmware(struct mtk_vcodec_fw *fw)
-{
- return vpu_load_firmware(fw->pdev);
-}
-
-static unsigned int mtk_vcodec_vpu_get_vdec_capa(struct mtk_vcodec_fw *fw)
-{
- return vpu_get_vdec_hw_capa(fw->pdev);
-}
-
-static unsigned int mtk_vcodec_vpu_get_venc_capa(struct mtk_vcodec_fw *fw)
-{
- return vpu_get_venc_hw_capa(fw->pdev);
-}
-
-static void *mtk_vcodec_vpu_map_dm_addr(struct mtk_vcodec_fw *fw,
- u32 dtcm_dmem_addr)
-{
- return vpu_mapping_dm_addr(fw->pdev, dtcm_dmem_addr);
-}
-
-static int mtk_vcodec_vpu_set_ipi_register(struct mtk_vcodec_fw *fw, int id,
- mtk_vcodec_ipi_handler handler,
- const char *name, void *priv)
-{
- /*
- * The handler we receive takes a void * as its first argument. We
- * cannot change this because it needs to be passed down to the rproc
- * subsystem when SCP is used. VPU takes a const argument, which is
- * more constrained, so the conversion below is safe.
- */
- ipi_handler_t handler_const = (ipi_handler_t)handler;
-
- return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
-}
-
-static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
- unsigned int len, unsigned int wait)
-{
- return vpu_ipi_send(fw->pdev, id, buf, len);
-}
-
-static void mtk_vcodec_vpu_release(struct mtk_vcodec_fw *fw)
-{
- put_device(&fw->pdev->dev);
-}
-
-static void mtk_vcodec_vpu_reset_handler(void *priv)
-{
- struct mtk_vcodec_dev *dev = priv;
- struct mtk_vcodec_ctx *ctx;
-
- mtk_v4l2_err("Watchdog timeout!!");
-
- mutex_lock(&dev->dev_mutex);
- list_for_each_entry(ctx, &dev->ctx_list, list) {
- ctx->state = MTK_STATE_ABORT;
- mtk_v4l2_debug(0, "[%d] Change to state MTK_STATE_ABORT",
- ctx->id);
- }
- mutex_unlock(&dev->dev_mutex);
-}
-
-static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
- .load_firmware = mtk_vcodec_vpu_load_firmware,
- .get_vdec_capa = mtk_vcodec_vpu_get_vdec_capa,
- .get_venc_capa = mtk_vcodec_vpu_get_venc_capa,
- .map_dm_addr = mtk_vcodec_vpu_map_dm_addr,
- .ipi_register = mtk_vcodec_vpu_set_ipi_register,
- .ipi_send = mtk_vcodec_vpu_ipi_send,
- .release = mtk_vcodec_vpu_release,
-};
-
-struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
- enum mtk_vcodec_fw_use fw_use)
-{
- struct platform_device *fw_pdev;
- struct mtk_vcodec_fw *fw;
- enum rst_id rst_id;
-
- switch (fw_use) {
- case ENCODER:
- rst_id = VPU_RST_ENC;
- break;
- case DECODER:
- default:
- rst_id = VPU_RST_DEC;
- break;
- }
-
- fw_pdev = vpu_get_plat_device(dev->plat_dev);
- if (!fw_pdev) {
- mtk_v4l2_err("firmware device is not ready");
- return ERR_PTR(-EINVAL);
- }
- vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id);
-
- fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
- if (!fw)
- return ERR_PTR(-ENOMEM);
- fw->type = VPU;
- fw->ops = &mtk_vcodec_vpu_msg;
- fw->pdev = fw_pdev;
-
- return fw;
-}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
deleted file mode 100644
index 552b4c93d972..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#include <linux/errno.h>
-#include <linux/wait.h>
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_intr.h"
-#include "mtk_vcodec_util.h"
-
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
- int command, unsigned int timeout_ms,
- unsigned int hw_id)
-{
- long timeout_jiff, ret;
- int status = 0;
-
- timeout_jiff = msecs_to_jiffies(timeout_ms);
- ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
- ctx->int_cond[hw_id],
- timeout_jiff);
-
- if (!ret) {
- status = -1; /* timeout */
- mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
- ctx->id, command, ctx->type, timeout_ms,
- ctx->int_cond[hw_id], ctx->int_type[hw_id]);
- } else if (-ERESTARTSYS == ret) {
- status = -1;
- mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
- ctx->id, command, ctx->type,
- ctx->int_cond[hw_id], ctx->int_type[hw_id]);
- }
-
- ctx->int_cond[hw_id] = 0;
- ctx->int_type[hw_id] = 0;
-
- return status;
-}
-EXPORT_SYMBOL(mtk_vcodec_wait_for_done_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
deleted file mode 100644
index 9681f492813b..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#ifndef _MTK_VCODEC_INTR_H_
-#define _MTK_VCODEC_INTR_H_
-
-#define MTK_INST_IRQ_RECEIVED 0x1
-
-struct mtk_vcodec_ctx;
-
-/* timeout is ms */
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
- int command, unsigned int timeout_ms,
- unsigned int hw_id);
-
-#endif /* _MTK_VCODEC_INTR_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
deleted file mode 100644
index ace78c4b5b9e..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-
-#include "mtk_vcodec_dec_hw.h"
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_util.h"
-
-void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
- unsigned int reg_idx)
-{
- struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
-
- if (!data || reg_idx >= NUM_MAX_VCODEC_REG_BASE) {
- mtk_v4l2_err("Invalid arguments, reg_idx=%d", reg_idx);
- return NULL;
- }
- return ctx->dev->reg_base[reg_idx];
-}
-EXPORT_SYMBOL(mtk_vcodec_get_reg_addr);
-
-int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
- struct mtk_vcodec_mem *mem)
-{
- unsigned long size = mem->size;
- struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
- struct device *dev = &ctx->dev->plat_dev->dev;
-
- mem->va = dma_alloc_coherent(dev, size, &mem->dma_addr, GFP_KERNEL);
- if (!mem->va) {
- mtk_v4l2_err("%s dma_alloc size=%ld failed!", dev_name(dev),
- size);
- return -ENOMEM;
- }
-
- mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va);
- mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id,
- (unsigned long)mem->dma_addr);
- mtk_v4l2_debug(3, "[%d] size = 0x%lx", ctx->id, size);
-
- return 0;
-}
-EXPORT_SYMBOL(mtk_vcodec_mem_alloc);
-
-void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
- struct mtk_vcodec_mem *mem)
-{
- unsigned long size = mem->size;
- struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)data;
- struct device *dev = &ctx->dev->plat_dev->dev;
-
- if (!mem->va) {
- mtk_v4l2_err("%s dma_free size=%ld failed!", dev_name(dev),
- size);
- return;
- }
-
- mtk_v4l2_debug(3, "[%d] - va = %p", ctx->id, mem->va);
- mtk_v4l2_debug(3, "[%d] - dma = 0x%lx", ctx->id,
- (unsigned long)mem->dma_addr);
- mtk_v4l2_debug(3, "[%d] size = 0x%lx", ctx->id, size);
-
- dma_free_coherent(dev, size, mem->va, mem->dma_addr);
- mem->va = NULL;
- mem->dma_addr = 0;
- mem->size = 0;
-}
-EXPORT_SYMBOL(mtk_vcodec_mem_free);
-
-void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx)
-{
- if (hw_idx >= MTK_VDEC_HW_MAX || hw_idx < 0 || !dev->subdev_dev[hw_idx]) {
- mtk_v4l2_err("hw idx is out of range:%d", hw_idx);
- return NULL;
- }
-
- return dev->subdev_dev[hw_idx];
-}
-EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
-
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
- struct mtk_vcodec_ctx *ctx, int hw_idx)
-{
- unsigned long flags;
- struct mtk_vdec_hw_dev *subdev_dev;
-
- spin_lock_irqsave(&vdec_dev->irqlock, flags);
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev");
- spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
- return;
- }
- subdev_dev->curr_ctx = ctx;
- } else {
- vdec_dev->curr_ctx = ctx;
- }
- spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
-}
-EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
-
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
- unsigned int hw_idx)
-{
- unsigned long flags;
- struct mtk_vcodec_ctx *ctx;
- struct mtk_vdec_hw_dev *subdev_dev;
-
- spin_lock_irqsave(&vdec_dev->irqlock, flags);
- if (vdec_dev->vdec_pdata->is_subdev_supported) {
- subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
- if (!subdev_dev) {
- mtk_v4l2_err("Failed to get hw dev");
- spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
- return NULL;
- }
- ctx = subdev_dev->curr_ctx;
- } else {
- ctx = vdec_dev->curr_ctx;
- }
- spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
- return ctx;
-}
-EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Mediatek video codec driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
deleted file mode 100644
index 71956627a0e2..000000000000
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
-* Copyright (c) 2016 MediaTek Inc.
-* Author: PC Chen <pc.chen@mediatek.com>
-* Tiffany Lin <tiffany.lin@mediatek.com>
-*/
-
-#ifndef _MTK_VCODEC_UTIL_H_
-#define _MTK_VCODEC_UTIL_H_
-
-#include <linux/types.h>
-#include <linux/dma-direction.h>
-
-struct mtk_vcodec_mem {
- size_t size;
- void *va;
- dma_addr_t dma_addr;
-};
-
-struct mtk_vcodec_fb {
- size_t size;
- dma_addr_t dma_addr;
-};
-
-struct mtk_vcodec_ctx;
-struct mtk_vcodec_dev;
-
-#undef pr_fmt
-#define pr_fmt(fmt) "%s(),%d: " fmt, __func__, __LINE__
-
-#define mtk_v4l2_err(fmt, args...) \
- pr_err("[MTK_V4L2][ERROR] " fmt "\n", ##args)
-
-#define mtk_vcodec_err(h, fmt, args...) \
- pr_err("[MTK_VCODEC][ERROR][%d]: " fmt "\n", \
- ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args)
-
-
-#define mtk_v4l2_debug(level, fmt, args...) pr_debug(fmt, ##args)
-
-#define mtk_v4l2_debug_enter() mtk_v4l2_debug(3, "+")
-#define mtk_v4l2_debug_leave() mtk_v4l2_debug(3, "-")
-
-#define mtk_vcodec_debug(h, fmt, args...) \
- pr_debug("[MTK_VCODEC][%d]: " fmt "\n", \
- ((struct mtk_vcodec_ctx *)(h)->ctx)->id, ##args)
-
-#define mtk_vcodec_debug_enter(h) mtk_vcodec_debug(h, "+")
-#define mtk_vcodec_debug_leave(h) mtk_vcodec_debug(h, "-")
-
-void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
- unsigned int reg_idx);
-int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
- struct mtk_vcodec_mem *mem);
-void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
- struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
- struct mtk_vcodec_ctx *ctx, int hw_idx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
- unsigned int hw_idx);
-void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx);
-
-#endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
deleted file mode 100644
index 481655bb6016..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ /dev/null
@@ -1,503 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "../vdec_drv_if.h"
-#include "../mtk_vcodec_util.h"
-#include "../mtk_vcodec_dec.h"
-#include "../mtk_vcodec_intr.h"
-#include "../vdec_vpu_if.h"
-#include "../vdec_drv_base.h"
-
-#define NAL_NON_IDR_SLICE 0x01
-#define NAL_IDR_SLICE 0x05
-#define NAL_H264_PPS 0x08
-#define NAL_TYPE(value) ((value) & 0x1F)
-
-#define BUF_PREDICTION_SZ (32 * 1024)
-
-#define MB_UNIT_LEN 16
-
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ 64
-
-#define H264_MAX_FB_NUM 17
-#define HDR_PARSING_BUF_SZ 1024
-
-#define DEC_ERR_RET(ret) ((ret) >> 16)
-#define H264_ERR_NOT_VALID 3
-
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va : virtual address of struct vdec_fb
- * @y_fb_dma : dma address of Y frame buffer (luma)
- * @c_fb_dma : dma address of C frame buffer (chroma)
- * @poc : picture order count of frame buffer
- * @reserved : for 8 bytes alignment
- */
-struct h264_fb {
- uint64_t vdec_fb_va;
- uint64_t y_fb_dma;
- uint64_t c_fb_dma;
- int32_t poc;
- uint32_t reserved;
-};
-
-/**
- * struct h264_ring_fb_list - ring frame buffer list
- * @fb_list : frame buffer array
- * @read_idx : read index
- * @write_idx : write index
- * @count : buffer count in list
- * @reserved : for 8 bytes alignment
- */
-struct h264_ring_fb_list {
- struct h264_fb fb_list[H264_MAX_FB_NUM];
- unsigned int read_idx;
- unsigned int write_idx;
- unsigned int count;
- unsigned int reserved;
-};
-
-/**
- * struct vdec_h264_dec_info - decode information
- * @dpb_sz : decoding picture buffer size
- * @resolution_changed : resolution change happen
- * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer
- * @reserved : for 8 bytes alignment
- * @bs_dma : Input bit-stream buffer dma address
- * @y_fb_dma : Y frame buffer dma address
- * @c_fb_dma : C frame buffer dma address
- * @vdec_fb_va : VDEC frame buffer struct virtual address
- */
-struct vdec_h264_dec_info {
- uint32_t dpb_sz;
- uint32_t resolution_changed;
- uint32_t realloc_mv_buf;
- uint32_t reserved;
- uint64_t bs_dma;
- uint64_t y_fb_dma;
- uint64_t c_fb_dma;
- uint64_t vdec_fb_va;
-};
-
-/**
- * struct vdec_h264_vsi - shared memory for decode information exchange
- * between VPU and Host.
- * The memory is allocated by VPU then mapping to Host
- * in vpu_dec_init() and freed in vpu_dec_deinit()
- * by VPU.
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @hdr_buf : Header parsing buffer (AP-W, VPU-R)
- * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R)
- * @mv_buf_dma : HW working motion vector buffer dma address (AP-W, VPU-R)
- * @list_free : free frame buffer ring list (AP-W/R, VPU-W)
- * @list_disp : display frame buffer ring list (AP-R, VPU-W)
- * @dec : decode information (AP-R, VPU-W)
- * @pic : picture information (AP-R, VPU-W)
- * @crop : crop information (AP-R, VPU-W)
- */
-struct vdec_h264_vsi {
- unsigned char hdr_buf[HDR_PARSING_BUF_SZ];
- uint64_t pred_buf_dma;
- uint64_t mv_buf_dma[H264_MAX_FB_NUM];
- struct h264_ring_fb_list list_free;
- struct h264_ring_fb_list list_disp;
- struct vdec_h264_dec_info dec;
- struct vdec_pic_info pic;
- struct v4l2_rect crop;
-};
-
-/**
- * struct vdec_h264_inst - h264 decoder instance
- * @num_nalu : how many nalus be decoded
- * @ctx : point to mtk_vcodec_ctx
- * @pred_buf : HW working predication buffer
- * @mv_buf : HW working motion vector buffer
- * @vpu : VPU instance
- * @vsi : VPU shared information
- */
-struct vdec_h264_inst {
- unsigned int num_nalu;
- struct mtk_vcodec_ctx *ctx;
- struct mtk_vcodec_mem pred_buf;
- struct mtk_vcodec_mem mv_buf[H264_MAX_FB_NUM];
- struct vdec_vpu_inst vpu;
- struct vdec_h264_vsi *vsi;
-};
-
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
- return HW_MB_STORE_SZ * (width/MB_UNIT_LEN) * (height/MB_UNIT_LEN);
-}
-
-static int allocate_predication_buf(struct vdec_h264_inst *inst)
-{
- int err = 0;
-
- inst->pred_buf.size = BUF_PREDICTION_SZ;
- err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf);
- if (err) {
- mtk_vcodec_err(inst, "failed to allocate ppl buf");
- return err;
- }
-
- inst->vsi->pred_buf_dma = inst->pred_buf.dma_addr;
- return 0;
-}
-
-static void free_predication_buf(struct vdec_h264_inst *inst)
-{
- struct mtk_vcodec_mem *mem = NULL;
-
- mtk_vcodec_debug_enter(inst);
-
- inst->vsi->pred_buf_dma = 0;
- mem = &inst->pred_buf;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-}
-
-static int alloc_mv_buf(struct vdec_h264_inst *inst, struct vdec_pic_info *pic)
-{
- int i;
- int err;
- struct mtk_vcodec_mem *mem = NULL;
- unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
-
- for (i = 0; i < H264_MAX_FB_NUM; i++) {
- mem = &inst->mv_buf[i];
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
- mem->size = buf_sz;
- err = mtk_vcodec_mem_alloc(inst->ctx, mem);
- if (err) {
- mtk_vcodec_err(inst, "failed to allocate mv buf");
- return err;
- }
- inst->vsi->mv_buf_dma[i] = mem->dma_addr;
- }
-
- return 0;
-}
-
-static void free_mv_buf(struct vdec_h264_inst *inst)
-{
- int i;
- struct mtk_vcodec_mem *mem = NULL;
-
- for (i = 0; i < H264_MAX_FB_NUM; i++) {
- inst->vsi->mv_buf_dma[i] = 0;
- mem = &inst->mv_buf[i];
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
- }
-}
-
-static int check_list_validity(struct vdec_h264_inst *inst, bool disp_list)
-{
- struct h264_ring_fb_list *list;
-
- list = disp_list ? &inst->vsi->list_disp : &inst->vsi->list_free;
-
- if (list->count > H264_MAX_FB_NUM ||
- list->read_idx >= H264_MAX_FB_NUM ||
- list->write_idx >= H264_MAX_FB_NUM) {
- mtk_vcodec_err(inst, "%s list err: cnt=%d r_idx=%d w_idx=%d",
- disp_list ? "disp" : "free", list->count,
- list->read_idx, list->write_idx);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void put_fb_to_free(struct vdec_h264_inst *inst, struct vdec_fb *fb)
-{
- struct h264_ring_fb_list *list;
-
- if (fb) {
- if (check_list_validity(inst, false))
- return;
-
- list = &inst->vsi->list_free;
- if (list->count == H264_MAX_FB_NUM) {
- mtk_vcodec_err(inst, "[FB] put fb free_list full");
- return;
- }
-
- mtk_vcodec_debug(inst, "[FB] put fb into free_list @(%p, %llx)",
- fb->base_y.va, (u64)fb->base_y.dma_addr);
-
- list->fb_list[list->write_idx].vdec_fb_va = (u64)(uintptr_t)fb;
- list->write_idx = (list->write_idx == H264_MAX_FB_NUM - 1) ?
- 0 : list->write_idx + 1;
- list->count++;
- }
-}
-
-static void get_pic_info(struct vdec_h264_inst *inst,
- struct vdec_pic_info *pic)
-{
- *pic = inst->vsi->pic;
- mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
- pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
- mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
- pic->fb_sz[0], pic->fb_sz[1]);
-}
-
-static void get_crop_info(struct vdec_h264_inst *inst, struct v4l2_rect *cr)
-{
- cr->left = inst->vsi->crop.left;
- cr->top = inst->vsi->crop.top;
- cr->width = inst->vsi->crop.width;
- cr->height = inst->vsi->crop.height;
-
- mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
- cr->left, cr->top, cr->width, cr->height);
-}
-
-static void get_dpb_size(struct vdec_h264_inst *inst, unsigned int *dpb_sz)
-{
- *dpb_sz = inst->vsi->dec.dpb_sz;
- mtk_vcodec_debug(inst, "sz=%d", *dpb_sz);
-}
-
-static int vdec_h264_init(struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_h264_inst *inst = NULL;
- int err;
-
- inst = kzalloc(sizeof(*inst), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- inst->ctx = ctx;
-
- inst->vpu.id = IPI_VDEC_H264;
- inst->vpu.ctx = ctx;
-
- err = vpu_dec_init(&inst->vpu);
- if (err) {
- mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
- goto error_free_inst;
- }
-
- inst->vsi = (struct vdec_h264_vsi *)inst->vpu.vsi;
- err = allocate_predication_buf(inst);
- if (err)
- goto error_deinit;
-
- mtk_vcodec_debug(inst, "H264 Instance >> %p", inst);
-
- ctx->drv_handle = inst;
- return 0;
-
-error_deinit:
- vpu_dec_deinit(&inst->vpu);
-
-error_free_inst:
- kfree(inst);
- return err;
-}
-
-static void vdec_h264_deinit(void *h_vdec)
-{
- struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
-
- mtk_vcodec_debug_enter(inst);
-
- vpu_dec_deinit(&inst->vpu);
- free_predication_buf(inst);
- free_mv_buf(inst);
-
- kfree(inst);
-}
-
-static int find_start_code(unsigned char *data, unsigned int data_sz)
-{
- if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
- return 3;
-
- if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
- data[3] == 1)
- return 4;
-
- return -1;
-}
-
-static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg)
-{
- struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
- struct vdec_vpu_inst *vpu = &inst->vpu;
- int nal_start_idx = 0;
- int err = 0;
- unsigned int nal_start;
- unsigned int nal_type;
- unsigned char *buf;
- unsigned int buf_sz;
- unsigned int data[2];
- uint64_t vdec_fb_va = (u64)(uintptr_t)fb;
- uint64_t y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
- uint64_t c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
-
- mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
- ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
-
- /* bs NULL means flush decoder */
- if (bs == NULL)
- return vpu_dec_reset(vpu);
-
- buf = (unsigned char *)bs->va;
- buf_sz = bs->size;
- nal_start_idx = find_start_code(buf, buf_sz);
- if (nal_start_idx < 0) {
- mtk_vcodec_err(inst, "invalid nal start code");
- err = -EIO;
- goto err_free_fb_out;
- }
-
- nal_start = buf[nal_start_idx];
- nal_type = NAL_TYPE(buf[nal_start_idx]);
- mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu,
- nal_type);
-
- if (nal_type == NAL_H264_PPS) {
- buf_sz -= nal_start_idx;
- if (buf_sz > HDR_PARSING_BUF_SZ) {
- err = -EILSEQ;
- goto err_free_fb_out;
- }
- memcpy(inst->vsi->hdr_buf, buf + nal_start_idx, buf_sz);
- }
-
- inst->vsi->dec.bs_dma = (uint64_t)bs->dma_addr;
- inst->vsi->dec.y_fb_dma = y_fb_dma;
- inst->vsi->dec.c_fb_dma = c_fb_dma;
- inst->vsi->dec.vdec_fb_va = vdec_fb_va;
-
- data[0] = buf_sz;
- data[1] = nal_start;
- err = vpu_dec_start(vpu, data, 2);
- if (err) {
- if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) {
- mtk_vcodec_err(inst, "- error bitstream - err = %d -",
- err);
- err = -EIO;
- }
- goto err_free_fb_out;
- }
-
- *res_chg = inst->vsi->dec.resolution_changed;
- if (*res_chg) {
- struct vdec_pic_info pic;
-
- mtk_vcodec_debug(inst, "- resolution changed -");
- get_pic_info(inst, &pic);
-
- if (inst->vsi->dec.realloc_mv_buf) {
- err = alloc_mv_buf(inst, &pic);
- if (err)
- goto err_free_fb_out;
- }
- }
-
- if (nal_type == NAL_NON_IDR_SLICE || nal_type == NAL_IDR_SLICE) {
- /* wait decoder done interrupt */
- err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
- MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0);
- if (err)
- goto err_free_fb_out;
-
- vpu_dec_end(vpu);
- }
-
- mtk_vcodec_debug(inst, "\n - NALU[%d] type=%d -\n", inst->num_nalu,
- nal_type);
- return 0;
-
-err_free_fb_out:
- put_fb_to_free(inst, fb);
- mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err);
- return err;
-}
-
-static void vdec_h264_get_fb(struct vdec_h264_inst *inst,
- struct h264_ring_fb_list *list,
- bool disp_list, struct vdec_fb **out_fb)
-{
- struct vdec_fb *fb;
-
- if (check_list_validity(inst, disp_list))
- return;
-
- if (list->count == 0) {
- mtk_vcodec_debug(inst, "[FB] there is no %s fb",
- disp_list ? "disp" : "free");
- *out_fb = NULL;
- return;
- }
-
- fb = (struct vdec_fb *)
- (uintptr_t)list->fb_list[list->read_idx].vdec_fb_va;
- fb->status |= (disp_list ? FB_ST_DISPLAY : FB_ST_FREE);
-
- *out_fb = fb;
- mtk_vcodec_debug(inst, "[FB] get %s fb st=%d poc=%d %llx",
- disp_list ? "disp" : "free",
- fb->status, list->fb_list[list->read_idx].poc,
- list->fb_list[list->read_idx].vdec_fb_va);
-
- list->read_idx = (list->read_idx == H264_MAX_FB_NUM - 1) ?
- 0 : list->read_idx + 1;
- list->count--;
-}
-
-static int vdec_h264_get_param(void *h_vdec, enum vdec_get_param_type type,
- void *out)
-{
- struct vdec_h264_inst *inst = (struct vdec_h264_inst *)h_vdec;
-
- switch (type) {
- case GET_PARAM_DISP_FRAME_BUFFER:
- vdec_h264_get_fb(inst, &inst->vsi->list_disp, true, out);
- break;
-
- case GET_PARAM_FREE_FRAME_BUFFER:
- vdec_h264_get_fb(inst, &inst->vsi->list_free, false, out);
- break;
-
- case GET_PARAM_PIC_INFO:
- get_pic_info(inst, out);
- break;
-
- case GET_PARAM_DPB_SIZE:
- get_dpb_size(inst, out);
- break;
-
- case GET_PARAM_CROP_INFO:
- get_crop_info(inst, out);
- break;
-
- default:
- mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-const struct vdec_common_if vdec_h264_if = {
- .init = vdec_h264_init,
- .decode = vdec_h264_decode,
- .get_param = vdec_h264_get_param,
- .deinit = vdec_h264_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
deleted file mode 100644
index 43542de11e9c..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ /dev/null
@@ -1,774 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-h264.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "../mtk_vcodec_util.h"
-#include "../mtk_vcodec_dec.h"
-#include "../mtk_vcodec_intr.h"
-#include "../vdec_drv_base.h"
-#include "../vdec_drv_if.h"
-#include "../vdec_vpu_if.h"
-
-#define BUF_PREDICTION_SZ (64 * 4096)
-#define MB_UNIT_LEN 16
-
-/* get used parameters for sps/pps */
-#define GET_MTK_VDEC_FLAG(cond, flag) \
- { dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
-#define GET_MTK_VDEC_PARAM(param) \
- { dst_param->param = src_param->param; }
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ 64
-
-#define H264_MAX_FB_NUM 17
-#define H264_MAX_MV_NUM 32
-#define HDR_PARSING_BUF_SZ 1024
-
-/**
- * struct mtk_h264_dpb_info - h264 dpb information
- * @y_dma_addr: Y bitstream physical address
- * @c_dma_addr: CbCr bitstream physical address
- * @reference_flag: reference picture flag (short/long term reference picture)
- * @field: field picture flag
- */
-struct mtk_h264_dpb_info {
- dma_addr_t y_dma_addr;
- dma_addr_t c_dma_addr;
- int reference_flag;
- int field;
-};
-
-/*
- * struct mtk_h264_sps_param - parameters for sps
- */
-struct mtk_h264_sps_param {
- unsigned char chroma_format_idc;
- unsigned char bit_depth_luma_minus8;
- unsigned char bit_depth_chroma_minus8;
- unsigned char log2_max_frame_num_minus4;
- unsigned char pic_order_cnt_type;
- unsigned char log2_max_pic_order_cnt_lsb_minus4;
- unsigned char max_num_ref_frames;
- unsigned char separate_colour_plane_flag;
- unsigned short pic_width_in_mbs_minus1;
- unsigned short pic_height_in_map_units_minus1;
- unsigned int max_frame_nums;
- unsigned char qpprime_y_zero_transform_bypass_flag;
- unsigned char delta_pic_order_always_zero_flag;
- unsigned char frame_mbs_only_flag;
- unsigned char mb_adaptive_frame_field_flag;
- unsigned char direct_8x8_inference_flag;
- unsigned char reserved[3];
-};
-
-/*
- * struct mtk_h264_pps_param - parameters for pps
- */
-struct mtk_h264_pps_param {
- unsigned char num_ref_idx_l0_default_active_minus1;
- unsigned char num_ref_idx_l1_default_active_minus1;
- unsigned char weighted_bipred_idc;
- char pic_init_qp_minus26;
- char chroma_qp_index_offset;
- char second_chroma_qp_index_offset;
- unsigned char entropy_coding_mode_flag;
- unsigned char pic_order_present_flag;
- unsigned char deblocking_filter_control_present_flag;
- unsigned char constrained_intra_pred_flag;
- unsigned char weighted_pred_flag;
- unsigned char redundant_pic_cnt_present_flag;
- unsigned char transform_8x8_mode_flag;
- unsigned char scaling_matrix_present_flag;
- unsigned char reserved[2];
-};
-
-struct slice_api_h264_scaling_matrix {
- unsigned char scaling_list_4x4[6][16];
- unsigned char scaling_list_8x8[6][64];
-};
-
-struct slice_h264_dpb_entry {
- unsigned long long reference_ts;
- unsigned short frame_num;
- unsigned short pic_num;
- /* Note that field is indicated by v4l2_buffer.field */
- int top_field_order_cnt;
- int bottom_field_order_cnt;
- unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
-};
-
-/*
- * struct slice_api_h264_decode_param - parameters for decode.
- */
-struct slice_api_h264_decode_param {
- struct slice_h264_dpb_entry dpb[16];
- unsigned short num_slices;
- unsigned short nal_ref_idc;
- unsigned char ref_pic_list_p0[32];
- unsigned char ref_pic_list_b0[32];
- unsigned char ref_pic_list_b1[32];
- int top_field_order_cnt;
- int bottom_field_order_cnt;
- unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
-};
-
-/*
- * struct mtk_h264_dec_slice_param - parameters for decode current frame
- */
-struct mtk_h264_dec_slice_param {
- struct mtk_h264_sps_param sps;
- struct mtk_h264_pps_param pps;
- struct slice_api_h264_scaling_matrix scaling_matrix;
- struct slice_api_h264_decode_param decode_params;
- struct mtk_h264_dpb_info h264_dpb_info[16];
-};
-
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va : virtual address of struct vdec_fb
- * @y_fb_dma : dma address of Y frame buffer (luma)
- * @c_fb_dma : dma address of C frame buffer (chroma)
- * @poc : picture order count of frame buffer
- * @reserved : for 8 bytes alignment
- */
-struct h264_fb {
- u64 vdec_fb_va;
- u64 y_fb_dma;
- u64 c_fb_dma;
- s32 poc;
- u32 reserved;
-};
-
-/**
- * struct vdec_h264_dec_info - decode information
- * @dpb_sz : decoding picture buffer size
- * @resolution_changed : resoltion change happen
- * @realloc_mv_buf : flag to notify driver to re-allocate mv buffer
- * @cap_num_planes : number planes of capture buffer
- * @bs_dma : Input bit-stream buffer dma address
- * @y_fb_dma : Y frame buffer dma address
- * @c_fb_dma : C frame buffer dma address
- * @vdec_fb_va : VDEC frame buffer struct virtual address
- */
-struct vdec_h264_dec_info {
- u32 dpb_sz;
- u32 resolution_changed;
- u32 realloc_mv_buf;
- u32 cap_num_planes;
- u64 bs_dma;
- u64 y_fb_dma;
- u64 c_fb_dma;
- u64 vdec_fb_va;
-};
-
-/**
- * struct vdec_h264_vsi - shared memory for decode information exchange
- * between VPU and Host.
- * The memory is allocated by VPU then mapping to Host
- * in vpu_dec_init() and freed in vpu_dec_deinit()
- * by VPU.
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @pred_buf_dma : HW working predication buffer dma address (AP-W, VPU-R)
- * @mv_buf_dma : HW working motion vector buffer dma address (AP-W, VPU-R)
- * @dec : decode information (AP-R, VPU-W)
- * @pic : picture information (AP-R, VPU-W)
- * @crop : crop information (AP-R, VPU-W)
- * @h264_slice_params : the parameters that hardware use to decode
- */
-struct vdec_h264_vsi {
- u64 pred_buf_dma;
- u64 mv_buf_dma[H264_MAX_MV_NUM];
- struct vdec_h264_dec_info dec;
- struct vdec_pic_info pic;
- struct v4l2_rect crop;
- struct mtk_h264_dec_slice_param h264_slice_params;
-};
-
-/**
- * struct vdec_h264_slice_inst - h264 decoder instance
- * @num_nalu : how many nalus be decoded
- * @ctx : point to mtk_vcodec_ctx
- * @pred_buf : HW working predication buffer
- * @mv_buf : HW working motion vector buffer
- * @vpu : VPU instance
- * @vsi_ctx : Local VSI data for this decoding context
- * @h264_slice_param : the parameters that hardware use to decode
- * @dpb : decoded picture buffer used to store reference buffer information
- */
-struct vdec_h264_slice_inst {
- unsigned int num_nalu;
- struct mtk_vcodec_ctx *ctx;
- struct mtk_vcodec_mem pred_buf;
- struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
- struct vdec_vpu_inst vpu;
- struct vdec_h264_vsi vsi_ctx;
- struct mtk_h264_dec_slice_param h264_slice_param;
-
- struct v4l2_h264_dpb_entry dpb[16];
-};
-
-static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
-{
- struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
-
- return ctrl->p_cur.p;
-}
-
-static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
- struct mtk_h264_dec_slice_param *slice_param)
-{
- struct vb2_queue *vq;
- struct vb2_buffer *vb;
- struct vb2_v4l2_buffer *vb2_v4l2;
- u64 index;
-
- vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-
- for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
- const struct slice_h264_dpb_entry *dpb;
- int vb2_index;
-
- dpb = &slice_param->decode_params.dpb[index];
- if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
- slice_param->h264_dpb_info[index].reference_flag = 0;
- continue;
- }
-
- vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
- if (vb2_index < 0) {
- mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
- index, dpb->reference_ts);
- continue;
- }
- /* 1 for short term reference, 2 for long term reference */
- if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
- slice_param->h264_dpb_info[index].reference_flag = 1;
- else
- slice_param->h264_dpb_info[index].reference_flag = 2;
-
- vb = vq->bufs[vb2_index];
- vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
- slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
-
- slice_param->h264_dpb_info[index].y_dma_addr =
- vb2_dma_contig_plane_dma_addr(vb, 0);
- if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
- slice_param->h264_dpb_info[index].c_dma_addr =
- vb2_dma_contig_plane_dma_addr(vb, 1);
- }
- }
-}
-
-static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
- const struct v4l2_ctrl_h264_sps *src_param)
-{
- GET_MTK_VDEC_PARAM(chroma_format_idc);
- GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
- GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
- GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
- GET_MTK_VDEC_PARAM(pic_order_cnt_type);
- GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
- GET_MTK_VDEC_PARAM(max_num_ref_frames);
- GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
- GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
-
- GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
- V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
- GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
- V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
- GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
- V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
- GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
- V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
- GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
- V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
- GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
- V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-}
-
-static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
- const struct v4l2_ctrl_h264_pps *src_param)
-{
- GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
- GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
- GET_MTK_VDEC_PARAM(weighted_bipred_idc);
- GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
- GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
- GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
-
- GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
- V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
- GET_MTK_VDEC_FLAG(pic_order_present_flag,
- V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
- GET_MTK_VDEC_FLAG(weighted_pred_flag,
- V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
- GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
- V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
- GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
- V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
- GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
- V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
- GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
- V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
- GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
- V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-}
-
-static void
-get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
- const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
-{
- memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
- sizeof(dst_matrix->scaling_list_4x4));
-
- memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
- sizeof(dst_matrix->scaling_list_8x8));
-}
-
-static void
-get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
- const struct v4l2_ctrl_h264_decode_params *src_params,
- const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
- struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
- const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
-
- dst_entry->reference_ts = src_entry->reference_ts;
- dst_entry->frame_num = src_entry->frame_num;
- dst_entry->pic_num = src_entry->pic_num;
- dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
- dst_entry->bottom_field_order_cnt =
- src_entry->bottom_field_order_cnt;
- dst_entry->flags = src_entry->flags;
- }
-
- /*
- * num_slices is a leftover from the old H.264 support and is ignored
- * by the firmware.
- */
- dst_params->num_slices = 0;
- dst_params->nal_ref_idc = src_params->nal_ref_idc;
- dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
- dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
- dst_params->flags = src_params->flags;
-}
-
-static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
- const struct v4l2_h264_dpb_entry *b)
-{
- return a->top_field_order_cnt == b->top_field_order_cnt &&
- a->bottom_field_order_cnt == b->bottom_field_order_cnt;
-}
-
-/*
- * Move DPB entries of dec_param that refer to a frame already existing in dpb
- * into the already existing slot in dpb, and move other entries into new slots.
- *
- * This function is an adaptation of the similarly-named function in
- * hantro_h264.c.
- */
-static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
- struct v4l2_h264_dpb_entry *dpb)
-{
- DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
- DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
- DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
- unsigned int i, j;
-
- /* Disable all entries by default, and mark the ones in use. */
- for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
- set_bit(i, in_use);
- dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
- }
-
- /* Try to match new DPB entries with existing ones by their POCs. */
- for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
- const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-
- if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
- continue;
-
- /*
- * To cut off some comparisons, iterate only on target DPB
- * entries were already used.
- */
- for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
- struct v4l2_h264_dpb_entry *cdpb;
-
- cdpb = &dpb[j];
- if (!dpb_entry_match(cdpb, ndpb))
- continue;
-
- *cdpb = *ndpb;
- set_bit(j, used);
- /* Don't reiterate on this one. */
- clear_bit(j, in_use);
- break;
- }
-
- if (j == ARRAY_SIZE(dec_param->dpb))
- set_bit(i, new);
- }
-
- /* For entries that could not be matched, use remaining free slots. */
- for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
- const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
- struct v4l2_h264_dpb_entry *cdpb;
-
- /*
- * Both arrays are of the same sizes, so there is no way
- * we can end up with no space in target array, unless
- * something is buggy.
- */
- j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
- if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
- return;
-
- cdpb = &dpb[j];
- *cdpb = *ndpb;
- set_bit(j, used);
- }
-}
-
-/*
- * The firmware expects unused reflist entries to have the value 0x20.
- */
-static void fixup_ref_list(u8 *ref_list, size_t num_valid)
-{
- memset(&ref_list[num_valid], 0x20, 32 - num_valid);
-}
-
-static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
-{
- const struct v4l2_ctrl_h264_decode_params *dec_params =
- get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
- const struct v4l2_ctrl_h264_sps *sps =
- get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
- const struct v4l2_ctrl_h264_pps *pps =
- get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
- const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
- get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
- struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
- struct v4l2_h264_reflist_builder reflist_builder;
- u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
- u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
- u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
-
- update_dpb(dec_params, inst->dpb);
-
- get_h264_sps_parameters(&slice_param->sps, sps);
- get_h264_pps_parameters(&slice_param->pps, pps);
- get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
- get_h264_decode_parameters(&slice_param->decode_params, dec_params,
- inst->dpb);
- get_h264_dpb_list(inst, slice_param);
-
- /* Build the reference lists */
- v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
- inst->dpb);
- v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
- v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
- /* Adapt the built lists to the firmware's expectations */
- fixup_ref_list(p0_reflist, reflist_builder.num_valid);
- fixup_ref_list(b0_reflist, reflist_builder.num_valid);
- fixup_ref_list(b1_reflist, reflist_builder.num_valid);
-
- memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
- sizeof(inst->vsi_ctx.h264_slice_params));
-}
-
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
- int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
-
- return HW_MB_STORE_SZ * unit_size;
-}
-
-static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
-{
- int err;
-
- inst->pred_buf.size = BUF_PREDICTION_SZ;
- err = mtk_vcodec_mem_alloc(inst->ctx, &inst->pred_buf);
- if (err) {
- mtk_vcodec_err(inst, "failed to allocate ppl buf");
- return err;
- }
-
- inst->vsi_ctx.pred_buf_dma = inst->pred_buf.dma_addr;
- return 0;
-}
-
-static void free_predication_buf(struct vdec_h264_slice_inst *inst)
-{
- struct mtk_vcodec_mem *mem = &inst->pred_buf;
-
- mtk_vcodec_debug_enter(inst);
-
- inst->vsi_ctx.pred_buf_dma = 0;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-}
-
-static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
- struct vdec_pic_info *pic)
-{
- int i;
- int err;
- struct mtk_vcodec_mem *mem = NULL;
- unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
-
- mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
- for (i = 0; i < H264_MAX_MV_NUM; i++) {
- mem = &inst->mv_buf[i];
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
- mem->size = buf_sz;
- err = mtk_vcodec_mem_alloc(inst->ctx, mem);
- if (err) {
- mtk_vcodec_err(inst, "failed to allocate mv buf");
- return err;
- }
- inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr;
- }
-
- return 0;
-}
-
-static void free_mv_buf(struct vdec_h264_slice_inst *inst)
-{
- int i;
- struct mtk_vcodec_mem *mem;
-
- for (i = 0; i < H264_MAX_MV_NUM; i++) {
- inst->vsi_ctx.mv_buf_dma[i] = 0;
- mem = &inst->mv_buf[i];
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
- }
-}
-
-static void get_pic_info(struct vdec_h264_slice_inst *inst,
- struct vdec_pic_info *pic)
-{
- struct mtk_vcodec_ctx *ctx = inst->ctx;
-
- ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, VCODEC_DEC_ALIGNED_64);
- ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, VCODEC_DEC_ALIGNED_64);
- ctx->picinfo.fb_sz[0] = ctx->picinfo.buf_w * ctx->picinfo.buf_h;
- ctx->picinfo.fb_sz[1] = ctx->picinfo.fb_sz[0] >> 1;
- inst->vsi_ctx.dec.cap_num_planes =
- ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
-
- *pic = ctx->picinfo;
- mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
- ctx->picinfo.pic_w, ctx->picinfo.pic_h,
- ctx->picinfo.buf_w, ctx->picinfo.buf_h);
- mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
- ctx->picinfo.fb_sz[1]);
-
- if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w ||
- ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) {
- inst->vsi_ctx.dec.resolution_changed = true;
- if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w ||
- ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h)
- inst->vsi_ctx.dec.realloc_mv_buf = true;
-
- mtk_v4l2_debug(1, "ResChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
- inst->vsi_ctx.dec.resolution_changed,
- inst->vsi_ctx.dec.realloc_mv_buf,
- ctx->last_decoded_picinfo.pic_w,
- ctx->last_decoded_picinfo.pic_h,
- ctx->picinfo.pic_w, ctx->picinfo.pic_h);
- }
-}
-
-static void get_crop_info(struct vdec_h264_slice_inst *inst, struct v4l2_rect *cr)
-{
- cr->left = inst->vsi_ctx.crop.left;
- cr->top = inst->vsi_ctx.crop.top;
- cr->width = inst->vsi_ctx.crop.width;
- cr->height = inst->vsi_ctx.crop.height;
-
- mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
- cr->left, cr->top, cr->width, cr->height);
-}
-
-static void get_dpb_size(struct vdec_h264_slice_inst *inst, unsigned int *dpb_sz)
-{
- *dpb_sz = inst->vsi_ctx.dec.dpb_sz;
- mtk_vcodec_debug(inst, "sz=%d", *dpb_sz);
-}
-
-static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_h264_slice_inst *inst;
- int err;
-
- inst = kzalloc(sizeof(*inst), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- inst->ctx = ctx;
-
- inst->vpu.id = SCP_IPI_VDEC_H264;
- inst->vpu.ctx = ctx;
-
- err = vpu_dec_init(&inst->vpu);
- if (err) {
- mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
- goto error_free_inst;
- }
-
- memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
- inst->vsi_ctx.dec.resolution_changed = true;
- inst->vsi_ctx.dec.realloc_mv_buf = true;
-
- err = allocate_predication_buf(inst);
- if (err)
- goto error_deinit;
-
- mtk_vcodec_debug(inst, "struct size = %zu,%zu,%zu,%zu\n",
- sizeof(struct mtk_h264_sps_param),
- sizeof(struct mtk_h264_pps_param),
- sizeof(struct mtk_h264_dec_slice_param),
- sizeof(struct mtk_h264_dpb_info));
-
- mtk_vcodec_debug(inst, "H264 Instance >> %p", inst);
-
- ctx->drv_handle = inst;
- return 0;
-
-error_deinit:
- vpu_dec_deinit(&inst->vpu);
-
-error_free_inst:
- kfree(inst);
- return err;
-}
-
-static void vdec_h264_slice_deinit(void *h_vdec)
-{
- struct vdec_h264_slice_inst *inst = h_vdec;
-
- mtk_vcodec_debug_enter(inst);
-
- vpu_dec_deinit(&inst->vpu);
- free_predication_buf(inst);
- free_mv_buf(inst);
-
- kfree(inst);
-}
-
-static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg)
-{
- struct vdec_h264_slice_inst *inst = h_vdec;
- const struct v4l2_ctrl_h264_decode_params *dec_params =
- get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
- struct vdec_vpu_inst *vpu = &inst->vpu;
- u32 data[2];
- u64 y_fb_dma;
- u64 c_fb_dma;
- int err;
-
- /* bs NULL means flush decoder */
- if (!bs)
- return vpu_dec_reset(vpu);
-
- y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
- c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
-
- mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
- ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
-
- inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
- inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
- inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
- inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
-
- get_vdec_decode_parameters(inst);
- data[0] = bs->size;
- /*
- * Reconstruct the first byte of the NAL unit, as the firmware requests
- * that information to be passed even though it is present in the stream
- * itself...
- */
- data[1] = (dec_params->nal_ref_idc << 5) |
- ((dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC)
- ? 0x5 : 0x1);
-
- *res_chg = inst->vsi_ctx.dec.resolution_changed;
- if (*res_chg) {
- mtk_vcodec_debug(inst, "- resolution changed -");
- if (inst->vsi_ctx.dec.realloc_mv_buf) {
- err = alloc_mv_buf(inst, &inst->ctx->picinfo);
- inst->vsi_ctx.dec.realloc_mv_buf = false;
- if (err)
- goto err_free_fb_out;
- }
- *res_chg = false;
- }
-
- memcpy(inst->vpu.vsi, &inst->vsi_ctx, sizeof(inst->vsi_ctx));
- err = vpu_dec_start(vpu, data, 2);
- if (err)
- goto err_free_fb_out;
-
- /* wait decoder done interrupt */
- err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
- MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0);
- if (err)
- goto err_free_fb_out;
- vpu_dec_end(vpu);
-
- memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
- mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
- return 0;
-
-err_free_fb_out:
- mtk_vcodec_err(inst, "\n - NALU[%d] err=%d -\n", inst->num_nalu, err);
- return err;
-}
-
-static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
-{
- struct vdec_h264_slice_inst *inst = h_vdec;
-
- switch (type) {
- case GET_PARAM_PIC_INFO:
- get_pic_info(inst, out);
- break;
-
- case GET_PARAM_DPB_SIZE:
- get_dpb_size(inst, out);
- break;
-
- case GET_PARAM_CROP_INFO:
- get_crop_info(inst, out);
- break;
-
- default:
- mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-const struct vdec_common_if vdec_h264_slice_if = {
- .init = vdec_h264_slice_init,
- .decode = vdec_h264_slice_decode,
- .get_param = vdec_h264_slice_get_param,
- .deinit = vdec_h264_slice_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
deleted file mode 100644
index 88c046731754..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ /dev/null
@@ -1,616 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Jungchang Tsao <jungchang.tsao@mediatek.com>
- * PC Chen <pc.chen@mediatek.com>
- */
-
-#include <linux/slab.h>
-#include "../vdec_drv_if.h"
-#include "../mtk_vcodec_util.h"
-#include "../mtk_vcodec_dec.h"
-#include "../mtk_vcodec_intr.h"
-#include "../vdec_vpu_if.h"
-#include "../vdec_drv_base.h"
-
-/* Decoding picture buffer size (3 reference frames plus current frame) */
-#define VP8_DPB_SIZE 4
-
-/* HW working buffer size (bytes) */
-#define VP8_WORKING_BUF_SZ (45 * 4096)
-
-/* HW control register address */
-#define VP8_SEGID_DRAM_ADDR 0x3c
-#define VP8_HW_VLD_ADDR 0x93C
-#define VP8_HW_VLD_VALUE 0x940
-#define VP8_BSASET 0x100
-#define VP8_BSDSET 0x104
-#define VP8_RW_CKEN_SET 0x0
-#define VP8_RW_DCM_CON 0x18
-#define VP8_WO_VLD_SRST 0x108
-#define VP8_RW_MISC_SYS_SEL 0x84
-#define VP8_RW_MISC_SPEC_CON 0xC8
-#define VP8_WO_VLD_SRST 0x108
-#define VP8_RW_VP8_CTRL 0xA4
-#define VP8_RW_MISC_DCM_CON 0xEC
-#define VP8_RW_MISC_SRST 0xF4
-#define VP8_RW_MISC_FUNC_CON 0xCC
-
-#define VP8_MAX_FRM_BUF_NUM 5
-#define VP8_MAX_FRM_BUF_NODE_NUM (VP8_MAX_FRM_BUF_NUM * 2)
-
-/* required buffer size (bytes) to store decode information */
-#define VP8_HW_SEGMENT_DATA_SZ 272
-#define VP8_HW_SEGMENT_UINT 4
-
-#define VP8_DEC_TABLE_PROC_LOOP 96
-#define VP8_DEC_TABLE_UNIT 3
-#define VP8_DEC_TABLE_SZ 300
-#define VP8_DEC_TABLE_OFFSET 2
-#define VP8_DEC_TABLE_RW_UNIT 4
-
-/**
- * struct vdec_vp8_dec_info - decode misc information
- * @working_buf_dma : working buffer dma address
- * @prev_y_dma : previous decoded frame buffer Y plane address
- * @cur_y_fb_dma : current plane Y frame buffer dma address
- * @cur_c_fb_dma : current plane C frame buffer dma address
- * @bs_dma : bitstream dma address
- * @bs_sz : bitstream size
- * @resolution_changed: resolution change flag 1 - changed, 0 - not change
- * @show_frame : display this frame or not
- * @wait_key_frame : wait key frame coming
- */
-struct vdec_vp8_dec_info {
- uint64_t working_buf_dma;
- uint64_t prev_y_dma;
- uint64_t cur_y_fb_dma;
- uint64_t cur_c_fb_dma;
- uint64_t bs_dma;
- uint32_t bs_sz;
- uint32_t resolution_changed;
- uint32_t show_frame;
- uint32_t wait_key_frame;
-};
-
-/**
- * struct vdec_vp8_vsi - VPU shared information
- * @dec : decoding information
- * @pic : picture information
- * @dec_table : decoder coefficient table
- * @segment_buf : segmentation buffer
- * @load_data : flag to indicate reload decode data
- */
-struct vdec_vp8_vsi {
- struct vdec_vp8_dec_info dec;
- struct vdec_pic_info pic;
- uint32_t dec_table[VP8_DEC_TABLE_SZ];
- uint32_t segment_buf[VP8_HW_SEGMENT_DATA_SZ][VP8_HW_SEGMENT_UINT];
- uint32_t load_data;
-};
-
-/**
- * struct vdec_vp8_hw_reg_base - HW register base
- * @sys : base address for sys
- * @misc : base address for misc
- * @ld : base address for ld
- * @top : base address for top
- * @cm : base address for cm
- * @hwd : base address for hwd
- * @hwb : base address for hwb
- */
-struct vdec_vp8_hw_reg_base {
- void __iomem *sys;
- void __iomem *misc;
- void __iomem *ld;
- void __iomem *top;
- void __iomem *cm;
- void __iomem *hwd;
- void __iomem *hwb;
-};
-
-/**
- * struct vdec_vp8_vpu_inst - VPU instance for VP8 decode
- * @wq_hd : Wait queue to wait VPU message ack
- * @signaled : 1 - Host has received ack message from VPU, 0 - not receive
- * @failure : VPU execution result status 0 - success, others - fail
- * @inst_addr : VPU decoder instance address
- */
-struct vdec_vp8_vpu_inst {
- wait_queue_head_t wq_hd;
- int signaled;
- int failure;
- uint32_t inst_addr;
-};
-
-/* frame buffer (fb) list
- * [available_fb_node_list] - decode fb are initialized to 0 and populated in
- * [fb_use_list] - fb is set after decode and is moved to this list
- * [fb_free_list] - fb is not needed for reference will be moved from
- * [fb_use_list] to [fb_free_list] and
- * once user remove fb from [fb_free_list],
- * it is circulated back to [available_fb_node_list]
- * [fb_disp_list] - fb is set after decode and is moved to this list
- * once user remove fb from [fb_disp_list] it is
- * circulated back to [available_fb_node_list]
- */
-
-/**
- * struct vdec_vp8_inst - VP8 decoder instance
- * @cur_fb : current frame buffer
- * @dec_fb : decode frame buffer node
- * @available_fb_node_list : list to store available frame buffer node
- * @fb_use_list : list to store frame buffer in use
- * @fb_free_list : list to store free frame buffer
- * @fb_disp_list : list to store display ready frame buffer
- * @working_buf : HW decoder working buffer
- * @reg_base : HW register base address
- * @frm_cnt : decode frame count
- * @ctx : V4L2 context
- * @vpu : VPU instance for decoder
- * @vsi : VPU share information
- */
-struct vdec_vp8_inst {
- struct vdec_fb *cur_fb;
- struct vdec_fb_node dec_fb[VP8_MAX_FRM_BUF_NODE_NUM];
- struct list_head available_fb_node_list;
- struct list_head fb_use_list;
- struct list_head fb_free_list;
- struct list_head fb_disp_list;
- struct mtk_vcodec_mem working_buf;
- struct vdec_vp8_hw_reg_base reg_base;
- unsigned int frm_cnt;
- struct mtk_vcodec_ctx *ctx;
- struct vdec_vpu_inst vpu;
- struct vdec_vp8_vsi *vsi;
-};
-
-static void get_hw_reg_base(struct vdec_vp8_inst *inst)
-{
- inst->reg_base.top = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_TOP);
- inst->reg_base.cm = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_CM);
- inst->reg_base.hwd = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWD);
- inst->reg_base.sys = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_SYS);
- inst->reg_base.misc = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_MISC);
- inst->reg_base.ld = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_LD);
- inst->reg_base.hwb = mtk_vcodec_get_reg_addr(inst->ctx, VDEC_HWB);
-}
-
-static void write_hw_segmentation_data(struct vdec_vp8_inst *inst)
-{
- int i, j;
- u32 seg_id_addr;
- u32 val;
- void __iomem *cm = inst->reg_base.cm;
- struct vdec_vp8_vsi *vsi = inst->vsi;
-
- seg_id_addr = readl(inst->reg_base.top + VP8_SEGID_DRAM_ADDR) >> 4;
-
- for (i = 0; i < ARRAY_SIZE(vsi->segment_buf); i++) {
- for (j = ARRAY_SIZE(vsi->segment_buf[i]) - 1; j >= 0; j--) {
- val = (1 << 16) + ((seg_id_addr + i) << 2) + j;
- writel(val, cm + VP8_HW_VLD_ADDR);
-
- val = vsi->segment_buf[i][j];
- writel(val, cm + VP8_HW_VLD_VALUE);
- }
- }
-}
-
-static void read_hw_segmentation_data(struct vdec_vp8_inst *inst)
-{
- int i, j;
- u32 seg_id_addr;
- u32 val;
- void __iomem *cm = inst->reg_base.cm;
- struct vdec_vp8_vsi *vsi = inst->vsi;
-
- seg_id_addr = readl(inst->reg_base.top + VP8_SEGID_DRAM_ADDR) >> 4;
-
- for (i = 0; i < ARRAY_SIZE(vsi->segment_buf); i++) {
- for (j = ARRAY_SIZE(vsi->segment_buf[i]) - 1; j >= 0; j--) {
- val = ((seg_id_addr + i) << 2) + j;
- writel(val, cm + VP8_HW_VLD_ADDR);
-
- val = readl(cm + VP8_HW_VLD_VALUE);
- vsi->segment_buf[i][j] = val;
- }
- }
-}
-
-/* reset HW and enable HW read/write data function */
-static void enable_hw_rw_function(struct vdec_vp8_inst *inst)
-{
- u32 val = 0;
- void __iomem *sys = inst->reg_base.sys;
- void __iomem *misc = inst->reg_base.misc;
- void __iomem *ld = inst->reg_base.ld;
- void __iomem *hwb = inst->reg_base.hwb;
- void __iomem *hwd = inst->reg_base.hwd;
-
- writel(0x1, sys + VP8_RW_CKEN_SET);
- writel(0x101, ld + VP8_WO_VLD_SRST);
- writel(0x101, hwb + VP8_WO_VLD_SRST);
-
- writel(1, sys);
- val = readl(misc + VP8_RW_MISC_SRST);
- writel((val & 0xFFFFFFFE), misc + VP8_RW_MISC_SRST);
-
- writel(0x1, misc + VP8_RW_MISC_SYS_SEL);
- writel(0x17F, misc + VP8_RW_MISC_SPEC_CON);
- writel(0x71201100, misc + VP8_RW_MISC_FUNC_CON);
- writel(0x0, ld + VP8_WO_VLD_SRST);
- writel(0x0, hwb + VP8_WO_VLD_SRST);
- writel(0x1, sys + VP8_RW_DCM_CON);
- writel(0x1, misc + VP8_RW_MISC_DCM_CON);
- writel(0x1, hwd + VP8_RW_VP8_CTRL);
-}
-
-static void store_dec_table(struct vdec_vp8_inst *inst)
-{
- int i, j;
- u32 addr = 0, val = 0;
- void __iomem *hwd = inst->reg_base.hwd;
- u32 *p = &inst->vsi->dec_table[VP8_DEC_TABLE_OFFSET];
-
- for (i = 0; i < VP8_DEC_TABLE_PROC_LOOP; i++) {
- writel(addr, hwd + VP8_BSASET);
- for (j = 0; j < VP8_DEC_TABLE_UNIT ; j++) {
- val = *p++;
- writel(val, hwd + VP8_BSDSET);
- }
- addr += VP8_DEC_TABLE_RW_UNIT;
- }
-}
-
-static void load_dec_table(struct vdec_vp8_inst *inst)
-{
- int i;
- u32 addr = 0;
- u32 *p = &inst->vsi->dec_table[VP8_DEC_TABLE_OFFSET];
- void __iomem *hwd = inst->reg_base.hwd;
-
- for (i = 0; i < VP8_DEC_TABLE_PROC_LOOP; i++) {
- writel(addr, hwd + VP8_BSASET);
- /* read total 11 bytes */
- *p++ = readl(hwd + VP8_BSDSET);
- *p++ = readl(hwd + VP8_BSDSET);
- *p++ = readl(hwd + VP8_BSDSET) & 0xFFFFFF;
- addr += VP8_DEC_TABLE_RW_UNIT;
- }
-}
-
-static void get_pic_info(struct vdec_vp8_inst *inst, struct vdec_pic_info *pic)
-{
- *pic = inst->vsi->pic;
-
- mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
- pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
- mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
- pic->fb_sz[0], pic->fb_sz[1]);
-}
-
-static void vp8_dec_finish(struct vdec_vp8_inst *inst)
-{
- struct vdec_fb_node *node;
- uint64_t prev_y_dma = inst->vsi->dec.prev_y_dma;
-
- mtk_vcodec_debug(inst, "prev fb base dma=%llx", prev_y_dma);
-
- /* put last decode ok frame to fb_free_list */
- if (prev_y_dma != 0) {
- list_for_each_entry(node, &inst->fb_use_list, list) {
- struct vdec_fb *fb = (struct vdec_fb *)node->fb;
-
- if (prev_y_dma == (uint64_t)fb->base_y.dma_addr) {
- list_move_tail(&node->list,
- &inst->fb_free_list);
- break;
- }
- }
- }
-
- /* available_fb_node_list -> fb_use_list */
- node = list_first_entry(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
- node->fb = inst->cur_fb;
- list_move_tail(&node->list, &inst->fb_use_list);
-
- /* available_fb_node_list -> fb_disp_list */
- if (inst->vsi->dec.show_frame) {
- node = list_first_entry(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
- node->fb = inst->cur_fb;
- list_move_tail(&node->list, &inst->fb_disp_list);
- }
-}
-
-static void move_fb_list_use_to_free(struct vdec_vp8_inst *inst)
-{
- struct vdec_fb_node *node, *tmp;
-
- list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list)
- list_move_tail(&node->list, &inst->fb_free_list);
-}
-
-static void init_list(struct vdec_vp8_inst *inst)
-{
- int i;
-
- INIT_LIST_HEAD(&inst->available_fb_node_list);
- INIT_LIST_HEAD(&inst->fb_use_list);
- INIT_LIST_HEAD(&inst->fb_free_list);
- INIT_LIST_HEAD(&inst->fb_disp_list);
-
- for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) {
- INIT_LIST_HEAD(&inst->dec_fb[i].list);
- inst->dec_fb[i].fb = NULL;
- list_add_tail(&inst->dec_fb[i].list,
- &inst->available_fb_node_list);
- }
-}
-
-static void add_fb_to_free_list(struct vdec_vp8_inst *inst, void *fb)
-{
- struct vdec_fb_node *node;
-
- if (fb) {
- node = list_first_entry(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
- node->fb = fb;
- list_move_tail(&node->list, &inst->fb_free_list);
- }
-}
-
-static int alloc_working_buf(struct vdec_vp8_inst *inst)
-{
- int err;
- struct mtk_vcodec_mem *mem = &inst->working_buf;
-
- mem->size = VP8_WORKING_BUF_SZ;
- err = mtk_vcodec_mem_alloc(inst->ctx, mem);
- if (err) {
- mtk_vcodec_err(inst, "Cannot allocate working buffer");
- return err;
- }
-
- inst->vsi->dec.working_buf_dma = (uint64_t)mem->dma_addr;
- return 0;
-}
-
-static void free_working_buf(struct vdec_vp8_inst *inst)
-{
- struct mtk_vcodec_mem *mem = &inst->working_buf;
-
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-
- inst->vsi->dec.working_buf_dma = 0;
-}
-
-static int vdec_vp8_init(struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_vp8_inst *inst;
- int err;
-
- inst = kzalloc(sizeof(*inst), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- inst->ctx = ctx;
-
- inst->vpu.id = IPI_VDEC_VP8;
- inst->vpu.ctx = ctx;
-
- err = vpu_dec_init(&inst->vpu);
- if (err) {
- mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
- goto error_free_inst;
- }
-
- inst->vsi = (struct vdec_vp8_vsi *)inst->vpu.vsi;
- init_list(inst);
- err = alloc_working_buf(inst);
- if (err)
- goto error_deinit;
-
- get_hw_reg_base(inst);
- mtk_vcodec_debug(inst, "VP8 Instance >> %p", inst);
-
- ctx->drv_handle = inst;
- return 0;
-
-error_deinit:
- vpu_dec_deinit(&inst->vpu);
-error_free_inst:
- kfree(inst);
- return err;
-}
-
-static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg)
-{
- struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec;
- struct vdec_vp8_dec_info *dec = &inst->vsi->dec;
- struct vdec_vpu_inst *vpu = &inst->vpu;
- unsigned char *bs_va;
- unsigned int data;
- int err = 0;
- uint64_t y_fb_dma;
- uint64_t c_fb_dma;
-
- /* bs NULL means flush decoder */
- if (bs == NULL) {
- move_fb_list_use_to_free(inst);
- return vpu_dec_reset(vpu);
- }
-
- y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
- c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
-
- mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx fb=%p",
- inst->frm_cnt, y_fb_dma, c_fb_dma, fb);
-
- inst->cur_fb = fb;
- dec->bs_dma = (unsigned long)bs->dma_addr;
- dec->bs_sz = bs->size;
- dec->cur_y_fb_dma = y_fb_dma;
- dec->cur_c_fb_dma = c_fb_dma;
-
- mtk_vcodec_debug(inst, "\n + FRAME[%d] +\n", inst->frm_cnt);
-
- write_hw_segmentation_data(inst);
- enable_hw_rw_function(inst);
- store_dec_table(inst);
-
- bs_va = (unsigned char *)bs->va;
-
- /* retrieve width/hight and scale info from header */
- data = (*(bs_va + 9) << 24) | (*(bs_va + 8) << 16) |
- (*(bs_va + 7) << 8) | *(bs_va + 6);
- err = vpu_dec_start(vpu, &data, 1);
- if (err) {
- add_fb_to_free_list(inst, fb);
- if (dec->wait_key_frame) {
- mtk_vcodec_debug(inst, "wait key frame !");
- return 0;
- }
-
- goto error;
- }
-
- if (dec->resolution_changed) {
- mtk_vcodec_debug(inst, "- resolution_changed -");
- *res_chg = true;
- add_fb_to_free_list(inst, fb);
- return 0;
- }
-
- /* wait decoder done interrupt */
- mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0);
-
- if (inst->vsi->load_data)
- load_dec_table(inst);
-
- vp8_dec_finish(inst);
- read_hw_segmentation_data(inst);
-
- err = vpu_dec_end(vpu);
- if (err)
- goto error;
-
- mtk_vcodec_debug(inst, "\n - FRAME[%d] - show=%d\n", inst->frm_cnt,
- dec->show_frame);
- inst->frm_cnt++;
- *res_chg = false;
- return 0;
-
-error:
- mtk_vcodec_err(inst, "\n - FRAME[%d] - err=%d\n", inst->frm_cnt, err);
- return err;
-}
-
-static void get_disp_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb)
-{
- struct vdec_fb_node *node;
- struct vdec_fb *fb;
-
- node = list_first_entry_or_null(&inst->fb_disp_list,
- struct vdec_fb_node, list);
- if (node) {
- list_move_tail(&node->list, &inst->available_fb_node_list);
- fb = (struct vdec_fb *)node->fb;
- fb->status |= FB_ST_DISPLAY;
- mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d",
- node->fb, fb->status);
- } else {
- fb = NULL;
- mtk_vcodec_debug(inst, "[FB] there is no disp fb");
- }
-
- *out_fb = fb;
-}
-
-static void get_free_fb(struct vdec_vp8_inst *inst, struct vdec_fb **out_fb)
-{
- struct vdec_fb_node *node;
- struct vdec_fb *fb;
-
- node = list_first_entry_or_null(&inst->fb_free_list,
- struct vdec_fb_node, list);
- if (node) {
- list_move_tail(&node->list, &inst->available_fb_node_list);
- fb = (struct vdec_fb *)node->fb;
- fb->status |= FB_ST_FREE;
- mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d",
- node->fb, fb->status);
- } else {
- fb = NULL;
- mtk_vcodec_debug(inst, "[FB] there is no free fb");
- }
-
- *out_fb = fb;
-}
-
-static void get_crop_info(struct vdec_vp8_inst *inst, struct v4l2_rect *cr)
-{
- cr->left = 0;
- cr->top = 0;
- cr->width = inst->vsi->pic.pic_w;
- cr->height = inst->vsi->pic.pic_h;
- mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d",
- cr->left, cr->top, cr->width, cr->height);
-}
-
-static int vdec_vp8_get_param(void *h_vdec, enum vdec_get_param_type type,
- void *out)
-{
- struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec;
-
- switch (type) {
- case GET_PARAM_DISP_FRAME_BUFFER:
- get_disp_fb(inst, out);
- break;
-
- case GET_PARAM_FREE_FRAME_BUFFER:
- get_free_fb(inst, out);
- break;
-
- case GET_PARAM_PIC_INFO:
- get_pic_info(inst, out);
- break;
-
- case GET_PARAM_CROP_INFO:
- get_crop_info(inst, out);
- break;
-
- case GET_PARAM_DPB_SIZE:
- *((unsigned int *)out) = VP8_DPB_SIZE;
- break;
-
- default:
- mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void vdec_vp8_deinit(void *h_vdec)
-{
- struct vdec_vp8_inst *inst = (struct vdec_vp8_inst *)h_vdec;
-
- mtk_vcodec_debug_enter(inst);
-
- vpu_dec_deinit(&inst->vpu);
- free_working_buf(inst);
- kfree(inst);
-}
-
-const struct vdec_common_if vdec_vp8_if = {
- .init = vdec_vp8_init,
- .decode = vdec_vp8_decode,
- .get_param = vdec_vp8_get_param,
- .deinit = vdec_vp8_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
deleted file mode 100644
index 70b8383f7c8e..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ /dev/null
@@ -1,1028 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
- * Kai-Sean Yang <kai-sean.yang@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/delay.h>
-#include <linux/time.h>
-
-#include "../mtk_vcodec_intr.h"
-#include "../vdec_drv_base.h"
-#include "../vdec_vpu_if.h"
-
-#define VP9_SUPER_FRAME_BS_SZ 64
-#define MAX_VP9_DPB_SIZE 9
-
-#define REFS_PER_FRAME 3
-#define MAX_NUM_REF_FRAMES 8
-#define VP9_MAX_FRM_BUF_NUM 9
-#define VP9_MAX_FRM_BUF_NODE_NUM (VP9_MAX_FRM_BUF_NUM * 2)
-#define VP9_SEG_ID_SZ 0x12000
-
-/**
- * struct vp9_dram_buf - contains buffer info for vpu
- * @va : cpu address
- * @pa : iova address
- * @sz : buffer size
- * @padding : for 64 bytes alignment
- */
-struct vp9_dram_buf {
- unsigned long va;
- unsigned long pa;
- unsigned int sz;
- unsigned int padding;
-};
-
-/**
- * struct vp9_fb_info - contains frame buffer info
- * @fb : frmae buffer
- * @reserved : reserved field used by vpu
- */
-struct vp9_fb_info {
- struct vdec_fb *fb;
- unsigned int reserved[32];
-};
-
-/**
- * struct vp9_ref_cnt_buf - contains reference buffer information
- * @buf : referenced frame buffer
- * @ref_cnt : referenced frame buffer's reference count.
- * When reference count=0, remove it from reference list
- */
-struct vp9_ref_cnt_buf {
- struct vp9_fb_info buf;
- unsigned int ref_cnt;
-};
-
-/**
- * struct vp9_ref_buf - contains current frame's reference buffer information
- * @buf : reference buffer
- * @idx : reference buffer index to frm_bufs
- * @reserved : reserved field used by vpu
- */
-struct vp9_ref_buf {
- struct vp9_fb_info *buf;
- unsigned int idx;
- unsigned int reserved[6];
-};
-
-/**
- * struct vp9_sf_ref_fb - contains frame buffer info
- * @fb : super frame reference frame buffer
- * @used : this reference frame info entry is used
- * @padding : for 64 bytes size align
- */
-struct vp9_sf_ref_fb {
- struct vdec_fb fb;
- int used;
- int padding;
-};
-
-/*
- * struct vdec_vp9_vsi - shared buffer between host and VPU firmware
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @sf_bs_buf : super frame backup buffer (AP-W, VPU-R)
- * @sf_ref_fb : record supoer frame reference buffer information
- * (AP-R/W, VPU-R/W)
- * @sf_next_ref_fb_idx : next available super frame (AP-W, VPU-R)
- * @sf_frm_cnt : super frame count, filled by vpu (AP-R, VPU-W)
- * @sf_frm_offset : super frame offset, filled by vpu (AP-R, VPU-W)
- * @sf_frm_sz : super frame size, filled by vpu (AP-R, VPU-W)
- * @sf_frm_idx : current super frame (AP-R, VPU-W)
- * @sf_init : inform super frame info already parsed by vpu (AP-R, VPU-W)
- * @fb : capture buffer (AP-W, VPU-R)
- * @bs : bs buffer (AP-W, VPU-R)
- * @cur_fb : current show capture buffer (AP-R/W, VPU-R/W)
- * @pic_w : picture width (AP-R, VPU-W)
- * @pic_h : picture height (AP-R, VPU-W)
- * @buf_w : codec width (AP-R, VPU-W)
- * @buf_h : coded height (AP-R, VPU-W)
- * @buf_sz_y_bs : ufo compressed y plane size (AP-R, VPU-W)
- * @buf_sz_c_bs : ufo compressed cbcr plane size (AP-R, VPU-W)
- * @buf_len_sz_y : size used to store y plane ufo info (AP-R, VPU-W)
- * @buf_len_sz_c : size used to store cbcr plane ufo info (AP-R, VPU-W)
-
- * @profile : profile sparsed from vpu (AP-R, VPU-W)
- * @show_frame : [BIT(0)] display this frame or not (AP-R, VPU-W)
- * [BIT(1)] reset segment data or not (AP-R, VPU-W)
- * [BIT(2)] trig decoder hardware or not (AP-R, VPU-W)
- * [BIT(3)] ask VPU to set bits(0~4) accordingly (AP-W, VPU-R)
- * [BIT(4)] do not reset segment data before every frame (AP-R, VPU-W)
- * @show_existing_frame : inform this frame is show existing frame
- * (AP-R, VPU-W)
- * @frm_to_show_idx : index to show frame (AP-R, VPU-W)
-
- * @refresh_frm_flags : indicate when frame need to refine reference count
- * (AP-R, VPU-W)
- * @resolution_changed : resolution change in this frame (AP-R, VPU-W)
-
- * @frm_bufs : maintain reference buffer info (AP-R/W, VPU-R/W)
- * @ref_frm_map : maintain reference buffer map info (AP-R/W, VPU-R/W)
- * @new_fb_idx : index to frm_bufs array (AP-R, VPU-W)
- * @frm_num : decoded frame number, include sub-frame count (AP-R, VPU-W)
- * @mv_buf : motion vector working buffer (AP-W, VPU-R)
- * @frm_refs : maintain three reference buffer info (AP-R/W, VPU-R/W)
- * @seg_id_buf : segmentation map working buffer (AP-W, VPU-R)
- */
-struct vdec_vp9_vsi {
- unsigned char sf_bs_buf[VP9_SUPER_FRAME_BS_SZ];
- struct vp9_sf_ref_fb sf_ref_fb[VP9_MAX_FRM_BUF_NUM-1];
- int sf_next_ref_fb_idx;
- unsigned int sf_frm_cnt;
- unsigned int sf_frm_offset[VP9_MAX_FRM_BUF_NUM-1];
- unsigned int sf_frm_sz[VP9_MAX_FRM_BUF_NUM-1];
- unsigned int sf_frm_idx;
- unsigned int sf_init;
- struct vdec_fb fb;
- struct mtk_vcodec_mem bs;
- struct vdec_fb cur_fb;
- unsigned int pic_w;
- unsigned int pic_h;
- unsigned int buf_w;
- unsigned int buf_h;
- unsigned int buf_sz_y_bs;
- unsigned int buf_sz_c_bs;
- unsigned int buf_len_sz_y;
- unsigned int buf_len_sz_c;
- unsigned int profile;
- unsigned int show_frame;
- unsigned int show_existing_frame;
- unsigned int frm_to_show_idx;
- unsigned int refresh_frm_flags;
- unsigned int resolution_changed;
-
- struct vp9_ref_cnt_buf frm_bufs[VP9_MAX_FRM_BUF_NUM];
- int ref_frm_map[MAX_NUM_REF_FRAMES];
- unsigned int new_fb_idx;
- unsigned int frm_num;
- struct vp9_dram_buf mv_buf;
-
- struct vp9_ref_buf frm_refs[REFS_PER_FRAME];
- struct vp9_dram_buf seg_id_buf;
-
-};
-
-/*
- * struct vdec_vp9_inst - vp9 decode instance
- * @mv_buf : working buffer for mv
- * @seg_id_buf : working buffer for segmentation map
- * @dec_fb : vdec_fb node to link fb to different fb_xxx_list
- * @available_fb_node_list : current available vdec_fb node
- * @fb_use_list : current used or referenced vdec_fb
- * @fb_free_list : current available to free vdec_fb
- * @fb_disp_list : current available to display vdec_fb
- * @cur_fb : current frame buffer
- * @ctx : current decode context
- * @vpu : vpu instance information
- * @vsi : shared buffer between host and VPU firmware
- * @total_frm_cnt : total frame count, it do not include sub-frames in super
- * frame
- * @mem : instance memory information
- */
-struct vdec_vp9_inst {
- struct mtk_vcodec_mem mv_buf;
- struct mtk_vcodec_mem seg_id_buf;
-
- struct vdec_fb_node dec_fb[VP9_MAX_FRM_BUF_NODE_NUM];
- struct list_head available_fb_node_list;
- struct list_head fb_use_list;
- struct list_head fb_free_list;
- struct list_head fb_disp_list;
- struct vdec_fb *cur_fb;
- struct mtk_vcodec_ctx *ctx;
- struct vdec_vpu_inst vpu;
- struct vdec_vp9_vsi *vsi;
- unsigned int total_frm_cnt;
- struct mtk_vcodec_mem mem;
-};
-
-static bool vp9_is_sf_ref_fb(struct vdec_vp9_inst *inst, struct vdec_fb *fb)
-{
- int i;
- struct vdec_vp9_vsi *vsi = inst->vsi;
-
- for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
- if (fb == &vsi->sf_ref_fb[i].fb)
- return true;
- }
- return false;
-}
-
-static struct vdec_fb *vp9_rm_from_fb_use_list(struct vdec_vp9_inst
- *inst, void *addr)
-{
- struct vdec_fb *fb = NULL;
- struct vdec_fb_node *node;
-
- list_for_each_entry(node, &inst->fb_use_list, list) {
- fb = (struct vdec_fb *)node->fb;
- if (fb->base_y.va == addr) {
- list_move_tail(&node->list,
- &inst->available_fb_node_list);
- break;
- }
- }
- return fb;
-}
-
-static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst,
- struct vdec_fb *fb)
-{
- struct vdec_fb_node *node;
-
- if (fb) {
- node = list_first_entry_or_null(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
-
- if (node) {
- node->fb = fb;
- list_move_tail(&node->list, &inst->fb_free_list);
- }
- } else {
- mtk_vcodec_debug(inst, "No free fb node");
- }
-}
-
-static void vp9_free_sf_ref_fb(struct vdec_fb *fb)
-{
- struct vp9_sf_ref_fb *sf_ref_fb =
- container_of(fb, struct vp9_sf_ref_fb, fb);
-
- sf_ref_fb->used = 0;
-}
-
-static void vp9_ref_cnt_fb(struct vdec_vp9_inst *inst, int *idx,
- int new_idx)
-{
- struct vdec_vp9_vsi *vsi = inst->vsi;
- int ref_idx = *idx;
-
- if (ref_idx >= 0 && vsi->frm_bufs[ref_idx].ref_cnt > 0) {
- vsi->frm_bufs[ref_idx].ref_cnt--;
-
- if (vsi->frm_bufs[ref_idx].ref_cnt == 0) {
- if (!vp9_is_sf_ref_fb(inst,
- vsi->frm_bufs[ref_idx].buf.fb)) {
- struct vdec_fb *fb;
-
- fb = vp9_rm_from_fb_use_list(inst,
- vsi->frm_bufs[ref_idx].buf.fb->base_y.va);
- vp9_add_to_fb_free_list(inst, fb);
- } else
- vp9_free_sf_ref_fb(
- vsi->frm_bufs[ref_idx].buf.fb);
- }
- }
-
- *idx = new_idx;
- vsi->frm_bufs[new_idx].ref_cnt++;
-}
-
-static void vp9_free_all_sf_ref_fb(struct vdec_vp9_inst *inst)
-{
- int i;
- struct vdec_vp9_vsi *vsi = inst->vsi;
-
- for (i = 0; i < ARRAY_SIZE(vsi->sf_ref_fb); i++) {
- if (vsi->sf_ref_fb[i].fb.base_y.va) {
- mtk_vcodec_mem_free(inst->ctx,
- &vsi->sf_ref_fb[i].fb.base_y);
- mtk_vcodec_mem_free(inst->ctx,
- &vsi->sf_ref_fb[i].fb.base_c);
- vsi->sf_ref_fb[i].used = 0;
- }
- }
-}
-
-/* For each sub-frame except the last one, the driver will dynamically
- * allocate reference buffer by calling vp9_get_sf_ref_fb()
- * The last sub-frame will use the original fb provided by the
- * vp9_dec_decode() interface
- */
-static int vp9_get_sf_ref_fb(struct vdec_vp9_inst *inst)
-{
- int idx;
- struct mtk_vcodec_mem *mem_basy_y;
- struct mtk_vcodec_mem *mem_basy_c;
- struct vdec_vp9_vsi *vsi = inst->vsi;
-
- for (idx = 0;
- idx < ARRAY_SIZE(vsi->sf_ref_fb);
- idx++) {
- if (vsi->sf_ref_fb[idx].fb.base_y.va &&
- vsi->sf_ref_fb[idx].used == 0) {
- return idx;
- }
- }
-
- for (idx = 0;
- idx < ARRAY_SIZE(vsi->sf_ref_fb);
- idx++) {
- if (vsi->sf_ref_fb[idx].fb.base_y.va == NULL)
- break;
- }
-
- if (idx == ARRAY_SIZE(vsi->sf_ref_fb)) {
- mtk_vcodec_err(inst, "List Full");
- return -1;
- }
-
- mem_basy_y = &vsi->sf_ref_fb[idx].fb.base_y;
- mem_basy_y->size = vsi->buf_sz_y_bs +
- vsi->buf_len_sz_y;
-
- if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_y)) {
- mtk_vcodec_err(inst, "Cannot allocate sf_ref_buf y_buf");
- return -1;
- }
-
- mem_basy_c = &vsi->sf_ref_fb[idx].fb.base_c;
- mem_basy_c->size = vsi->buf_sz_c_bs +
- vsi->buf_len_sz_c;
-
- if (mtk_vcodec_mem_alloc(inst->ctx, mem_basy_c)) {
- mtk_vcodec_err(inst, "Cannot allocate sf_ref_fb c_buf");
- return -1;
- }
- vsi->sf_ref_fb[idx].used = 0;
-
- return idx;
-}
-
-static bool vp9_alloc_work_buf(struct vdec_vp9_inst *inst)
-{
- struct vdec_vp9_vsi *vsi = inst->vsi;
- int result;
- struct mtk_vcodec_mem *mem;
-
- unsigned int max_pic_w;
- unsigned int max_pic_h;
-
-
- if (!(inst->ctx->dev->dec_capability &
- VCODEC_CAPABILITY_4K_DISABLED)) {
- max_pic_w = VCODEC_DEC_4K_CODED_WIDTH;
- max_pic_h = VCODEC_DEC_4K_CODED_HEIGHT;
- } else {
- max_pic_w = MTK_VDEC_MAX_W;
- max_pic_h = MTK_VDEC_MAX_H;
- }
-
- if ((vsi->pic_w > max_pic_w) ||
- (vsi->pic_h > max_pic_h)) {
- mtk_vcodec_err(inst, "Invalid w/h %d/%d",
- vsi->pic_w, vsi->pic_h);
- return false;
- }
-
- mtk_vcodec_debug(inst, "BUF CHG(%d): w/h/sb_w/sb_h=%d/%d/%d/%d",
- vsi->resolution_changed,
- vsi->pic_w,
- vsi->pic_h,
- vsi->buf_w,
- vsi->buf_h);
-
- mem = &inst->mv_buf;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-
- mem->size = ((vsi->buf_w / 64) *
- (vsi->buf_h / 64) + 2) * 36 * 16;
- result = mtk_vcodec_mem_alloc(inst->ctx, mem);
- if (result) {
- mem->size = 0;
- mtk_vcodec_err(inst, "Cannot allocate mv_buf");
- return false;
- }
- /* Set the va again */
- vsi->mv_buf.va = (unsigned long)mem->va;
- vsi->mv_buf.pa = (unsigned long)mem->dma_addr;
- vsi->mv_buf.sz = (unsigned int)mem->size;
-
-
- mem = &inst->seg_id_buf;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-
- mem->size = VP9_SEG_ID_SZ;
- result = mtk_vcodec_mem_alloc(inst->ctx, mem);
- if (result) {
- mem->size = 0;
- mtk_vcodec_err(inst, "Cannot allocate seg_id_buf");
- return false;
- }
- /* Set the va again */
- vsi->seg_id_buf.va = (unsigned long)mem->va;
- vsi->seg_id_buf.pa = (unsigned long)mem->dma_addr;
- vsi->seg_id_buf.sz = (unsigned int)mem->size;
-
-
- vp9_free_all_sf_ref_fb(inst);
- vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
-
- return true;
-}
-
-static bool vp9_add_to_fb_disp_list(struct vdec_vp9_inst *inst,
- struct vdec_fb *fb)
-{
- struct vdec_fb_node *node;
-
- if (!fb) {
- mtk_vcodec_err(inst, "fb == NULL");
- return false;
- }
-
- node = list_first_entry_or_null(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
- if (node) {
- node->fb = fb;
- list_move_tail(&node->list, &inst->fb_disp_list);
- } else {
- mtk_vcodec_err(inst, "No available fb node");
- return false;
- }
-
- return true;
-}
-
-/* If any buffer updating is signaled it should be done here. */
-static void vp9_swap_frm_bufs(struct vdec_vp9_inst *inst)
-{
- struct vdec_vp9_vsi *vsi = inst->vsi;
- struct vp9_fb_info *frm_to_show;
- int ref_index = 0, mask;
-
- for (mask = vsi->refresh_frm_flags; mask; mask >>= 1) {
- if (mask & 1)
- vp9_ref_cnt_fb(inst, &vsi->ref_frm_map[ref_index],
- vsi->new_fb_idx);
- ++ref_index;
- }
-
- frm_to_show = &vsi->frm_bufs[vsi->new_fb_idx].buf;
- vsi->frm_bufs[vsi->new_fb_idx].ref_cnt--;
-
- if (frm_to_show->fb != inst->cur_fb) {
- /* This frame is show exist frame and no decode output
- * copy frame data from frm_to_show to current CAPTURE
- * buffer
- */
- if ((frm_to_show->fb != NULL) &&
- (inst->cur_fb->base_y.size >=
- frm_to_show->fb->base_y.size) &&
- (inst->cur_fb->base_c.size >=
- frm_to_show->fb->base_c.size)) {
- memcpy((void *)inst->cur_fb->base_y.va,
- (void *)frm_to_show->fb->base_y.va,
- frm_to_show->fb->base_y.size);
- memcpy((void *)inst->cur_fb->base_c.va,
- (void *)frm_to_show->fb->base_c.va,
- frm_to_show->fb->base_c.size);
- } else {
- /* After resolution change case, current CAPTURE buffer
- * may have less buffer size than frm_to_show buffer
- * size
- */
- if (frm_to_show->fb != NULL)
- mtk_vcodec_err(inst,
- "inst->cur_fb->base_y.size=%zu, frm_to_show->fb.base_y.size=%zu",
- inst->cur_fb->base_y.size,
- frm_to_show->fb->base_y.size);
- }
- if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
- if (vsi->show_frame & BIT(0))
- vp9_add_to_fb_disp_list(inst, inst->cur_fb);
- }
- } else {
- if (!vp9_is_sf_ref_fb(inst, inst->cur_fb)) {
- if (vsi->show_frame & BIT(0))
- vp9_add_to_fb_disp_list(inst, frm_to_show->fb);
- }
- }
-
- /* when ref_cnt ==0, move this fb to fb_free_list. v4l2 driver will
- * clean fb_free_list
- */
- if (vsi->frm_bufs[vsi->new_fb_idx].ref_cnt == 0) {
- if (!vp9_is_sf_ref_fb(
- inst, vsi->frm_bufs[vsi->new_fb_idx].buf.fb)) {
- struct vdec_fb *fb;
-
- fb = vp9_rm_from_fb_use_list(inst,
- vsi->frm_bufs[vsi->new_fb_idx].buf.fb->base_y.va);
-
- vp9_add_to_fb_free_list(inst, fb);
- } else {
- vp9_free_sf_ref_fb(
- vsi->frm_bufs[vsi->new_fb_idx].buf.fb);
- }
- }
-
- /* if this super frame and it is not last sub-frame, get next fb for
- * sub-frame decode
- */
- if (vsi->sf_frm_cnt > 0 && vsi->sf_frm_idx != vsi->sf_frm_cnt - 1)
- vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
-}
-
-static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
-{
- struct mtk_vcodec_ctx *ctx = inst->ctx;
-
- mtk_vcodec_wait_for_done_ctx(inst->ctx,
- MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0);
-
- if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
- return true;
- else
- return false;
-}
-
-static struct vdec_vp9_inst *vp9_alloc_inst(struct mtk_vcodec_ctx *ctx)
-{
- int result;
- struct mtk_vcodec_mem mem;
- struct vdec_vp9_inst *inst;
-
- memset(&mem, 0, sizeof(mem));
- mem.size = sizeof(struct vdec_vp9_inst);
- result = mtk_vcodec_mem_alloc(ctx, &mem);
- if (result)
- return NULL;
-
- inst = mem.va;
- inst->mem = mem;
-
- return inst;
-}
-
-static void vp9_free_inst(struct vdec_vp9_inst *inst)
-{
- struct mtk_vcodec_mem mem;
-
- mem = inst->mem;
- if (mem.va)
- mtk_vcodec_mem_free(inst->ctx, &mem);
-}
-
-static bool vp9_decode_end_proc(struct vdec_vp9_inst *inst)
-{
- struct vdec_vp9_vsi *vsi = inst->vsi;
- bool ret = false;
-
- if (!vsi->show_existing_frame) {
- ret = vp9_wait_dec_end(inst);
- if (!ret) {
- mtk_vcodec_err(inst, "Decode failed, Decode Timeout @[%d]",
- vsi->frm_num);
- return false;
- }
-
- if (vpu_dec_end(&inst->vpu)) {
- mtk_vcodec_err(inst, "vp9_dec_vpu_end failed");
- return false;
- }
- mtk_vcodec_debug(inst, "Decode Ok @%d (%d/%d)", vsi->frm_num,
- vsi->pic_w, vsi->pic_h);
- } else {
- mtk_vcodec_debug(inst, "Decode Ok @%d (show_existing_frame)",
- vsi->frm_num);
- }
-
- vp9_swap_frm_bufs(inst);
- vsi->frm_num++;
- return true;
-}
-
-static bool vp9_is_last_sub_frm(struct vdec_vp9_inst *inst)
-{
- struct vdec_vp9_vsi *vsi = inst->vsi;
-
- if (vsi->sf_frm_cnt <= 0 || vsi->sf_frm_idx == vsi->sf_frm_cnt)
- return true;
-
- return false;
-}
-
-static struct vdec_fb *vp9_rm_from_fb_disp_list(struct vdec_vp9_inst *inst)
-{
- struct vdec_fb_node *node;
- struct vdec_fb *fb = NULL;
-
- node = list_first_entry_or_null(&inst->fb_disp_list,
- struct vdec_fb_node, list);
- if (node) {
- fb = (struct vdec_fb *)node->fb;
- fb->status |= FB_ST_DISPLAY;
- list_move_tail(&node->list, &inst->available_fb_node_list);
- mtk_vcodec_debug(inst, "[FB] get disp fb %p st=%d",
- node->fb, fb->status);
- } else
- mtk_vcodec_debug(inst, "[FB] there is no disp fb");
-
- return fb;
-}
-
-static bool vp9_add_to_fb_use_list(struct vdec_vp9_inst *inst,
- struct vdec_fb *fb)
-{
- struct vdec_fb_node *node;
-
- if (!fb) {
- mtk_vcodec_debug(inst, "fb == NULL");
- return false;
- }
-
- node = list_first_entry_or_null(&inst->available_fb_node_list,
- struct vdec_fb_node, list);
- if (node) {
- node->fb = fb;
- list_move_tail(&node->list, &inst->fb_use_list);
- } else {
- mtk_vcodec_err(inst, "No free fb node");
- return false;
- }
- return true;
-}
-
-static void vp9_reset(struct vdec_vp9_inst *inst)
-{
- struct vdec_fb_node *node, *tmp;
-
- list_for_each_entry_safe(node, tmp, &inst->fb_use_list, list)
- list_move_tail(&node->list, &inst->fb_free_list);
-
- vp9_free_all_sf_ref_fb(inst);
- inst->vsi->sf_next_ref_fb_idx = vp9_get_sf_ref_fb(inst);
-
- if (vpu_dec_reset(&inst->vpu))
- mtk_vcodec_err(inst, "vp9_dec_vpu_reset failed");
-
- /* Set the va again, since vpu_dec_reset will clear mv_buf in vpu */
- inst->vsi->mv_buf.va = (unsigned long)inst->mv_buf.va;
- inst->vsi->mv_buf.pa = (unsigned long)inst->mv_buf.dma_addr;
- inst->vsi->mv_buf.sz = (unsigned long)inst->mv_buf.size;
-
- /* Set the va again, since vpu_dec_reset will clear seg_id_buf in vpu */
- inst->vsi->seg_id_buf.va = (unsigned long)inst->seg_id_buf.va;
- inst->vsi->seg_id_buf.pa = (unsigned long)inst->seg_id_buf.dma_addr;
- inst->vsi->seg_id_buf.sz = (unsigned long)inst->seg_id_buf.size;
-
-}
-
-static void init_all_fb_lists(struct vdec_vp9_inst *inst)
-{
- int i;
-
- INIT_LIST_HEAD(&inst->available_fb_node_list);
- INIT_LIST_HEAD(&inst->fb_use_list);
- INIT_LIST_HEAD(&inst->fb_free_list);
- INIT_LIST_HEAD(&inst->fb_disp_list);
-
- for (i = 0; i < ARRAY_SIZE(inst->dec_fb); i++) {
- INIT_LIST_HEAD(&inst->dec_fb[i].list);
- inst->dec_fb[i].fb = NULL;
- list_add_tail(&inst->dec_fb[i].list,
- &inst->available_fb_node_list);
- }
-}
-
-static void get_pic_info(struct vdec_vp9_inst *inst, struct vdec_pic_info *pic)
-{
- pic->fb_sz[0] = inst->vsi->buf_sz_y_bs + inst->vsi->buf_len_sz_y;
- pic->fb_sz[1] = inst->vsi->buf_sz_c_bs + inst->vsi->buf_len_sz_c;
-
- pic->pic_w = inst->vsi->pic_w;
- pic->pic_h = inst->vsi->pic_h;
- pic->buf_w = inst->vsi->buf_w;
- pic->buf_h = inst->vsi->buf_h;
-
- mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
- pic->pic_w, pic->pic_h, pic->buf_w, pic->buf_h);
- mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
- pic->fb_sz[0],
- pic->fb_sz[1]);
-}
-
-static void get_disp_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
-{
-
- *out_fb = vp9_rm_from_fb_disp_list(inst);
- if (*out_fb)
- (*out_fb)->status |= FB_ST_DISPLAY;
-}
-
-static void get_free_fb(struct vdec_vp9_inst *inst, struct vdec_fb **out_fb)
-{
- struct vdec_fb_node *node;
- struct vdec_fb *fb = NULL;
-
- node = list_first_entry_or_null(&inst->fb_free_list,
- struct vdec_fb_node, list);
- if (node) {
- list_move_tail(&node->list, &inst->available_fb_node_list);
- fb = (struct vdec_fb *)node->fb;
- fb->status |= FB_ST_FREE;
- mtk_vcodec_debug(inst, "[FB] get free fb %p st=%d",
- node->fb, fb->status);
- } else {
- mtk_vcodec_debug(inst, "[FB] there is no free fb");
- }
-
- *out_fb = fb;
-}
-
-static int validate_vsi_array_indexes(struct vdec_vp9_inst *inst,
- struct vdec_vp9_vsi *vsi) {
- if (vsi->sf_frm_idx >= VP9_MAX_FRM_BUF_NUM - 1) {
- mtk_vcodec_err(inst, "Invalid vsi->sf_frm_idx=%u.",
- vsi->sf_frm_idx);
- return -EIO;
- }
- if (vsi->frm_to_show_idx >= VP9_MAX_FRM_BUF_NUM) {
- mtk_vcodec_err(inst, "Invalid vsi->frm_to_show_idx=%u.",
- vsi->frm_to_show_idx);
- return -EIO;
- }
- if (vsi->new_fb_idx >= VP9_MAX_FRM_BUF_NUM) {
- mtk_vcodec_err(inst, "Invalid vsi->new_fb_idx=%u.",
- vsi->new_fb_idx);
- return -EIO;
- }
- return 0;
-}
-
-static void vdec_vp9_deinit(void *h_vdec)
-{
- struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
- struct mtk_vcodec_mem *mem;
- int ret = 0;
-
- ret = vpu_dec_deinit(&inst->vpu);
- if (ret)
- mtk_vcodec_err(inst, "vpu_dec_deinit failed");
-
- mem = &inst->mv_buf;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-
- mem = &inst->seg_id_buf;
- if (mem->va)
- mtk_vcodec_mem_free(inst->ctx, mem);
-
- vp9_free_all_sf_ref_fb(inst);
- vp9_free_inst(inst);
-}
-
-static int vdec_vp9_init(struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_vp9_inst *inst;
-
- inst = vp9_alloc_inst(ctx);
- if (!inst)
- return -ENOMEM;
-
- inst->total_frm_cnt = 0;
- inst->ctx = ctx;
-
- inst->vpu.id = IPI_VDEC_VP9;
- inst->vpu.ctx = ctx;
-
- if (vpu_dec_init(&inst->vpu)) {
- mtk_vcodec_err(inst, "vp9_dec_vpu_init failed");
- goto err_deinit_inst;
- }
-
- inst->vsi = (struct vdec_vp9_vsi *)inst->vpu.vsi;
-
- inst->vsi->show_frame |= BIT(3);
-
- init_all_fb_lists(inst);
-
- ctx->drv_handle = inst;
- return 0;
-
-err_deinit_inst:
- vp9_free_inst(inst);
-
- return -EINVAL;
-}
-
-static int vdec_vp9_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg)
-{
- int ret = 0;
- struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
- struct vdec_vp9_vsi *vsi = inst->vsi;
- u32 data[3];
- int i;
-
- *res_chg = false;
-
- if ((bs == NULL) && (fb == NULL)) {
- mtk_vcodec_debug(inst, "[EOS]");
- vp9_reset(inst);
- return ret;
- }
-
- if (bs == NULL) {
- mtk_vcodec_err(inst, "bs == NULL");
- return -EINVAL;
- }
-
- mtk_vcodec_debug(inst, "Input BS Size = %zu", bs->size);
-
- while (1) {
- struct vdec_fb *cur_fb = NULL;
-
- data[0] = *((unsigned int *)bs->va);
- data[1] = *((unsigned int *)(bs->va + 4));
- data[2] = *((unsigned int *)(bs->va + 8));
-
- vsi->bs = *bs;
-
- if (fb)
- vsi->fb = *fb;
-
- if (!vsi->sf_init) {
- unsigned int sf_bs_sz;
- unsigned int sf_bs_off;
- unsigned char *sf_bs_src;
- unsigned char *sf_bs_dst;
-
- sf_bs_sz = bs->size > VP9_SUPER_FRAME_BS_SZ ?
- VP9_SUPER_FRAME_BS_SZ : bs->size;
- sf_bs_off = VP9_SUPER_FRAME_BS_SZ - sf_bs_sz;
- sf_bs_src = bs->va + bs->size - sf_bs_sz;
- sf_bs_dst = vsi->sf_bs_buf + sf_bs_off;
- memcpy(sf_bs_dst, sf_bs_src, sf_bs_sz);
- } else {
- if ((vsi->sf_frm_cnt > 0) &&
- (vsi->sf_frm_idx < vsi->sf_frm_cnt)) {
- unsigned int idx = vsi->sf_frm_idx;
-
- memcpy((void *)bs->va,
- (void *)(bs->va +
- vsi->sf_frm_offset[idx]),
- vsi->sf_frm_sz[idx]);
- }
- }
-
- if (!(vsi->show_frame & BIT(4)))
- memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);
-
- ret = vpu_dec_start(&inst->vpu, data, 3);
- if (ret) {
- mtk_vcodec_err(inst, "vpu_dec_start failed");
- goto DECODE_ERROR;
- }
-
- if (vsi->show_frame & BIT(1)) {
- memset(inst->seg_id_buf.va, 0, inst->seg_id_buf.size);
-
- if (vsi->show_frame & BIT(2)) {
- ret = vpu_dec_start(&inst->vpu, NULL, 0);
- if (ret) {
- mtk_vcodec_err(inst, "vpu trig decoder failed");
- goto DECODE_ERROR;
- }
- }
- }
-
- ret = validate_vsi_array_indexes(inst, vsi);
- if (ret) {
- mtk_vcodec_err(inst, "Invalid values from VPU.");
- goto DECODE_ERROR;
- }
-
- if (vsi->resolution_changed) {
- if (!vp9_alloc_work_buf(inst)) {
- ret = -EIO;
- goto DECODE_ERROR;
- }
- }
-
- if (vsi->sf_frm_cnt > 0) {
- cur_fb = &vsi->sf_ref_fb[vsi->sf_next_ref_fb_idx].fb;
-
- if (vsi->sf_frm_idx < vsi->sf_frm_cnt)
- inst->cur_fb = cur_fb;
- else
- inst->cur_fb = fb;
- } else {
- inst->cur_fb = fb;
- }
-
- vsi->frm_bufs[vsi->new_fb_idx].buf.fb = inst->cur_fb;
- if (!vp9_is_sf_ref_fb(inst, inst->cur_fb))
- vp9_add_to_fb_use_list(inst, inst->cur_fb);
-
- mtk_vcodec_debug(inst, "[#pic %d]", vsi->frm_num);
-
- if (vsi->show_existing_frame)
- mtk_vcodec_debug(inst,
- "drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
- vsi->new_fb_idx, vsi->frm_to_show_idx);
-
- if (vsi->show_existing_frame && (vsi->frm_to_show_idx <
- VP9_MAX_FRM_BUF_NUM)) {
- mtk_vcodec_debug(inst,
- "Skip Decode drv->new_fb_idx=%d, drv->frm_to_show_idx=%d",
- vsi->new_fb_idx, vsi->frm_to_show_idx);
-
- vp9_ref_cnt_fb(inst, &vsi->new_fb_idx,
- vsi->frm_to_show_idx);
- }
-
- /* VPU assign the buffer pointer in its address space,
- * reassign here
- */
- for (i = 0; i < ARRAY_SIZE(vsi->frm_refs); i++) {
- unsigned int idx = vsi->frm_refs[i].idx;
-
- vsi->frm_refs[i].buf = &vsi->frm_bufs[idx].buf;
- }
-
- if (vsi->resolution_changed) {
- *res_chg = true;
- mtk_vcodec_debug(inst, "VDEC_ST_RESOLUTION_CHANGED");
-
- ret = 0;
- goto DECODE_ERROR;
- }
-
- if (!vp9_decode_end_proc(inst)) {
- mtk_vcodec_err(inst, "vp9_decode_end_proc");
- ret = -EINVAL;
- goto DECODE_ERROR;
- }
-
- if (vp9_is_last_sub_frm(inst))
- break;
-
- }
- inst->total_frm_cnt++;
-
-DECODE_ERROR:
- if (ret < 0)
- vp9_add_to_fb_free_list(inst, fb);
-
- return ret;
-}
-
-static void get_crop_info(struct vdec_vp9_inst *inst, struct v4l2_rect *cr)
-{
- cr->left = 0;
- cr->top = 0;
- cr->width = inst->vsi->pic_w;
- cr->height = inst->vsi->pic_h;
- mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d\n",
- cr->left, cr->top, cr->width, cr->height);
-}
-
-static int vdec_vp9_get_param(void *h_vdec, enum vdec_get_param_type type,
- void *out)
-{
- struct vdec_vp9_inst *inst = (struct vdec_vp9_inst *)h_vdec;
- int ret = 0;
-
- switch (type) {
- case GET_PARAM_DISP_FRAME_BUFFER:
- get_disp_fb(inst, out);
- break;
- case GET_PARAM_FREE_FRAME_BUFFER:
- get_free_fb(inst, out);
- break;
- case GET_PARAM_PIC_INFO:
- get_pic_info(inst, out);
- break;
- case GET_PARAM_DPB_SIZE:
- *((unsigned int *)out) = MAX_VP9_DPB_SIZE;
- break;
- case GET_PARAM_CROP_INFO:
- get_crop_info(inst, out);
- break;
- default:
- mtk_vcodec_err(inst, "not supported param type %d", type);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-const struct vdec_common_if vdec_vp9_if = {
- .init = vdec_vp9_init,
- .decode = vdec_vp9_decode,
- .get_param = vdec_vp9_get_param,
- .deinit = vdec_vp9_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_base.h b/drivers/media/platform/mtk-vcodec/vdec_drv_base.h
deleted file mode 100644
index e913f963b7db..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_base.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- */
-
-#ifndef _VDEC_DRV_BASE_
-#define _VDEC_DRV_BASE_
-
-#include "vdec_drv_if.h"
-
-struct vdec_common_if {
- /**
- * (*init)() - initialize decode driver
- * @ctx : [in] mtk v4l2 context
- * @h_vdec : [out] driver handle
- */
- int (*init)(struct mtk_vcodec_ctx *ctx);
-
- /**
- * (*decode)() - trigger decode
- * @h_vdec : [in] driver handle
- * @bs : [in] input bitstream
- * @fb : [in] frame buffer to store decoded frame
- * @res_chg : [out] resolution change happen
- */
- int (*decode)(void *h_vdec, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg);
-
- /**
- * (*get_param)() - get driver's parameter
- * @h_vdec : [in] driver handle
- * @type : [in] input parameter type
- * @out : [out] buffer to store query result
- */
- int (*get_param)(void *h_vdec, enum vdec_get_param_type type,
- void *out);
-
- /**
- * (*deinit)() - deinitialize driver.
- * @h_vdec : [in] driver handle to be deinit
- */
- void (*deinit)(void *h_vdec);
-};
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
deleted file mode 100644
index 05a5b240e906..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "vdec_drv_if.h"
-#include "mtk_vcodec_dec.h"
-#include "vdec_drv_base.h"
-#include "mtk_vcodec_dec_pm.h"
-
-int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
-{
- int ret = 0;
-
- switch (fourcc) {
- case V4L2_PIX_FMT_H264_SLICE:
- ctx->dec_if = &vdec_h264_slice_if;
- break;
- case V4L2_PIX_FMT_H264:
- ctx->dec_if = &vdec_h264_if;
- ctx->hw_id = MTK_VDEC_CORE;
- break;
- case V4L2_PIX_FMT_VP8:
- ctx->dec_if = &vdec_vp8_if;
- ctx->hw_id = MTK_VDEC_CORE;
- break;
- case V4L2_PIX_FMT_VP9:
- ctx->dec_if = &vdec_vp9_if;
- ctx->hw_id = MTK_VDEC_CORE;
- break;
- default:
- return -EINVAL;
- }
-
- mtk_vdec_lock(ctx);
- mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
- ret = ctx->dec_if->init(ctx);
- mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
- mtk_vdec_unlock(ctx);
-
- return ret;
-}
-
-int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg)
-{
- int ret = 0;
-
- if (bs) {
- if ((bs->dma_addr & 63) != 0) {
- mtk_v4l2_err("bs dma_addr should 64 byte align");
- return -EINVAL;
- }
- }
-
- if (fb) {
- if (((fb->base_y.dma_addr & 511) != 0) ||
- ((fb->base_c.dma_addr & 511) != 0)) {
- mtk_v4l2_err("frame buffer dma_addr should 512 byte align");
- return -EINVAL;
- }
- }
-
- if (!ctx->drv_handle)
- return -EIO;
-
- mtk_vdec_lock(ctx);
-
- mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
- mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
- ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
- mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
- mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
-
- mtk_vdec_unlock(ctx);
-
- return ret;
-}
-
-int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
- void *out)
-{
- int ret = 0;
-
- if (!ctx->drv_handle)
- return -EIO;
-
- mtk_vdec_lock(ctx);
- ret = ctx->dec_if->get_param(ctx->drv_handle, type, out);
- mtk_vdec_unlock(ctx);
-
- return ret;
-}
-
-void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
-{
- if (!ctx->drv_handle)
- return;
-
- mtk_vdec_lock(ctx);
- mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
- ctx->dec_if->deinit(ctx->drv_handle);
- mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
- mtk_vdec_unlock(ctx);
-
- ctx->drv_handle = NULL;
-}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
deleted file mode 100644
index d467e8af4a84..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _VDEC_DRV_IF_H_
-#define _VDEC_DRV_IF_H_
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_dec.h"
-#include "mtk_vcodec_util.h"
-
-
-/**
- * enum vdec_fb_status - decoder frame buffer status
- * @FB_ST_NORMAL: initial state
- * @FB_ST_DISPLAY: frame buffer is ready to be displayed
- * @FB_ST_FREE: frame buffer is not used by decoder any more
- */
-enum vdec_fb_status {
- FB_ST_NORMAL = 0,
- FB_ST_DISPLAY = (1 << 0),
- FB_ST_FREE = (1 << 1)
-};
-
-/* For GET_PARAM_DISP_FRAME_BUFFER and GET_PARAM_FREE_FRAME_BUFFER,
- * the caller does not own the returned buffer. The buffer will not be
- * released before vdec_if_deinit.
- * GET_PARAM_DISP_FRAME_BUFFER : get next displayable frame buffer,
- * struct vdec_fb**
- * GET_PARAM_FREE_FRAME_BUFFER : get non-referenced framebuffer, vdec_fb**
- * GET_PARAM_PIC_INFO : get picture info, struct vdec_pic_info*
- * GET_PARAM_CROP_INFO : get crop info, struct v4l2_crop*
- * GET_PARAM_DPB_SIZE : get dpb size, unsigned int*
- */
-enum vdec_get_param_type {
- GET_PARAM_DISP_FRAME_BUFFER,
- GET_PARAM_FREE_FRAME_BUFFER,
- GET_PARAM_PIC_INFO,
- GET_PARAM_CROP_INFO,
- GET_PARAM_DPB_SIZE
-};
-
-/**
- * struct vdec_fb_node - decoder frame buffer node
- * @list : list to hold this node
- * @fb : point to frame buffer (vdec_fb), fb could point to frame buffer and
- * working buffer this is for maintain buffers in different state
- */
-struct vdec_fb_node {
- struct list_head list;
- struct vdec_fb *fb;
-};
-
-extern const struct vdec_common_if vdec_h264_if;
-extern const struct vdec_common_if vdec_h264_slice_if;
-extern const struct vdec_common_if vdec_vp8_if;
-extern const struct vdec_common_if vdec_vp9_if;
-
-/**
- * vdec_if_init() - initialize decode driver
- * @ctx : [in] v4l2 context
- * @fourcc : [in] video format fourcc, V4L2_PIX_FMT_H264/VP8/VP9..
- */
-int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc);
-
-/**
- * vdec_if_deinit() - deinitialize decode driver
- * @ctx : [in] v4l2 context
- *
- */
-void vdec_if_deinit(struct mtk_vcodec_ctx *ctx);
-
-/**
- * vdec_if_decode() - trigger decode
- * @ctx : [in] v4l2 context
- * @bs : [in] input bitstream
- * @fb : [in] frame buffer to store decoded frame, when null means parse
- * header only
- * @res_chg : [out] resolution change happens if current bs have different
- * picture width/height
- * Note: To flush the decoder when reaching EOF, set input bitstream as NULL.
- *
- * Return: 0 on success. -EIO on unrecoverable error.
- */
-int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
- struct vdec_fb *fb, bool *res_chg);
-
-/**
- * vdec_if_get_param() - get driver's parameter
- * @ctx : [in] v4l2 context
- * @type : [in] input parameter type
- * @out : [out] buffer to store query result
- */
-int vdec_if_get_param(struct mtk_vcodec_ctx *ctx, enum vdec_get_param_type type,
- void *out);
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
deleted file mode 100644
index bf54d6d9a857..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- */
-
-#ifndef _VDEC_IPI_MSG_H_
-#define _VDEC_IPI_MSG_H_
-
-/*
- * enum vdec_ipi_msgid - message id between AP and VPU
- * @AP_IPIMSG_XXX : AP to VPU cmd message id
- * @VPU_IPIMSG_XXX_ACK : VPU ack AP cmd message id
- */
-enum vdec_ipi_msgid {
- AP_IPIMSG_DEC_INIT = 0xA000,
- AP_IPIMSG_DEC_START = 0xA001,
- AP_IPIMSG_DEC_END = 0xA002,
- AP_IPIMSG_DEC_DEINIT = 0xA003,
- AP_IPIMSG_DEC_RESET = 0xA004,
- AP_IPIMSG_DEC_CORE = 0xA005,
- AP_IPIMSG_DEC_CORE_END = 0xA006,
-
- VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
- VPU_IPIMSG_DEC_START_ACK = 0xB001,
- VPU_IPIMSG_DEC_END_ACK = 0xB002,
- VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
- VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
- VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
- VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
-};
-
-/**
- * struct vdec_ap_ipi_cmd - generic AP to VPU ipi command format
- * @msg_id : vdec_ipi_msgid
- * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
- * @inst_id : instance ID. Used if the ABI version >= 2.
- * @codec_type : codec fourcc
- * @reserved : reserved param
- */
-struct vdec_ap_ipi_cmd {
- uint32_t msg_id;
- union {
- uint32_t vpu_inst_addr;
- uint32_t inst_id;
- };
- u32 codec_type;
- u32 reserved;
-};
-
-/**
- * struct vdec_vpu_ipi_ack - generic VPU to AP ipi command format
- * @msg_id : vdec_ipi_msgid
- * @status : VPU exeuction result
- * @ap_inst_addr : AP video decoder instance address
- */
-struct vdec_vpu_ipi_ack {
- uint32_t msg_id;
- int32_t status;
- uint64_t ap_inst_addr;
-};
-
-/**
- * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
- * @msg_id : AP_IPIMSG_DEC_INIT
- * @codec_type : codec fourcc
- * @ap_inst_addr : AP video decoder instance address
- */
-struct vdec_ap_ipi_init {
- uint32_t msg_id;
- u32 codec_type;
- uint64_t ap_inst_addr;
-};
-
-/**
- * struct vdec_ap_ipi_dec_start - for AP_IPIMSG_DEC_START
- * @msg_id : AP_IPIMSG_DEC_START
- * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
- * @inst_id : instance ID. Used if the ABI version >= 2.
- * @data : Header info
- * H264 decoder [0]:buf_sz [1]:nal_start
- * VP8 decoder [0]:width/height
- * VP9 decoder [0]:profile, [1][2] width/height
- * @codec_type : codec fourcc
- */
-struct vdec_ap_ipi_dec_start {
- uint32_t msg_id;
- union {
- uint32_t vpu_inst_addr;
- uint32_t inst_id;
- };
- uint32_t data[3];
- u32 codec_type;
-};
-
-/**
- * struct vdec_vpu_ipi_init_ack - for VPU_IPIMSG_DEC_INIT_ACK
- * @msg_id : VPU_IPIMSG_DEC_INIT_ACK
- * @status : VPU exeuction result
- * @ap_inst_addr : AP vcodec_vpu_inst instance address
- * @vpu_inst_addr : VPU decoder instance address
- * @vdec_abi_version: ABI version of the firmware. Kernel can use it to
- * ensure that it is compatible with the firmware.
- * This field is not valid for MT8173 and must not be
- * accessed for this chip.
- * @inst_id : instance ID. Valid only if the ABI version >= 2.
- */
-struct vdec_vpu_ipi_init_ack {
- uint32_t msg_id;
- int32_t status;
- uint64_t ap_inst_addr;
- uint32_t vpu_inst_addr;
- uint32_t vdec_abi_version;
- uint32_t inst_id;
-};
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
deleted file mode 100644
index 4b062a8128b4..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ /dev/null
@@ -1,290 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2021 MediaTek Inc.
- * Author: Yunfei Dong <yunfei.dong@mediatek.com>
- */
-
-#include <linux/freezer.h>
-#include <linux/interrupt.h>
-#include <linux/kthread.h>
-
-#include "mtk_vcodec_dec_pm.h"
-#include "mtk_vcodec_drv.h"
-#include "vdec_msg_queue.h"
-
-#define VDEC_MSG_QUEUE_TIMEOUT_MS 1500
-
-/* the size used to store lat slice header information */
-#define VDEC_LAT_SLICE_HEADER_SZ (640 * SZ_1K)
-
-/* the size used to store avc error information */
-#define VDEC_ERR_MAP_SZ_AVC (17 * SZ_1K)
-
-/* core will read the trans buffer which decoded by lat to decode again.
- * The trans buffer size of FHD and 4K bitstreams are different.
- */
-static int vde_msg_queue_get_trans_size(int width, int height)
-{
- if (width > 1920 || height > 1088)
- return 30 * SZ_1M;
- else
- return 6 * SZ_1M;
-}
-
-void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index)
-{
- init_waitqueue_head(&ctx->ready_to_use);
- INIT_LIST_HEAD(&ctx->ready_queue);
- spin_lock_init(&ctx->ready_lock);
- ctx->ready_num = 0;
- ctx->hardware_index = hardware_index;
-}
-
-static struct list_head *vdec_get_buf_list(int hardware_index, struct vdec_lat_buf *buf)
-{
- switch (hardware_index) {
- case MTK_VDEC_CORE:
- return &buf->core_list;
- case MTK_VDEC_LAT0:
- return &buf->lat_list;
- default:
- return NULL;
- }
-}
-
-int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf)
-{
- struct list_head *head;
-
- head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
- if (!head) {
- mtk_v4l2_err("fail to qbuf: %d", msg_ctx->hardware_index);
- return -EINVAL;
- }
-
- spin_lock(&msg_ctx->ready_lock);
- list_add_tail(head, &msg_ctx->ready_queue);
- msg_ctx->ready_num++;
-
- if (msg_ctx->hardware_index != MTK_VDEC_CORE)
- wake_up_all(&msg_ctx->ready_to_use);
- else
- queue_work(buf->ctx->dev->core_workqueue,
- &buf->ctx->msg_queue.core_work);
-
- mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
- msg_ctx->hardware_index, buf, msg_ctx->ready_num);
- spin_unlock(&msg_ctx->ready_lock);
-
- return 0;
-}
-
-static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *msg_ctx)
-{
- int ret;
-
- ret = wait_event_timeout(msg_ctx->ready_to_use,
- !list_empty(&msg_ctx->ready_queue),
- msecs_to_jiffies(VDEC_MSG_QUEUE_TIMEOUT_MS));
- if (!ret)
- return false;
-
- return true;
-}
-
-struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx)
-{
- struct vdec_lat_buf *buf;
- struct list_head *head;
- int ret;
-
- spin_lock(&msg_ctx->ready_lock);
- if (list_empty(&msg_ctx->ready_queue)) {
- mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
- msg_ctx->hardware_index, msg_ctx->ready_num);
- spin_unlock(&msg_ctx->ready_lock);
-
- if (msg_ctx->hardware_index == MTK_VDEC_CORE)
- return NULL;
-
- ret = vdec_msg_queue_wait_event(msg_ctx);
- if (!ret)
- return NULL;
- spin_lock(&msg_ctx->ready_lock);
- }
-
- if (msg_ctx->hardware_index == MTK_VDEC_CORE)
- buf = list_first_entry(&msg_ctx->ready_queue,
- struct vdec_lat_buf, core_list);
- else
- buf = list_first_entry(&msg_ctx->ready_queue,
- struct vdec_lat_buf, lat_list);
-
- head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
- if (!head) {
- spin_unlock(&msg_ctx->ready_lock);
- mtk_v4l2_err("fail to dqbuf: %d", msg_ctx->hardware_index);
- return NULL;
- }
- list_del(head);
-
- msg_ctx->ready_num--;
- mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
- msg_ctx->hardware_index, buf, msg_ctx->ready_num);
- spin_unlock(&msg_ctx->ready_lock);
-
- return buf;
-}
-
-void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr)
-{
- spin_lock(&msg_queue->lat_ctx.ready_lock);
- msg_queue->wdma_rptr_addr = ube_rptr;
- mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
- spin_unlock(&msg_queue->lat_ctx.ready_lock);
-}
-
-void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr)
-{
- spin_lock(&msg_queue->lat_ctx.ready_lock);
- msg_queue->wdma_wptr_addr = ube_wptr;
- mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
- msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr,
- ube_wptr);
- spin_unlock(&msg_queue->lat_ctx.ready_lock);
-}
-
-bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
-{
- long timeout_jiff;
- int ret;
-
- timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
- ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
- msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
- timeout_jiff);
- if (ret) {
- mtk_v4l2_debug(3, "success to get lat buf: %d",
- msg_queue->lat_ctx.ready_num);
- return true;
- }
- mtk_v4l2_err("failed with lat buf isn't full: %d",
- msg_queue->lat_ctx.ready_num);
- return false;
-}
-
-void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
- struct mtk_vcodec_ctx *ctx)
-{
- struct vdec_lat_buf *lat_buf;
- struct mtk_vcodec_mem *mem;
- int i;
-
- mem = &msg_queue->wdma_addr;
- if (mem->va)
- mtk_vcodec_mem_free(ctx, mem);
- for (i = 0; i < NUM_BUFFER_COUNT; i++) {
- lat_buf = &msg_queue->lat_buf[i];
-
- mem = &lat_buf->wdma_err_addr;
- if (mem->va)
- mtk_vcodec_mem_free(ctx, mem);
-
- mem = &lat_buf->slice_bc_addr;
- if (mem->va)
- mtk_vcodec_mem_free(ctx, mem);
-
- kfree(lat_buf->private_data);
- }
-}
-
-static void vdec_msg_queue_core_work(struct work_struct *work)
-{
- struct vdec_msg_queue *msg_queue =
- container_of(work, struct vdec_msg_queue, core_work);
- struct mtk_vcodec_ctx *ctx =
- container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue);
- struct mtk_vcodec_dev *dev = ctx->dev;
- struct vdec_lat_buf *lat_buf;
-
- lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
- if (!lat_buf)
- return;
-
- ctx = lat_buf->ctx;
- mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
-
- lat_buf->core_decode(lat_buf);
-
- mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
- vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
-
- if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
- mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
- dev->msg_queue_core_ctx.ready_num);
- queue_work(dev->core_workqueue, &msg_queue->core_work);
- }
-}
-
-int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
- struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
- int private_size)
-{
- struct vdec_lat_buf *lat_buf;
- int i, err;
-
- /* already init msg queue */
- if (msg_queue->wdma_addr.size)
- return 0;
-
- vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
- INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
- msg_queue->wdma_addr.size =
- vde_msg_queue_get_trans_size(ctx->picinfo.buf_w,
- ctx->picinfo.buf_h);
-
- err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
- if (err) {
- mtk_v4l2_err("failed to allocate wdma_addr buf");
- return -ENOMEM;
- }
- msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
- msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
-
- for (i = 0; i < NUM_BUFFER_COUNT; i++) {
- lat_buf = &msg_queue->lat_buf[i];
-
- lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
- err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
- if (err) {
- mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
- goto mem_alloc_err;
- }
-
- lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
- err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
- if (err) {
- mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
- goto mem_alloc_err;
- }
-
- lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
- if (!lat_buf->private_data) {
- err = -ENOMEM;
- goto mem_alloc_err;
- }
-
- lat_buf->ctx = ctx;
- lat_buf->core_decode = core_decode;
- err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
- if (err) {
- mtk_v4l2_err("failed to qbuf buf[%d]", i);
- goto mem_alloc_err;
- }
- }
- return 0;
-
-mem_alloc_err:
- vdec_msg_queue_deinit(msg_queue, ctx);
- return err;
-}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
deleted file mode 100644
index b6ba66d3e026..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2021 MediaTek Inc.
- * Author: Yunfei Dong <yunfei.dong@mediatek.com>
- */
-
-#ifndef _VDEC_MSG_QUEUE_H_
-#define _VDEC_MSG_QUEUE_H_
-
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-#include <linux/slab.h>
-#include <media/videobuf2-v4l2.h>
-
-#include "mtk_vcodec_util.h"
-
-#define NUM_BUFFER_COUNT 3
-
-struct vdec_lat_buf;
-struct mtk_vcodec_ctx;
-struct mtk_vcodec_dev;
-typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
-
-/**
- * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed
- * @ready_to_use: ready used queue used to signalize when get a job queue
- * @ready_queue: list of ready lat buffer queues
- * @ready_lock: spin lock to protect the lat buffer usage
- * @ready_num: number of buffers ready to be processed
- * @hardware_index: hardware id that this queue is used for
- */
-struct vdec_msg_queue_ctx {
- wait_queue_head_t ready_to_use;
- struct list_head ready_queue;
- /* protect lat buffer */
- spinlock_t ready_lock;
- int ready_num;
- int hardware_index;
-};
-
-/**
- * struct vdec_lat_buf - lat buffer message used to store lat info for core decode
- * @wdma_err_addr: wdma error address used for lat hardware
- * @slice_bc_addr: slice bc address used for lat hardware
- * @ts_info: need to set timestamp from output to capture
- *
- * @private_data: shared information used to lat and core hardware
- * @ctx: mtk vcodec context information
- * @core_decode: different codec use different decode callback function
- * @lat_list: add lat buffer to lat head list
- * @core_list: add lat buffer to core head list
- */
-struct vdec_lat_buf {
- struct mtk_vcodec_mem wdma_err_addr;
- struct mtk_vcodec_mem slice_bc_addr;
- struct vb2_v4l2_buffer ts_info;
-
- void *private_data;
- struct mtk_vcodec_ctx *ctx;
- core_decode_cb_t core_decode;
- struct list_head lat_list;
- struct list_head core_list;
-};
-
-/**
- * struct vdec_msg_queue - used to store lat buffer message
- * @lat_buf: lat buffer used to store lat buffer information
- * @wdma_addr: wdma address used for ube
- * @wdma_rptr_addr: ube read point
- * @wdma_wptr_addr: ube write point
- * @core_work: core hardware work
- * @lat_ctx: used to store lat buffer list
- */
-struct vdec_msg_queue {
- struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
-
- struct mtk_vcodec_mem wdma_addr;
- u64 wdma_rptr_addr;
- u64 wdma_wptr_addr;
-
- struct work_struct core_work;
- struct vdec_msg_queue_ctx lat_ctx;
-};
-
-/**
- * vdec_msg_queue_init - init lat buffer information.
- * @msg_queue: used to store the lat buffer information
- * @ctx: v4l2 ctx
- * @core_decode: core decode callback for each codec
- * @private_size: the private data size used to share with core
- *
- * Return: returns 0 if init successfully, or fail.
- */
-int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
- struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
- int private_size);
-
-/**
- * vdec_msg_queue_init_ctx - used to init msg queue context information.
- * @ctx: message queue context
- * @hardware_index: hardware index
- */
-void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index);
-
-/**
- * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
- * @ctx: message queue context
- * @buf: current lat buffer
- *
- * Return: returns 0 if qbuf successfully, or fail.
- */
-int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx, struct vdec_lat_buf *buf);
-
-/**
- * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
- * @ctx: message queue context
- *
- * Return: returns not null if dq successfully, or fail.
- */
-struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
-
-/**
- * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
- * @msg_queue: used to store the lat buffer information
- * @ube_rptr: current ube read point
- */
-void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr);
-
-/**
- * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
- * @msg_queue: used to store the lat buffer information
- * @ube_wptr: current ube write point
- */
-void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr);
-
-/**
- * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
- * in lat list.
- * @msg_queue: used to store the lat buffer information
- *
- * Return: returns true if successfully, or fail.
- */
-bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
-
-/**
- * vdec_msg_queue_deinit - deinit lat buffer information.
- * @msg_queue: used to store the lat buffer information
- * @ctx: v4l2 ctx
- */
-void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
- struct mtk_vcodec_ctx *ctx);
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
deleted file mode 100644
index dd35d2c5f920..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ /dev/null
@@ -1,243 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- */
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_util.h"
-#include "vdec_ipi_msg.h"
-#include "vdec_vpu_if.h"
-#include "mtk_vcodec_fw.h"
-
-static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
-{
- struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
- (unsigned long)msg->ap_inst_addr;
-
- mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr);
-
- /* 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);
- vpu->inst_addr = msg->vpu_inst_addr;
-
- mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr);
-
- /* Set default ABI version if dealing with unversioned firmware. */
- vpu->fw_abi_version = 0;
- /*
- * Instance ID is only used if ABI version >= 2. Initialize it with
- * garbage by default.
- */
- vpu->inst_id = 0xdeadbeef;
-
- /* Firmware version field does not exist on MT8173. */
- if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
- return;
-
- /* Check firmware version. */
- vpu->fw_abi_version = msg->vdec_abi_version;
- mtk_vcodec_debug(vpu, "firmware version 0x%x\n", vpu->fw_abi_version);
- switch (vpu->fw_abi_version) {
- case 1:
- break;
- case 2:
- vpu->inst_id = msg->inst_id;
- break;
- default:
- mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n",
- vpu->fw_abi_version);
- vpu->failure = 1;
- break;
- }
-}
-
-/*
- * vpu_dec_ipi_handler - Handler for VPU ipi message.
- *
- * @data: ipi message
- * @len : length of ipi message
- * @priv: callback private data which is passed by decoder when register.
- *
- * This function runs in interrupt context and it means there's an IPI MSG
- * from VPU.
- */
-static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
-{
- const struct vdec_vpu_ipi_ack *msg = data;
- struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
- (unsigned long)msg->ap_inst_addr;
-
- mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id);
-
- vpu->failure = msg->status;
- vpu->signaled = 1;
-
- if (msg->status == 0) {
- switch (msg->msg_id) {
- case VPU_IPIMSG_DEC_INIT_ACK:
- handle_init_ack_msg(data);
- break;
-
- case VPU_IPIMSG_DEC_START_ACK:
- case VPU_IPIMSG_DEC_END_ACK:
- case VPU_IPIMSG_DEC_DEINIT_ACK:
- case VPU_IPIMSG_DEC_RESET_ACK:
- case VPU_IPIMSG_DEC_CORE_ACK:
- case VPU_IPIMSG_DEC_CORE_END_ACK:
- break;
-
- default:
- mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id);
- break;
- }
- }
-
- mtk_vcodec_debug(vpu, "- id=%X", msg->msg_id);
-}
-
-static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
-{
- int err, id, msgid;
-
- msgid = *(uint32_t *)msg;
- mtk_vcodec_debug(vpu, "id=%X", msgid);
-
- vpu->failure = 0;
- vpu->signaled = 0;
-
- if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
- if (msgid == AP_IPIMSG_DEC_CORE ||
- msgid == AP_IPIMSG_DEC_CORE_END)
- id = vpu->core_id;
- else
- id = vpu->id;
- } else {
- id = vpu->id;
- }
-
- err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
- len, 2000);
- if (err) {
- mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
- id, msgid, err);
- return err;
- }
-
- return vpu->failure;
-}
-
-static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
-{
- struct vdec_ap_ipi_cmd msg;
- int err = 0;
-
- mtk_vcodec_debug(vpu, "+ id=%X", msg_id);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_id = msg_id;
- if (vpu->fw_abi_version < 2)
- msg.vpu_inst_addr = vpu->inst_addr;
- else
- msg.inst_id = vpu->inst_id;
- msg.codec_type = vpu->codec_type;
-
- err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
- mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
- return err;
-}
-
-int vpu_dec_init(struct vdec_vpu_inst *vpu)
-{
- struct vdec_ap_ipi_init msg;
- int err;
-
- mtk_vcodec_debug_enter(vpu);
-
- init_waitqueue_head(&vpu->wq);
- vpu->handler = vpu_dec_ipi_handler;
-
- err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
- vpu->handler, "vdec", NULL);
- if (err) {
- mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
- return err;
- }
-
- if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
- err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
- vpu->core_id, vpu->handler,
- "vdec", NULL);
- if (err) {
- mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
- return err;
- }
- }
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_id = AP_IPIMSG_DEC_INIT;
- msg.ap_inst_addr = (unsigned long)vpu;
- msg.codec_type = vpu->codec_type;
-
- mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
-
- err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
- mtk_vcodec_debug(vpu, "- ret=%d", err);
- return err;
-}
-
-int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
-{
- struct vdec_ap_ipi_dec_start msg;
- int i;
- int err = 0;
-
- mtk_vcodec_debug_enter(vpu);
-
- if (len > ARRAY_SIZE(msg.data)) {
- mtk_vcodec_err(vpu, "invalid len = %d\n", len);
- return -EINVAL;
- }
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_id = AP_IPIMSG_DEC_START;
- if (vpu->fw_abi_version < 2)
- msg.vpu_inst_addr = vpu->inst_addr;
- else
- msg.inst_id = vpu->inst_id;
-
- for (i = 0; i < len; i++)
- msg.data[i] = data[i];
- msg.codec_type = vpu->codec_type;
-
- err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
- mtk_vcodec_debug(vpu, "- ret=%d", err);
- return err;
-}
-
-int vpu_dec_core(struct vdec_vpu_inst *vpu)
-{
- return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
-}
-
-int vpu_dec_end(struct vdec_vpu_inst *vpu)
-{
- return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
-}
-
-int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
-{
- return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
-}
-
-int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
-{
- return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
-}
-
-int vpu_dec_reset(struct vdec_vpu_inst *vpu)
-{
- return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_RESET);
-}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
deleted file mode 100644
index 4cb3c7f5a3ad..000000000000
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PC Chen <pc.chen@mediatek.com>
- */
-
-#ifndef _VDEC_VPU_IF_H_
-#define _VDEC_VPU_IF_H_
-
-#include "mtk_vcodec_fw.h"
-
-struct mtk_vcodec_ctx;
-
-/**
- * struct vdec_vpu_inst - VPU instance for video codec
- * @id : ipi msg id for each decoder
- * @core_id : core id used to separate different hardware
- * @vsi : driver structure allocated by VPU side and shared to AP side
- * for control and info share
- * @failure : VPU execution result status, 0: success, others: fail
- * @inst_addr : VPU decoder instance address
- * @fw_abi_version : ABI version of the firmware.
- * @inst_id : if fw_abi_version >= 2, contains the instance ID to be given
- * in place of inst_addr in messages.
- * @signaled : 1 - Host has received ack message from VPU, 0 - not received
- * @ctx : context for v4l2 layer integration
- * @dev : platform device of VPU
- * @wq : wait queue to wait VPU message ack
- * @handler : ipi handler for each decoder
- * @codec_type : use codec type to separate different codecs
- */
-struct vdec_vpu_inst {
- int id;
- int core_id;
- void *vsi;
- int32_t failure;
- uint32_t inst_addr;
- uint32_t fw_abi_version;
- uint32_t inst_id;
- unsigned int signaled;
- struct mtk_vcodec_ctx *ctx;
- wait_queue_head_t wq;
- mtk_vcodec_ipi_handler handler;
- unsigned int codec_type;
-};
-
-/**
- * vpu_dec_init - init decoder instance and allocate required resource in VPU.
- *
- * @vpu: instance for vdec_vpu_inst
- */
-int vpu_dec_init(struct vdec_vpu_inst *vpu);
-
-/**
- * vpu_dec_start - start decoding, basically the function will be invoked once
- * every frame.
- *
- * @vpu : instance for vdec_vpu_inst
- * @data: meta data to pass bitstream info to VPU decoder
- * @len : meta data length
- */
-int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len);
-
-/**
- * vpu_dec_end - end decoding, basically the function will be invoked once
- * when HW decoding done interrupt received successfully. The
- * decoder in VPU will continue to do reference frame management
- * and check if there is a new decoded frame available to display.
- *
- * @vpu : instance for vdec_vpu_inst
- */
-int vpu_dec_end(struct vdec_vpu_inst *vpu);
-
-/**
- * vpu_dec_deinit - deinit decoder instance and resource freed in VPU.
- *
- * @vpu: instance for vdec_vpu_inst
- */
-int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
-
-/**
- * vpu_dec_reset - reset decoder, use for flush decoder when end of stream or
- * seek. Remainig non displayed frame will be pushed to display.
- *
- * @vpu: instance for vdec_vpu_inst
- */
-int vpu_dec_reset(struct vdec_vpu_inst *vpu);
-
-/**
- * vpu_dec_core - core start decoding, basically the function will be invoked once
- * every frame.
- *
- * @vpu : instance for vdec_vpu_inst
- */
-int vpu_dec_core(struct vdec_vpu_inst *vpu);
-
-/**
- * vpu_dec_core_end - core end decoding, basically the function will be invoked once
- * when core HW decoding done and receive interrupt successfully. The
- * decoder in VPU will updata hardware information and deinit hardware
- * and check if there is a new decoded frame available to display.
- *
- * @vpu : instance for vdec_vpu_inst
- */
-int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
deleted file mode 100644
index 4d9b8798dffe..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ /dev/null
@@ -1,708 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Jungchang Tsao <jungchang.tsao@mediatek.com>
- * Daniel Hsiao <daniel.hsiao@mediatek.com>
- * PoChun Lin <pochun.lin@mediatek.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "../mtk_vcodec_drv.h"
-#include "../mtk_vcodec_util.h"
-#include "../mtk_vcodec_intr.h"
-#include "../mtk_vcodec_enc.h"
-#include "../mtk_vcodec_enc_pm.h"
-#include "../venc_drv_base.h"
-#include "../venc_ipi_msg.h"
-#include "../venc_vpu_if.h"
-
-static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc};
-
-#define H264_FILLER_MARKER_SIZE ARRAY_SIZE(h264_filler_marker)
-#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
-
-/*
- * enum venc_h264_frame_type - h264 encoder output bitstream frame type
- */
-enum venc_h264_frame_type {
- VENC_H264_IDR_FRM,
- VENC_H264_I_FRM,
- VENC_H264_P_FRM,
- VENC_H264_B_FRM,
-};
-
-/*
- * enum venc_h264_vpu_work_buf - h264 encoder buffer index
- */
-enum venc_h264_vpu_work_buf {
- VENC_H264_VPU_WORK_BUF_RC_INFO,
- VENC_H264_VPU_WORK_BUF_RC_CODE,
- VENC_H264_VPU_WORK_BUF_REC_LUMA,
- VENC_H264_VPU_WORK_BUF_REC_CHROMA,
- VENC_H264_VPU_WORK_BUF_REF_LUMA,
- VENC_H264_VPU_WORK_BUF_REF_CHROMA,
- VENC_H264_VPU_WORK_BUF_MV_INFO_1,
- VENC_H264_VPU_WORK_BUF_MV_INFO_2,
- VENC_H264_VPU_WORK_BUF_SKIP_FRAME,
- VENC_H264_VPU_WORK_BUF_MAX,
-};
-
-/*
- * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode
- */
-enum venc_h264_bs_mode {
- H264_BS_MODE_SPS,
- H264_BS_MODE_PPS,
- H264_BS_MODE_FRAME,
-};
-
-/*
- * struct venc_h264_vpu_config - Structure for h264 encoder configuration
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @input_fourcc: input fourcc
- * @bitrate: target bitrate (in bps)
- * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
- * to be used for display purposes; must be smaller or equal to buffer
- * size.
- * @pic_h: picture height
- * @buf_w: buffer width. Buffer size is stream resolution in pixels aligned to
- * hardware requirements.
- * @buf_h: buffer height
- * @gop_size: group of picture size (idr frame)
- * @intra_period: intra frame period
- * @framerate: frame rate in fps
- * @profile: as specified in standard
- * @level: as specified in standard
- * @wfd: WFD mode 1:on, 0:off
- */
-struct venc_h264_vpu_config {
- u32 input_fourcc;
- u32 bitrate;
- u32 pic_w;
- u32 pic_h;
- u32 buf_w;
- u32 buf_h;
- u32 gop_size;
- u32 intra_period;
- u32 framerate;
- u32 profile;
- u32 level;
- u32 wfd;
-};
-
-/*
- * struct venc_h264_vpu_buf - Structure for buffer information
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @iova: IO virtual address
- * @vpua: VPU side memory addr which is used by RC_CODE
- * @size: buffer size (in bytes)
- */
-struct venc_h264_vpu_buf {
- u32 iova;
- u32 vpua;
- u32 size;
-};
-
-/*
- * struct venc_h264_vsi - Structure for VPU driver control and info share
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * This structure is allocated in VPU side and shared to AP side.
- * @config: h264 encoder configuration
- * @work_bufs: working buffer information in VPU side
- * The work_bufs here is for storing the 'size' info shared to AP side.
- * The similar item in struct venc_h264_inst is for memory allocation
- * in AP side. The AP driver will copy the 'size' from here to the one in
- * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate
- * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for
- * register setting in VPU side.
- */
-struct venc_h264_vsi {
- struct venc_h264_vpu_config config;
- struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
-};
-
-/*
- * struct venc_h264_inst - h264 encoder AP driver instance
- * @hw_base: h264 encoder hardware register base
- * @work_bufs: working buffer
- * @pps_buf: buffer to store the pps bitstream
- * @work_buf_allocated: working buffer allocated flag
- * @frm_cnt: encoded frame count
- * @prepend_hdr: when the v4l2 layer send VENC_SET_PARAM_PREPEND_HEADER cmd
- * through h264_enc_set_param interface, it will set this flag and prepend the
- * sps/pps in h264_enc_encode function.
- * @vpu_inst: VPU instance to exchange information between AP and VPU
- * @vsi: driver structure allocated by VPU side and shared to AP side for
- * control and info share
- * @ctx: context for v4l2 layer integration
- */
-struct venc_h264_inst {
- void __iomem *hw_base;
- struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
- struct mtk_vcodec_mem pps_buf;
- bool work_buf_allocated;
- unsigned int frm_cnt;
- unsigned int skip_frm_cnt;
- unsigned int prepend_hdr;
- struct venc_vpu_inst vpu_inst;
- struct venc_h264_vsi *vsi;
- struct mtk_vcodec_ctx *ctx;
-};
-
-static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
-{
- return readl(inst->hw_base + addr);
-}
-
-static unsigned int h264_get_profile(struct venc_h264_inst *inst,
- unsigned int profile)
-{
- switch (profile) {
- case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
- return 66;
- case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
- return 77;
- case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
- return 100;
- case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
- mtk_vcodec_err(inst, "unsupported CONSTRAINED_BASELINE");
- return 0;
- case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
- mtk_vcodec_err(inst, "unsupported EXTENDED");
- return 0;
- default:
- mtk_vcodec_debug(inst, "unsupported profile %d", profile);
- return 100;
- }
-}
-
-static unsigned int h264_get_level(struct venc_h264_inst *inst,
- unsigned int level)
-{
- switch (level) {
- case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
- mtk_vcodec_err(inst, "unsupported 1B");
- return 0;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
- return 10;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
- return 11;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
- return 12;
- case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
- return 13;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
- return 20;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
- return 21;
- case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
- return 22;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
- return 30;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
- return 31;
- case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
- return 32;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
- return 40;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
- return 41;
- case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
- return 42;
- case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
- return 50;
- case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
- return 51;
- default:
- mtk_vcodec_debug(inst, "unsupported level %d", level);
- return 31;
- }
-}
-
-static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
-{
- int i;
-
- mtk_vcodec_debug_enter(inst);
-
- /* Except the SKIP_FRAME buffers,
- * other buffers need to be freed by AP.
- */
- for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
- if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
- mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
- }
-
- mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
-
- mtk_vcodec_debug_leave(inst);
-}
-
-static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
-{
- int i;
- int ret = 0;
- struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
-
- mtk_vcodec_debug_enter(inst);
-
- for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
- /*
- * This 'wb' structure is set by VPU side and shared to AP for
- * buffer allocation and IO virtual addr mapping. For most of
- * the buffers, AP will allocate the buffer according to 'size'
- * field and store the IO virtual addr in 'iova' field. There
- * are two exceptions:
- * (1) RC_CODE buffer, it's pre-allocated in the VPU side, and
- * save the VPU addr in the 'vpua' field. The AP will translate
- * the VPU addr to the corresponding IO virtual addr and store
- * in 'iova' field for reg setting in VPU side.
- * (2) SKIP_FRAME buffer, it's pre-allocated in the VPU side,
- * and save the VPU addr in the 'vpua' field. The AP will
- * translate the VPU addr to the corresponding AP side virtual
- * address and do some memcpy access to move to bitstream buffer
- * assigned by v4l2 layer.
- */
- inst->work_bufs[i].size = wb[i].size;
- if (i == VENC_H264_VPU_WORK_BUF_SKIP_FRAME) {
- struct mtk_vcodec_fw *handler;
-
- handler = inst->vpu_inst.ctx->dev->fw_handler;
- inst->work_bufs[i].va =
- mtk_vcodec_fw_map_dm_addr(handler, wb[i].vpua);
- inst->work_bufs[i].dma_addr = 0;
- } else {
- ret = mtk_vcodec_mem_alloc(inst->ctx,
- &inst->work_bufs[i]);
- if (ret) {
- mtk_vcodec_err(inst,
- "cannot allocate buf %d", i);
- goto err_alloc;
- }
- /*
- * This RC_CODE is pre-allocated by VPU and saved in VPU
- * addr. So we need use memcpy to copy RC_CODE from VPU
- * addr into IO virtual addr in 'iova' field for reg
- * setting in VPU side.
- */
- if (i == VENC_H264_VPU_WORK_BUF_RC_CODE) {
- struct mtk_vcodec_fw *handler;
- void *tmp_va;
-
- handler = inst->vpu_inst.ctx->dev->fw_handler;
- tmp_va = mtk_vcodec_fw_map_dm_addr(handler,
- wb[i].vpua);
- memcpy(inst->work_bufs[i].va, tmp_va,
- wb[i].size);
- }
- }
- wb[i].iova = inst->work_bufs[i].dma_addr;
-
- mtk_vcodec_debug(inst,
- "work_buf[%d] va=0x%p iova=%pad size=%zu",
- i, inst->work_bufs[i].va,
- &inst->work_bufs[i].dma_addr,
- inst->work_bufs[i].size);
- }
-
- /* the pps_buf is used by AP side only */
- inst->pps_buf.size = 128;
- ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->pps_buf);
- if (ret) {
- mtk_vcodec_err(inst, "cannot allocate pps_buf");
- goto err_alloc;
- }
-
- mtk_vcodec_debug_leave(inst);
-
- return ret;
-
-err_alloc:
- h264_enc_free_work_buf(inst);
-
- return ret;
-}
-
-static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
-{
- unsigned int irq_status = 0;
- struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
-
- if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0)) {
- irq_status = ctx->irq_status;
- mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
- }
- return irq_status;
-}
-
-static int h264_frame_type(struct venc_h264_inst *inst)
-{
- if ((inst->vsi->config.gop_size != 0 &&
- (inst->frm_cnt % inst->vsi->config.gop_size) == 0) ||
- (inst->frm_cnt == 0 && inst->vsi->config.gop_size == 0)) {
- /* IDR frame */
- return VENC_H264_IDR_FRM;
- } else if ((inst->vsi->config.intra_period != 0 &&
- (inst->frm_cnt % inst->vsi->config.intra_period) == 0) ||
- (inst->frm_cnt == 0 && inst->vsi->config.intra_period == 0)) {
- /* I frame */
- return VENC_H264_I_FRM;
- } else {
- return VENC_H264_P_FRM; /* Note: B frames are not supported */
- }
-}
-static int h264_encode_sps(struct venc_h264_inst *inst,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- int ret = 0;
- unsigned int irq_status;
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL);
- if (ret)
- return ret;
-
- irq_status = h264_enc_wait_venc_done(inst);
- if (irq_status != MTK_VENC_IRQ_STATUS_SPS) {
- mtk_vcodec_err(inst, "expect irq status %d",
- MTK_VENC_IRQ_STATUS_SPS);
- return -EINVAL;
- }
-
- *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
- mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
-
- return ret;
-}
-
-static int h264_encode_pps(struct venc_h264_inst *inst,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- int ret = 0;
- unsigned int irq_status;
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL);
- if (ret)
- return ret;
-
- irq_status = h264_enc_wait_venc_done(inst);
- if (irq_status != MTK_VENC_IRQ_STATUS_PPS) {
- mtk_vcodec_err(inst, "expect irq status %d",
- MTK_VENC_IRQ_STATUS_PPS);
- return -EINVAL;
- }
-
- *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
- mtk_vcodec_debug(inst, "bs size %d <-", *bs_size);
-
- return ret;
-}
-
-static int h264_encode_header(struct venc_h264_inst *inst,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- int ret = 0;
- unsigned int bs_size_sps;
- unsigned int bs_size_pps;
-
- ret = h264_encode_sps(inst, bs_buf, &bs_size_sps);
- if (ret)
- return ret;
-
- ret = h264_encode_pps(inst, &inst->pps_buf, &bs_size_pps);
- if (ret)
- return ret;
-
- memcpy(bs_buf->va + bs_size_sps, inst->pps_buf.va, bs_size_pps);
- *bs_size = bs_size_sps + bs_size_pps;
-
- return ret;
-}
-
-static int h264_encode_frame(struct venc_h264_inst *inst,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- int ret = 0;
- unsigned int irq_status;
- struct venc_frame_info frame_info;
-
- mtk_vcodec_debug_enter(inst);
- mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt);
- frame_info.frm_count = inst->frm_cnt;
- frame_info.skip_frm_count = inst->skip_frm_cnt;
- frame_info.frm_type = h264_frame_type(inst);
- mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
- frame_info.frm_count, frame_info.skip_frm_count,
- frame_info.frm_type);
- ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info);
- if (ret)
- return ret;
-
- /*
- * skip frame case: The skip frame buffer is composed by vpu side only,
- * it does not trigger the hw, so skip the wait interrupt operation.
- */
- if (inst->vpu_inst.state == VEN_IPI_MSG_ENC_STATE_SKIP) {
- *bs_size = inst->vpu_inst.bs_size;
- memcpy(bs_buf->va,
- inst->work_bufs[VENC_H264_VPU_WORK_BUF_SKIP_FRAME].va,
- *bs_size);
- ++inst->frm_cnt;
- ++inst->skip_frm_cnt;
- return ret;
- }
-
- irq_status = h264_enc_wait_venc_done(inst);
- if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
- mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
- return -EIO;
- }
-
- *bs_size = h264_read_reg(inst, VENC_PIC_BITSTREAM_BYTE_CNT);
-
- ++inst->frm_cnt;
- mtk_vcodec_debug(inst, "frm %d bs_size %d key_frm %d <-",
- inst->frm_cnt, *bs_size, inst->vpu_inst.is_key_frm);
-
- return ret;
-}
-
-static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
- int size)
-{
- unsigned char *p = buf;
-
- if (size < H264_FILLER_MARKER_SIZE) {
- mtk_vcodec_err(inst, "filler size too small %d", size);
- return;
- }
-
- memcpy(p, h264_filler_marker, ARRAY_SIZE(h264_filler_marker));
- size -= H264_FILLER_MARKER_SIZE;
- p += H264_FILLER_MARKER_SIZE;
- memset(p, 0xff, size);
-}
-
-static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
-{
- const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
- int ret = 0;
- struct venc_h264_inst *inst;
-
- inst = kzalloc(sizeof(*inst), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- inst->ctx = ctx;
- inst->vpu_inst.ctx = ctx;
- inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
- inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_init(&inst->vpu_inst);
-
- inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
-
- mtk_vcodec_debug_leave(inst);
-
- if (ret)
- kfree(inst);
- else
- ctx->drv_handle = inst;
-
- return ret;
-}
-
-static int h264_enc_encode(void *handle,
- enum venc_start_opt opt,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_done_result *result)
-{
- int ret = 0;
- struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
- struct mtk_vcodec_ctx *ctx = inst->ctx;
-
- mtk_vcodec_debug(inst, "opt %d ->", opt);
-
- enable_irq(ctx->dev->enc_irq);
-
- switch (opt) {
- case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
- unsigned int bs_size_hdr;
-
- ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
- if (ret)
- goto encode_err;
-
- result->bs_size = bs_size_hdr;
- result->is_key_frm = false;
- break;
- }
-
- case VENC_START_OPT_ENCODE_FRAME: {
- int hdr_sz;
- int hdr_sz_ext;
- int filler_sz = 0;
- const int bs_alignment = 128;
- struct mtk_vcodec_mem tmp_bs_buf;
- unsigned int bs_size_hdr;
- unsigned int bs_size_frm;
-
- if (!inst->prepend_hdr) {
- ret = h264_encode_frame(inst, frm_buf, bs_buf,
- &result->bs_size);
- if (ret)
- goto encode_err;
- result->is_key_frm = inst->vpu_inst.is_key_frm;
- break;
- }
-
- mtk_vcodec_debug(inst, "h264_encode_frame prepend SPS/PPS");
-
- ret = h264_encode_header(inst, bs_buf, &bs_size_hdr);
- if (ret)
- goto encode_err;
-
- hdr_sz = bs_size_hdr;
- hdr_sz_ext = (hdr_sz & (bs_alignment - 1));
- if (hdr_sz_ext) {
- filler_sz = bs_alignment - hdr_sz_ext;
- if (hdr_sz_ext + H264_FILLER_MARKER_SIZE > bs_alignment)
- filler_sz += bs_alignment;
- h264_encode_filler(inst, bs_buf->va + hdr_sz,
- filler_sz);
- }
-
- tmp_bs_buf.va = bs_buf->va + hdr_sz + filler_sz;
- tmp_bs_buf.dma_addr = bs_buf->dma_addr + hdr_sz + filler_sz;
- tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
-
- ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf,
- &bs_size_frm);
- if (ret)
- goto encode_err;
-
- result->bs_size = hdr_sz + filler_sz + bs_size_frm;
-
- mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
- hdr_sz, filler_sz, bs_size_frm,
- result->bs_size);
-
- inst->prepend_hdr = 0;
- result->is_key_frm = inst->vpu_inst.is_key_frm;
- break;
- }
-
- default:
- mtk_vcodec_err(inst, "venc_start_opt %d not supported", opt);
- ret = -EINVAL;
- break;
- }
-
-encode_err:
-
- disable_irq(ctx->dev->enc_irq);
- mtk_vcodec_debug(inst, "opt %d <-", opt);
-
- return ret;
-}
-
-static int h264_enc_set_param(void *handle,
- enum venc_set_param_type type,
- struct venc_enc_param *enc_prm)
-{
- int ret = 0;
- struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
-
- mtk_vcodec_debug(inst, "->type=%d", type);
-
- switch (type) {
- case VENC_SET_PARAM_ENC:
- inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
- inst->vsi->config.bitrate = enc_prm->bitrate;
- inst->vsi->config.pic_w = enc_prm->width;
- inst->vsi->config.pic_h = enc_prm->height;
- inst->vsi->config.buf_w = enc_prm->buf_width;
- inst->vsi->config.buf_h = enc_prm->buf_height;
- inst->vsi->config.gop_size = enc_prm->gop_size;
- inst->vsi->config.framerate = enc_prm->frm_rate;
- inst->vsi->config.intra_period = enc_prm->intra_period;
- inst->vsi->config.profile =
- h264_get_profile(inst, enc_prm->h264_profile);
- inst->vsi->config.level =
- h264_get_level(inst, enc_prm->h264_level);
- inst->vsi->config.wfd = 0;
- ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
- if (ret)
- break;
- if (inst->work_buf_allocated) {
- h264_enc_free_work_buf(inst);
- inst->work_buf_allocated = false;
- }
- ret = h264_enc_alloc_work_buf(inst);
- if (ret)
- break;
- inst->work_buf_allocated = true;
- break;
-
- case VENC_SET_PARAM_PREPEND_HEADER:
- inst->prepend_hdr = 1;
- mtk_vcodec_debug(inst, "set prepend header mode");
- break;
- case VENC_SET_PARAM_FORCE_INTRA:
- case VENC_SET_PARAM_GOP_SIZE:
- case VENC_SET_PARAM_INTRA_PERIOD:
- inst->frm_cnt = 0;
- inst->skip_frm_cnt = 0;
- fallthrough;
- default:
- ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
- break;
- }
-
- mtk_vcodec_debug_leave(inst);
-
- return ret;
-}
-
-static int h264_enc_deinit(void *handle)
-{
- int ret = 0;
- struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_deinit(&inst->vpu_inst);
-
- if (inst->work_buf_allocated)
- h264_enc_free_work_buf(inst);
-
- mtk_vcodec_debug_leave(inst);
- kfree(inst);
-
- return ret;
-}
-
-const struct venc_common_if venc_h264_if = {
- .init = h264_enc_init,
- .encode = h264_enc_encode,
- .set_param = h264_enc_set_param,
- .deinit = h264_enc_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
deleted file mode 100644
index 56ce58f761f1..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ /dev/null
@@ -1,468 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
- * PoChun Lin <pochun.lin@mediatek.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "../mtk_vcodec_drv.h"
-#include "../mtk_vcodec_util.h"
-#include "../mtk_vcodec_intr.h"
-#include "../mtk_vcodec_enc.h"
-#include "../mtk_vcodec_enc_pm.h"
-#include "../venc_drv_base.h"
-#include "../venc_ipi_msg.h"
-#include "../venc_vpu_if.h"
-
-#define VENC_BITSTREAM_FRAME_SIZE 0x0098
-#define VENC_BITSTREAM_HEADER_LEN 0x00e8
-
-/* This ac_tag is vp8 frame tag. */
-#define MAX_AC_TAG_SIZE 10
-
-/*
- * enum venc_vp8_vpu_work_buf - vp8 encoder buffer index
- */
-enum venc_vp8_vpu_work_buf {
- VENC_VP8_VPU_WORK_BUF_LUMA,
- VENC_VP8_VPU_WORK_BUF_LUMA2,
- VENC_VP8_VPU_WORK_BUF_LUMA3,
- VENC_VP8_VPU_WORK_BUF_CHROMA,
- VENC_VP8_VPU_WORK_BUF_CHROMA2,
- VENC_VP8_VPU_WORK_BUF_CHROMA3,
- VENC_VP8_VPU_WORK_BUF_MV_INFO,
- VENC_VP8_VPU_WORK_BUF_BS_HEADER,
- VENC_VP8_VPU_WORK_BUF_PROB_BUF,
- VENC_VP8_VPU_WORK_BUF_RC_INFO,
- VENC_VP8_VPU_WORK_BUF_RC_CODE,
- VENC_VP8_VPU_WORK_BUF_RC_CODE2,
- VENC_VP8_VPU_WORK_BUF_RC_CODE3,
- VENC_VP8_VPU_WORK_BUF_MAX,
-};
-
-/*
- * struct venc_vp8_vpu_config - Structure for vp8 encoder configuration
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @input_fourcc: input fourcc
- * @bitrate: target bitrate (in bps)
- * @pic_w: picture width. Picture size is visible stream resolution, in pixels,
- * to be used for display purposes; must be smaller or equal to buffer
- * size.
- * @pic_h: picture height
- * @buf_w: buffer width (with 16 alignment). Buffer size is stream resolution
- * in pixels aligned to hardware requirements.
- * @buf_h: buffer height (with 16 alignment)
- * @gop_size: group of picture size (key frame)
- * @framerate: frame rate in fps
- * @ts_mode: temporal scalability mode (0: disable, 1: enable)
- * support three temporal layers - 0: 7.5fps 1: 7.5fps 2: 15fps.
- */
-struct venc_vp8_vpu_config {
- u32 input_fourcc;
- u32 bitrate;
- u32 pic_w;
- u32 pic_h;
- u32 buf_w;
- u32 buf_h;
- u32 gop_size;
- u32 framerate;
- u32 ts_mode;
-};
-
-/*
- * struct venc_vp8_vpu_buf - Structure for buffer information
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * @iova: IO virtual address
- * @vpua: VPU side memory addr which is used by RC_CODE
- * @size: buffer size (in bytes)
- */
-struct venc_vp8_vpu_buf {
- u32 iova;
- u32 vpua;
- u32 size;
-};
-
-/*
- * struct venc_vp8_vsi - Structure for VPU driver control and info share
- * AP-W/R : AP is writer/reader on this item
- * VPU-W/R: VPU is write/reader on this item
- * This structure is allocated in VPU side and shared to AP side.
- * @config: vp8 encoder configuration
- * @work_bufs: working buffer information in VPU side
- * The work_bufs here is for storing the 'size' info shared to AP side.
- * The similar item in struct venc_vp8_inst is for memory allocation
- * in AP side. The AP driver will copy the 'size' from here to the one in
- * struct mtk_vcodec_mem, then invoke mtk_vcodec_mem_alloc to allocate
- * the buffer. After that, bypass the 'dma_addr' to the 'iova' field here for
- * register setting in VPU side.
- */
-struct venc_vp8_vsi {
- struct venc_vp8_vpu_config config;
- struct venc_vp8_vpu_buf work_bufs[VENC_VP8_VPU_WORK_BUF_MAX];
-};
-
-/*
- * struct venc_vp8_inst - vp8 encoder AP driver instance
- * @hw_base: vp8 encoder hardware register base
- * @work_bufs: working buffer
- * @work_buf_allocated: working buffer allocated flag
- * @frm_cnt: encoded frame count, it's used for I-frame judgement and
- * reset when force intra cmd received.
- * @ts_mode: temporal scalability mode (0: disable, 1: enable)
- * support three temporal layers - 0: 7.5fps 1: 7.5fps 2: 15fps.
- * @vpu_inst: VPU instance to exchange information between AP and VPU
- * @vsi: driver structure allocated by VPU side and shared to AP side for
- * control and info share
- * @ctx: context for v4l2 layer integration
- */
-struct venc_vp8_inst {
- void __iomem *hw_base;
- struct mtk_vcodec_mem work_bufs[VENC_VP8_VPU_WORK_BUF_MAX];
- bool work_buf_allocated;
- unsigned int frm_cnt;
- unsigned int ts_mode;
- struct venc_vpu_inst vpu_inst;
- struct venc_vp8_vsi *vsi;
- struct mtk_vcodec_ctx *ctx;
-};
-
-static inline u32 vp8_enc_read_reg(struct venc_vp8_inst *inst, u32 addr)
-{
- return readl(inst->hw_base + addr);
-}
-
-static void vp8_enc_free_work_buf(struct venc_vp8_inst *inst)
-{
- int i;
-
- mtk_vcodec_debug_enter(inst);
-
- /* Buffers need to be freed by AP. */
- for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
- if (inst->work_bufs[i].size == 0)
- continue;
- mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
- }
-
- mtk_vcodec_debug_leave(inst);
-}
-
-static int vp8_enc_alloc_work_buf(struct venc_vp8_inst *inst)
-{
- int i;
- int ret = 0;
- struct venc_vp8_vpu_buf *wb = inst->vsi->work_bufs;
-
- mtk_vcodec_debug_enter(inst);
-
- for (i = 0; i < VENC_VP8_VPU_WORK_BUF_MAX; i++) {
- if (wb[i].size == 0)
- continue;
- /*
- * This 'wb' structure is set by VPU side and shared to AP for
- * buffer allocation and IO virtual addr mapping. For most of
- * the buffers, AP will allocate the buffer according to 'size'
- * field and store the IO virtual addr in 'iova' field. For the
- * RC_CODEx buffers, they are pre-allocated in the VPU side
- * because they are inside VPU SRAM, and save the VPU addr in
- * the 'vpua' field. The AP will translate the VPU addr to the
- * corresponding IO virtual addr and store in 'iova' field.
- */
- inst->work_bufs[i].size = wb[i].size;
- ret = mtk_vcodec_mem_alloc(inst->ctx, &inst->work_bufs[i]);
- if (ret) {
- mtk_vcodec_err(inst,
- "cannot alloc work_bufs[%d]", i);
- goto err_alloc;
- }
- /*
- * This RC_CODEx is pre-allocated by VPU and saved in VPU addr.
- * So we need use memcpy to copy RC_CODEx from VPU addr into IO
- * virtual addr in 'iova' field for reg setting in VPU side.
- */
- if (i == VENC_VP8_VPU_WORK_BUF_RC_CODE ||
- i == VENC_VP8_VPU_WORK_BUF_RC_CODE2 ||
- i == VENC_VP8_VPU_WORK_BUF_RC_CODE3) {
- struct mtk_vcodec_fw *handler;
- void *tmp_va;
-
- handler = inst->vpu_inst.ctx->dev->fw_handler;
- tmp_va = mtk_vcodec_fw_map_dm_addr(handler,
- wb[i].vpua);
- memcpy(inst->work_bufs[i].va, tmp_va, wb[i].size);
- }
- wb[i].iova = inst->work_bufs[i].dma_addr;
-
- mtk_vcodec_debug(inst,
- "work_bufs[%d] va=0x%p,iova=%pad,size=%zu",
- i, inst->work_bufs[i].va,
- &inst->work_bufs[i].dma_addr,
- inst->work_bufs[i].size);
- }
-
- mtk_vcodec_debug_leave(inst);
-
- return ret;
-
-err_alloc:
- vp8_enc_free_work_buf(inst);
-
- return ret;
-}
-
-static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
-{
- unsigned int irq_status = 0;
- struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
-
- if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
- WAIT_INTR_TIMEOUT_MS, 0)) {
- irq_status = ctx->irq_status;
- mtk_vcodec_debug(inst, "isr return %x", irq_status);
- }
- return irq_status;
-}
-
-/*
- * Compose ac_tag, bitstream header and bitstream payload into
- * one bitstream buffer.
- */
-static int vp8_enc_compose_one_frame(struct venc_vp8_inst *inst,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- unsigned int not_key;
- u32 bs_frm_size;
- u32 bs_hdr_len;
- unsigned int ac_tag_size;
- u8 ac_tag[MAX_AC_TAG_SIZE];
- u32 tag;
-
- bs_frm_size = vp8_enc_read_reg(inst, VENC_BITSTREAM_FRAME_SIZE);
- bs_hdr_len = vp8_enc_read_reg(inst, VENC_BITSTREAM_HEADER_LEN);
-
- /* if a frame is key frame, not_key is 0 */
- not_key = !inst->vpu_inst.is_key_frm;
- tag = (bs_hdr_len << 5) | 0x10 | not_key;
- ac_tag[0] = tag & 0xff;
- ac_tag[1] = (tag >> 8) & 0xff;
- ac_tag[2] = (tag >> 16) & 0xff;
-
- /* key frame */
- if (not_key == 0) {
- ac_tag_size = MAX_AC_TAG_SIZE;
- ac_tag[3] = 0x9d;
- ac_tag[4] = 0x01;
- ac_tag[5] = 0x2a;
- ac_tag[6] = inst->vsi->config.pic_w;
- ac_tag[7] = inst->vsi->config.pic_w >> 8;
- ac_tag[8] = inst->vsi->config.pic_h;
- ac_tag[9] = inst->vsi->config.pic_h >> 8;
- } else {
- ac_tag_size = 3;
- }
-
- if (bs_buf->size < bs_hdr_len + bs_frm_size + ac_tag_size) {
- mtk_vcodec_err(inst, "bitstream buf size is too small(%zu)",
- bs_buf->size);
- return -EINVAL;
- }
-
- /*
- * (1) The vp8 bitstream header and body are generated by the HW vp8
- * encoder separately at the same time. We cannot know the bitstream
- * header length in advance.
- * (2) From the vp8 spec, there is no stuffing byte allowed between the
- * ac tag, bitstream header and bitstream body.
- */
- memmove(bs_buf->va + bs_hdr_len + ac_tag_size,
- bs_buf->va, bs_frm_size);
- memcpy(bs_buf->va + ac_tag_size,
- inst->work_bufs[VENC_VP8_VPU_WORK_BUF_BS_HEADER].va,
- bs_hdr_len);
- memcpy(bs_buf->va, ac_tag, ac_tag_size);
- *bs_size = bs_frm_size + bs_hdr_len + ac_tag_size;
-
- return 0;
-}
-
-static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- unsigned int *bs_size)
-{
- int ret = 0;
- unsigned int irq_status;
-
- mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
-
- ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, NULL);
- if (ret)
- return ret;
-
- irq_status = vp8_enc_wait_venc_done(inst);
- if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
- mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
- return -EIO;
- }
-
- if (vp8_enc_compose_one_frame(inst, bs_buf, bs_size)) {
- mtk_vcodec_err(inst, "vp8_enc_compose_one_frame failed");
- return -EINVAL;
- }
-
- inst->frm_cnt++;
- mtk_vcodec_debug(inst, "<-size=%d key_frm=%d", *bs_size,
- inst->vpu_inst.is_key_frm);
-
- return ret;
-}
-
-static int vp8_enc_init(struct mtk_vcodec_ctx *ctx)
-{
- int ret = 0;
- struct venc_vp8_inst *inst;
-
- inst = kzalloc(sizeof(*inst), GFP_KERNEL);
- if (!inst)
- return -ENOMEM;
-
- inst->ctx = ctx;
- inst->vpu_inst.ctx = ctx;
- inst->vpu_inst.id = IPI_VENC_VP8;
- inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_LT_SYS);
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_init(&inst->vpu_inst);
-
- inst->vsi = (struct venc_vp8_vsi *)inst->vpu_inst.vsi;
-
- mtk_vcodec_debug_leave(inst);
-
- if (ret)
- kfree(inst);
- else
- ctx->drv_handle = inst;
-
- return ret;
-}
-
-static int vp8_enc_encode(void *handle,
- enum venc_start_opt opt,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_done_result *result)
-{
- int ret = 0;
- struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
- struct mtk_vcodec_ctx *ctx = inst->ctx;
-
- mtk_vcodec_debug_enter(inst);
-
- enable_irq(ctx->dev->enc_irq);
-
- switch (opt) {
- case VENC_START_OPT_ENCODE_FRAME:
- ret = vp8_enc_encode_frame(inst, frm_buf, bs_buf,
- &result->bs_size);
- if (ret)
- goto encode_err;
- result->is_key_frm = inst->vpu_inst.is_key_frm;
- break;
-
- default:
- mtk_vcodec_err(inst, "opt not support:%d", opt);
- ret = -EINVAL;
- break;
- }
-
-encode_err:
-
- disable_irq(ctx->dev->enc_irq);
- mtk_vcodec_debug_leave(inst);
-
- return ret;
-}
-
-static int vp8_enc_set_param(void *handle,
- enum venc_set_param_type type,
- struct venc_enc_param *enc_prm)
-{
- int ret = 0;
- struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
-
- mtk_vcodec_debug(inst, "->type=%d", type);
-
- switch (type) {
- case VENC_SET_PARAM_ENC:
- inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
- inst->vsi->config.bitrate = enc_prm->bitrate;
- inst->vsi->config.pic_w = enc_prm->width;
- inst->vsi->config.pic_h = enc_prm->height;
- inst->vsi->config.buf_w = enc_prm->buf_width;
- inst->vsi->config.buf_h = enc_prm->buf_height;
- inst->vsi->config.gop_size = enc_prm->gop_size;
- inst->vsi->config.framerate = enc_prm->frm_rate;
- inst->vsi->config.ts_mode = inst->ts_mode;
- ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
- if (ret)
- break;
- if (inst->work_buf_allocated) {
- vp8_enc_free_work_buf(inst);
- inst->work_buf_allocated = false;
- }
- ret = vp8_enc_alloc_work_buf(inst);
- if (ret)
- break;
- inst->work_buf_allocated = true;
- break;
-
- /*
- * VENC_SET_PARAM_TS_MODE must be called before VENC_SET_PARAM_ENC
- */
- case VENC_SET_PARAM_TS_MODE:
- inst->ts_mode = 1;
- mtk_vcodec_debug(inst, "set ts_mode");
- break;
-
- default:
- ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
- break;
- }
-
- mtk_vcodec_debug_leave(inst);
-
- return ret;
-}
-
-static int vp8_enc_deinit(void *handle)
-{
- int ret = 0;
- struct venc_vp8_inst *inst = (struct venc_vp8_inst *)handle;
-
- mtk_vcodec_debug_enter(inst);
-
- ret = vpu_enc_deinit(&inst->vpu_inst);
-
- if (inst->work_buf_allocated)
- vp8_enc_free_work_buf(inst);
-
- mtk_vcodec_debug_leave(inst);
- kfree(inst);
-
- return ret;
-}
-
-const struct venc_common_if venc_vp8_if = {
- .init = vp8_enc_init,
- .encode = vp8_enc_encode,
- .set_param = vp8_enc_set_param,
- .deinit = vp8_enc_deinit,
-};
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_base.h b/drivers/media/platform/mtk-vcodec/venc_drv_base.h
deleted file mode 100644
index 3d718411dc73..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_drv_base.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
- * Jungchang Tsao <jungchang.tsao@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _VENC_DRV_BASE_
-#define _VENC_DRV_BASE_
-
-#include "mtk_vcodec_drv.h"
-
-#include "venc_drv_if.h"
-
-struct venc_common_if {
- /**
- * (*init)() - initialize driver
- * @ctx: [in] mtk v4l2 context
- * @handle: [out] driver handle
- */
- int (*init)(struct mtk_vcodec_ctx *ctx);
-
- /**
- * (*encode)() - trigger encode
- * @handle: [in] driver handle
- * @opt: [in] encode option
- * @frm_buf: [in] frame buffer to store input frame
- * @bs_buf: [in] bitstream buffer to store output bitstream
- * @result: [out] encode result
- */
- int (*encode)(void *handle, enum venc_start_opt opt,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_done_result *result);
-
- /**
- * (*set_param)() - set driver's parameter
- * @handle: [in] driver handle
- * @type: [in] parameter type
- * @in: [in] buffer to store the parameter
- */
- int (*set_param)(void *handle, enum venc_set_param_type type,
- struct venc_enc_param *in);
-
- /**
- * (*deinit)() - deinitialize driver.
- * @handle: [in] driver handle
- */
- int (*deinit)(void *handle);
-};
-
-#endif
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
deleted file mode 100644
index ce0bce811615..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
- * Jungchang Tsao <jungchang.tsao@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "venc_drv_base.h"
-#include "venc_drv_if.h"
-
-#include "mtk_vcodec_enc.h"
-#include "mtk_vcodec_enc_pm.h"
-
-int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
-{
- int ret = 0;
-
- switch (fourcc) {
- case V4L2_PIX_FMT_VP8:
- ctx->enc_if = &venc_vp8_if;
- break;
- case V4L2_PIX_FMT_H264:
- ctx->enc_if = &venc_h264_if;
- break;
- default:
- return -EINVAL;
- }
-
- mtk_venc_lock(ctx);
- mtk_vcodec_enc_clock_on(&ctx->dev->pm);
- ret = ctx->enc_if->init(ctx);
- mtk_vcodec_enc_clock_off(&ctx->dev->pm);
- mtk_venc_unlock(ctx);
-
- return ret;
-}
-
-int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
- enum venc_set_param_type type, struct venc_enc_param *in)
-{
- int ret = 0;
-
- mtk_venc_lock(ctx);
- mtk_vcodec_enc_clock_on(&ctx->dev->pm);
- ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
- mtk_vcodec_enc_clock_off(&ctx->dev->pm);
- mtk_venc_unlock(ctx);
-
- return ret;
-}
-
-int venc_if_encode(struct mtk_vcodec_ctx *ctx,
- enum venc_start_opt opt, struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_done_result *result)
-{
- int ret = 0;
- unsigned long flags;
-
- mtk_venc_lock(ctx);
-
- spin_lock_irqsave(&ctx->dev->irqlock, flags);
- ctx->dev->curr_ctx = ctx;
- spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
-
- mtk_vcodec_enc_clock_on(&ctx->dev->pm);
- ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
- bs_buf, result);
- mtk_vcodec_enc_clock_off(&ctx->dev->pm);
-
- spin_lock_irqsave(&ctx->dev->irqlock, flags);
- ctx->dev->curr_ctx = NULL;
- spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
-
- mtk_venc_unlock(ctx);
- return ret;
-}
-
-int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
-{
- int ret = 0;
-
- if (!ctx->drv_handle)
- return 0;
-
- mtk_venc_lock(ctx);
- mtk_vcodec_enc_clock_on(&ctx->dev->pm);
- ret = ctx->enc_if->deinit(ctx->drv_handle);
- mtk_vcodec_enc_clock_off(&ctx->dev->pm);
- mtk_venc_unlock(ctx);
-
- ctx->drv_handle = NULL;
-
- return ret;
-}
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
deleted file mode 100644
index 0b04a1020873..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Daniel Hsiao <daniel.hsiao@mediatek.com>
- * Jungchang Tsao <jungchang.tsao@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _VENC_DRV_IF_H_
-#define _VENC_DRV_IF_H_
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_util.h"
-
-/*
- * enum venc_yuv_fmt - The type of input yuv format
- * (VPU related: If you change the order, you must also update the VPU codes.)
- * @VENC_YUV_FORMAT_I420: I420 YUV format
- * @VENC_YUV_FORMAT_YV12: YV12 YUV format
- * @VENC_YUV_FORMAT_NV12: NV12 YUV format
- * @VENC_YUV_FORMAT_NV21: NV21 YUV format
- */
-enum venc_yuv_fmt {
- VENC_YUV_FORMAT_I420 = 3,
- VENC_YUV_FORMAT_YV12 = 5,
- VENC_YUV_FORMAT_NV12 = 6,
- VENC_YUV_FORMAT_NV21 = 7,
-};
-
-/*
- * enum venc_start_opt - encode frame option used in venc_if_encode()
- * @VENC_START_OPT_ENCODE_SEQUENCE_HEADER: encode SPS/PPS for H264
- * @VENC_START_OPT_ENCODE_FRAME: encode normal frame
- */
-enum venc_start_opt {
- VENC_START_OPT_ENCODE_SEQUENCE_HEADER,
- VENC_START_OPT_ENCODE_FRAME,
-};
-
-/*
- * enum venc_set_param_type - The type of set parameter used in
- * venc_if_set_param()
- * (VPU related: If you change the order, you must also update the VPU codes.)
- * @VENC_SET_PARAM_ENC: set encoder parameters
- * @VENC_SET_PARAM_FORCE_INTRA: force an intra frame
- * @VENC_SET_PARAM_ADJUST_BITRATE: adjust bitrate (in bps)
- * @VENC_SET_PARAM_ADJUST_FRAMERATE: set frame rate
- * @VENC_SET_PARAM_GOP_SIZE: set IDR interval
- * @VENC_SET_PARAM_INTRA_PERIOD: set I frame interval
- * @VENC_SET_PARAM_SKIP_FRAME: set H264 skip one frame
- * @VENC_SET_PARAM_PREPEND_HEADER: set H264 prepend SPS/PPS before IDR
- * @VENC_SET_PARAM_TS_MODE: set VP8 temporal scalability mode
- */
-enum venc_set_param_type {
- VENC_SET_PARAM_ENC,
- VENC_SET_PARAM_FORCE_INTRA,
- VENC_SET_PARAM_ADJUST_BITRATE,
- VENC_SET_PARAM_ADJUST_FRAMERATE,
- VENC_SET_PARAM_GOP_SIZE,
- VENC_SET_PARAM_INTRA_PERIOD,
- VENC_SET_PARAM_SKIP_FRAME,
- VENC_SET_PARAM_PREPEND_HEADER,
- VENC_SET_PARAM_TS_MODE,
-};
-
-/*
- * struct venc_enc_prm - encoder settings for VENC_SET_PARAM_ENC used in
- * venc_if_set_param()
- * @input_fourcc: input yuv format
- * @h264_profile: V4L2 defined H.264 profile
- * @h264_level: V4L2 defined H.264 level
- * @width: image width
- * @height: image height
- * @buf_width: buffer width
- * @buf_height: buffer height
- * @frm_rate: frame rate in fps
- * @intra_period: intra frame period
- * @bitrate: target bitrate in bps
- * @gop_size: group of picture size
- */
-struct venc_enc_param {
- enum venc_yuv_fmt input_yuv_fmt;
- unsigned int h264_profile;
- unsigned int h264_level;
- unsigned int width;
- unsigned int height;
- unsigned int buf_width;
- unsigned int buf_height;
- unsigned int frm_rate;
- unsigned int intra_period;
- unsigned int bitrate;
- unsigned int gop_size;
-};
-
-/**
- * struct venc_frame_info - per-frame information to pass to the firmware.
- *
- * @frm_count: sequential number for this frame
- * @skip_frm_count: number of frames skipped so far while decoding
- * @frm_type: type of the frame, from enum venc_h264_frame_type
- */
-struct venc_frame_info {
- unsigned int frm_count; /* per frame update */
- unsigned int skip_frm_count; /* per frame update */
- unsigned int frm_type; /* per frame update */
-};
-
-/*
- * struct venc_frm_buf - frame buffer information used in venc_if_encode()
- * @fb_addr: plane frame buffer addresses
- */
-struct venc_frm_buf {
- struct mtk_vcodec_fb fb_addr[MTK_VCODEC_MAX_PLANES];
-};
-
-/*
- * struct venc_done_result - This is return information used in venc_if_encode()
- * @bs_size: output bitstream size
- * @is_key_frm: output is key frame or not
- */
-struct venc_done_result {
- unsigned int bs_size;
- bool is_key_frm;
-};
-
-extern const struct venc_common_if venc_h264_if;
-extern const struct venc_common_if venc_vp8_if;
-
-/*
- * venc_if_init - Create the driver handle
- * @ctx: device context
- * @fourcc: encoder input format
- * Return: 0 if creating handle successfully, otherwise it is failed.
- */
-int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc);
-
-/*
- * venc_if_deinit - Release the driver handle
- * @ctx: device context
- * Return: 0 if releasing handle successfully, otherwise it is failed.
- */
-int venc_if_deinit(struct mtk_vcodec_ctx *ctx);
-
-/*
- * venc_if_set_param - Set parameter to driver
- * @ctx: device context
- * @type: parameter type
- * @in: input parameter
- * Return: 0 if setting param successfully, otherwise it is failed.
- */
-int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
- enum venc_set_param_type type,
- struct venc_enc_param *in);
-
-/*
- * venc_if_encode - Encode one frame
- * @ctx: device context
- * @opt: encode frame option
- * @frm_buf: input frame buffer information
- * @bs_buf: output bitstream buffer infomraiton
- * @result: encode result
- * Return: 0 if encoding frame successfully, otherwise it is failed.
- */
-int venc_if_encode(struct mtk_vcodec_ctx *ctx,
- enum venc_start_opt opt,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_done_result *result);
-
-#endif /* _VENC_DRV_IF_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h b/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h
deleted file mode 100644
index 587a2cf15b76..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_ipi_msg.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: Jungchang Tsao <jungchang.tsao@mediatek.com>
- * Daniel Hsiao <daniel.hsiao@mediatek.com>
- * Tiffany Lin <tiffany.lin@mediatek.com>
- */
-
-#ifndef _VENC_IPI_MSG_H_
-#define _VENC_IPI_MSG_H_
-
-#define AP_IPIMSG_VENC_BASE 0xC000
-#define VPU_IPIMSG_VENC_BASE 0xD000
-
-/*
- * enum venc_ipi_msg_id - message id between AP and VPU
- * (ipi stands for inter-processor interrupt)
- * @AP_IPIMSG_ENC_XXX: AP to VPU cmd message id
- * @VPU_IPIMSG_ENC_XXX_DONE: VPU ack AP cmd message id
- */
-enum venc_ipi_msg_id {
- AP_IPIMSG_ENC_INIT = AP_IPIMSG_VENC_BASE,
- AP_IPIMSG_ENC_SET_PARAM,
- AP_IPIMSG_ENC_ENCODE,
- AP_IPIMSG_ENC_DEINIT,
-
- VPU_IPIMSG_ENC_INIT_DONE = VPU_IPIMSG_VENC_BASE,
- VPU_IPIMSG_ENC_SET_PARAM_DONE,
- VPU_IPIMSG_ENC_ENCODE_DONE,
- VPU_IPIMSG_ENC_DEINIT_DONE,
-};
-
-/**
- * struct venc_ap_ipi_msg_init - AP to VPU init cmd structure
- * @msg_id: message id (AP_IPIMSG_XXX_ENC_INIT)
- * @reserved: reserved for future use. vpu is running in 32bit. Without
- * this reserved field, if kernel run in 64bit. this struct size
- * will be different between kernel and vpu
- * @venc_inst: AP encoder instance
- * (struct venc_vp8_inst/venc_h264_inst *)
- */
-struct venc_ap_ipi_msg_init {
- uint32_t msg_id;
- uint32_t reserved;
- uint64_t venc_inst;
-};
-
-/**
- * struct venc_ap_ipi_msg_set_param - AP to VPU set_param cmd structure
- * @msg_id: message id (AP_IPIMSG_XXX_ENC_SET_PARAM)
- * @vpu_inst_addr: VPU encoder instance addr
- * (struct venc_vp8_vsi/venc_h264_vsi *)
- * @param_id: parameter id (venc_set_param_type)
- * @data_item: number of items in the data array
- * @data: data array to store the set parameters
- */
-struct venc_ap_ipi_msg_set_param {
- uint32_t msg_id;
- uint32_t vpu_inst_addr;
- uint32_t param_id;
- uint32_t data_item;
- uint32_t data[8];
-};
-
-struct venc_ap_ipi_msg_set_param_ext {
- struct venc_ap_ipi_msg_set_param base;
- uint32_t data_ext[24];
-};
-
-/**
- * struct venc_ap_ipi_msg_enc - AP to VPU enc cmd structure
- * @msg_id: message id (AP_IPIMSG_XXX_ENC_ENCODE)
- * @vpu_inst_addr: VPU encoder instance addr
- * (struct venc_vp8_vsi/venc_h264_vsi *)
- * @bs_mode: bitstream mode for h264
- * (H264_BS_MODE_SPS/H264_BS_MODE_PPS/H264_BS_MODE_FRAME)
- * @input_addr: pointer to input image buffer plane
- * @bs_addr: pointer to output bit stream buffer
- * @bs_size: bit stream buffer size
- */
-struct venc_ap_ipi_msg_enc {
- uint32_t msg_id;
- uint32_t vpu_inst_addr;
- uint32_t bs_mode;
- uint32_t input_addr[3];
- uint32_t bs_addr;
- uint32_t bs_size;
-};
-
-/**
- * struct venc_ap_ipi_msg_enc_ext - AP to SCP extended enc cmd structure
- *
- * @base: base msg structure
- * @data_item: number of items in the data array
- * @data: data array to store the set parameters
- */
-struct venc_ap_ipi_msg_enc_ext {
- struct venc_ap_ipi_msg_enc base;
- uint32_t data_item;
- uint32_t data[32];
-};
-
-/**
- * struct venc_ap_ipi_msg_deinit - AP to VPU deinit cmd structure
- * @msg_id: message id (AP_IPIMSG_XXX_ENC_DEINIT)
- * @vpu_inst_addr: VPU encoder instance addr
- * (struct venc_vp8_vsi/venc_h264_vsi *)
- */
-struct venc_ap_ipi_msg_deinit {
- uint32_t msg_id;
- uint32_t vpu_inst_addr;
-};
-
-/*
- * enum venc_ipi_msg_status - VPU ack AP cmd status
- */
-enum venc_ipi_msg_status {
- VENC_IPI_MSG_STATUS_OK,
- VENC_IPI_MSG_STATUS_FAIL,
-};
-
-/**
- * struct venc_vpu_ipi_msg_common - VPU ack AP cmd common structure
- * @msg_id: message id (VPU_IPIMSG_XXX_DONE)
- * @status: cmd status (venc_ipi_msg_status)
- * @venc_inst: AP encoder instance (struct venc_vp8_inst/venc_h264_inst *)
- */
-struct venc_vpu_ipi_msg_common {
- uint32_t msg_id;
- uint32_t status;
- uint64_t venc_inst;
-};
-
-/**
- * struct venc_vpu_ipi_msg_init - VPU ack AP init cmd structure
- * @msg_id: message id (VPU_IPIMSG_XXX_ENC_SET_PARAM_DONE)
- * @status: cmd status (venc_ipi_msg_status)
- * @venc_inst: AP encoder instance (struct venc_vp8_inst/venc_h264_inst *)
- * @vpu_inst_addr: VPU encoder instance addr
- * (struct venc_vp8_vsi/venc_h264_vsi *)
- * @venc_abi_version: ABI version of the firmware. Kernel can use it to
- * ensure that it is compatible with the firmware.
- * For MT8173 the value of this field is undefined and
- * should not be used.
- */
-struct venc_vpu_ipi_msg_init {
- uint32_t msg_id;
- uint32_t status;
- uint64_t venc_inst;
- uint32_t vpu_inst_addr;
- uint32_t venc_abi_version;
-};
-
-/**
- * struct venc_vpu_ipi_msg_set_param - VPU ack AP set_param cmd structure
- * @msg_id: message id (VPU_IPIMSG_XXX_ENC_SET_PARAM_DONE)
- * @status: cmd status (venc_ipi_msg_status)
- * @venc_inst: AP encoder instance (struct venc_vp8_inst/venc_h264_inst *)
- * @param_id: parameter id (venc_set_param_type)
- * @data_item: number of items in the data array
- * @data: data array to store the return result
- */
-struct venc_vpu_ipi_msg_set_param {
- uint32_t msg_id;
- uint32_t status;
- uint64_t venc_inst;
- uint32_t param_id;
- uint32_t data_item;
- uint32_t data[6];
-};
-
-/**
- * enum venc_ipi_msg_enc_state - Type of encode state
- * @VEN_IPI_MSG_ENC_STATE_FRAME: one frame being encoded
- * @VEN_IPI_MSG_ENC_STATE_PART: bit stream buffer full
- * @VEN_IPI_MSG_ENC_STATE_SKIP: encoded skip frame
- * @VEN_IPI_MSG_ENC_STATE_ERROR: encounter error
- */
-enum venc_ipi_msg_enc_state {
- VEN_IPI_MSG_ENC_STATE_FRAME,
- VEN_IPI_MSG_ENC_STATE_PART,
- VEN_IPI_MSG_ENC_STATE_SKIP,
- VEN_IPI_MSG_ENC_STATE_ERROR,
-};
-
-/**
- * struct venc_vpu_ipi_msg_enc - VPU ack AP enc cmd structure
- * @msg_id: message id (VPU_IPIMSG_XXX_ENC_ENCODE_DONE)
- * @status: cmd status (venc_ipi_msg_status)
- * @venc_inst: AP encoder instance (struct venc_vp8_inst/venc_h264_inst *)
- * @state: encode state (venc_ipi_msg_enc_state)
- * @is_key_frm: whether the encoded frame is key frame
- * @bs_size: encoded bitstream size
- * @reserved: reserved for future use. vpu is running in 32bit. Without
- * this reserved field, if kernel run in 64bit. this struct size
- * will be different between kernel and vpu
- */
-struct venc_vpu_ipi_msg_enc {
- uint32_t msg_id;
- uint32_t status;
- uint64_t venc_inst;
- uint32_t state;
- uint32_t is_key_frm;
- uint32_t bs_size;
- uint32_t reserved;
-};
-
-/**
- * struct venc_vpu_ipi_msg_deinit - VPU ack AP deinit cmd structure
- * @msg_id: message id (VPU_IPIMSG_XXX_ENC_DEINIT_DONE)
- * @status: cmd status (venc_ipi_msg_status)
- * @venc_inst: AP encoder instance (struct venc_vp8_inst/venc_h264_inst *)
- */
-struct venc_vpu_ipi_msg_deinit {
- uint32_t msg_id;
- uint32_t status;
- uint64_t venc_inst;
-};
-
-#endif /* _VENC_IPI_MSG_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
deleted file mode 100644
index e7899d8a3e4e..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ /dev/null
@@ -1,293 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PoChun Lin <pochun.lin@mediatek.com>
- */
-
-#include "mtk_vcodec_drv.h"
-#include "mtk_vcodec_fw.h"
-#include "venc_ipi_msg.h"
-#include "venc_vpu_if.h"
-
-static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
-{
- const struct venc_vpu_ipi_msg_init *msg = data;
-
- vpu->inst_addr = msg->vpu_inst_addr;
- vpu->vsi = mtk_vcodec_fw_map_dm_addr(vpu->ctx->dev->fw_handler,
- msg->vpu_inst_addr);
-
- /* Firmware version field value is unspecified on MT8173. */
- if (vpu->ctx->dev->venc_pdata->chip == MTK_MT8173)
- return;
-
- /* Check firmware version. */
- mtk_vcodec_debug(vpu, "firmware version: 0x%x\n",
- msg->venc_abi_version);
- switch (msg->venc_abi_version) {
- case 1:
- break;
- default:
- mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n",
- msg->venc_abi_version);
- vpu->failure = 1;
- break;
- }
-}
-
-static void handle_enc_encode_msg(struct venc_vpu_inst *vpu, const void *data)
-{
- const struct venc_vpu_ipi_msg_enc *msg = data;
-
- vpu->state = msg->state;
- vpu->bs_size = msg->bs_size;
- vpu->is_key_frm = msg->is_key_frm;
-}
-
-static void vpu_enc_ipi_handler(void *data, unsigned int len, void *priv)
-{
- const struct venc_vpu_ipi_msg_common *msg = data;
- struct venc_vpu_inst *vpu =
- (struct venc_vpu_inst *)(unsigned long)msg->venc_inst;
-
- mtk_vcodec_debug(vpu, "msg_id %x inst %p status %d",
- msg->msg_id, vpu, msg->status);
-
- vpu->signaled = 1;
- vpu->failure = (msg->status != VENC_IPI_MSG_STATUS_OK);
- if (vpu->failure)
- goto failure;
-
- switch (msg->msg_id) {
- case VPU_IPIMSG_ENC_INIT_DONE:
- handle_enc_init_msg(vpu, data);
- break;
- case VPU_IPIMSG_ENC_SET_PARAM_DONE:
- break;
- case VPU_IPIMSG_ENC_ENCODE_DONE:
- handle_enc_encode_msg(vpu, data);
- break;
- case VPU_IPIMSG_ENC_DEINIT_DONE:
- break;
- default:
- mtk_vcodec_err(vpu, "unknown msg id %x", msg->msg_id);
- break;
- }
-
-failure:
- mtk_vcodec_debug_leave(vpu);
-}
-
-static int vpu_enc_send_msg(struct venc_vpu_inst *vpu, void *msg,
- int len)
-{
- int status;
-
- mtk_vcodec_debug_enter(vpu);
-
- if (!vpu->ctx->dev->fw_handler) {
- mtk_vcodec_err(vpu, "inst dev is NULL");
- return -EINVAL;
- }
-
- status = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
- len, 2000);
- if (status) {
- mtk_vcodec_err(vpu, "vpu_ipi_send msg_id %x len %d fail %d",
- *(uint32_t *)msg, len, status);
- return -EINVAL;
- }
- if (vpu->failure)
- return -EINVAL;
-
- mtk_vcodec_debug_leave(vpu);
-
- return 0;
-}
-
-int vpu_enc_init(struct venc_vpu_inst *vpu)
-{
- int status;
- struct venc_ap_ipi_msg_init out;
-
- mtk_vcodec_debug_enter(vpu);
-
- init_waitqueue_head(&vpu->wq_hd);
- vpu->signaled = 0;
- vpu->failure = 0;
-
- status = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
- vpu_enc_ipi_handler, "venc", NULL);
-
- if (status) {
- mtk_vcodec_err(vpu, "vpu_ipi_register fail %d", status);
- return -EINVAL;
- }
-
- memset(&out, 0, sizeof(out));
- out.msg_id = AP_IPIMSG_ENC_INIT;
- out.venc_inst = (unsigned long)vpu;
- if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
- mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_INIT fail");
- return -EINVAL;
- }
-
- mtk_vcodec_debug_leave(vpu);
-
- return 0;
-}
-
-static unsigned int venc_enc_param_crop_right(struct venc_vpu_inst *vpu,
- struct venc_enc_param *enc_prm)
-{
- unsigned int img_crop_right = enc_prm->buf_width - enc_prm->width;
-
- return img_crop_right % 16;
-}
-
-static unsigned int venc_enc_param_crop_bottom(struct venc_enc_param *enc_prm)
-{
- return round_up(enc_prm->height, 16) - enc_prm->height;
-}
-
-static unsigned int venc_enc_param_num_mb(struct venc_enc_param *enc_prm)
-{
- return DIV_ROUND_UP(enc_prm->width, 16) *
- DIV_ROUND_UP(enc_prm->height, 16);
-}
-
-int vpu_enc_set_param(struct venc_vpu_inst *vpu,
- enum venc_set_param_type id,
- struct venc_enc_param *enc_param)
-{
- const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
- size_t msg_size = is_ext ?
- sizeof(struct venc_ap_ipi_msg_set_param_ext) :
- sizeof(struct venc_ap_ipi_msg_set_param);
- struct venc_ap_ipi_msg_set_param_ext out;
-
- mtk_vcodec_debug(vpu, "id %d ->", id);
-
- memset(&out, 0, sizeof(out));
- out.base.msg_id = AP_IPIMSG_ENC_SET_PARAM;
- out.base.vpu_inst_addr = vpu->inst_addr;
- out.base.param_id = id;
- switch (id) {
- case VENC_SET_PARAM_ENC:
- if (is_ext) {
- out.base.data_item = 3;
- out.base.data[0] =
- venc_enc_param_crop_right(vpu, enc_param);
- out.base.data[1] =
- venc_enc_param_crop_bottom(enc_param);
- out.base.data[2] = venc_enc_param_num_mb(enc_param);
- } else {
- out.base.data_item = 0;
- }
- break;
- case VENC_SET_PARAM_FORCE_INTRA:
- out.base.data_item = 0;
- break;
- case VENC_SET_PARAM_ADJUST_BITRATE:
- out.base.data_item = 1;
- out.base.data[0] = enc_param->bitrate;
- break;
- case VENC_SET_PARAM_ADJUST_FRAMERATE:
- out.base.data_item = 1;
- out.base.data[0] = enc_param->frm_rate;
- break;
- case VENC_SET_PARAM_GOP_SIZE:
- out.base.data_item = 1;
- out.base.data[0] = enc_param->gop_size;
- break;
- case VENC_SET_PARAM_INTRA_PERIOD:
- out.base.data_item = 1;
- out.base.data[0] = enc_param->intra_period;
- break;
- case VENC_SET_PARAM_SKIP_FRAME:
- out.base.data_item = 0;
- break;
- default:
- mtk_vcodec_err(vpu, "id %d not supported", id);
- return -EINVAL;
- }
- if (vpu_enc_send_msg(vpu, &out, msg_size)) {
- mtk_vcodec_err(vpu,
- "AP_IPIMSG_ENC_SET_PARAM %d fail", id);
- return -EINVAL;
- }
-
- mtk_vcodec_debug(vpu, "id %d <-", id);
-
- return 0;
-}
-
-int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_frame_info *frame_info)
-{
- const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
- size_t msg_size = is_ext ?
- sizeof(struct venc_ap_ipi_msg_enc_ext) :
- sizeof(struct venc_ap_ipi_msg_enc);
- struct venc_ap_ipi_msg_enc_ext out;
-
- mtk_vcodec_debug(vpu, "bs_mode %d ->", bs_mode);
-
- memset(&out, 0, sizeof(out));
- out.base.msg_id = AP_IPIMSG_ENC_ENCODE;
- out.base.vpu_inst_addr = vpu->inst_addr;
- out.base.bs_mode = bs_mode;
- if (frm_buf) {
- if ((frm_buf->fb_addr[0].dma_addr % 16 == 0) &&
- (frm_buf->fb_addr[1].dma_addr % 16 == 0) &&
- (frm_buf->fb_addr[2].dma_addr % 16 == 0)) {
- out.base.input_addr[0] = frm_buf->fb_addr[0].dma_addr;
- out.base.input_addr[1] = frm_buf->fb_addr[1].dma_addr;
- out.base.input_addr[2] = frm_buf->fb_addr[2].dma_addr;
- } else {
- mtk_vcodec_err(vpu, "dma_addr not align to 16");
- return -EINVAL;
- }
- }
- if (bs_buf) {
- out.base.bs_addr = bs_buf->dma_addr;
- out.base.bs_size = bs_buf->size;
- }
- if (is_ext && frame_info) {
- out.data_item = 3;
- out.data[0] = frame_info->frm_count;
- out.data[1] = frame_info->skip_frm_count;
- out.data[2] = frame_info->frm_type;
- }
- if (vpu_enc_send_msg(vpu, &out, msg_size)) {
- mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
- bs_mode);
- return -EINVAL;
- }
-
- mtk_vcodec_debug(vpu, "bs_mode %d state %d size %d key_frm %d <-",
- bs_mode, vpu->state, vpu->bs_size, vpu->is_key_frm);
-
- return 0;
-}
-
-int vpu_enc_deinit(struct venc_vpu_inst *vpu)
-{
- struct venc_ap_ipi_msg_deinit out;
-
- mtk_vcodec_debug_enter(vpu);
-
- memset(&out, 0, sizeof(out));
- out.msg_id = AP_IPIMSG_ENC_DEINIT;
- out.vpu_inst_addr = vpu->inst_addr;
- if (vpu_enc_send_msg(vpu, &out, sizeof(out))) {
- mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_DEINIT fail");
- return -EINVAL;
- }
-
- mtk_vcodec_debug_leave(vpu);
-
- return 0;
-}
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
deleted file mode 100644
index f83bc1b3f2bf..000000000000
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2016 MediaTek Inc.
- * Author: PoChun Lin <pochun.lin@mediatek.com>
- */
-
-#ifndef _VENC_VPU_IF_H_
-#define _VENC_VPU_IF_H_
-
-#include "mtk_vcodec_fw.h"
-#include "venc_drv_if.h"
-
-/*
- * struct venc_vpu_inst - encoder VPU driver instance
- * @wq_hd: wait queue used for vpu cmd trigger then wait vpu interrupt done
- * @signaled: flag used for checking vpu interrupt done
- * @failure: flag to show vpu cmd succeeds or not
- * @state: enum venc_ipi_msg_enc_state
- * @bs_size: bitstream size for skip frame case usage
- * @is_key_frm: key frame flag
- * @inst_addr: VPU instance addr
- * @vsi: driver structure allocated by VPU side and shared to AP side for
- * control and info share
- * @id: the id of inter-processor interrupt
- * @ctx: context for v4l2 layer integration
- * @dev: device for v4l2 layer integration
- */
-struct venc_vpu_inst {
- wait_queue_head_t wq_hd;
- int signaled;
- int failure;
- int state;
- int bs_size;
- int is_key_frm;
- unsigned int inst_addr;
- void *vsi;
- int id;
- struct mtk_vcodec_ctx *ctx;
-};
-
-int vpu_enc_init(struct venc_vpu_inst *vpu);
-int vpu_enc_set_param(struct venc_vpu_inst *vpu,
- enum venc_set_param_type id,
- struct venc_enc_param *param);
-int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
- struct venc_frm_buf *frm_buf,
- struct mtk_vcodec_mem *bs_buf,
- struct venc_frame_info *frame_info);
-int vpu_enc_deinit(struct venc_vpu_inst *vpu);
-
-#endif