From nobody Thu Oct 2 02:18:05 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 35DA425A623 for ; Tue, 30 Sep 2025 03:56:52 +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=1759204617; cv=none; b=oBLdZVZa0wkn4AkYjr7j88G/H+9th2YpmnJoQ4iOKztrpmAdPt9spoBaEmoDJQNM3s3F2jNPcJGKPyuWMdhEk9Ri/0sr98UDvX8kFiBB9wMkh+jvdmtdPcX0simJtpbexWD+44KVA23kFnEwcRZ1swfTRd62xHnYvSzwG08KXKI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759204617; c=relaxed/simple; bh=dnuiF9taoSpEVXutekDkhOjcISTQ4v8OhWetOwZyKNk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:MIME-Version: Content-Type:References; b=tOwIlpDagMciqIKKbqTPK/JgpaZf2Xp3X6b0Hh9nIgyckSBYsIvQayRsYsJP5J6YJK+SWVWwOsemV8KyN9E3hMMPViakTDUUjhwAG1JPbkofFIntjipdqB0d32af7n2CmCMtUJ5wPw9hPeAzzcBXh8vNIvt0qqtFX2WJcdce0PE= 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=D7JNlpT1; 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="D7JNlpT1" Received: from epcas5p4.samsung.com (unknown [182.195.41.42]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20250930035650epoutp04a62b7be99fbc499c86edfdefc2862f5a~p80XQQSzl2088220882epoutp04M for ; Tue, 30 Sep 2025 03:56:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20250930035650epoutp04a62b7be99fbc499c86edfdefc2862f5a~p80XQQSzl2088220882epoutp04M DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1759204610; bh=FRlzfMbQXPkh6PtdyInbjSItki1kicdByfqh3BQZpvQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D7JNlpT1Vo/uKExsPIAQ0vj8rOv/7gy1FyJvXGIoNXM0VAqQsU7//+oJF6cxpYH8c Nhokfz3B3nDXki1dW5KaDrvtfLaJg5a26nR6xpJLl5nKW36fznOk80jKoPSVDcT/RF qn2DekTRWYcOxCFWRAL0nJUaXpzr+C2qXKBCw9vk= Received: from epsnrtp01.localdomain (unknown [182.195.42.153]) by epcas5p1.samsung.com (KnoxPortal) with ESMTPS id 20250930035648epcas5p1bcfc137b71de0107d684089a0db0af02~p80VrfTLi2306123061epcas5p1p; Tue, 30 Sep 2025 03:56:48 +0000 (GMT) Received: from epcas5p3.samsung.com (unknown [182.195.38.94]) by epsnrtp01.localdomain (Postfix) with ESMTP id 4cbPPq64Zqz6B9mB; Tue, 30 Sep 2025 03:56:47 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas5p2.samsung.com (KnoxPortal) with ESMTPA id 20250930035646epcas5p2f4a9694c7f89ffe27384f8b7b8227802~p80Tw1LC70812408124epcas5p2i; Tue, 30 Sep 2025 03:56:46 +0000 (GMT) Received: from bose.samsungds.net (unknown [107.108.83.9]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250930035644epsmtip1ba8c3ef96b0eca6504d23b66b64064d6~p80RVraPo2931929319epsmtip10; Tue, 30 Sep 2025 03:56:44 +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 21/29] =?UTF-8?q?media:=20mfc:=20Add=20multi=E2=80=91codec?= =?UTF-8?q?=20support=20&=20QoS=20improvements?= Date: Tue, 30 Sep 2025 09:33:40 +0530 Message-Id: <20250930040348.3702923-22-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: 20250930035646epcas5p2f4a9694c7f89ffe27384f8b7b8227802 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: 20250930035646epcas5p2f4a9694c7f89ffe27384f8b7b8227802 References: <20250930040348.3702923-1-h.dewangan@samsung.com> From: Nagaraju Siddineni - Enable HEVC, AV1, VP8/9, MPEG=E2=80=914 (incl. MVC, VC=E2=80=911=E2=80=AF= RCV) . - Extend DPB/buffer structures for AV1 and high=E2=80=91resolution/multifra= me streams. - Add codec=E2=80=91specific QoS weight parameters (10=E2=80=91bit, 4:2:2, = B=E2=80=91frames) and update DT bandwidth entries. - Enhance format tables with colour=E2=80=91range/space and HDR parsing for= VP9. - Detect display=E2=80=91resolution changes and multiframe flags for VP9/AV= 1. - Introduce utility helpers (CRC, aspect=E2=80=91ratio, colour primaries) and minor safety fixes. Signed-off-by: Nagaraju Siddineni Signed-off-by: Himanshu Dewangan --- .../samsung/exynos-mfc/base/mfc_buf.c | 70 +++++++++ .../samsung/exynos-mfc/base/mfc_common.h | 42 ++++- .../samsung/exynos-mfc/base/mfc_data_struct.h | 20 +++ .../samsung/exynos-mfc/base/mfc_format.h | 136 ++++++++++++++++ .../samsung/exynos-mfc/base/mfc_qos.c | 58 +++++++ .../samsung/exynos-mfc/base/mfc_queue.c | 5 + .../samsung/exynos-mfc/base/mfc_utils.c | 8 +- .../media/platform/samsung/exynos-mfc/mfc.c | 53 +++++++ .../platform/samsung/exynos-mfc/mfc_core.c | 2 + .../samsung/exynos-mfc/mfc_core_buf_ctrl.c | 9 ++ .../samsung/exynos-mfc/mfc_core_cmd.c | 11 ++ .../samsung/exynos-mfc/mfc_core_isr.c | 147 ++++++++++++++++-- .../samsung/exynos-mfc/mfc_core_reg_api.c | 46 +++++- .../samsung/exynos-mfc/mfc_core_reg_api.h | 75 ++++++++- .../samsung/exynos-mfc/mfc_core_run.c | 4 + .../platform/samsung/exynos-mfc/mfc_dec_vb2.c | 1 + 16 files changed, 665 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c b/dri= vers/media/platform/samsung/exynos-mfc/base/mfc_buf.c index bd1baf34e0b0..84f97ca230bb 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_buf.c @@ -116,8 +116,25 @@ int mfc_alloc_instance_context(struct mfc_core_ctx *co= re_ctx) switch (ctx->codec_mode) { case MFC_REG_CODEC_H264_DEC: case MFC_REG_CODEC_H264_MVC_DEC: + case MFC_REG_CODEC_HEVC_DEC: core_ctx->instance_ctx_buf.size =3D buf_size->h264_dec_ctx; break; + case MFC_REG_CODEC_MPEG4_DEC: + case MFC_REG_CODEC_H263_DEC: + case MFC_REG_CODEC_VC1_RCV_DEC: + case MFC_REG_CODEC_VC1_DEC: + case MFC_REG_CODEC_MPEG2_DEC: + case MFC_REG_CODEC_VP8_DEC: + case MFC_REG_CODEC_VP9_DEC: + case MFC_REG_CODEC_FIMV1_DEC: + case MFC_REG_CODEC_FIMV2_DEC: + case MFC_REG_CODEC_FIMV3_DEC: + case MFC_REG_CODEC_FIMV4_DEC: + core_ctx->instance_ctx_buf.size =3D buf_size->other_dec_ctx; + break; + case MFC_REG_CODEC_AV1_DEC: + core_ctx->instance_ctx_buf.size =3D buf_size->av1_dec_ctx; + break; default: core_ctx->instance_ctx_buf.size =3D 0; mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode); @@ -155,6 +172,59 @@ static void __mfc_dec_calc_codec_buffer_size(struct mf= c_core_ctx *core_ctx) /* Codecs have different memory requirements */ switch (ctx->codec_mode) { case MFC_REG_CODEC_H264_DEC: + case MFC_REG_CODEC_H264_MVC_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + ctx->mv_buf.size =3D dec->mv_count * ctx->mv_size; + break; + case MFC_REG_CODEC_MPEG4_DEC: + case MFC_REG_CODEC_FIMV1_DEC: + case MFC_REG_CODEC_FIMV2_DEC: + case MFC_REG_CODEC_FIMV3_DEC: + case MFC_REG_CODEC_FIMV4_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + if (dec->loop_filter_mpeg4) { + ctx->loopfilter_luma_size =3D ALIGN(ctx->raw_buf.plane_size[0], SZ_256); + ctx->loopfilter_chroma_size =3D ALIGN(ctx->raw_buf.plane_size[1] + + ctx->raw_buf.plane_size[2], SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size + + (NUM_MPEG4_LF_BUF * (ctx->loopfilter_luma_size + + ctx->loopfilter_chroma_size)); + } else { + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + } + break; + case MFC_REG_CODEC_VC1_RCV_DEC: + case MFC_REG_CODEC_VC1_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + break; + case MFC_REG_CODEC_MPEG2_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + break; + case MFC_REG_CODEC_H263_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + break; + case MFC_REG_CODEC_VP8_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D ctx->scratch_buf_size; + break; + case MFC_REG_CODEC_VP9_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D + ctx->scratch_buf_size + + DEC_STATIC_BUFFER_SIZE; + break; + case MFC_REG_CODEC_AV1_DEC: + ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); + core_ctx->codec_buf.size =3D + ctx->scratch_buf_size + + DEC_AV1_STATIC_BUFFER_SIZE(ctx->img_width, ctx->img_height); + ctx->mv_buf.size =3D dec->mv_count * ctx->mv_size; + break; + case MFC_REG_CODEC_HEVC_DEC: ctx->scratch_buf_size =3D ALIGN(ctx->scratch_buf_size, SZ_256); core_ctx->codec_buf.size =3D ctx->scratch_buf_size; ctx->mv_buf.size =3D dec->mv_count * ctx->mv_size; diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h b/= drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h index de22c28d1625..5392c8566e42 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_common.h @@ -153,7 +153,47 @@ =20 /* Decoder codec mode check */ #define IS_H264_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_H264_DEC) +#define IS_H264_MVC_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_H264_= MVC_DEC) +#define IS_MPEG4_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_MPEG4_DE= C) +#define IS_FIMV1_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_FIMV1_DE= C) +#define IS_FIMV2_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_FIMV2_DE= C) +#define IS_FIMV3_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_FIMV3_DE= C) +#define IS_FIMV4_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_FIMV4_DE= C) +#define IS_VC1_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_VC1_DEC) +#define IS_VC1_RCV_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_VC1_RC= V_DEC) +#define IS_MPEG2_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_MPEG2_DE= C) +#define IS_HEVC_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_HEVC_DEC) +#define IS_VP8_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_VP8_DEC) +#define IS_VP9_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_VP9_DEC) +#define IS_AV1_DEC(ctx) ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_AV1_DEC) +#define IS_MV_HEVC_DEC(ctx, profile) \ + ((ctx)->codec_mode =3D=3D MFC_REG_CODEC_HEVC_DEC && \ + (profile) =3D=3D MFC_REG_D_PROFILE_MULTIVIEW_HEVC_MAIN) + +#define CODEC_NOT_CODED(ctx) ({ \ + typeof(ctx) _ctx =3D (ctx); \ + (IS_MPEG4_DEC(_ctx) || IS_VC1_DEC(_ctx) || IS_VC1_RCV_DEC(_ctx) || \ + IS_VP9_DEC(_ctx)); \ +}) +#define CODEC_INTERLACED(ctx) ({ \ + typeof(ctx) _ctx =3D (ctx); \ + (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_MPEG2_DEC(_ctx) || \ + IS_MPEG4_DEC(_ctx) || IS_VC1_DEC(_ctx) || IS_VC1_RCV_DEC(_ctx)); \ +}) +#define CODEC_MBAFF(ctx) ({ \ + typeof(ctx) _ctx =3D (ctx); \ + (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx)); \ +}) +#define CODEC_MULTIFRAME(ctx) ({ \ + typeof(ctx) _ctx =3D (ctx); \ + (IS_MPEG4_DEC(_ctx) || IS_VP9_DEC(_ctx) || IS_FIMV2_DEC(_ctx) || \ + IS_FIMV3_DEC(_ctx) || IS_FIMV4_DEC(_ctx) || IS_AV1_DEC(_ctx)); \ +}) =20 +#define CODEC_422FORMAT(ctx) ({ \ + typeof(ctx) _ctx =3D (ctx); \ + (IS_HEVC_DEC(_ctx) || IS_VP9_DEC(_ctx)); \ +}) #define ON_RES_CHANGE(ctx) ({ \ typeof(ctx) _ctx =3D (ctx); \ ((_ctx->state >=3D MFCINST_RES_CHANGE_INIT) && \ @@ -177,7 +217,7 @@ }) #define CODEC_HAS_IDR(ctx) ({ \ typeof(ctx) _ctx =3D (ctx); \ - (IS_H264_DEC(_ctx)); \ + (IS_H264_DEC(_ctx) || IS_H264_MVC_DEC(_ctx) || IS_HEVC_DEC(_ctx)); \ }) =20 /* diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct= .h b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h index 34b4b13b4f01..6b93fe3ab138 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_data_struct.h @@ -503,6 +503,8 @@ struct mfc_fw { struct mfc_ctx_buf_size { size_t dev_ctx; size_t h264_dec_ctx; + size_t av1_dec_ctx; + size_t other_dec_ctx; size_t dbg_info_buf; }; =20 @@ -710,6 +712,14 @@ struct mfc_bw_data { =20 struct mfc_bw_info { struct mfc_bw_data bw_dec_h264; + struct mfc_bw_data bw_dec_hevc; + struct mfc_bw_data bw_dec_hevc_10bit; + struct mfc_bw_data bw_dec_vp8; + struct mfc_bw_data bw_dec_vp9; + struct mfc_bw_data bw_dec_vp9_10bit; + struct mfc_bw_data bw_dec_av1; + struct mfc_bw_data bw_dec_av1_10bit; + struct mfc_bw_data bw_dec_mpeg4; }; =20 /* @@ -723,6 +733,7 @@ struct mfc_qos { unsigned int freq_int; unsigned int freq_mif; unsigned int mo_value; + unsigned int mo_10bit_value; unsigned int time_fw; unsigned int bts_scen_idx; const char *name; @@ -747,8 +758,17 @@ struct mfc_qos_ctrl { =20 struct mfc_qos_weight { unsigned int weight_h264_hevc; + unsigned int weight_vp8_vp9; + unsigned int weight_av1; + unsigned int weight_other_codec; unsigned int weight_3plane; + unsigned int weight_10bit; + unsigned int weight_422; + unsigned int weight_bframe; + unsigned int weight_num_of_ref; + unsigned int weight_gpb; unsigned int weight_num_of_tile; + unsigned int weight_super64_bframe; unsigned int weight_mbaff; }; =20 diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h b/= drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h index 3307c2eeaebb..0d48f2373e8d 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_format.h @@ -127,6 +127,142 @@ static struct mfc_fmt mfc_formats[] =3D { .num_planes =3D 1, .mem_planes =3D 1, }, + { + .name =3D "DEC H264/MVC", + .fourcc =3D V4L2_PIX_FMT_H264_MVC, + .codec_mode =3D MFC_REG_CODEC_H264_MVC_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC H263", + .fourcc =3D V4L2_PIX_FMT_H263, + .codec_mode =3D MFC_REG_CODEC_H263_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC MPEG1", + .fourcc =3D V4L2_PIX_FMT_MPEG1, + .codec_mode =3D MFC_REG_CODEC_MPEG2_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC MPEG2", + .fourcc =3D V4L2_PIX_FMT_MPEG2, + .codec_mode =3D MFC_REG_CODEC_MPEG2_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC MPEG4", + .fourcc =3D V4L2_PIX_FMT_MPEG4, + .codec_mode =3D MFC_REG_CODEC_MPEG4_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC FIMV", + .fourcc =3D V4L2_PIX_FMT_FIMV, + .codec_mode =3D MFC_REG_CODEC_MPEG4_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC FIMV1", + .fourcc =3D V4L2_PIX_FMT_FIMV1, + .codec_mode =3D MFC_REG_CODEC_FIMV1_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC FIMV2", + .fourcc =3D V4L2_PIX_FMT_FIMV2, + .codec_mode =3D MFC_REG_CODEC_FIMV2_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC FIMV3", + .fourcc =3D V4L2_PIX_FMT_FIMV3, + .codec_mode =3D MFC_REG_CODEC_FIMV3_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC FIMV4", + .fourcc =3D V4L2_PIX_FMT_FIMV4, + .codec_mode =3D MFC_REG_CODEC_FIMV4_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC XviD", + .fourcc =3D V4L2_PIX_FMT_XVID, + .codec_mode =3D MFC_REG_CODEC_MPEG4_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC VC1", + .fourcc =3D V4L2_PIX_FMT_VC1_ANNEX_G, + .codec_mode =3D MFC_REG_CODEC_VC1_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC VC1 RCV", + .fourcc =3D V4L2_PIX_FMT_VC1_ANNEX_L, + .codec_mode =3D MFC_REG_CODEC_VC1_RCV_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC VP8", + .fourcc =3D V4L2_PIX_FMT_VP8, + .codec_mode =3D MFC_REG_CODEC_VP8_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC VP9", + .fourcc =3D V4L2_PIX_FMT_VP9, + .codec_mode =3D MFC_REG_CODEC_VP9_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC AV1", + .fourcc =3D V4L2_PIX_FMT_AV1, + .codec_mode =3D MFC_REG_CODEC_AV1_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, + { + .name =3D "DEC HEVC", + .fourcc =3D V4L2_PIX_FMT_HEVC, + .codec_mode =3D MFC_REG_CODEC_HEVC_DEC, + .type =3D MFC_FMT_STREAM | MFC_FMT_DEC, + .num_planes =3D 1, + .mem_planes =3D 1, + }, }; =20 #endif /* __MFC_FORMAT_H */ diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c b/dri= vers/media/platform/samsung/exynos-mfc/base/mfc_qos.c index f6548543f07c..9922c2396b94 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_qos.c @@ -38,6 +38,7 @@ static inline unsigned long __mfc_qos_add_weight(struct m= fc_ctx *ctx, unsigned l =20 switch (ctx->codec_mode) { case MFC_REG_CODEC_H264_DEC: + case MFC_REG_CODEC_H264_MVC_DEC: weight =3D (weight * 100) / qos_weight->weight_h264_hevc; mfc_ctx_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight / 10); if (num_planes =3D=3D 3) { @@ -45,6 +46,63 @@ static inline unsigned long __mfc_qos_add_weight(struct = mfc_ctx *ctx, unsigned l mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); } break; + + case MFC_REG_CODEC_VP8_DEC: + weight =3D (weight * 100) / qos_weight->weight_vp8_vp9; + mfc_ctx_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 10); + if (num_planes =3D=3D 3) { + weight =3D (weight * 100) / qos_weight->weight_3plane; + mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); + } + break; + + case MFC_REG_CODEC_HEVC_DEC: + weight =3D (weight * 100) / qos_weight->weight_h264_hevc; + mfc_ctx_debug(3, "[QoS] h264, hevc codec, weight: %d\n", weight / 10); + if (num_planes =3D=3D 3) { + weight =3D (weight * 100) / qos_weight->weight_3plane; + mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); + } else { + if (ctx->is_422) { + weight =3D (weight * 100) / qos_weight->weight_422; + mfc_ctx_debug(3, "[QoS] 422foramt, weight: %d\n", weight / 10); + } + } + break; + + case MFC_REG_CODEC_AV1_DEC: + weight =3D (weight * 100) / qos_weight->weight_av1; + mfc_ctx_debug(3, "[QoS] av1 codec, weight: %d\n", weight / 10); + break; + + case MFC_REG_CODEC_VP9_DEC: + weight =3D (weight * 100) / qos_weight->weight_vp8_vp9; + mfc_ctx_debug(3, "[QoS] vp8, vp9 codec, weight: %d\n", weight / 10); + + if (num_planes =3D=3D 3) { + weight =3D (weight * 100) / qos_weight->weight_3plane; + mfc_ctx_debug(3, "[QoS] 3 plane, weight: %d\n", weight / 10); + } else { + if (ctx->is_422) { + weight =3D (weight * 100) / qos_weight->weight_422; + mfc_ctx_debug(3, "[QoS] 422foramt, weight: %d\n", weight / 10); + } + } + break; + + case MFC_REG_CODEC_MPEG4_DEC: + case MFC_REG_CODEC_FIMV1_DEC: + case MFC_REG_CODEC_FIMV2_DEC: + case MFC_REG_CODEC_FIMV3_DEC: + case MFC_REG_CODEC_FIMV4_DEC: + case MFC_REG_CODEC_H263_DEC: + case MFC_REG_CODEC_VC1_RCV_DEC: + case MFC_REG_CODEC_VC1_DEC: + case MFC_REG_CODEC_MPEG2_DEC: + weight =3D (weight * 100) / qos_weight->weight_other_codec; + mfc_ctx_debug(3, "[QoS] other codec, weight: %d\n", weight / 10); + break; + default: mfc_ctx_err("[QoS] wrong codec_mode (%d), no weight\n", ctx->codec_mode); } diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c b/d= rivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c index f56e800c55f0..6dc9bc7a1873 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_queue.c @@ -154,6 +154,11 @@ struct mfc_buf *mfc_get_del_if_consumed(struct mfc_ctx= *ctx, consumed, strm_size); } =20 + if (remained && IS_MULTI_MODE(ctx) && !CODEC_MULTIFRAME(ctx)) { + mfc_ctx_info("[2CORE][MULTIFRAME] multicore mode couldn't handle multifr= ame\n"); + remained =3D 0; + } + if (consumed > 0 && remained > min_bytes && IS_NO_ERROR(error) && !exceed) { /* do not delete from queue */ diff --git a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c b/d= rivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c index b0698b2bb0c0..83cdae3dee57 100644 --- a/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c +++ b/drivers/media/platform/samsung/exynos-mfc/base/mfc_utils.c @@ -187,9 +187,15 @@ void mfc_dec_calc_dpb_size(struct mfc_ctx *ctx, struct= mfc_raw_info *raw, struct } mfc_ctx_debug(2, "[FRAME] total plane size: %d\n", raw->total_plane_size); =20 - if (IS_H264_DEC(ctx)) { + if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx)) { ctx->mv_size =3D DEC_MV_SIZE_MB(ctx->img_width, ctx->img_height); ctx->mv_size =3D ALIGN(ctx->mv_size, 32); + } else if (IS_HEVC_DEC(ctx)) { + ctx->mv_size =3D DEC_HEVC_MV_SIZE(ctx->img_width, ctx->img_height); + ctx->mv_size =3D ALIGN(ctx->mv_size, 32); + } else if (IS_AV1_DEC(ctx)) { + ctx->mv_size =3D DEC_AV1_MV_SIZE(ctx->img_width, ctx->img_height); + ctx->mv_size =3D ALIGN(ctx->mv_size, 32); } else { ctx->mv_size =3D 0; } diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc.c b/drivers/medi= a/platform/samsung/exynos-mfc/mfc.c index fb9a7317e812..293a353c49fa 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc.c @@ -646,18 +646,69 @@ static int __mfc_parse_dt(struct device_node *np, str= uct mfc_dev *mfc) of_property_read_u32_array (np, "bw_dec_h264", &pdata->mfc_bw_info.bw_dec_h264.peak, 3); + of_property_read_u32_array + (np, "bw_dec_hevc", + &pdata->mfc_bw_info.bw_dec_hevc.peak, 3); + of_property_read_u32_array + (np, "bw_dec_hevc_10bit", + &pdata->mfc_bw_info.bw_dec_hevc_10bit.peak, 3); + of_property_read_u32_array + (np, "bw_dec_vp8", + &pdata->mfc_bw_info.bw_dec_vp8.peak, 3); + of_property_read_u32_array + (np, "bw_dec_vp9", + &pdata->mfc_bw_info.bw_dec_vp9.peak, 3); + of_property_read_u32_array + (np, "bw_dec_vp9_10bit", + &pdata->mfc_bw_info.bw_dec_vp9_10bit.peak, 3); + of_property_read_u32_array + (np, "bw_dec_av1", + &pdata->mfc_bw_info.bw_dec_av1.peak, 3); + of_property_read_u32_array + (np, "bw_dec_av1_10bit", + &pdata->mfc_bw_info.bw_dec_av1_10bit.peak, 3); + of_property_read_u32_array + (np, "bw_dec_mpeg4", + &pdata->mfc_bw_info.bw_dec_mpeg4.peak, 3); =20 /* QoS weight */ of_property_read_u32(np, "dynamic_weight", &pdata->dynamic_weight); of_property_read_u32 (np, "qos_weight_h264_hevc", &pdata->qos_weight.weight_h264_hevc); + of_property_read_u32 + (np, "qos_weight_vp8_vp9", + &pdata->qos_weight.weight_vp8_vp9); + of_property_read_u32 + (np, "qos_weight_av1", + &pdata->qos_weight.weight_av1); + of_property_read_u32 + (np, "qos_weight_other_codec", + &pdata->qos_weight.weight_other_codec); of_property_read_u32 (np, "qos_weight_3plane", &pdata->qos_weight.weight_3plane); + of_property_read_u32 + (np, "qos_weight_10bit", + &pdata->qos_weight.weight_10bit); + of_property_read_u32 + (np, "qos_weight_422", + &pdata->qos_weight.weight_422); + of_property_read_u32 + (np, "qos_weight_bframe", + &pdata->qos_weight.weight_bframe); + of_property_read_u32 + (np, "qos_weight_num_of_ref", + &pdata->qos_weight.weight_num_of_ref); + of_property_read_u32 + (np, "qos_weight_gpb", + &pdata->qos_weight.weight_gpb); of_property_read_u32 (np, "qos_weight_num_of_tile", &pdata->qos_weight.weight_num_of_tile); + of_property_read_u32 + (np, "qos_weight_super64_bframe", + &pdata->qos_weight.weight_super64_bframe); of_property_read_u32 (np, "qos_weight_mbaff", &pdata->qos_weight.weight_mbaff); @@ -1075,6 +1126,8 @@ static const struct dev_pm_ops mfc_pm_ops =3D { struct mfc_ctx_buf_size mfc_ctx_buf_size =3D { .dev_ctx =3D PAGE_ALIGN(0x7800), /* 30KB */ .h264_dec_ctx =3D PAGE_ALIGN(0x200000), /* 1.6MB */ + .av1_dec_ctx =3D PAGE_ALIGN(0x19000), /* 100KB */ + .other_dec_ctx =3D PAGE_ALIGN(0xF000), /* 60KB */ .dbg_info_buf =3D PAGE_ALIGN(0x1000), /* 4KB for DEBUG INFO */ }; =20 diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c b/drivers= /media/platform/samsung/exynos-mfc/mfc_core.c index af6fd088fad3..aad3273ce2ba 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core.c @@ -77,6 +77,8 @@ static int __mfc_core_parse_mfc_qos_platdata(struct devic= e_node *np, of_property_read_u32(np_qos, "freq_int", &qosdata->freq_int); of_property_read_u32(np_qos, "freq_mif", &qosdata->freq_mif); of_property_read_u32(np_qos, "mo_value", &qosdata->mo_value); + of_property_read_u32(np_qos, "mo_10bit_value", + &qosdata->mo_10bit_value); of_property_read_u32(np_qos, "time_fw", &qosdata->time_fw); =20 of_property_read_string(np_qos, "bts_scen", &qosdata->name); diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c = b/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c index 56dc3e734d02..38f09d6ef2dd 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_buf_ctrl.c @@ -63,6 +63,7 @@ static int mfc_core_get_buf_ctrls(struct mfc_core *core, struct mfc_ctx *ctx, struct list_head *head) { struct mfc_buf_ctrl *buf_ctrl; + struct mfc_dec *dec =3D ctx->dec_priv; unsigned int value =3D 0; =20 list_for_each_entry(buf_ctrl, head, list) { @@ -77,6 +78,14 @@ static int mfc_core_get_buf_ctrls(struct mfc_core *core, buf_ctrl->val =3D value; buf_ctrl->has_new =3D 1; =20 + if (IS_VP9_DEC(ctx) && dec) { + if (buf_ctrl->id =3D=3D V4L2_CID_MPEG_VIDEO_FULL_RANGE_FLAG) + buf_ctrl->val =3D dec->color_range; + else if (buf_ctrl->id =3D=3D + V4L2_CID_MPEG_VIDEO_COLOUR_PRIMARIES) + buf_ctrl->val =3D dec->color_space; + } + if (buf_ctrl->id =3D=3D V4L2_CID_MPEG_VIDEO_FRAME_ERROR_TYPE) buf_ctrl->val =3D mfc_get_frame_error_type(ctx, value); =20 diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c b/dri= vers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c index fe7946bb49e7..aaf216741575 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_cmd.c @@ -230,6 +230,10 @@ void mfc_core_cmd_dec_seq_header(struct mfc_core *core= , struct mfc_ctx *ctx) reg |=3D ((dec->idr_decoding & MFC_REG_D_DEC_OPT_IDR_DECODING_MASK) << MFC_REG_D_DEC_OPT_IDR_DECODING_SHIFT); =20 + /* VC1 RCV: Discard to parse additional header as default */ + if (IS_VC1_RCV_DEC(ctx)) + reg |=3D BIT(MFC_REG_D_DEC_OPT_DISCARD_RCV_HEADER_SHIFT); + /* conceal control to specific color */ reg |=3D (0x4 << MFC_REG_D_DEC_OPT_CONCEAL_CONTROL_SHIFT); =20 @@ -248,6 +252,13 @@ void mfc_core_cmd_dec_seq_header(struct mfc_core *core= , struct mfc_ctx *ctx) =20 MFC_CORE_WRITEL(MFC_CONCEAL_COLOR, MFC_REG_D_FORCE_PIXEL_VAL); =20 + if (IS_FIMV1_DEC(ctx)) { + mfc_debug(2, "Setting FIMV1 resolution to %dx%d\n", + ctx->img_width, ctx->img_height); + MFC_CORE_WRITEL(ctx->img_width, MFC_REG_D_SET_FRAME_WIDTH); + MFC_CORE_WRITEL(ctx->img_height, MFC_REG_D_SET_FRAME_HEIGHT); + } + mfc_core_set_pixel_format(core, ctx, ctx->dst_fmt->fourcc); =20 reg =3D 0; diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c b/dri= vers/media/platform/samsung/exynos-mfc/mfc_core_isr.c index 94cc3c4dfdc5..aa2c0b618c19 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_isr.c @@ -126,10 +126,11 @@ static unsigned int __mfc_handle_frame_field(struct m= fc_core *core, unsigned int interlace_type =3D 0, is_interlace =3D 0; unsigned int field; =20 - if (IS_H264_DEC(ctx)) { - dec->is_mbaff =3D mfc_core_is_mbaff_picture(); + if (CODEC_INTERLACED(ctx)) is_interlace =3D mfc_core_is_interlace_picture(); - } + + if (CODEC_MBAFF(ctx)) + dec->is_mbaff =3D mfc_core_is_mbaff_picture(); =20 if (is_interlace) { interlace_type =3D mfc_core_get_interlace_type(); @@ -482,6 +483,27 @@ static struct mfc_buf *__mfc_handle_frame_output_del(s= truct mfc_core *core, } } =20 + if (IS_VP9_DEC(ctx) && + MFC_FEATURE_SUPPORT(dev, dev->pdata->color_aspect_dec)) { + if (dec->color_space !=3D MFC_REG_D_COLOR_UNKNOWN) { + mfc_set_mb_flag(dst_mb, + MFC_FLAG_HDR_COLOUR_DESC); + mfc_ctx_debug(2, "[HDR] color space parsed\n"); + } + mfc_set_mb_flag(dst_mb, MFC_FLAG_HDR_VIDEO_SIGNAL_TYPE); + mfc_ctx_debug(2, "[HDR] color range parsed\n"); + } + + if ((IS_VP9_DEC(ctx) && mfc_core_get_disp_res_change()) || + (IS_AV1_DEC(ctx) && mfc_core_get_disp_res_change_av1())) { + mfc_ctx_info("[FRAME][DRC] display resolution changed\n"); + mutex_lock(&ctx->drc_wait_mutex); + ctx->wait_state =3D WAIT_G_FMT; + mfc_core_get_img_size(core, ctx, MFC_GET_RESOL_SIZE); + mfc_set_mb_flag(dst_mb, MFC_FLAG_DISP_RES_CHANGE); + mutex_unlock(&ctx->drc_wait_mutex); + } + if (dec->black_bar_updated) { mfc_set_mb_flag(dst_mb, MFC_FLAG_BLACKBAR_DETECT); mfc_ctx_debug(3, "[BLACKBAR] black bar detected\n"); @@ -498,6 +520,11 @@ static struct mfc_buf *__mfc_handle_frame_output_del(s= truct mfc_core *core, mfc_ctx_debug(2, "[FRAME] Last display frame\n"); } =20 + if ((IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx)) && dec->has_multiframe) { + mfc_set_mb_flag(dst_mb, MFC_FLAG_MULTIFRAME); + mfc_ctx_debug(2, "[MULTIFRAME] multiframe detected\n"); + } + if (ctx->dst_fmt->mem_planes =3D=3D 1) { vb2_set_plane_payload(&dst_mb->vb.vb2_buf, 0, raw->total_plane_size); @@ -542,6 +569,8 @@ static struct mfc_buf *__mfc_handle_frame_output_del(st= ruct mfc_core *core, =20 mutex_unlock(&dec->dpb_mutex); } else { + if (IS_AV1_DEC(ctx) && mfc_core_get_multiple_show_frame()) + dec->is_multiple_show =3D 1; mfc_print_dpb_queue_with_lock(core->core_ctx[ctx->num], dec); } =20 @@ -708,11 +737,18 @@ static struct mfc_buf *__mfc_handle_frame_output(stru= ct mfc_core *core, { struct mfc_dec *dec =3D ctx->dec_priv; unsigned int frame_type; + int mvc_view_id; =20 frame_type =3D mfc_core_get_disp_frame_type(); + mvc_view_id =3D mfc_core_get_mvc_disp_view_id(); =20 - if (!ctx->multi_view_enable || ctx->select_view_irq =3D=3D MFC_VIEW_ID_SU= B) - ctx->sequence++; + if (IS_H264_MVC_DEC(ctx)) { + if (mvc_view_id =3D=3D 0) + ctx->sequence++; + } else { + if (!ctx->multi_view_enable || ctx->select_view_irq =3D=3D MFC_VIEW_ID_S= UB) + ctx->sequence++; + } =20 if (dec->immediate_display =3D=3D 1) frame_type =3D mfc_core_get_dec_frame_type(); @@ -721,7 +757,8 @@ static struct mfc_buf *__mfc_handle_frame_output(struct= mfc_core *core, =20 /* If frame is same as previous then skip and do not dequeue */ if (frame_type =3D=3D MFC_REG_DISPLAY_FRAME_NOT_CODED) - return NULL; + if (!CODEC_NOT_CODED(ctx)) + return NULL; =20 /* Dequeued display buffer for user */ return __mfc_handle_frame_output_del(core, ctx, err); @@ -894,6 +931,7 @@ static void __mfc_handle_frame_input(struct mfc_core *c= ore, struct mfc_ctx *ctx, unsigned int err) { + struct mfc_dev *dev =3D ctx->dev; struct mfc_core_ctx *core_ctx =3D core->core_ctx[ctx->num]; struct mfc_dec *dec =3D ctx->dec_priv; struct mfc_buf *src_mb; @@ -945,6 +983,54 @@ static void __mfc_handle_frame_input(struct mfc_core *= core, =20 mfc_clear_mb_flag(src_mb); =20 + if ((IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx)) && dec->has_multiframe && + mfc_core_get_disp_status() =3D=3D MFC_REG_DEC_STATUS_DECODING_ONLY) { + mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); + mfc_debug(2, "[STREAM][MULTIFRAME] last frame is decoding only\n"); + } + + /* + * VP8 decoder has decoding only frame, + * it will be used for reference frame only not displayed. + * So, driver inform to user this input has no destination. + */ + if (((IS_VP8_DEC(ctx) || IS_VP9_DEC(ctx)) && + mfc_core_get_disp_status() =3D=3D MFC_REG_DEC_STATUS_DECODING_ONLY) = || + mfc_core_get_int_reason() =3D=3D MFC_REG_R2H_CMD_FIELD_DONE_RET) { + mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); + mfc_debug(2, "[STREAM] %s decoding only stream has no buffer to DQ\n", + ctx->src_fmt->name); + } + + /* + * Because AV1 has a no show frame, there are two cases that + * driver should inform to user this input has no destination buffer. + * 1) If it's decoding only and it's not showable frame, + * it will be used for reference frame only not displayed. + * 2) If the buffer that has already DQ to display comes to new display, + * it is multiple show frame. + */ + if (IS_AV1_DEC(ctx)) { + if ((mfc_core_get_disp_status() =3D=3D MFC_REG_DEC_STATUS_DECODING_ONLY)= && + !mfc_core_get_showable_frame()) { + mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); + mfc_debug(2, "[STREAM] AV1 no showable frame has no buffer to DQ\n"); + } + if (dec->is_multiple_show) { + mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); + dec->is_multiple_show =3D 0; + mfc_info("[STREAM] AV1 multiple show frame has no buffer to DQ\n"); + } + } + + /* If pic_output_flag is 0 in HEVC, it is no destination buffer */ + if (IS_HEVC_DEC(ctx) && + MFC_FEATURE_SUPPORT(dev, dev->pdata->hevc_pic_output_flag) && + !mfc_core_get_hevc_pic_output_flag()) { + mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); + mfc_debug(2, "[STREAM] HEVC pic_output_flag off has no buffer to DQ\n"); + } + if (mfc_core_get_disp_status() =3D=3D MFC_REG_DEC_STATUS_DECODING_ONLY && mfc_core_get_dec_y_addr() =3D=3D 0) { mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); @@ -955,6 +1041,8 @@ static void __mfc_handle_frame_input(struct mfc_core *= core, mfc_err("failed in core_get_buf_ctrls\n"); =20 dec->consumed =3D 0; + if (IS_VP9_DEC(ctx) || IS_AV1_DEC(ctx)) + dec->has_multiframe =3D 0; =20 if (ctx->multi_view_enable && ctx->select_view =3D=3D 0) mfc_set_mb_flag(src_mb, MFC_FLAG_CONSUMED_ONLY); @@ -978,7 +1066,7 @@ static void __mfc_handle_frame(struct mfc_core *core, unsigned int res_change, need_dpb_change, need_scratch_change; struct mfc_buf *mfc_buf =3D NULL; bool qos_update =3D false; - int index; + int index, profile; =20 dst_frame_status =3D mfc_core_get_disp_status(); res_change =3D mfc_core_get_res_change(); @@ -1048,6 +1136,15 @@ static void __mfc_handle_frame(struct mfc_core *core, index =3D mfc_buf->vb.vb2_buf.index; call_bop(ctx, core_restore_buf_ctrls, ctx, &ctx->src_ctrls[index]); } + + /* It could because of sub-view header (MV-HEVC) */ + if (!ctx->multi_view_enable) { + profile =3D mfc_core_get_profile(); + if (IS_MV_HEVC_DEC(ctx, profile)) { + mfc_debug(2, "Ready to enable, possibly a sub-view header.\n"); + ctx->ready_to_be_multi_view_enable =3D 1; + } + } return; } =20 @@ -1110,7 +1207,7 @@ static void __mfc_handle_frame(struct mfc_core *core, } =20 /* Detection for QoS weight */ - if (!dec->num_of_tile_over_4 && + if (!dec->num_of_tile_over_4 && !IS_HEVC_DEC(ctx) && mfc_core_get_num_of_tile() >=3D 4) { dec->num_of_tile_over_4 =3D 1; qos_update =3D true; @@ -1185,7 +1282,7 @@ static int __mfc_handle_seq_dec(struct mfc_core *core= , struct mfc_ctx *ctx) struct mfc_core_ctx *core_ctx =3D core->core_ctx[ctx->num]; struct mfc_dec *dec =3D ctx->dec_priv; struct mfc_buf *src_mb; - int i, is_interlace; + int i, is_interlace, profile; unsigned int strm_size, consumed; =20 if (ctx->src_fmt->fourcc !=3D V4L2_PIX_FMT_FIMV1) { @@ -1196,13 +1293,34 @@ static int __mfc_handle_seq_dec(struct mfc_core *co= re, struct mfc_ctx *ctx) mfc_info("[STREAM] resolution w: %d, h: %d\n", ctx->img_width, ctx->img_= height); } =20 - ctx->dpb_count =3D mfc_core_get_dpb_count(); + if (IS_AV1_DEC(ctx) || (IS_VP9_DEC(ctx) && UNDER_4K_RES(ctx))) + ctx->dpb_count =3D mfc_core_get_dpb_count() + 7 - MFC_EXTRA_DPB; + else + ctx->dpb_count =3D mfc_core_get_dpb_count(); mfc_ctx_debug(2, "dpb_count: %d\n", ctx->dpb_count); =20 ctx->scratch_buf_size =3D mfc_core_get_scratch_size(); =20 mfc_core_dec_get_crop_info(core, ctx); dec->mv_count =3D mfc_core_get_mv_count(); + profile =3D mfc_core_get_profile(); + + if (CODEC_422FORMAT(ctx) && dev->pdata->support_422) { + if (mfc_core_get_chroma_format() =3D=3D MFC_REG_D_CHROMA_422) { + ctx->is_422 =3D 1; + mfc_info("[STREAM] 422 chroma format\n"); + } + } + + if (IS_MV_HEVC_DEC(ctx, profile)) { + if (ctx->ready_to_be_multi_view_enable) { + mfc_debug(2, "It will be enabled later, pending DPB_FLUSH.\n"); + } else { + mfc_debug(2, "[MV-HEVC] enabled\n"); + ctx->multi_view_enable =3D 1; + ctx->select_view =3D MFC_VIEW_ID_MAIN; + } + } =20 if (ctx->img_width =3D=3D 0 || ctx->img_height =3D=3D 0) { mfc_err("[STREAM] wrong resolution w: %d, h: %d\n", @@ -1243,7 +1361,7 @@ static int __mfc_handle_seq_dec(struct mfc_core *core= , struct mfc_ctx *ctx) strm_size =3D mfc_dec_get_strm_size(ctx, src_mb); mfc_debug(2, "[STREAM] header size, %d, %#x, consumed, %d, %#x\n", strm_size, strm_size, consumed, consumed); - if ((IS_H264_DEC(ctx)) && + if ((IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx)) && (consumed > 0 && strm_size > consumed)) { dec->consumed +=3D consumed; mfc_debug(2, "[STREAM] there is remained bytes(%d) after header parsing= \n", @@ -1257,6 +1375,13 @@ static int __mfc_handle_seq_dec(struct mfc_core *cor= e, struct mfc_ctx *ctx) mfc_debug(2, "[FRAME] display delay for first frame %d\n", dec->frame_display_delay); =20 + if (IS_VP9_DEC(ctx)) { + dec->color_range =3D mfc_core_get_color_range(); + dec->color_space =3D mfc_core_get_color_space(); + mfc_debug(2, "color range: %d, color space: %d, It's valid for VP9\n", + dec->color_range, dec->color_space); + } + mfc_change_state(core_ctx, MFCINST_HEAD_PARSED); =20 return 0; diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c b= /drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c index 6950b8451c3d..0cc5d1d9433e 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.c @@ -52,7 +52,8 @@ unsigned int mfc_get_frame_error_type(struct mfc_ctx *ctx= , unsigned int err) return MFC_ERR_FRAME_NO_ERR; } =20 - if (mfc_get_warn(err) =3D=3D MFC_REG_ERR_BROKEN_LINK) { + if ((IS_VC1_RCV_DEC(ctx) && (mfc_get_warn(err) =3D=3D MFC_REG_ERR_SYNC_PO= INT_NOT_RECEIVED)) || + (mfc_get_warn(err) =3D=3D MFC_REG_ERR_BROKEN_LINK)) { mfc_ctx_debug(2, "[FRAME] Broken frame error (%d)\n", mfc_get_warn(err)); return MFC_ERR_FRAME_BROKEN; } else if (mfc_get_warn(err) =3D=3D MFC_REG_ERR_SYNC_POINT_NOT_RECEIVED) { @@ -104,6 +105,7 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ctx = *core_ctx) int buf_size; int align_gap; unsigned int reg =3D 0; + unsigned int av1_static_buf_size =3D 0; =20 buf_addr =3D core_ctx->codec_buf.daddr; buf_size =3D core_ctx->codec_buf.size; @@ -124,14 +126,50 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ct= x *core_ctx) buf_addr +=3D ctx->scratch_buf_size; buf_size -=3D ctx->scratch_buf_size; =20 - if (IS_H264_DEC(ctx)) + if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_AV= 1_DEC(ctx)) MFC_CORE_WRITEL(ctx->mv_size, MFC_REG_D_MV_BUFFER_SIZE); =20 + if (IS_VP9_DEC(ctx)) { + MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR); + MFC_CORE_WRITEL(DEC_STATIC_BUFFER_SIZE, MFC_REG_D_STATIC_BUFFER_SIZE); + buf_addr +=3D DEC_STATIC_BUFFER_SIZE; + buf_size -=3D DEC_STATIC_BUFFER_SIZE; + } else if (IS_AV1_DEC(ctx)) { + av1_static_buf_size =3D DEC_AV1_STATIC_BUFFER_SIZE(ctx->img_width, ctx->= img_height); + MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_STATIC_BUFFER_ADDR); + MFC_CORE_WRITEL(av1_static_buf_size, MFC_REG_D_STATIC_BUFFER_SIZE); + buf_addr +=3D av1_static_buf_size; + buf_size -=3D av1_static_buf_size; + } + + if (IS_MPEG4_DEC(ctx) && dec->loop_filter_mpeg4) { + mfc_debug(2, "Add DPB for loop filter of MPEG4\n"); + for (i =3D 0; i < NUM_MPEG4_LF_BUF; i++) { + MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_LUMA_DPB0 + (4 * i)= ); + buf_addr +=3D ctx->loopfilter_luma_size; + buf_size -=3D ctx->loopfilter_luma_size; + + MFC_CORE_DMA_WRITEL(buf_addr, MFC_REG_D_POST_FILTER_CHROMA_DPB0 + (4 * = i)); + buf_addr +=3D ctx->loopfilter_chroma_size; + buf_size -=3D ctx->loopfilter_chroma_size; + } + reg |=3D ((dec->loop_filter_mpeg4 & MFC_REG_D_INIT_BUF_OPT_LF_CTRL_MASK) + << MFC_REG_D_INIT_BUF_OPT_LF_CTRL_SHIFT); + } + reg |=3D (dec->is_dynamic_dpb << MFC_REG_D_INIT_BUF_OPT_DYNAMIC_DPB_SET_S= HIFT); =20 + if (CODEC_NOT_CODED(ctx)) { + reg |=3D BIT(MFC_REG_D_INIT_BUF_OPT_COPY_NOT_CODED_SHIFT); + mfc_debug(2, "Notcoded frame copy mode start\n"); + } + /* 16byte align, It is valid only for VP9 */ reg &=3D ~BIT(MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN); - + if (IS_VP9_DEC(ctx) && MFC_FEATURE_SUPPORT(dev, dev->pdata->vp9_stride_al= ign)) { + reg &=3D ~(0x3 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN); + reg |=3D (0x2 << MFC_REG_D_INIT_BUF_OPT_STRIDE_SIZE_ALIGN); + } reg &=3D ~BIT(MFC_REG_D_INIT_BUF_OPT_TWO_MODE_ENABLE_SHIFT); if (IS_MULTI_MODE(ctx)) { reg |=3D BIT(MFC_REG_D_INIT_BUF_OPT_TWO_MODE_ENABLE_SHIFT); @@ -158,7 +196,7 @@ int mfc_core_set_dec_codec_buffers(struct mfc_core_ctx = *core_ctx) =20 frame_size_mv =3D ctx->mv_size; MFC_CORE_WRITEL(dec->mv_count, MFC_REG_D_NUM_MV); - if (IS_H264_DEC(ctx)) { + if (IS_H264_DEC(ctx) || IS_H264_MVC_DEC(ctx) || IS_HEVC_DEC(ctx) || IS_AV= 1_DEC(ctx)) { if (ctx->mv_buffer_allocated && buf_size && buf_size > ctx->mv_buf.dma_buf->size) { mfc_info("[MEMINFO] Not enough MV buf size %d alloc size %zu\n", diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h b= /drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h index e7c28b2f2b5d..08f74bd56f3f 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_reg_api.h @@ -89,12 +89,15 @@ >> MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_SHIFT)\ & MFC_REG_D_H264_INFO_MBAFF_FRAME_FLAG_MASK) =20 +#define mfc_core_get_aspect_ratio() MFC_CORE_READL(MFC_REG_D_DISPLAY_ASPEC= T_RATIO) #define mfc_core_get_img_width() MFC_CORE_READL(MFC_REG_D_DISPLAY_FRAME_W= IDTH) #define mfc_core_get_img_height() MFC_CORE_READL(MFC_REG_D_DISPLAY_FRAME_H= EIGHT) #define mfc_core_get_disp_y_addr() MFC_CORE_DMA_READL(MFC_REG_D_DISPLAY_LU= MA_ADDR) #define mfc_core_get_dec_y_addr() MFC_CORE_DMA_READL(MFC_REG_D_DECODED_LUM= A_ADDR) #define mfc_core_get_crc_luma() MFC_CORE_READL(MFC_REG_D_DISPLAY_FIRST_PL= ANE_CRC) #define mfc_core_get_crc_chroma() MFC_CORE_READL(MFC_REG_D_DISPLAY_SECOND_= PLANE_CRC) +#define mfc_core_get_crc_luma_2bit() MFC_CORE_READL(MFC_REG_D_DISPLAY_FIRS= T_PLANE_2BIT_CRC) +#define mfc_core_get_crc_chroma_2bit() MFC_CORE_READL(MFC_REG_D_DISPLAY_SE= COND_PLANE_2BIT_CRC) =20 /* kind of interrupt */ #define mfc_core_get_int_err() MFC_CORE_READL(MFC_REG_ERROR_CODE) @@ -104,10 +107,13 @@ #define mfc_core_get_dpb_count() MFC_CORE_READL(MFC_REG_D_MIN_NUM_DPB) #define mfc_core_get_min_dpb_size(x) \ MFC_CORE_READL(MFC_REG_D_MIN_FIRST_PLANE_DPB_SIZE + ((x) * 4)) +#define mfc_core_get_min_dpb_size_2bit(x) \ + MFC_CORE_READL(MFC_REG_D_MIN_FIRST_PLANE_2BIT_DPB_SIZE + ((x) * 4)) #define mfc_core_get_scratch_size() MFC_CORE_READL(MFC_REG_D_MIN_SCRATCH_= BUFFER_SIZE) #define mfc_core_get_stride_size(x) \ MFC_CORE_READL(MFC_REG_D_FIRST_PLANE_DPB_STRIDE_SIZE + ((x) * 4)) - +#define mfc_core_get_stride_size_2bit(x) \ + MFC_CORE_READL(MFC_REG_D_FIRST_PLANE_2BIT_DPB_STRIDE_SIZE + ((x) * 4)) #define mfc_core_get_mv_count() MFC_CORE_READL(MFC_REG_D_MIN_NUM_MV) #define mfc_core_get_inst_no() MFC_CORE_READL(MFC_REG_RET_INSTANCE_ID) #define mfc_core_get_sei_avail() MFC_CORE_READL(MFC_REG_D_SEI_AVAIL) @@ -133,14 +139,27 @@ #define mfc_core_get_sei_avail_mastering_display() ((MFC_CORE_READL(MFC_RE= G_D_SEI_AVAIL) \ >> MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_SHIFT) \ & MFC_REG_D_SEI_AVAIL_MASTERING_DISPLAY_MASK) - +#define mfc_core_get_sei_avail_st_2094_40() ((MFC_CORE_READL(MFC_REG_D_SE= I_AVAIL) \ + >> MFC_REG_D_SEI_AVAIL_ST_2094_40_SHIFT) \ + & MFC_REG_D_SEI_AVAIL_ST_2094_40_MASK) +#define mfc_core_get_sei_nal_meta_status() ((MFC_CORE_READL(MFC_REG_METADA= TA_STATUS) \ + >> MFC_REG_SEI_NAL_STATUS_SHIFT) \ + & MFC_REG_SEI_NAL_STATUS_MASK) #define mfc_core_get_video_signal_type() ((MFC_CORE_READL(MFC_REG_D_VIDEO_= SIGNAL_TYPE) \ >> MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_SHIFT) \ & MFC_REG_D_VIDEO_SIGNAL_TYPE_FLAG_MASK) #define mfc_core_get_colour_description() ((MFC_CORE_READL(MFC_REG_D_VIDEO= _SIGNAL_TYPE) \ >> MFC_REG_D_COLOUR_DESCRIPTION_FLAG_SHIFT) \ & MFC_REG_D_COLOUR_DESCRIPTION_FLAG_MASK) - +#define mfc_core_get_primaries() ((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_= TYPE) \ + >> MFC_REG_D_COLOUR_PRIMARIES_SHIFT) \ + & MFC_REG_D_COLOUR_PRIMARIES_MASK) +#define mfc_core_get_transfer() ((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGNAL_= TYPE) \ + >> MFC_REG_D_TRANSFER_CHARACTERISTICS_SHIFT) \ + & MFC_REG_D_TRANSFER_CHARACTERISTICS_MASK) +#define mfc_core_get_matrix_coeff() ((MFC_CORE_READL(MFC_REG_D_VIDEO_SIGN= AL_TYPE) \ + >> MFC_REG_D_MATRIX_COEFFICIENTS_SHIFT) \ + & MFC_REG_D_MATRIX_COEFFICIENTS_MASK) #define mfc_core_get_black_bar_pos_x() ((MFC_CORE_READL(MFC_REG_D_BLACK_B= AR_START_POS) \ >> MFC_REG_D_BLACK_BAR_START_X_SHIFT) \ & MFC_REG_D_BLACK_BAR_START_X_MASK) @@ -160,12 +179,25 @@ & MFC_REG_D_MVC_VIEW_ID_DEC_MASK) #define mfc_core_get_mvc_view_id_disp_order() (MFC_CORE_READL(MFC_REG_D_MV= C_VIEW_ID) \ & MFC_REG_D_MVC_VIEW_ID_DISP_MASK) +#define mfc_core_get_mvc_left_view_id() ((MFC_CORE_READL(MFC_REG_D_MVC_VI= EW_ID) \ + >> MFC_REG_D_MVC_LEFT_VIEW_ID_SHIFT) \ + & MFC_REG_D_MVC_LEFT_VIEW_ID_MASK) #define mfc_core_get_mvc_right_view_id() ((MFC_CORE_READL(MFC_REG_D_MVC_VI= EW_ID) \ >> MFC_REG_D_MVC_RIGHT_VIEW_ID_SHIFT) \ & MFC_REG_D_MVC_RIGHT_VIEW_ID_MASK) #define mfc_core_get_profile() (MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_= PROFILE) \ & MFC_REG_D_DECODED_PIC_PROFILE_MASK) - +#define mfc_core_get_level() ((MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_P= ROFILE) \ + >> MFC_REG_D_PIC_LEVEL_SHIFT) \ + & MFC_REG_D_PIC_LEVEL_MASK) +#define mfc_core_get_luma_bit_depth_minus8() ((MFC_CORE_READL \ + (MFC_REG_D_DECODED_PICTURE_PROFILE) \ + >> MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_SHIFT) \ + & MFC_REG_D_BIT_DEPTH_LUMA_MINUS8_MASK) +#define mfc_core_get_chroma_bit_depth_minus8() ((MFC_CORE_READL \ + (MFC_REG_D_DECODED_PICTURE_PROFILE) \ + >> MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_SHIFT) \ + & MFC_REG_D_BIT_DEPTH_CHROMA_MINUS8_MASK) #define mfc_core_get_display_delay() \ ((MFC_CORE_READL(MFC_REG_D_DECODED_PICTURE_PROFILE) \ >> MFC_REG_D_DISPLAY_DELAY_SHIFT) \ @@ -177,10 +209,34 @@ #define mfc_core_get_dec_used_flag() (((unsigned long)(MFC_CORE_READL \ (MFC_REG_D_USED_DPB_FLAG_UPPER)) << 32) | \ MFC_CORE_READL(MFC_REG_D_USED_DPB_FLAG_LOWER)) - +#define mfc_core_get_chroma_format() (MFC_CORE_READL(MFC_REG_D_CHROMA_FOR= MAT) \ + & MFC_REG_D_CHROMA_FORMAT_MASK) +#define mfc_core_get_color_range() ((MFC_CORE_READL(MFC_REG_D_CHROMA_FORM= AT) \ + >> MFC_REG_D_COLOR_RANGE_SHIFT) \ + & MFC_REG_D_COLOR_RANGE_MASK) +#define mfc_core_get_color_space() ((MFC_CORE_READL(MFC_REG_D_CHROMA_FORM= AT) \ + >> MFC_REG_D_COLOR_SPACE_SHIFT) \ + & MFC_REG_D_COLOR_SPACE_MASK) #define mfc_core_get_num_of_tile() ((MFC_CORE_READL(MFC_REG_D_DECODED_STA= TUS) \ >> MFC_REG_DEC_STATUS_NUM_OF_TILE_SHIFT) \ & MFC_REG_DEC_STATUS_NUM_OF_TILE_MASK) +#define mfc_core_get_lcu_size() (MFC_CORE_READL(MFC_REG_D_HEVC_INFO) \ + & MFC_REG_D_HEVC_INFO_LCU_SIZE_MASK) +#define mfc_core_get_disp_res_change() ((MFC_CORE_READL(MFC_REG_D_VP9_INF= O) \ + >> MFC_REG_D_VP9_INFO_DISP_RES_SHIFT) \ + & MFC_REG_D_VP9_INFO_DISP_RES_MASK) +#define mfc_core_get_disp_res_change_av1() ((MFC_CORE_READL(MFC_REG_D_AV1_= INFO) \ + >> MFC_REG_D_AV1_INFO_DISP_RES_SHIFT) \ + & MFC_REG_D_AV1_INFO_DISP_RES_MASK) +#define mfc_core_get_showable_frame() ((MFC_CORE_READL(MFC_REG_D_AV1_INFO= ) \ + >> MFC_REG_D_AV1_INFO_SHOWABLE_FRAME_SHIFT) \ + & MFC_REG_D_AV1_INFO_SHOWABLE_FRAME_MASK) +#define mfc_core_get_multiple_show_frame() ((MFC_CORE_READL(MFC_REG_D_AV1_= INFO) \ + >> MFC_REG_D_AV1_INFO_MULTIPLE_SHOW_SHIFT) \ + & MFC_REG_D_AV1_INFO_MULTIPLE_SHOW_MASK) +#define mfc_core_get_hevc_pic_output_flag() ((MFC_CORE_READL(MFC_REG_D_HEV= C_INFO) \ + >> MFC_REG_D_HEVC_INFO_PIC_OUTPUT_FLAG_SHIFT) \ + & MFC_REG_D_HEVC_INFO_PIC_OUTPUT_FLAG_MASK) =20 static inline void mfc_core_dec_get_crop_info(struct mfc_core *core, struct mfc_ctx *ctx) @@ -201,6 +257,15 @@ static inline void mfc_core_dec_get_crop_info(struct m= fc_core *core, dec->cr_bot =3D bottom; } =20 +static inline void mfc_core_clear_roi_enable(struct mfc_core *core) +{ + unsigned int reg =3D 0; + + reg =3D MFC_CORE_READL(MFC_REG_E_RC_ROI_CTRL); + reg &=3D ~(0x1); + MFC_CORE_WRITEL(reg, MFC_REG_E_RC_ROI_CTRL); +} + static inline void mfc_core_update_tag(struct mfc_core *core, struct mfc_c= tx *ctx, int tag) { diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c b/dri= vers/media/platform/samsung/exynos-mfc/mfc_core_run.c index 118108f910e2..127d19c4d1cb 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_run.c @@ -369,6 +369,10 @@ int mfc_core_run_dec_frame(struct mfc_core *core, stru= ct mfc_ctx *ctx) last_frame =3D __mfc_check_last_frame(core_ctx, src_mb); ret =3D mfc_core_cmd_dec_one_frame(core, ctx, last_frame, src_index); =20 + if (dec->consumed && IS_MULTI_MODE(ctx) && !CODEC_MULTIFRAME(ctx)) { + mfc_debug(2, "[STREAM][2CORE] clear consumed for next core\n"); + dec->consumed =3D 0; + } return ret; } =20 diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c b/driv= ers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c index 3097a6c0bf14..626c8db5f93b 100644 --- a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c +++ b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_vb2.c @@ -9,6 +9,7 @@ * Himanshu Dewangan, */ =20 +#include "mfc_dec_v4l2.h" #include "mfc_dec_vb2.h" =20 #include "mfc_rm.h" --=20 2.34.1