From nobody Thu Oct 2 02:18:02 2025 Received: from mailout4.samsung.com (mailout4.samsung.com [203.254.224.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C3DA27FD49 for ; Tue, 30 Sep 2025 03:57:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.34 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759204624; cv=none; b=eLMwpxavunssSvQLsT3OwttluavZnt1xUHlUON2yNbnsskSQLw+oX6RyYbkSO0FvA5dl7CC4Y6iAS48rafSaTMLH+ThJndOYoReByEeTH8LyKgVH/cJiMuhdl/3LWfwJpyySizzW8KAk9+uxLaB347+92WEaVcXc0XGoS5ibNmI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759204624; c=relaxed/simple; bh=/J59iFRvwaBgA6PUGWRDu+OLlx8yfYvWCRctdokSgmQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=pORc3nCK9/9LBtSJV5bOpumdjYU2F7bePn8dijnQEWuzu5DWq+O/zBgGhfTFw+2KRy6mosQnTNTWA0HBejcMxTN9Gl/r6cXieGsiAHWRPuntZS6ckLRHUzgKJJjQOoP3+P7U6Nqa0zBCE1++ko8pC2DovZ93IAukQmVvMswQW7o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=GZn+rXXb; arc=none smtp.client-ip=203.254.224.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="GZn+rXXb" Received: from epcas5p3.samsung.com (unknown [182.195.41.41]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20250930035659epoutp0466ea931a1d5a0cd5dcad428089111280~p80fuIfD82087020870epoutp04M for ; Tue, 30 Sep 2025 03:56:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20250930035659epoutp0466ea931a1d5a0cd5dcad428089111280~p80fuIfD82087020870epoutp04M DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1759204619; bh=Opmcn1eBkxs4yvNdgaabKkETHQwug3qB+xi5yQ+tmfo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GZn+rXXbXo3Xqw0kLH4uZDwh9IeHlDm4ZlTocjQbwNkC7oK4WOAdmDxXti0/Vae6j kKCwtsBMAWKoLpw0turFqbOeY20dZEsyxqFHFEhtRAkzNEw71ZtlzJbv94Gsh9OowW ySkHl/WC2AKj9NNfVEjmfIcGsW/QAzzNJKqtLn9E= Received: from epsnrtp04.localdomain (unknown [182.195.42.156]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20250930035658epcas5p14da69819905bbbb3d9eea3c25b88f97a~p80fB-F5M1532615326epcas5p1p; Tue, 30 Sep 2025 03:56:58 +0000 (GMT) Received: from epcas5p3.samsung.com (unknown [182.195.38.87]) by epsnrtp04.localdomain (Postfix) with ESMTP id 4cbPQ203tZz6B9mF; Tue, 30 Sep 2025 03:56:58 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPA id 20250930035657epcas5p17d3e94c7c1ba5eeace97b0ff81053653~p80daA7Jw2306123061epcas5p1-; Tue, 30 Sep 2025 03:56:57 +0000 (GMT) Received: from bose.samsungds.net (unknown [107.108.83.9]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250930035654epsmtip159f5d79a4cd8ce016a4981d692a91c06~p80a56pxn2938429384epsmtip1P; Tue, 30 Sep 2025 03:56:54 +0000 (GMT) From: Himanshu Dewangan To: mchehab@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, sumit.semwal@linaro.org, christian.koenig@amd.com, alim.akhtar@samsung.com, manjun@samsung.com, nagaraju.s@samsung.com, ih0206.lee@samsung.com, jehyung.lee@samsung.com Cc: linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, Himanshu Dewangan Subject: [PATCH 24/29] media: mfc: Add encoder VB2 support to driver Date: Tue, 30 Sep 2025 09:33:43 +0530 Message-Id: <20250930040348.3702923-25-h.dewangan@samsung.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250930040348.3702923-1-h.dewangan@samsung.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20250930035657epcas5p17d3e94c7c1ba5eeace97b0ff81053653 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" CMS-TYPE: 105P cpgsPolicy: CPGSC10-542,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20250930035657epcas5p17d3e94c7c1ba5eeace97b0ff81053653 References: <20250930040348.3702923-1-h.dewangan@samsung.com> From: Nagaraju Siddineni Introduce encoder VB2 support. This enables proper V4L2 output for the Exynos MFC encoder, handling queue setup, buffers, and streaming control. Signed-off-by: Nagaraju Siddineni Signed-off-by: Himanshu Dewangan --- .../platform/samsung/exynos-mfc/Makefile | 2 +- .../platform/samsung/exynos-mfc/mfc_enc_vb2.c | 443 ++++++++++++++++++ .../platform/samsung/exynos-mfc/mfc_enc_vb2.h | 19 + 3 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.c create mode 100644 drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.h diff --git a/drivers/media/platform/samsung/exynos-mfc/Makefile b/drivers/m= edia/platform/samsung/exynos-mfc/Makefile index a257d5b0a576..dad94a7c468c 100644 --- a/drivers/media/platform/samsung/exynos-mfc/Makefile +++ b/drivers/media/platform/samsung/exynos-mfc/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_VIDEO_EXYNOS_MFC) :=3D exynos_mfc.o ccflags-y +=3D -I$(srctree)/$(src) =20 #Dev interface layer -exynos_mfc-y +=3D mfc.o mfc_dec_v4l2.o mfc_dec_vb2.o +exynos_mfc-y +=3D mfc.o mfc_dec_v4l2.o mfc_dec_vb2.o mfc_enc_vb2.o #Dev control layer exynos_mfc-y +=3D mfc_rm.o mfc_ctx_ctrl.o mfc_debugfs.o #Core interface layer diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.c b/driv= ers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.c new file mode 100644 index 000000000000..7164c334585b --- /dev/null +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.c @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * mfc_enc_vb2.c file + * + * Nagaraju Siddineni, + * Himanshu Dewangan, + */ + +#include "mfc_rm.h" + +#include "base/mfc_queue.h" +#include "base/mfc_utils.h" +#include "base/mfc_buf.h" +#include "base/mfc_mem.h" +#include "mfc_enc_vb2.h" + +static int mfc_enc_queue_setup(struct vb2_queue *vq, + unsigned int *buf_count, unsigned int *plane_count, + unsigned int psize[], struct device *alloc_devs[]) +{ + struct mfc_ctx *ctx =3D vq->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + struct mfc_enc *enc =3D ctx->enc_priv; + struct mfc_core *core; + struct mfc_core_ctx *core_ctx; + int i; + + mfc_ctx_debug_enter(); + + /* Encoder works only single core */ + core =3D mfc_get_main_core_lock(dev, ctx); + core_ctx =3D core->core_ctx[ctx->num]; + + if (core_ctx->state !=3D MFCINST_GOT_INST && + vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + mfc_err("invalid state: %d\n", core_ctx->state); + return -EINVAL; + } + if (core_ctx->state >=3D MFCINST_FINISHING && + vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + mfc_err("invalid state: %d\n", core_ctx->state); + return -EINVAL; + } + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + mfc_debug(4, "enc dst\n"); + if (ctx->dst_fmt) + *plane_count =3D ctx->dst_fmt->mem_planes; + else + *plane_count =3D MFC_ENC_CAP_PLANE_COUNT; + + if (*buf_count < 1) + *buf_count =3D 1; + if (*buf_count > MFC_MAX_BUFFERS) + *buf_count =3D MFC_MAX_BUFFERS; + + psize[0] =3D enc->dst_buf_size; + alloc_devs[0] =3D dev->device; + /* In case of VP8/VP9 encoder, part of stream buffer should be read */ + vq->dma_dir =3D DMA_BIDIRECTIONAL; + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + mfc_ctx_debug(4, "enc src\n"); + + if (ctx->src_fmt) + *plane_count =3D ctx->num_fd_frame; + else + *plane_count =3D MFC_ENC_OUT_PLANE_COUNT; + + if (*buf_count < 1) + *buf_count =3D 1; + if (*buf_count > MFC_MAX_BUFFERS) + *buf_count =3D MFC_MAX_BUFFERS; + + /* need to use minimum size to prevent qbuf fail */ + if (*plane_count =3D=3D 1) { + psize[0] =3D 1; + alloc_devs[0] =3D dev->device; + } else { + for (i =3D 0; i < *plane_count; i++) { + psize[i] =3D 1; + alloc_devs[i] =3D dev->device; + } + } + } else { + mfc_err("invalid queue type: %d\n", vq->type); + return -EINVAL; + } + + mfc_debug(2, "buf_count: %d, plane_count: %d, type: %#x\n", + *buf_count, *plane_count, vq->type); + for (i =3D 0; i < *plane_count; i++) + mfc_debug(2, "plane[%d] size: %d\n", i, psize[i]); + + mfc_ctx_debug_leave(); + + return 0; +} + +static void mfc_enc_unlock(struct vb2_queue *q) +{ + struct mfc_ctx *ctx =3D q->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + + mutex_unlock(&dev->mfc_mutex); +} + +static void mfc_enc_lock(struct vb2_queue *q) +{ + struct mfc_ctx *ctx =3D q->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + + mutex_lock(&dev->mfc_mutex); +} + +static int mfc_enc_buf_init(struct vb2_buffer *vb) +{ + struct vb2_queue *vq =3D vb->vb2_queue; + struct mfc_ctx *ctx =3D vq->drv_priv; + int ret; + + mfc_ctx_debug_enter(); + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret =3D mfc_check_vb_with_fmt(ctx->dst_fmt, vb); + if (ret < 0) + return ret; + + if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_DST, + vb->index) < 0) + mfc_ctx_err("failed in init_buf_ctrls\n"); + + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + ret =3D mfc_check_vb_with_fmt(ctx->src_fmt, vb); + if (ret < 0) + return ret; + + if (call_cop(ctx, init_buf_ctrls, ctx, MFC_CTRL_TYPE_SRC, + vb->index) < 0) + mfc_ctx_err("failed in init_buf_ctrls\n"); + } else { + mfc_ctx_err("invalid queue type: %d\n", vq->type); + return -EINVAL; + } + + mfc_ctx_debug_leave(); + + return 0; +} + +static int mfc_enc_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_queue *vq =3D vb->vb2_queue; + struct mfc_ctx *ctx =3D vq->drv_priv; + struct mfc_enc *enc =3D ctx->enc_priv; + struct mfc_raw_info *raw; + unsigned int index =3D vb->index; + struct mfc_buf *buf =3D vb_to_mfc_buf(vb); + struct dma_buf *bufcon_dmabuf[MFC_MAX_PLANES]; + int i, mem_get_count =3D 0; + size_t buf_size; + + mfc_ctx_debug_enter(); + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + buf_size =3D vb2_plane_size(vb, 0); + mfc_ctx_debug(2, "[STREAM] vb size: %lu, calc size: %u\n", + buf_size, enc->dst_buf_size); + + if (buf_size < enc->dst_buf_size) { + mfc_ctx_err("[STREAM] size(%lu) is smaller than (%d)\n", + buf_size, enc->dst_buf_size); + return -EINVAL; + } + + buf->addr[0][0] =3D mfc_mem_get_daddr_vb(vb, 0); + + /* Copy dst buffer flag to buf_ctrl */ + buf->flag =3D call_cop(ctx, get_buf_ctrl_val, ctx, + &ctx->dst_ctrls[index], + V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG); + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + raw =3D &ctx->raw_buf; + if (ctx->src_fmt->mem_planes =3D=3D 1) { + buf_size =3D vb2_plane_size(vb, 0); + mfc_ctx_debug(2, "[FRAME] single plane vb size: %lu, calc size: %d\n", + buf_size, raw->total_plane_size); + if (buf_size < raw->total_plane_size) { + mfc_ctx_err("[FRAME] single plane size(%lu) is smaller than (%d)\n", + buf_size, raw->total_plane_size); + return -EINVAL; + } + } else { + for (i =3D 0; i < ctx->src_fmt->mem_planes; i++) { + buf_size =3D vb2_plane_size(vb, i); + mfc_ctx_debug(2, "[FRAME] plane[%d] vb size: %lu, calc size: %d\n", + i, buf_size, raw->plane_size[i]); + if (buf_size < raw->plane_size[i]) { + mfc_ctx_err("[FRAME] plane[%d] size(%lu) is smaller than (%d)\n", + i, buf_size, raw->plane_size[i]); + return -EINVAL; + } + } + } + + for (i =3D 0; i < ctx->src_fmt->mem_planes; i++) { + bufcon_dmabuf[i] =3D dma_buf_get(vb->planes[i].m.fd); + if (IS_ERR(bufcon_dmabuf[i])) { + mfc_ctx_err("failed to get bufcon dmabuf\n"); + goto err_mem_put; + } + mem_get_count++; + + dma_buf_put(bufcon_dmabuf[i]); + mfc_calc_base_addr(ctx, vb, ctx->src_fmt); + } + + call_cop(ctx, to_buf_ctrls, ctx, &ctx->src_ctrls[index]); + + /* Copy src buffer flag to buf_ctrl */ + buf->flag =3D call_cop(ctx, get_buf_ctrl_val, ctx, + &ctx->src_ctrls[index], + V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG); + } else { + mfc_ctx_err("invalid queue type: %d\n", vq->type); + return -EINVAL; + } + + mfc_mem_buf_prepare(vb, 0); + + mfc_ctx_debug_leave(); + return 0; + +err_mem_put: + for (i =3D 0; i < mem_get_count; i++) + dma_buf_put(bufcon_dmabuf[i]); + + return -ENOMEM; +} + +static void mfc_enc_buf_finish(struct vb2_buffer *vb) +{ + struct mfc_buf *buf =3D vb_to_mfc_buf(vb); + struct vb2_queue *vq =3D vb->vb2_queue; + struct mfc_ctx *ctx =3D vq->drv_priv; + unsigned int index =3D vb->index; + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + /* Copy to dst buffer flag */ + call_cop(ctx, update_buf_val, ctx, &ctx->dst_ctrls[index], + V4L2_CID_MPEG_VIDEO_DST_BUF_FLAG, buf->flag); + mfc_ctx_debug(4, "[FLAG] dst update buf[%d] flag =3D %#x\n", + index, buf->flag); + + call_cop(ctx, to_ctx_ctrls, ctx, &ctx->dst_ctrls[index]); + + mfc_mem_buf_finish(vb, 1); + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + /* Copy to src buffer flag */ + call_cop(ctx, update_buf_val, ctx, &ctx->src_ctrls[index], + V4L2_CID_MPEG_VIDEO_SRC_BUF_FLAG, buf->flag); + mfc_ctx_debug(4, "[FLAG] src update buf[%d] flag =3D %#x\n", + index, buf->flag); + + call_cop(ctx, to_ctx_ctrls, ctx, &ctx->src_ctrls[index]); + } +} + +static void mfc_enc_buf_cleanup(struct vb2_buffer *vb) +{ + struct vb2_queue *vq =3D vb->vb2_queue; + struct mfc_ctx *ctx =3D vq->drv_priv; + unsigned int index =3D vb->index; + + mfc_ctx_debug_enter(); + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + if (call_cop(ctx, cleanup_buf_ctrls, ctx, + MFC_CTRL_TYPE_DST, index) < 0) + mfc_ctx_err("failed in cleanup_buf_ctrls\n"); + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (call_cop(ctx, cleanup_buf_ctrls, ctx, + MFC_CTRL_TYPE_SRC, index) < 0) + mfc_ctx_err("failed in cleanup_buf_ctrls\n"); + } else { + mfc_ctx_err("unknown queue type\n"); + } + + mfc_ctx_debug_leave(); +} + +static int mfc_enc_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct mfc_ctx *ctx =3D q->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + struct mfc_core *core; + struct mfc_core_ctx *core_ctx; + + /* Encoder works only single core */ + core =3D mfc_get_main_core_lock(dev, ctx); + core_ctx =3D core->core_ctx[ctx->num]; + + if (q->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && + core_ctx->state =3D=3D MFCINST_FINISHED) { + mfc_change_state(core_ctx, MFCINST_GOT_INST); + mfc_info("enc start_streaming changes state %d\n", + core_ctx->state); + MFC_TRACE_CTX("** ENC streamon, state: %d\n", + core_ctx->state); + } + + mfc_rm_update_real_time(ctx); + mfc_rm_request_work(dev, MFC_WORK_TRY, ctx); + + return 0; +} + +static void mfc_enc_stop_streaming(struct vb2_queue *q) +{ + struct mfc_ctx *ctx =3D q->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + + mfc_ctx_info("enc stop_streaming is called, type : %d\n", q->type); + MFC_TRACE_CTX("** ENC streamoff(type:%d)\n", q->type); + + mfc_rm_instance_enc_stop(dev, ctx, q->type); +} + +static void mfc_enc_buf_queue(struct vb2_buffer *vb) +{ + struct vb2_queue *vq =3D vb->vb2_queue; + struct mfc_core *core; + struct mfc_core_ctx *core_ctx; + struct mfc_ctx *ctx =3D vq->drv_priv; + struct mfc_dev *dev =3D ctx->dev; + struct mfc_buf *buf =3D vb_to_mfc_buf(vb); + int i; + int is_dst_buf_ready; + + mfc_ctx_debug_enter(); + + buf->next_index =3D 0; + buf->done_index =3D 0; + + if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + mfc_ctx_debug(2, "[BUFINFO] ctx[%d] add dst index: %d, addr: 0x%08llx\n", + ctx->num, vb->index, buf->addr[0][0]); + + /* Mark destination as available for use by MFC */ + mfc_add_tail_buf(ctx, &ctx->dst_buf_queue, buf); + mfc_rm_qos_control(ctx, MFC_QOS_TRIGGER); + } else if (vq->type =3D=3D V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + buf->src_index =3D ctx->serial_src_index++; + if (ctx->multi_view_enable) { + for (i =3D 0; i < ctx->raw_buf.num_planes; i++) + mfc_ctx_debug(2, "%s[%d] %s: %d(%d), addr[0][%d]: 0x%08llx\n", + "[BUFINFO-view0] ctx", ctx->num, + "add src index", vb->index, + buf->src_index, i, + buf->addr[0][i]); + for (i =3D 0; i < ctx->raw_buf.num_planes; i++) + mfc_ctx_debug(2, "%s[%d] %s: %d(%d), addr[2][%d]: 0x%08llx\n", + "[BUFINFO-view1] ctx", ctx->num, + "add src index", vb->index, + buf->src_index, i, + buf->addr[2][i]); + } else { + if (ctx->num_fd_frame > 3) { + mfc_ctx_err("if not multi_view_enable, num_fd_frame must be <=3D 3\n"); + } else { + for (i =3D 0; i < ctx->num_fd_frame; i++) { + mfc_ctx_debug(2, "%s[%d] %s: %d(%d), addr[%d]: 0x%08llx\n", + "[BUFINFO] ctx", ctx->num, + "add src index", vb->index, + buf->src_index, i, buf->addr[0][i]); + } + } + } + mfc_add_tail_buf(ctx, &ctx->src_buf_ready_queue, buf); + + if (dev->debugfs.debug_ts =3D=3D 1) + mfc_ctx_info("[TS] framerate: %ld, timestamp: %lld\n", + ctx->framerate, buf->vb.vb2_buf.timestamp); + + mfc_rate_update_last_framerate(ctx, buf->vb.vb2_buf.timestamp); + mfc_rm_qos_control(ctx, MFC_QOS_TRIGGER); + } else { + mfc_ctx_err("unsupported buffer type (%d)\n", vq->type); + } + + if (ctx->stream_op_mode =3D=3D MFC_OP_TWO_MODE1) + is_dst_buf_ready =3D + mfc_is_queue_count_greater(&ctx->buf_queue_lock, + &ctx->dst_buf_queue, 0); + + mfc_rm_request_work(dev, MFC_WORK_TRY, ctx); + + if (!mfc_rm_query_state(ctx, EQUAL_BIGGER, MFCINST_HEAD_PARSED) && + ctx->stream_op_mode =3D=3D MFC_OP_TWO_MODE1 && is_dst_buf_ready) { + core =3D mfc_get_main_core(dev, ctx); + if (!core) { + mfc_ctx_err("[RM] main core is NULL\n"); + return; + } + core_ctx =3D core->core_ctx[ctx->num]; + + if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_SEQ_DONE_RET)) { + mfc_ctx_err("[RM] sub core header parsing failed\n"); + return; + } + + mfc_ctx_info("[2CORE] start the sub core\n"); + if (ctx->op_core_num[MFC_CORE_SUB] =3D=3D MFC_CORE_INVALID) { + if (mfc_rm_instance_setup(dev, ctx)) + mfc_ctx_err("[2CORE] failed to setup sub core\n"); + } else { + if (mfc_rm_subcore_seq_start(dev, ctx)) + mfc_ctx_err("[2CORE] failed to seq_start sub core\n"); + } + } + + mfc_ctx_debug_leave(); +} + +static const struct vb2_ops mfc_enc_qops =3D { + .queue_setup =3D mfc_enc_queue_setup, + .wait_prepare =3D mfc_enc_unlock, + .wait_finish =3D mfc_enc_lock, + .buf_init =3D mfc_enc_buf_init, + .buf_prepare =3D mfc_enc_buf_prepare, + .buf_finish =3D mfc_enc_buf_finish, + .buf_cleanup =3D mfc_enc_buf_cleanup, + .start_streaming =3D mfc_enc_start_streaming, + .stop_streaming =3D mfc_enc_stop_streaming, + .buf_queue =3D mfc_enc_buf_queue, +}; + +const struct vb2_ops *mfc_get_enc_vb2_ops(void) +{ + return &mfc_enc_qops; +} diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.h b/driv= ers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.h new file mode 100644 index 000000000000..d3cb99f0bf84 --- /dev/null +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_enc_vb2.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2025 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * mfc_enc_vb2.h file + * + * Nagaraju Siddineni, + * Himanshu Dewangan, + */ + +#ifndef __MFC_ENC_VB2_H +#define __MFC_ENC_VB2_H __FILE__ + +#include "base/mfc_common.h" + +const struct vb2_ops *mfc_get_enc_vb2_ops(void); + +#endif /* __MFC_ENC_VB2_H */ --=20 2.34.1