From patchwork Fri Aug 6 04:15:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422673 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91081C4338F for ; Fri, 6 Aug 2021 04:16:33 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2AC3E608FC for ; Fri, 6 Aug 2021 04:16:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2AC3E608FC Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=t8Giad2N8kLt4l515zOh3OaICBkfeyaG/Z0guObTlw0=; b=Ut7xRMEntpfpnQyz2nNNpUofZT KRzszc2fg3acVg4bUzqgnQeD0RyiZdC+BDOVblft0gKNVDazhemZyhULTJjOg9DCSXt5eavCi6PQ8 C89RtHbfio87dRhLn3HiFBX+kkwtS+8IOoW+RnHwyc34SFPN/V6Vcn4SHr+f2l+GlRThUVWvYaCwy A+4RRA5BsTBRjLCH9eNo4TxWcSrDsVbyNu8ebsgBrNh+3mcn4FYDZA9yTa++Vmgt04OFfmLlZgmE+ Pyf9VCGwc8p2svGbfCcaTPm1Q8wTZQvnV7cGk059DXadVhvUGJr/DjwWT+wel3vXQiO256eBrVKVW H4NjWjqQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHT-00BT10-Gt; Fri, 06 Aug 2021 04:16:23 +0000 Received: from mail-qt1-x84a.google.com ([2607:f8b0:4864:20::84a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrH5-00BSrU-Ct for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:00 +0000 Received: by mail-qt1-x84a.google.com with SMTP id e3-20020ac80b030000b029028ac1c46c2aso3780271qti.2 for ; Thu, 05 Aug 2021 21:15:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=WL3xTLZhfFrhkuc0OkQrHT12omffck/a/CybJO83okg=; b=R5gi+wfQozM+tZmJxMGO77+NbPcGSEqShKmY1tmDXb6iXvWLefwje5oDCIr0Oi12TI s2WSxUGQMGewK6zp1nesYCPh5Ju/7pZkDZ2NFVDRBbC2oQp9ejMIPzqfVYyb0MOpfvnr 0SmKzgDLbJBY+J3tyHxpiduBBbftX2KWf1KTG4XKOCEUyvK49508x3muFkf75Pd4VgE0 6UGaCSvcSzPttBpWBfHDjhrodXR/JAE2nUrttIB/xQfzSHJmWrJx4msrXI1OCbmM8sRd eTW4R7eT7ADmyCtNRccrfaLZ0n0CR5N8FgcYjyGw4ykYBR/jwJCtch0SJrJXh0KoMkeW USCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=WL3xTLZhfFrhkuc0OkQrHT12omffck/a/CybJO83okg=; b=oIenfmzR2hG427hEiCMdbI8FJdouBOTXJY0W9JWHA7pgunAPtwxD5sGdPj8a8x0d6O /uHJ65U40Cj5AY7O70UVpHtqkseuKhwDGe36QYvRFKnUf+KyS78ahuxx3n97/N6mFHhj Cb9BjhArZCR3ggn660hmZ0TUYbD6VPKfyzOwfebKTGmUBCiHiT1hKZt4mo1/Yz4ZzB+5 czdxmZ+cQT9bZKL/HbkOwxE20jJbmrao+0xupY5E3l4BQGEPUTEhypI5yhcTbIAxmBGL mx360kvz2Ms2GQatVvbMYvz6MbxpWdMooZZuBNQ+2bDgtxyXPRJ+JTeYEAX+uS28mny5 4r7w== X-Gm-Message-State: AOAM531XfQI4hSHsVAPFA7vIykRaQKdK4rBWJ0hQR9qF3E9vvjFl9ZYb DGOfSmu4rESM0ukb8VCkCin+JgeUiLMJ X-Google-Smtp-Source: ABdhPJxBsaIDHmyQ29WaZg2znI4qKV7rxgagb+NJIsfnJzseCynAI4hpCV8igttTVtE9rT4oRwzVuBmDRsN2 X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a05:6214:3001:: with SMTP id ke1mr9176750qvb.52.1628223355982; Thu, 05 Aug 2021 21:15:55 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:17 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-2-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 01/14] media: mtk-vcodec: vdec: Support H264 profile control From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com, Hirokazu Honda X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211559_465781_FEF57EA4 X-CRM114-Status: UNSURE ( 8.03 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Hirokazu Honda Add H264 profiles supported by the MediaTek 8173 decoder. Signed-off-by: Hirokazu Honda [acourbot: fix commit log a bit, move to mtk_vcodec_dec.c] Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 56d86e59421e..8df8bcfe5e9c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -1421,6 +1421,16 @@ int mtk_vcodec_dec_ctrls_setup(struct mtk_vcodec_ctx *ctx) 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", From patchwork Fri Aug 6 04:15:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422675 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E10E7C4320E for ; Fri, 6 Aug 2021 04:16:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A9A0A608FC for ; Fri, 6 Aug 2021 04:16:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A9A0A608FC Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=KyG8XnfuaUR94MAUz8CIAwLqoQeceSg9XQ6M2Jtj/O0=; b=Tdo1tFWtRu+tJ/if0woTRW+GyH IiBX/rcSIfTyOQ9bcId/SeKeC7EHEelOZL2yNoIL1GFTwHZV65qZobdqXVpdVZp/NCkgSSHlsaqdL XYXK6Mt85438hOZWY+Hp8UM/qbiF1UXUPdvOiVWwYcnmRAWyqvhybny9AgGHSK47bs5x/Xdkk4aya avsFZSWMqknSYslkNMkf/L6vogwWghONPeaCIwXeo3OoZK2YQOO42TVzh0oAH7rn079RORvGLAowT VL9bZEGVyIhXJzG6/V7Ez+UwzdT3ZOiOzMj3J+v2ApkY8gmTvpEYceiLnD6dA5gogmNVm7W7XPlRu KAjucD3g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHV-00BT2A-Ni; Fri, 06 Aug 2021 04:16:25 +0000 Received: from mail-qt1-x849.google.com ([2607:f8b0:4864:20::849]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrH7-00BSsO-VJ for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:03 +0000 Received: by mail-qt1-x849.google.com with SMTP id 21-20020ac857150000b029024e8c2383c1so3765644qtw.5 for ; Thu, 05 Aug 2021 21:16:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DhkoP3CndI6xOQyniDPb4V1Ek5PJMvMmCPk1Pl/SFdk=; b=uE4ntQ3e6/bd319jhZU2640yqFPUWgI9Z1oQV6U50RDeC8CGxXBq7QWAVZaWSkPUCY Z8MRdY6/n6QIl7KSfmwzK4yf51Iy8sXYxYqgHGS//Fhz4/Cyoj2WJSUbd4FsXMiyVSI1 otDzL4yIQuLjaEDO5J6QHCbAEOihaTVaZe6QOpzKmSbsCo9KbB3JHbCiPpYqpovSLX+y pbcHEITB9K7/f/1vHV0w2D/7XdAYxMzK3KYP7+hxiZZuRogOhivHt9PRKHAIolD704nH 0ScMhmeZF4OOr3qriS0+ytBI/fdZC0BXt2HAf2EZzWLFeH2x9dQp5VOPTxdYhrBVMhmT ecEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DhkoP3CndI6xOQyniDPb4V1Ek5PJMvMmCPk1Pl/SFdk=; b=O/LiXI/38yhrXy+ICSI7lRt++WIsisi286C+KS9VrjilYhs5a0M+xLaHktnYeWAJRn 1I2/GKIij6tO+AaD8N4kYC8Ou6OHV/T5tOd48jlNv6Z5n7m9dZfPNjLqlnslIpPYf4H2 /AdfWyF5r3NBP3Ep7lk7ibyzwL5/FV8E81AzN4AYr88IbVLJR/g9vEBF+3zI49E6Ye+F 0IxcUiXC/n2eHpP8Lw1LZy+3AVTAFmgPlH0m5MKW9RUxU8CEKYYcfhIOkdzwVteWJIaY uZXr5700c8lbmwgOyjA+J2FPYsivaxb2AgnebL66JalebFQFd26I+F1D4JN2utz7vlou dGPA== X-Gm-Message-State: AOAM531/dENcrWEy+SvSWIKfYQUCz3gxtoVqdfcphu8Ftbm4wFso5LhD 5wHeICCvcXqZlrAqLAvzEMTe90tKY/wb X-Google-Smtp-Source: ABdhPJwDOZAFSB2KFl1TezoMeHIutNrC0Fy4BBTwqgurX8ctFKbAVKr3I5BgwGL0MmxhDupCCXCF9+RjcYUF X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a05:6214:2a85:: with SMTP id jr5mr9022641qvb.5.1628223359525; Thu, 05 Aug 2021 21:15:59 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:18 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-3-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 02/14] media: mtk-vcodec: vdec: use helpers in VIDIOC_(TRY_)DECODER_CMD From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211602_040696_8DBC39F5 X-CRM114-Status: UNSURE ( 9.41 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot Let's use the dedicated helpers to make sure we get the expected behavior and remove redundant code. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 8df8bcfe5e9c..1a633b485a69 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -484,18 +484,7 @@ static void mtk_vdec_worker(struct work_struct *work) static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { - switch (cmd->cmd) { - case V4L2_DEC_CMD_STOP: - case V4L2_DEC_CMD_START: - if (cmd->flags != 0) { - mtk_v4l2_err("cmd->flags=%u", cmd->flags); - return -EINVAL; - } - break; - default: - return -EINVAL; - } - return 0; + return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd); } From patchwork Fri Aug 6 04:15:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE7A1C4338F for ; Fri, 6 Aug 2021 04:16:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6721C611C5 for ; Fri, 6 Aug 2021 04:16:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6721C611C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=IngNQVUGVqGta5G9TJ5AMcOvTiiC5oljk0AttG8ej6E=; b=UIGXQxAAJw9kGGjt2MqOIT3ddk CsDSKqxfTPxyuVW2SdkB2WIOX/kDJ7XnPyaLh6Oz1q1hQa8N7MTgfhWlCuUHbmP/nY2yykx/fh6Cf rSZDNJyrsb8nQ7+3aTPvDCKtO9KFsMr+CBR3KeCDhMHnE/YQHz9DrqxiVUtwi3Y+7fUcKHzJ6FqIw bQe0tH4yX3NjnKstpdjvF1v7jAnFVrLgE2VxaEXSJ2QhjE6xr9gQFft1whpk0y5M+hDRYan3MgCd7 0cFAikjGGdMogiLz9nuySI9e2QHAuKoDqeK9V7sQvgJNffgCRc1MvaHOwv/Mh9aVljFThfDSgJVtx 2Ic2AG7g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHu-00BTIn-3s; Fri, 06 Aug 2021 04:16:50 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHA-00BStV-R8 for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:06 +0000 Received: by mail-yb1-xb49.google.com with SMTP id q3-20020a25bfc30000b02905592911c932so8377188ybm.15 for ; Thu, 05 Aug 2021 21:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=FlUyCuv7nkwXTSJ3TTeSOKCRVd1rmSaLBcPma8bxmIM=; b=pMYzDnLMqRNNyVX7IyuBXL5iUhkbKDXXpG0CxRp58y7sq4gjNrB3bz4oxGfwUiKR64 VjThSogoktlM+DG5BrtqtQvZ0bR0uRyK3tnL78Pr82fGOVHWURGaGEh9juJVyas8h8kN g/VZ0mB5H86LnfK7zM5awlyoPkGBLet+GtFWs7V/ql2mpIsO8jX7+DaCxcgeid0NWltU dOMbnMntZ3UdQe+MWCyEwz+5Xe2qrPfHqTUBBmyVX8vxNNHCRvjM1213/jShbPO84Dzg +00LwAAKtR6qMy1HbI6IjgozhgFWeSjF0y83cCRfypy0vz3Dco/Z42vUkKi1nibgoQl+ L/2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=FlUyCuv7nkwXTSJ3TTeSOKCRVd1rmSaLBcPma8bxmIM=; b=ifsxWEQPVKzKUeFEiV4xpH6aDLH0uRdiN7yOsvNdgYaNsdIuQHUOqtIfGDNbXYpxz3 26MtLGZKjOD6pLDGTEMnHBTE9QFYJnoR7typc0Kvl3BZFWjR2J8TjmuochWh6+n4GI7Y ryxvq3441pylESDAf4aqd3QqmyjYZRkof8YM9Q4B5E7EOWiJfu1Nv+z1czgS76FO9Cai a484RNevjlm4PJgrvGuUC+ycYeDksqoenLlPlFHT+enq4dOODBNmyVsb0vnqjpCzQCn6 wvmxdMssGV3agMBLoOBD+W4WSMQJbv4QEP3N63i23oknJlz06Mw9cgLxOpQXd8BAgF1X wF/g== X-Gm-Message-State: AOAM5337y0XQg5ag4dKQnIAWGvbJ03ecLN7SBqbgpzRBSDk27DZMDMWK ReNPr092BY5hh84zAqVB9ScIZek1VWpt X-Google-Smtp-Source: ABdhPJxQsftZR7o7MRHdKIkC/yVIzT3BAW7EZW5HLGDHihPAsV9sxnwfsKyRFnWdjjB/0CB/Lo9V4t1gqchB X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a25:7810:: with SMTP id t16mr10800664ybc.352.1628223363503; Thu, 05 Aug 2021 21:16:03 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:19 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-4-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 03/14] media: mtk-vcodec: vdec: clamp OUTPUT resolution to hardware limits From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211604_924101_9B081479 X-CRM114-Status: GOOD ( 12.05 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot Calling S_FMT or TRY_FMT on the OUTPUT queue should adjust the resolution to the limits supported by the hardware. Until now this was only done on the CAPTURE queue, which could make clients believe that unsupported resolutions can be used when they set the coded size on the OUTPUT queue. In the case of the stateless decoder, the problem was even bigger since subsequently calling G_FMT on the CAPTURE queue would result in the unclamped resolution being returned, further inducing the client into error. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 1a633b485a69..16e057f73789 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -649,19 +649,17 @@ static int vidioc_try_fmt(struct v4l2_format *f, 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; - pix_fmt_mp->height = clamp(pix_fmt_mp->height, - MTK_VDEC_MIN_H, - MTK_VDEC_MAX_H); - pix_fmt_mp->width = clamp(pix_fmt_mp->width, - MTK_VDEC_MIN_W, - MTK_VDEC_MAX_W); - /* * Find next closer width align 64, heign align 64, size align * 64 rectangle From patchwork Fri Aug 6 04:15:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422679 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E42DC4338F for ; Fri, 6 Aug 2021 04:17:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F3A5260C3F for ; Fri, 6 Aug 2021 04:17:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F3A5260C3F Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=k102PYm2QxbIYm0+QnVgUXJQM9bXkHpasvYAE3zh9XE=; b=uRmvlsHHfDqyVpf51hYFPb70Fx uC1qEQ4OZ7TfJWYp3xcV32aU6StXp4e8Gb32BK84FKhxvOoFwlXcKYT3kfAR8PaV//Bd7PHCtE023 MpRmm0up80Bs3cGmkbhlgsbRauljAqtm2W1gUlZZqvaxrKShkT58fHWB4aNvK80t+4MzB/VsjN5ae b2NhEvPLhXfZ+4EFO88vMg32SQx9dRQnI0Rk1ZXJSi4dtNUe13Clq4xgDOPpxm0lhjT7MX9n8+dmD 5RUDWrpwZJv2Yq4qdH6xdOWLn+7Dk2rGTUX5Ahzxqwr8fTfavcfffmqDsusV3Iz67sbSQhCCGLeX1 BqoEs6ig==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrIC-00BTU4-DF; Fri, 06 Aug 2021 04:17:08 +0000 Received: from mail-qk1-x74a.google.com ([2607:f8b0:4864:20::74a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHE-00BSuU-Vm for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:11 +0000 Received: by mail-qk1-x74a.google.com with SMTP id c196-20020ae9edcd0000b02903c9e325c3b2so5489624qkg.2 for ; Thu, 05 Aug 2021 21:16:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=eYcWw1nW7jHB277kKKn0ceDffDK/7XF/xGVoXBkrBY8=; b=OuMZS7D7lGu+ZVa6XXIrkUCUShUtisWb9l1JVhda/ltA6EVfVmw1PN0xr8Db7QReEy tZ8VyH/CmEteUbXgUKTJfoU0ZcfsLE4BEv0NlqsBCw7L2PCiZ2X7+gB9foXrICk/9jdC tRSVCjbnHCrT1SbzVh3lRG9VMpAVz94kQ7dRrISgmkCoyQTP52dZh40MuKnrfauMxlME AqK8loxaOcHwUN6PJlmIkS690dnTAuatvGLq4MOIMnIFynRrT6u4+SPzphInhpwe5xGD gLjxpqPuP+MP8LjUk176j1VZZQgb1SWReODw1wXuGzTPZLGH3p5DKo0wKqLRJVXFjrZg lSDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=eYcWw1nW7jHB277kKKn0ceDffDK/7XF/xGVoXBkrBY8=; b=dsAApr9BLYvDFDy3is+VoGajQ5TRF6pAiulFqEKEfC9bEMxttwAHKq1PA/xMOqaA7o 3QD94WBLKVw1lJFSVCNEa751cuvXLuapCM6FdR1B+w4GtqVXTKf06Zjd+KlN55herDYx e7n1B6aSW6tNbVCET6gyHWAUWnQqTnelyXklSAAv0ZXm0I/HgFRmi2m2NPFF3ahMR6K5 lSznWSyxb/9Yl2U61E8OWo8BPzs3Pp9e5E6Pk+uLkYJfgcfunSuerRN4wmuknpf001F4 nKTPi+/B9vIu+1WZYYC0g08WrSWuFYR2EMzY1zJkmrtTWyBXCzmQcodsWHjC6pSoNXzW Wu5g== X-Gm-Message-State: AOAM531mn5LE6MJKGuWXJaBJsnS1TmmorXBpE+frucI5cXM2fcN5UAk0 nBBAGWNP7bqE5iz6IwFZSUnwqYw2ZhJG X-Google-Smtp-Source: ABdhPJxfnNpIju3kspgRlCFg2/ZYUG+rN2HaDKiEmN/sVCGSnId5BWf/0qeqzEb93duwcgVLP6vcxph4O0jv X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a05:6214:c6f:: with SMTP id t15mr9156602qvj.52.1628223366920; Thu, 05 Aug 2021 21:16:06 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:20 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-5-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 04/14] media: mtk-vcodec: make flush buffer reusable by encoder From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211609_127611_DEF5091E X-CRM114-Status: GOOD ( 18.19 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot The flush buffer is a special buffer that tells the decoder driver to send an empty CAPTURE frame to the client with V4L2_BUF_FLAG_LAST set. We need similar functionality for the encoder ; however currently the flush buffer depends on decoder-specific structures and thus cannot be reused with the encoder. Fix this by testing for this buffer by its VB2 address, and not through a dedicated flag stored in a higher-level decoder structure. This also allows us to remove said flag and simplify the code a bit. Since the flush buffer should never be used in the stateless decoder, also add safeguards to check against it. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- .../platform/mtk-vcodec/mtk_vcodec_dec.c | 24 +++++++++---------- .../platform/mtk-vcodec/mtk_vcodec_dec.h | 2 -- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 12 +--------- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 6 +++-- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 16e057f73789..7edd6266dc6a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -368,8 +368,6 @@ static void mtk_vdec_worker(struct work_struct *work) return; } - src_buf_info = container_of(src_buf, struct mtk_video_dec_buf, - m2m_buf.vb); dst_buf_info = container_of(dst_buf, struct mtk_video_dec_buf, m2m_buf.vb); @@ -390,7 +388,7 @@ static void mtk_vdec_worker(struct work_struct *work) pfb->base_y.va, &pfb->base_y.dma_addr, &pfb->base_c.dma_addr, pfb->base_y.size); - if (src_buf_info->lastframe) { + 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); @@ -411,6 +409,10 @@ static void mtk_vdec_worker(struct work_struct *work) 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; @@ -514,8 +516,7 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, 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->m2m_buf.vb); + v4l2_m2m_buf_queue(ctx->m2m_ctx, &ctx->empty_flush_buf.vb); v4l2_m2m_try_schedule(ctx->m2m_ctx); break; @@ -1122,7 +1123,6 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) unsigned int dpbsize = 1, i = 0; struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vb2_v4l2 = NULL; - struct mtk_video_dec_buf *buf = NULL; struct mtk_q_data *dst_q_data; mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", @@ -1132,6 +1132,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *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); @@ -1161,8 +1163,8 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) mtk_v4l2_err("No src buffer"); return; } - buf = container_of(src_buf, struct mtk_video_dec_buf, m2m_buf.vb); - if (buf->lastframe) { + + 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); @@ -1267,8 +1269,6 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { buf->used = false; buf->queued_in_v4l2 = false; - } else { - buf->lastframe = false; } return 0; @@ -1294,9 +1294,7 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { while ((src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx))) { - struct mtk_video_dec_buf *buf_info = container_of( - src_buf, struct mtk_video_dec_buf, m2m_buf.vb); - if (!buf_info->lastframe) + if (src_buf != &ctx->empty_flush_buf.vb) v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index cf26b6c1486a..1f8b7300dce6 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -40,7 +40,6 @@ struct vdec_fb { * @queued_in_vb2: Capture buffer is queue in vb2 * @queued_in_v4l2: Capture buffer is in v4l2 driver, but not in vb2 * queue yet - * @lastframe: Intput buffer is last buffer - EOS * @error: An unrecoverable error occurs on this buffer. * @frame_buffer: Decode status, and buffer information of Capture buffer * @@ -52,7 +51,6 @@ struct mtk_video_dec_buf { bool used; bool queued_in_vb2; bool queued_in_v4l2; - bool lastframe; bool error; struct vdec_fb frame_buffer; }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index f87dc47d9e63..5ce7f1b83e4e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -81,21 +81,14 @@ static int fops_vcodec_open(struct file *file) { struct mtk_vcodec_dev *dev = video_drvdata(file); struct mtk_vcodec_ctx *ctx = NULL; - struct mtk_video_dec_buf *mtk_buf = NULL; int ret = 0; struct vb2_queue *src_vq; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; - mtk_buf = kzalloc(sizeof(*mtk_buf), GFP_KERNEL); - if (!mtk_buf) { - kfree(ctx); - return -ENOMEM; - } mutex_lock(&dev->dev_mutex); - ctx->empty_flush_buf = mtk_buf; ctx->id = dev->id_counter++; v4l2_fh_init(&ctx->fh, video_devdata(file)); file->private_data = &ctx->fh; @@ -121,8 +114,7 @@ static int fops_vcodec_open(struct file *file) } src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); - ctx->empty_flush_buf->m2m_buf.vb.vb2_buf.vb2_queue = src_vq; - ctx->empty_flush_buf->lastframe = true; + 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)) { @@ -162,7 +154,6 @@ static int fops_vcodec_open(struct file *file) err_ctrls_setup: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); - kfree(ctx->empty_flush_buf); kfree(ctx); mutex_unlock(&dev->dev_mutex); @@ -193,7 +184,6 @@ static int fops_vcodec_release(struct file *file) v4l2_ctrl_handler_free(&ctx->ctrl_hdl); list_del_init(&ctx->list); - kfree(ctx->empty_flush_buf); kfree(ctx); mutex_unlock(&dev->dev_mutex); return 0; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index c6c7672fecfb..cad52d8b1463 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "mtk_vcodec_util.h" @@ -249,7 +250,8 @@ struct vdec_pic_info { * @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 + * @empty_flush_buf: a fake size-0 capture buffer that indicates flush. Only + * to be used with encoder and stateful decoder. * * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding @@ -288,7 +290,7 @@ struct mtk_vcodec_ctx { struct work_struct decode_work; struct work_struct encode_work; struct vdec_pic_info last_decoded_picinfo; - struct mtk_video_dec_buf *empty_flush_buf; + struct v4l2_m2m_buffer empty_flush_buf; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; From patchwork Fri Aug 6 04:15:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422681 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67A52C4338F for ; Fri, 6 Aug 2021 04:17:40 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F2F1A611C6 for ; Fri, 6 Aug 2021 04:17:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F2F1A611C6 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=+LVM+g6YUWWLtYpK6E4vxW+X5mYwU64UsxAlg81obHE=; b=mtIw2SGtZc1iODgSNUBZ5ur59t eO8/OI/WpSDWfVGUCrKuZVkyCuqRiZBLsgKGO7G/mUoTL2ITLUItOuPk4EixoW1A9/s0j3HmR8oQx oZZocMaPwGSuj55sy/lmTYVn188ltym/mFVKzT3TUSjz8O700eojUbtsR3qW+gWog+ch7hagfqmlN NgEh7TrjxjnoNB7GkcAmtqQTmM9grLxC5zTY7wvvJyeGbP8YXsH0dR4bbryBdZZXNHvwiHhLvcwAH 7YT/WtVF7Ztewv6+vYxZqOTAyyjCLvOYxPNVp/5QG12V/5POKDCv+anT/xVgTHu1hD+hpFQ0YhJhN j//dB/lQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrIY-00BThO-Am; Fri, 06 Aug 2021 04:17:30 +0000 Received: from mail-qt1-x84a.google.com ([2607:f8b0:4864:20::84a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHH-00BSvs-SZ for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:13 +0000 Received: by mail-qt1-x84a.google.com with SMTP id i8-20020ac85c080000b029026ae3f4adc9so3760601qti.13 for ; Thu, 05 Aug 2021 21:16:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=051WVDzFkrbf0YEHzSxCZ97mCd1m32E+Jb6OrfqpVzE=; b=LIm/3uNLQXpaFzuqj01FdvOZRgZkWSOpY7S4z1EJDHfeP71tCfVOjHmbOPEReR5W8T ws9TU/MTo1VzDMQgebtABwcJTo+wMjY3qKbYqLsb7gmZS7KQkaSmFmht5kVbo+BL1P6L bRUoiCIg0U36+q8gVnfse0/uNXqVJWkgZ8oHcUfgyX+KfOdtbaobCPtNVml1PMrNOrI3 dKWohBSWPnbjE68LxeRllCwGd++Q+rjLAN4CPs7HwatwNlAjs2uMR6/HK02o84mAFFwR ogWbWAL03yWfom5pE3jNFq98/kExdKDKGh0SO2LdMEYR4Tyh4KNTbsSzI7qRBbxa4rfP aqkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=051WVDzFkrbf0YEHzSxCZ97mCd1m32E+Jb6OrfqpVzE=; b=fpjyy+BzQQh2zBgZkHd4EHqLPNtDD2Lp8lVBLsGIhrtvrlbWTLPP6phVSljYid2AFa jbXAi/D+uwe8vrilb4iJPXK8RXDMRfKfpj734mEqYYhgncY2NXgBtoQEI4+u7Ttr8Qsk wmrSEgZIoWT6rhUZ2CM1rYvDSJfk4kvLUYHFuXQIN59u8csyPXv5gPTdKBIQLKj2J24S jQ0WbaGRzR/RnLeV8hnUvozKYRJvPi8RMYycfoIKCYigSvzF0nB6V474v13pxcOqWk6q TOK5tsOjpK8irJ5HqvmQrkupa/iMq0scp8elxNk+ezT0K7T7pCcm4Glzvj/qNXV3beph KCpQ== X-Gm-Message-State: AOAM5335UH0L2VhRTxIP6bzXsqAQXYTAiAndr5Vb/c7sHm6IQmISTXx3 qWD6waKvFG2oWfa7/ygbzH0Qt/7aHCMl X-Google-Smtp-Source: ABdhPJwsDi+IsyxfTKYMvq0PS5q9D2EvSQGns+iOwSbLc/teUDOkbJtasdIzm+YJmK9Fjl69FxTt7DFPGf3s X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a05:6214:2a45:: with SMTP id jf5mr9264242qvb.25.1628223370414; Thu, 05 Aug 2021 21:16:10 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:21 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-6-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 05/14] media: mtk-vcodec: venc: support START and STOP commands From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com, Hsin-Yi Wang X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211611_988438_D30DABE2 X-CRM114-Status: GOOD ( 28.05 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot The V4L2 encoder specification requires encoders to support the V4L2_ENC_CMD_START and V4L2_ENC_CMD_STOP commands. Add support for these to the mtk-vcodec encoder by reusing the same flush buffer as used by the decoder driver. Signed-off-by: Alexandre Courbot [hsinyi: fix double-free issue if flush buffer was not dequeued by the time streamoff is called] Signed-off-by: Hsin-Yi Wang Signed-off-by: Tzung-Bi Shih --- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 2 + .../platform/mtk-vcodec/mtk_vcodec_enc.c | 140 +++++++++++++++++- .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 6 +- 3 files changed, 140 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index cad52d8b1463..cb248d8daa7b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -252,6 +252,7 @@ struct vdec_pic_info { * @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. * * @colorspace: enum v4l2_colorspace; supplemental to pixelformat * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding @@ -291,6 +292,7 @@ struct mtk_vcodec_ctx { struct work_struct encode_work; struct vdec_pic_info last_decoded_picinfo; struct v4l2_m2m_buffer empty_flush_buf; + bool is_flushing; enum v4l2_colorspace colorspace; enum v4l2_ycbcr_encoding ycbcr_enc; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 416f356af363..efa53ea573a2 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -672,6 +672,7 @@ 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", @@ -679,7 +680,83 @@ static int vidioc_venc_dqbuf(struct file *file, void *priv, return -EIO; } - return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); + 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 = { @@ -715,6 +792,9 @@ const struct v4l2_ioctl_ops mtk_venc_ioctl_ops = { .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, @@ -882,9 +962,38 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q) dst_buf->vb2_buf.planes[0].bytesused = 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))) - v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); + 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 && @@ -984,12 +1093,15 @@ 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 = - container_of(vb2_v4l2, struct mtk_video_enc_buf, - m2m_buf.vb); - + 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; @@ -1075,6 +1187,20 @@ static void mtk_venc_worker(struct work_struct *work) } 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 = diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c index 45d1870c83dd..4167e865b23f 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -131,6 +131,7 @@ 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) @@ -157,13 +158,16 @@ static int fops_vcodec_open(struct file *file) goto err_ctrls_setup; } ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev_enc, ctx, - &mtk_vcodec_enc_queue_init); + &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)) { From patchwork Fri Aug 6 04:15:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422689 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF751C432BE for ; Fri, 6 Aug 2021 04:20:05 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6A4A2611C5 for ; Fri, 6 Aug 2021 04:20:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 6A4A2611C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=3wmc5JBnihyS2V2Qcb4sfWED5rLxehkimXhbKsWdGNw=; b=P6tglAEq9EbBaTgh+tLhl37Y27 NAsy0K7tWq4ENnizk3uFQTySoOvhY8suBqlCuzOiuHecwBjcthav8ECASR4onagEPAQSLDc8dA8ix LsYWLkyNb7MmFyk5skkU3N65MDZln7BQyQTRLpfC3m+LSUhM9ftTQzsb5AsxZ/YefSy+BKsGNtsHN uaWkThRZl4CckR6SIEIKegNYqbhOsMZ573xjirh53v3h57HEm6hjVKdzSLAfJL+L5J8I9q3Daf4G0 IwBRM6FOCf623U6cO1O3uCobUsSic3vIEAnkonHQ1bB40Z/T+lptIZrsfNzxaE7x9AzMDwaJVCDuz zeU7bFcw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrKr-00BUvj-1i; Fri, 06 Aug 2021 04:19:53 +0000 Received: from mail-pj1-x104a.google.com ([2607:f8b0:4864:20::104a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHM-00BSxh-Cd for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:27 +0000 Received: by mail-pj1-x104a.google.com with SMTP id na18-20020a17090b4c12b0290178153d1c65so9424029pjb.4 for ; Thu, 05 Aug 2021 21:16:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=gxQ4Dbd/UTPoo7RnHN03fNevFygdipct9lT5oq4NezU=; b=AirrHqAQnUGDa1+9dK2DXL977r8eBCZdHBwP7lp+cv4SZaFivI2SpheYQTGXKsMptN sT6EhGVfYW2e9rx0dH0E8eT2mUxSVX/UuCfCGGuJfpZ2Ek3q01oe3LDw08qFDiEgkljH w01tqRJvWOtTIZJtESBjPj7hx1oT7A7fClYAV0dBOzwC3sojAwvBMewQrDK/s4lssVI3 5ZigMxNREAVe5br9cxeYHSX/J12iWtCyTBF+5KRkApI8AucQ8m+Lkosr0/4+G8xIeWNo fHiU3VYQeWn/A9IogI+UutK8QXvZkLs7OlQ/AM7mkWhKJ8dCdzU1Sr1VcWlwQe/r3T1R 9a7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=gxQ4Dbd/UTPoo7RnHN03fNevFygdipct9lT5oq4NezU=; b=Cn2AMy1mca2g5YGkOVZUirLnRSr3rbSWJKuxKee381Udzv7U52OFg05qcwo6xU8OWQ hazQH4zO6ZlJynm+MkbhOWj9nTHT5GSuhWrs5hmZ3CufRwKJMUfmFhi1Gx1zkKQ1UrCS XxJLSYFzFTzfvGr3uXyGcowboVTb9S/egiNf9u7URAH2PTm5qqi1StbfbwgpfEyYKzdg 1OuZw1Kh9pApsuni14O17Y/P5Nw1b/RbF8osZyUC6mfKlbQUYVUgOgI30yQ26zO4RawM 1M3dLBVI5kOmJPEFM7LhYi175tPoemk2AwBfZwJECFqjlkqzV7PiuA4zA8wvmNfvxZ7J HRCQ== X-Gm-Message-State: AOAM530hh92hVrA9hQ1480lFkclPf/mKWBhL88NB2fT74OPkh9jpolCt X+f16iqLV2SFdku+wsJrrZbRkFa+z47M X-Google-Smtp-Source: ABdhPJynkkkQ3x7yXfeexvgzro5MZi5oovPvW+myhvp6g9FD9qqK0chLB9f6Z/BVF1llRQc86FZrr10Whdnf X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a62:2945:0:b029:3c6:f4e6:c182 with SMTP id p66-20020a6229450000b02903c6f4e6c182mr6763913pfp.72.1628223374427; Thu, 05 Aug 2021 21:16:14 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:22 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-7-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 06/14] media: mtk-vcodec: vdec: move stateful ops into their own file From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211616_539197_B9010543 X-CRM114-Status: GOOD ( 29.88 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yunfei Dong We are planning to add support for stateless decoders to this driver. Part of the driver will be shared between stateful and stateless codecs, but a few ops need to be specialized for both. Extract the stateful part of the driver and move it into its own file, accessible through ops that the common driver parts can call. This patch only moves code around and introduces a set of abstractions ; the behavior of the driver should not be changed in any way. Changes to code styling has been done to accommodate 'checkpatch.pl --strict'. Signed-off-by: Yunfei Dong [acourbot: refactor, cleanup and split] Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot [tzungbi: fix errors from 'checkpatch.pl --strict'] Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/Makefile | 1 + .../platform/mtk-vcodec/mtk_vcodec_dec.c | 737 ++---------------- .../platform/mtk-vcodec/mtk_vcodec_dec.h | 15 +- .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 10 +- .../mtk-vcodec/mtk_vcodec_dec_stateful.c | 627 +++++++++++++++ .../platform/mtk-vcodec/mtk_vcodec_drv.h | 41 + 6 files changed, 750 insertions(+), 681 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 4618d43dbbc8..9c3cbb5b800e 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -11,6 +11,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec_drv_if.o \ vdec_vpu_if.o \ mtk_vcodec_dec.o \ + mtk_vcodec_dec_stateful.o \ mtk_vcodec_dec_pm.o \ mtk-vcodec-enc-y := venc/venc_vp8_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 7edd6266dc6a..a220532802f9 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -16,68 +16,18 @@ #include "vdec_drv_if.h" #include "mtk_vcodec_dec_pm.h" -#define OUT_FMT_IDX 0 -#define CAP_FMT_IDX 3 - -#define MTK_VDEC_MIN_W 64U -#define MTK_VDEC_MIN_H 64U #define DFT_CFG_WIDTH MTK_VDEC_MIN_W #define DFT_CFG_HEIGHT MTK_VDEC_MIN_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, - }, -}; - -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) -#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats) - -static const struct mtk_video_fmt *mtk_vdec_find_format(struct v4l2_format *f) +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 < NUM_FORMATS; k++) { - fmt = &mtk_video_formats[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; } @@ -94,395 +44,6 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, return &ctx->q_data[MTK_Q_DATA_DST]; } -/* - * 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 == NULL) { - 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 == NULL) { - 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) -{ - struct vb2_buffer *framptr; - - do { - framptr = get_display_buffer(ctx); - } while (framptr); -} - -static void clean_free_buffer(struct mtk_vcodec_ctx *ctx) -{ - struct vb2_buffer *framptr; - - do { - framptr = get_free_buffer(ctx); - } while (framptr); -} - -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 void mtk_vdec_flush_decoder(struct mtk_vcodec_ctx *ctx) -{ - bool res_chg; - int ret = 0; - - 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); -} - -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 == NULL) { - 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 == NULL) { - 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 int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { @@ -551,10 +112,12 @@ 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, mtk_vdec_worker); + 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; @@ -564,7 +127,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) 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 = &mtk_video_formats[OUT_FMT_IDX]; + 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; @@ -576,7 +139,7 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx) q_data->visible_height = DFT_CFG_HEIGHT; q_data->coded_width = DFT_CFG_WIDTH; q_data->coded_height = DFT_CFG_HEIGHT; - q_data->fmt = &mtk_video_formats[CAP_FMT_IDX]; + q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt; q_data->field = V4L2_FIELD_NONE; v4l_bound_align_image(&q_data->coded_width, @@ -710,11 +273,14 @@ 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); + fmt = mtk_vdec_find_format(f, dec_pdata); if (!fmt) { - f->fmt.pix.pixelformat = mtk_video_formats[CAP_FMT_IDX].fourcc; - fmt = mtk_vdec_find_format(f); + 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); @@ -725,11 +291,14 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, { 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); + fmt = mtk_vdec_find_format(f, dec_pdata); if (!fmt) { - f->fmt.pix.pixelformat = mtk_video_formats[OUT_FMT_IDX].fourcc; - fmt = mtk_vdec_find_format(f); + 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) { @@ -819,6 +388,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, 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); @@ -847,16 +417,16 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, ret = -EBUSY; } - fmt = mtk_vdec_find_format(f); + fmt = mtk_vdec_find_format(f, dec_pdata); if (fmt == NULL) { if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { f->fmt.pix.pixelformat = - mtk_video_formats[OUT_FMT_IDX].fourcc; - fmt = mtk_vdec_find_format(f); + 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 = - mtk_video_formats[CAP_FMT_IDX].fourcc; - fmt = mtk_vdec_find_format(f); + dec_pdata->default_cap_fmt->fourcc; + fmt = mtk_vdec_find_format(f, dec_pdata); } } if (fmt == NULL) @@ -893,16 +463,17 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, { 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 < NUM_SUPPORTED_FRAMESIZE; ++i) { - if (fsize->pixel_format != mtk_vdec_framesizes[i].fourcc) + 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 = mtk_vdec_framesizes[i].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"); @@ -925,16 +496,20 @@ static int vidioc_enum_framesizes(struct file *file, void *priv, return -EINVAL; } -static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) +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 < NUM_FORMATS; i++) { - if (output_queue && (mtk_video_formats[i].type != MTK_FMT_DEC)) + 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 && - (mtk_video_formats[i].type != MTK_FMT_FRAME)) + dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME) continue; if (j == f->index) @@ -942,10 +517,10 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) ++j; } - if (i == NUM_FORMATS) + if (i == dec_pdata->num_formats) return -EINVAL; - fmt = &mtk_video_formats[i]; + fmt = &dec_pdata->vdec_formats[i]; f->pixelformat = fmt->fourcc; f->flags = fmt->flags; @@ -955,13 +530,13 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) static int vidioc_vdec_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - return vidioc_enum_fmt(f, false); + 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, true); + return vidioc_enum_fmt(f, priv, true); } static int vidioc_vdec_g_fmt(struct file *file, void *priv, @@ -1052,11 +627,9 @@ static int vidioc_vdec_g_fmt(struct file *file, void *priv, return 0; } -static 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_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; @@ -1076,7 +649,7 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, } } else { if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - *nplanes = 2; + *nplanes = q_data->fmt->num_planes; else *nplanes = 1; @@ -1092,7 +665,7 @@ static int vb2ops_vdec_queue_setup(struct vb2_queue *vq, return 0; } -static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) +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; @@ -1114,129 +687,7 @@ static int vb2ops_vdec_buf_prepare(struct vb2_buffer *vb) return 0; } -static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *src_buf; - struct mtk_vcodec_mem src_mem; - bool res_chg = false; - int ret = 0; - unsigned int dpbsize = 1, i = 0; - struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_v4l2_buffer *vb2_v4l2 = NULL; - 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 void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) +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; @@ -1259,7 +710,7 @@ static void vb2ops_vdec_buf_finish(struct vb2_buffer *vb) } } -static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) +int vb2ops_vdec_buf_init(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf); @@ -1274,7 +725,7 @@ static int vb2ops_vdec_buf_init(struct vb2_buffer *vb) return 0; } -static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) +int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) { struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); @@ -1284,10 +735,11 @@ static int vb2ops_vdec_start_streaming(struct vb2_queue *q, unsigned int count) return 0; } -static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) +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); @@ -1319,7 +771,9 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q) ctx->last_decoded_picinfo.buf_w, ctx->last_decoded_picinfo.buf_h); - mtk_vdec_flush_decoder(ctx); + ret = ctx->dev->vdec_pdata->flush_decoder(ctx); + if (ret) + mtk_v4l2_err("DecodeFinal failed, ret=%d", ret); } ctx->state = MTK_STATE_FLUSH; @@ -1366,85 +820,12 @@ static void m2mops_vdec_job_abort(void *priv) ctx->state = MTK_STATE_ABORT; } -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, -}; - -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; -} - 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, }; -static const struct vb2_ops mtk_vdec_vb2_ops = { - .queue_setup = vb2ops_vdec_queue_setup, - .buf_prepare = vb2ops_vdec_buf_prepare, - .buf_queue = vb2ops_vdec_buf_queue, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .buf_init = vb2ops_vdec_buf_init, - .buf_finish = vb2ops_vdec_buf_finish, - .start_streaming = vb2ops_vdec_start_streaming, - .stop_streaming = vb2ops_vdec_stop_streaming, -}; - const struct v4l2_ioctl_ops mtk_vdec_ioctl_ops = { .vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, @@ -1491,7 +872,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, 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 = &mtk_vdec_vb2_ops; + 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; @@ -1506,7 +887,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, 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 = &mtk_vdec_vb2_ops; + 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; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index 1f8b7300dce6..76856c0b2db8 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -16,6 +16,8 @@ #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 @@ -71,7 +73,18 @@ 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); -int mtk_vcodec_dec_ctrls_setup(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 index 5ce7f1b83e4e..1460951f302c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -99,7 +99,7 @@ static int fops_vcodec_open(struct file *file) mutex_init(&ctx->lock); ctx->type = MTK_INST_DECODER; - ret = mtk_vcodec_dec_ctrls_setup(ctx); + ret = dev->vdec_pdata->ctrls_setup(ctx); if (ret) { mtk_v4l2_err("Failed to setup mt vcodec controls"); goto err_ctrls_setup; @@ -214,6 +214,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev) 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; @@ -341,8 +342,13 @@ static int mtk_vcodec_probe(struct platform_device *pdev) return ret; } +extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata; + static const struct of_device_id mtk_vcodec_match[] = { - {.compatible = "mediatek,mt8173-vcodec-dec",}, + { + .compatible = "mediatek,mt8173-vcodec-dec", + .data = &mtk_vdec_8173_pdata, + }, {}, }; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c new file mode 100644 index 000000000000..d77a7688688a --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c @@ -0,0 +1,627 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include + +#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 = { + .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, +}; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index cb248d8daa7b..a3c401022567 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -310,6 +310,45 @@ enum mtk_chip { MTK_MT8192, }; +/** + * 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 + * + * @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; + + bool uses_stateless_api; +}; + /** * struct mtk_vcodec_enc_pdata - compatible data for each IC * @@ -353,6 +392,7 @@ struct mtk_vcodec_enc_pdata { * @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. @@ -388,6 +428,7 @@ struct mtk_vcodec_dev { 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; From patchwork Fri Aug 6 04:15:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422683 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A0EFC4338F for ; Fri, 6 Aug 2021 04:18:43 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 47AA261154 for ; Fri, 6 Aug 2021 04:18:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 47AA261154 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=NhmDOgOh0Eo597HizbSq0o8SKFZnEa1tom7Le2P4rPE=; b=HSQqNDfc0QY5iy0lgKinTRBboW yi4YTUAe5szWSFzg0GKauWh2etuJn9puZiJz2ZMzEhK6fApZZeAuW5kQ3e588MKpaamZs6ygQwYLx tKq87Sry646chGOi4elqlIGx9/Qq0y00jvCHzwvV3YCFyCEJOPvTLRKQzySRLUFFOcBWUp4k4AAE+ b6opCfxJ1+JHr0XnSWeB202263MQWjgWb64AmVhQuBnXctTpLK3kCqgBuvUqSjBalHJqK7Y1bLBcO huvIUSpiKmefPJ24uMh0mMNQ5j3RiveE8689y08A9mSzDInmR1Xu89cVqaJ6awazHcOPS9SBX+kjm mdeyt4mg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrJY-00BUFz-1C; Fri, 06 Aug 2021 04:18:32 +0000 Received: from mail-qv1-xf49.google.com ([2607:f8b0:4864:20::f49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHP-00BSyx-IC for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:23 +0000 Received: by mail-qv1-xf49.google.com with SMTP id s12-20020ad4446c0000b029033a9344451cso5512368qvt.21 for ; Thu, 05 Aug 2021 21:16:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=bMfQaW0c9ygmG1HL2EBTMMtbC3gy/zuhRkysjbbwDZE=; b=G1r/Vt4JTwmVH0RLEgrPMC8VD0S1dv6qzknA/Uc6JdUSqR1ESUvfIeYHS1cvTUocQ/ zvh70XMr/AblVO79lUgyf2hiyqUyd9AaInQBQvOj1b2E4Zn+2KrbfRgVr3JEt2MMm33O 4ydZHWMziHIqb4uLYUhiZ9FpUdfF32djs1uG8+x6KMY9mxD/lTxRYMOpykUeKTRrkStI zB47jlZL8VDA2blAo/T7JUdYUzJ05ygJutiss9dF6AeKD3khEbwMi1VDMDVr1PnYbRdI 1xwgN96gzjLyv35fUBnBwGvfCu1HwTkXR6rlg3E9AtSzpPYLbdjGUFenjPZwsSuxvlyq hHYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=bMfQaW0c9ygmG1HL2EBTMMtbC3gy/zuhRkysjbbwDZE=; b=gncSBZtnOGd3tNVX7u8y0smziqYUi19PzTstjpmLNCKcRE4OTePVFVtGngWxqi1RRY u3YRSZpJl6+M0RUFtO8BZNzDvDsVV6z+eCslNveimi9E5q0rlcYMhFUy2YqaqmPsAuiR xPtkreijZh4ZynVh0M4UMeIZqt6+Ku4tP/gEEs5rTHwbeCwa8DwehInk6P3EwubAPvaQ UxKYqFZpsVGf8+GTAgK/g0cw/jQP1PPxbWdSgDcRl327b7hNP3MrjfzCmIh8IFVxhQcA IUcSA5gopmmqfQCtakEu2CVvze6iEUqn4kbjl/Y7IurvsrozBDQUmav50BzPfuHTLhsK 2uYQ== X-Gm-Message-State: AOAM533U0FCHetbDC2XeCOMcC2ODptnjVMGxVe8F43UJF+oXMQrZhp3h 2HW/Hf2d+Ci+Xk3MbYf7KaAMXfNiX3vw X-Google-Smtp-Source: ABdhPJzyAq+5cZNvcxvEmI7f+b9UDpMUVJDyph4f6xOIx0BzT20sitCWaYTHY+MakssHRt9b2cHXwTWaKjxK X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a05:6214:1585:: with SMTP id m5mr9060205qvw.48.1628223377884; Thu, 05 Aug 2021 21:16:17 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:23 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-8-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 07/14] media: mtk-vcodec: vdec: handle firmware version field From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211619_633373_6B04A793 X-CRM114-Status: GOOD ( 18.88 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot Firmwares for decoders newer than MT8173 will include an ABI version number in their initialization ack message. Add the capacity to manage it and make initialization fail if the firmware ABI is of a version that we don't support. For MT8173, this ABI version field does not exist ; thus ignore it on this chip. There should only be one firmware version available for it anyway. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- .../mtk-vcodec/mtk_vcodec_dec_stateful.c | 1 + .../platform/mtk-vcodec/mtk_vcodec_drv.h | 4 ++++ .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 5 +++++ .../media/platform/mtk-vcodec/vdec_vpu_if.c | 21 +++++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c index d77a7688688a..bef49244e61b 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c @@ -613,6 +613,7 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = { }; 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, diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index a3c401022567..17c960aa5262 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -327,6 +327,8 @@ enum mtk_chip { * @vdec_framesizes: supported video decoder frame sizes * @num_framesizes: count of video decoder frame sizes * + * @chip: chip this decoder is compatible with + * * @uses_stateless_api: whether the decoder uses the stateless API with requests */ @@ -346,6 +348,8 @@ struct mtk_vcodec_dec_pdata { const struct mtk_codec_framesizes *vdec_framesizes; const int num_framesizes; + enum mtk_chip chip; + bool uses_stateless_api; }; diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 68e8d5cb16d7..236bd32dcacc 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -83,12 +83,17 @@ struct vdec_ap_ipi_dec_start { * @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. */ 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; }; #endif diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c index 58b0e6fa8fd2..203089213e67 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -24,6 +24,22 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) vpu->inst_addr = msg->vpu_inst_addr; mtk_vcodec_debug(vpu, "- vpu_inst_addr = 0x%x", vpu->inst_addr); + + /* Firmware version field does not exist on MT8173. */ + if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173) + return; + + /* Check firmware version. */ + mtk_vcodec_debug(vpu, "firmware version 0x%x\n", msg->vdec_abi_version); + switch (msg->vdec_abi_version) { + case 1: + break; + default: + mtk_vcodec_err(vpu, "unhandled firmware version 0x%x\n", + msg->vdec_abi_version); + vpu->failure = 1; + break; + } } /* @@ -44,6 +60,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) 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: @@ -63,8 +82,6 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) } mtk_vcodec_debug(vpu, "- id=%X", msg->msg_id); - vpu->failure = msg->status; - vpu->signaled = 1; } static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len) From patchwork Fri Aug 6 04:15:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422685 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BAC5C4338F for ; Fri, 6 Aug 2021 04:19:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1D8A611CA for ; Fri, 6 Aug 2021 04:19:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F1D8A611CA Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=nK1trG+yEMa6PIFL6gpFXn+qqFx0WW6xbeb8OJkUOqM=; b=B9HNOsnDquMthr9TYG2+J9SPDN JKNOmvvTwUAkBaRziBadcfwGvwALUSvxqHFOwT+lGoNKNNfh6nOABCpN3IhLCBSVvkgx5B1R7dLp+ 1ymAoEXSoPPzF4+gUUunM57pyjdiTnaCl0wL/wtRVoh9aSKWVYaCPm1yCGt9pNHuFuLOzCVvZJxwo vo057ahUlkc+t1vjGWs0KaS+Ng0glKnzXSA9OD9On6CYWLG4MBh8abxB2IoxVZu5SIuc1Jw+/iaWz e4akfGtBYxaNSQqjx2X9ZyFdNn09zwW3veFE8fDxueQJWFUYyerrIlD25Drz57Cn2fZ6u/LS6TW+B YhQWfC4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrKA-00BUaN-0a; Fri, 06 Aug 2021 04:19:10 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHT-00BT0f-72 for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:25 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id 203-20020a250bd40000b02905933fff7091so834759ybl.16 for ; Thu, 05 Aug 2021 21:16:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=KMiHuHCQErhrN5SjWpJpkjbEpv0zQVG783xP6dnXcrg=; b=eAOUxAVIfbG5XOft5w1BYskdV864IeYAz9rMTYPYZ3Kj2hYV21uCuf0UeDs+VocOj8 TSYSlmdjYA3v87OCitnh2NdWEOgpf6SUXyQKmpn+YnM2RicsUPn4vu/1s8EG6LM19b7e B+3FY4DED9oixGR+LDuxTs4U7OsB+ibJaE3OgEphvKNhzlc31eSqcjQ2TGg3YJUEdDWp +9nGU1z0sHEI0ZMBheIKkEHJvmHIIiWPxXG3TUKEAKpKOVUPFnssex0O442Hr8iOuGW+ NwgIXPGovK3dBm0PfzOmgpCVIp55E9fxVa04zUkR/DJPP6OnzofM4KFueWGSEsADj/Km y81Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=KMiHuHCQErhrN5SjWpJpkjbEpv0zQVG783xP6dnXcrg=; b=OfTpu0P5b4+0ehMpPjTmuTN/F617iS1gLS9yqByE0NK1xP2dym9DoxsGZZKLJF+h+S CoX0Y/3jd4WUf2lsXKyjOapRf+s/oWwV97mbgWxa/pUTEfs16MDKDNR98ximadRtpAlH 2rP7rSHQtYmAdRw2lbC9CQ97merC/QalRAD1p7wJYHcYArps9H+Hmd+JNq58tXF5BI2T nyWBMlYSGbGyE8z1RYpNPbICSYpQJVppSpn6ZuhwISSht2DBb8REYSs3h8rK2K1wABkG yquRXAAlReg9BUdK/UPRMpG0VW7BwwvRBXZxdevlUcBB5KYzP+GroZsB2unwddPbPvrB Sagw== X-Gm-Message-State: AOAM530Xu5pCm+5gZZwmtA/hMlpBl2MmPjKKXhXqdNOfzewxRw8wTLey oXPgeOMdpp/jdTWn4xNEVVc6lIKgc57+ X-Google-Smtp-Source: ABdhPJyyIZ7b/efH3D85r4EhAPyGiUPsY1y/vv+rYuYhSb3kmXj4BCIs82vh/h4hICjvfBZFS6GvGbad9Euy X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a25:7cc6:: with SMTP id x189mr11499866ybc.371.1628223381729; Thu, 05 Aug 2021 21:16:21 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:24 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-9-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 08/14] media: mtk-vcodec: support version 2 of decoder firmware ABI From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211623_448135_5C5B77CB X-CRM114-Status: GOOD ( 18.44 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot Add support for decoder firmware version 2, which makes the kernel responsible for managing the VSI context and is used for stateless codecs. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- .../media/platform/mtk-vcodec/vdec_ipi_msg.h | 18 +++++++++--- .../media/platform/mtk-vcodec/vdec_vpu_if.c | 28 +++++++++++++++---- .../media/platform/mtk-vcodec/vdec_vpu_if.h | 5 ++++ 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h index 236bd32dcacc..5f45a537beb4 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h +++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h @@ -29,11 +29,15 @@ enum vdec_ipi_msgid { /** * struct vdec_ap_ipi_cmd - generic AP to VPU ipi command format * @msg_id : vdec_ipi_msgid - * @vpu_inst_addr : VPU decoder instance address + * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2. + * @inst_id : instance ID. Used if the ABI version >= 2. */ struct vdec_ap_ipi_cmd { uint32_t msg_id; - uint32_t vpu_inst_addr; + union { + uint32_t vpu_inst_addr; + uint32_t inst_id; + }; }; /** @@ -63,7 +67,8 @@ struct vdec_ap_ipi_init { /** * struct vdec_ap_ipi_dec_start - for AP_IPIMSG_DEC_START * @msg_id : AP_IPIMSG_DEC_START - * @vpu_inst_addr : VPU decoder instance address + * @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 @@ -72,7 +77,10 @@ struct vdec_ap_ipi_init { */ struct vdec_ap_ipi_dec_start { uint32_t msg_id; - uint32_t vpu_inst_addr; + union { + uint32_t vpu_inst_addr; + uint32_t inst_id; + }; uint32_t data[3]; uint32_t reserved; }; @@ -87,6 +95,7 @@ struct vdec_ap_ipi_dec_start { * 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; @@ -94,6 +103,7 @@ struct vdec_vpu_ipi_init_ack { 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_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c index 203089213e67..5dffc459a33d 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c @@ -25,18 +25,30 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg) 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. */ - mtk_vcodec_debug(vpu, "firmware version 0x%x\n", msg->vdec_abi_version); - switch (msg->vdec_abi_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", - msg->vdec_abi_version); + vpu->fw_abi_version); vpu->failure = 1; break; } @@ -113,7 +125,10 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id) memset(&msg, 0, sizeof(msg)); msg.msg_id = msg_id; - msg.vpu_inst_addr = vpu->inst_addr; + if (vpu->fw_abi_version < 2) + msg.vpu_inst_addr = vpu->inst_addr; + else + msg.inst_id = vpu->inst_id; err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg)); mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err); @@ -163,7 +178,10 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len) memset(&msg, 0, sizeof(msg)); msg.msg_id = AP_IPIMSG_DEC_START; - msg.vpu_inst_addr = vpu->inst_addr; + 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]; diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h index 85224eb7e34b..c2ed5b6cab8b 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h +++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h @@ -18,6 +18,9 @@ struct mtk_vcodec_ctx; * 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 @@ -29,6 +32,8 @@ struct vdec_vpu_inst { 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; From patchwork Fri Aug 6 04:15:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422687 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FA11C4320E for ; Fri, 6 Aug 2021 04:20:07 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B543561154 for ; Fri, 6 Aug 2021 04:20:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B543561154 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=za7tU7KoQIHtmw73tkdEg2IzWcxP7fnlQnS9Mmm61uM=; b=W+e8PlF5UPDGxexiOtaW36g23l r4e8xKHitQu8kK8FMJQJO3RPiiYi/iX5tlRW8PDHyVfhvvSITZymzZ4iOkQqwF+mBxDWwetEPxFrU LQR92PgN2zZMzgDumbdALwHKPSpHxgTtWM7oUHMP9k1lM+Ei6LgbCXkJ18O+AKHuHAYpfplldwjw/ uW5r7l7lJF9vgKZXab9mqeQ1Z3Gjq/MqZKB4qtdET3Y3aNcJOTlKEdX/KIhHrMayHBb5xpdfdhpua hoeFY7nMlTZ6q1fFx/ZZuGsOkjma5RZnQpqsj6zr9YB7ooz2s6cF7pvDjS4nKYMdeAsPhQlPQYkNG DBhk+0hQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrKu-00BUxO-R1; Fri, 06 Aug 2021 04:19:56 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHW-00BT2H-SK for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:28 +0000 Received: by mail-yb1-xb49.google.com with SMTP id b9-20020a5b07890000b0290558245b7eabso8358886ybq.10 for ; Thu, 05 Aug 2021 21:16:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Rsk8mIk4NwGxcjmp10DQpgJja1pgzgMacDksVnB64/o=; b=E83KNjyD6f2ijKsOirozZyWrM3b9FzL5lre5NgdVK3PpHsDxEAnljSjqikUGv+uznH Cv5fr7wOv0r93E9RyZWV0pbqwBG5EylwUyPJJ20qd3YAtbzqjhXAyL1ySXNevTsDvgI8 Q6OglpVh/rglb/jayX5U2qhUbA7nW/eVeGNRleNg//Bbs0qwDkgmqRTaUnUXOA6QUIhl 38rTajZWL3w0cpgv0+a6EfFavEhbweMbRr9VMjBJ0gd4plcH6G9yE4Pkw6kiJ8cH5F6c bopVOVk9n5IfXVdUeP/MvEaHIypuKMLZK7iIdXThWDEVYDRJFUsXQsel/BQ5VlyLAc1z 6ZlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Rsk8mIk4NwGxcjmp10DQpgJja1pgzgMacDksVnB64/o=; b=N6tZZQfR5/DGyKnsTZl6lENRvl4BPEcHa/Tw1o3P78NrZFrZW9eRtJuZtAFaDTXWkw astfl7eRGdT+EcZqw5STrKcu37RI38U0SJLm/Y2XWtk8LHOvoxQShaoQayBV81S7giIp olBbfmiWztHeUsJ9oL2Gv8lZ0S/0DhYZKRiIsfUTy8Z8aeZS+tB0U15g2lMatTOeybk7 l123wh1h5lZYe6TAQlVN516ITZO6vbN/5KgUG+qnb2QwhDsgfPxCE5LxX/X2KMmWFTQK Tret9OlWC0LDI3m4Y8T8eFeYqnL2HIKwcBE2XYnWXXIR0HA1gLEASyGTNlbQ2E3FejUe Nbvg== X-Gm-Message-State: AOAM531xuMJ3ScHI1uDf69wE+l/e5EmlwFJPHZR2EicU5TsOKYFj0HgQ q7oM4WhwMa/F/W/G8+vnZiWwqOLNBSXd X-Google-Smtp-Source: ABdhPJxsM4qGrQbL2g5YSGWG8rqFeBL4viRpVSL06TzLyTQO4wOhxnYyLr43IoMyC0RrGixmrTlDLQp+8UzG X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a25:8445:: with SMTP id r5mr11095742ybm.20.1628223385460; Thu, 05 Aug 2021 21:16:25 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:25 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-10-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 09/14] media: add Mediatek's MM21 format From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211627_023117_D6E26DD1 X-CRM114-Status: GOOD ( 10.81 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot Add Mediatek's non-compressed 8 bit block video mode. This format is produced by the MT8183 codec and can be converted to a non-proprietary format by the MDP3 component. Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- Documentation/userspace-api/media/v4l/pixfmt-reserved.rst | 7 +++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 3 files changed, 9 insertions(+) diff --git a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst index 0b879c0da713..42357b0b3535 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-reserved.rst @@ -246,6 +246,13 @@ please make a proposal on the linux-media mailing list. It is an opaque intermediate format and the MDP hardware must be used to convert ``V4L2_PIX_FMT_MT21C`` to ``V4L2_PIX_FMT_NV12M``, ``V4L2_PIX_FMT_YUV420M`` or ``V4L2_PIX_FMT_YVU420``. + * .. _V4L2-PIX-FMT-MM21: + + - ``V4L2_PIX_FMT_MM21`` + - 'MM21' + - Non-compressed, tiled two-planar format used by Mediatek MT8183. + This is an opaque intermediate format and the MDP3 hardware can be + used to convert it to other formats. * .. _V4L2-PIX-FMT-SUNXI-TILED-NV12: - ``V4L2_PIX_FMT_SUNXI_TILED_NV12`` diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 05d5db3d85e5..b394a2b7cfd7 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1346,6 +1346,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; + case V4L2_PIX_FMT_MM21: descr = "Mediatek 8-bit Block Format"; break; case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 9260791b8438..bc1dc5adc071 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -733,6 +733,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') /* Greyscale 12-bit L/R interleaved */ #define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') /* Depth data 16-bit */ #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ +#define V4L2_PIX_FMT_MM21 v4l2_fourcc('M', 'M', '2', '1') /* Mediatek 8-bit block mode, two non-contiguous planes */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */ #define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */ From patchwork Fri Aug 6 04:15:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422703 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 572B4C4338F for ; Fri, 6 Aug 2021 04:20:51 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EC9EB61154 for ; Fri, 6 Aug 2021 04:20:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org EC9EB61154 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=p0ZHHwk9KT18V4vqJIfrdEkNMgu71F4B7J38Z4HMzJw=; b=RobMTtiTCY4rtEjtmbbEJ/9MKg E8nsxV4W2YK5O1GVFmSPcTK+Di4mCtVNqAMYN0kiZnfxH5QgRaSyK1Y8xdjah8jUXlEm+r7Dvk16S uLv4EtkNDx9w4fANmW9mlwpR5Rg9+NsdC6wwXmxCqPpllbt77j/iEXS7Lk+8Td/r9M9lM6g5GpVKP LJz8wfr6l6WNfKomZ43V/JTGyONL8yGZVvAgWVjTX5RtgB+YB+X48clqP8oA2y/90yl8smfrGKPzZ daDmnQF1asGOFOC5dIIm25GxRqeILHKXJHwiDQHtQIPcmzL4vsVB9CoEOzu6olnl5GC9B/xgPfvP6 NBKsVLRQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrLb-00BVKR-Au; Fri, 06 Aug 2021 04:20:39 +0000 Received: from mail-qk1-x749.google.com ([2607:f8b0:4864:20::749]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHa-00BT4k-CM for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:33 +0000 Received: by mail-qk1-x749.google.com with SMTP id c196-20020ae9edcd0000b02903c9e325c3b2so5490069qkg.2 for ; Thu, 05 Aug 2021 21:16:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=GTLl3eNSoOtEcD4f/EwLDhZ5HVKcKh5UhzMMj82Q/+U=; b=UNJsp1GdlEVYf96AIy5vnfpIiN1GUwudh16mjwEwEnCoiDuD1GPRvmmqhBfp66o0sD ok6QXtJq+EzfFfOV4xnCw+N+iqJkz0uShyr5pMofOeSv8Du4xe5v2XF5H2skzQ+A3NSS ko0ic2Vk+kzKdXFiSLoRvpnxcTfWDGy4dlaipQzLZNQNPc16tILOfAqHR9d8TDEK2G// m8IRCeU4CMFhElCX7eyuSaYWkFWP39BHOjj7cEzYve1OCQgxlrs6TlUvXIdpoLHxSLRq uUErIfGC14N8MnBV7ePrpladj4IcrrP+rRUBNdtqJBIpBL6/1NgITa5h2FGI4VsDs+ar 99ZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=GTLl3eNSoOtEcD4f/EwLDhZ5HVKcKh5UhzMMj82Q/+U=; b=f5FO0oc3qEdcOE1Jmfgl+kOzYXYBe8+8NZn0zq9m7CKr296P4lniivrseQSrMm3U7Z sfRer8bq6XJcjPdZe8F6aSI41/i5OpyLuuyFwf0xrb4DWeK+lQSwv8uNyA7EGypNS0+t 3LUD1k6wpHMzKqbil0+FDXsWGKug7V9hNoEGEHyx+V/TtlwdOLw0EN8jyfLjpr+FYyIU uoKO5qYecwRcq/IGSmO9ast88ConmYDouuR/ABIqU0JzLo3GEB4bX9+qZGBoDjww97pd biN3l5XcKbScZSvaw3fmRmdJu+mUDKeCszPBtNgPitIrUlve5YlR046Ih7tX0o0xLFbt iWEA== X-Gm-Message-State: AOAM533hjwX4sJngX+8WsoznuzbdJc9eaHPHOD4NO2nd59M9lkKyfwEw LL/cP6vJGS+qsZeVDoqsJjsbsjS5axen X-Google-Smtp-Source: ABdhPJx8gwF3x1OquPDqAT66DAKCQPwYSky9S5sdHjad8v1K9MPrBa7Gnr7bN+gI9CvI6Ggvv3oRwg0sA7y3 X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:ad4:44aa:: with SMTP id n10mr9142859qvt.18.1628223389008; Thu, 05 Aug 2021 21:16:29 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:26 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-11-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 10/14] media: mtk-vcodec: vdec: support stateless API From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211630_496583_4866E1C2 X-CRM114-Status: GOOD ( 24.32 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yunfei Dong Support the stateless codec API that will be used by MT8183. Signed-off-by: Yunfei Dong [acourbot: refactor, cleanup and split] Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/Makefile | 1 + .../platform/mtk-vcodec/mtk_vcodec_dec.c | 66 +++- .../platform/mtk-vcodec/mtk_vcodec_dec.h | 8 +- .../mtk-vcodec/mtk_vcodec_dec_stateless.c | 360 ++++++++++++++++++ .../platform/mtk-vcodec/mtk_vcodec_drv.h | 3 + 5 files changed, 434 insertions(+), 4 deletions(-) create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 9c3cbb5b800e..4ba93d838ab6 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -12,6 +12,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \ vdec_vpu_if.o \ mtk_vcodec_dec.o \ mtk_vcodec_dec_stateful.o \ + mtk_vcodec_dec_stateless.o \ mtk_vcodec_dec_pm.o \ mtk-vcodec-enc-y := venc/venc_vp8_if.o \ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index a220532802f9..2b334a8a81c6 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -47,7 +47,14 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { - return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, 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); } @@ -62,6 +69,10 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, 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); @@ -401,7 +412,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, * Setting OUTPUT format after OUTPUT buffers are allocated is invalid * if using the stateful API. */ - if ((f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) && + 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; @@ -444,6 +456,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, 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) { @@ -455,6 +468,48 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv, } } + /* + * 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; } @@ -746,9 +801,14 @@ void vb2ops_vdec_stop_streaming(struct vb2_queue *q) 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) + 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; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h index 76856c0b2db8..9fbd24186c1a 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h @@ -44,6 +44,7 @@ struct vdec_fb { * 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 */ @@ -54,11 +55,16 @@ struct mtk_video_dec_buf { bool queued_in_vb2; bool queued_in_v4l2; bool error; - struct vdec_fb frame_buffer; + + 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; /* diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c new file mode 100644 index 000000000000..8f4a1f0a0769 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#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 = &framebuf->frame_buffer; + 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, +}; diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 17c960aa5262..8fb333a99a40 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -253,6 +253,7 @@ struct vdec_pic_info { * @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 @@ -294,6 +295,8 @@ struct mtk_vcodec_ctx { 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; From patchwork Fri Aug 6 04:15:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422707 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47B87C4338F for ; Fri, 6 Aug 2021 04:22:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0948D611C5 for ; Fri, 6 Aug 2021 04:22:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 0948D611C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=dSIce+/SUAO8zVbhU/OraU6TwshIi1royL+GHwb7vhc=; b=pgshltwIY9v6rW7ldeSSD1oe7K FAIRwKinrvv0FKHw4C2ihtg+OBDptrAJC+wqBX9/XHgethCRF9vhRQ+4ZeeMGTy/o1/Ghy0kaZkwy iezPIJpTtdGUiUkNVp2qlDZzRsB4yPskH7JmB8v111lGLgE5ksqIlg0sY37XE9IAwPPGOfajzuwBZ Qka9E+MSLc2XTc9Dh+VFpBOzp2kF55y1/boI1RK+hYqR9lq7oBRAl8UB69M0ZKgwpRbjIjr2Hd2+4 31TfhPfoffGt89at/ZMhhU+jGIHwZiQGpXV5jkJLpyRBmgHVKMqah1F9dZ9B5kIlp7nOGgopRgXsG FrfKMBcw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrNL-00BW6C-UL; Fri, 06 Aug 2021 04:22:28 +0000 Received: from mail-qv1-xf4a.google.com ([2607:f8b0:4864:20::f4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHe-00BT7G-SJ for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:41 +0000 Received: by mail-qv1-xf4a.google.com with SMTP id w10-20020a0cfc4a0000b0290335dd22451dso5552476qvp.5 for ; Thu, 05 Aug 2021 21:16:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=8Hj7QTRReMR49Q7lc0c4H0i3GEtDIS+A93iyijxdtkc=; b=i/aqDAMmJvUhGYMLV/ne9VpNbheuN9lmvGoKX8m+T3jyGp8fYo27Sf2lsVKyyZwSS5 arybNcPP3GGKQNdecTtDa7L/4jOHsbGNGZTOaOCPCMtDf1da/G/4JV0k27WM/Gg16+xX dQbLAi/k1bFXa/JBVoSr9rLbutywDqwhdkqXMVVqxCJGlgfpzfLNareQf1JcUaJbKHoe 40EuiH9WLZkqI7ePcxh6NdD+dsIw7xbBPz8l0I7RuZRNRBHYRhtV/klG9tW/N3rA9V+l uChufrE/rf1h1Z6DxYJHlZ8nJzWA//mlQpzRDLPSgMQGfTLb6jW+ZWaIsQG/1/boBxGe 57pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8Hj7QTRReMR49Q7lc0c4H0i3GEtDIS+A93iyijxdtkc=; b=POCT3C4eR9ZhIT/JLKJtURd23/MNPFGoMakHEO9S9yQxt9q1hGQ0gjfFo8A1KPJ+Qf gNxws744JehRmZdXhxOP+ZWm0Y88BrK2CVSGFQNrQfxcbzhkc8cxSFPKEiY/uUod5pYj /0wt4j1qhjYPIWS8nm69omDLr8FPuhKEsOoUIASucDPFQbZpwRUwKCgffzGCk0tQ7Ibz oGN6wq5GWm3HqkJgh0QG0E9UzHjixZjgT7ZI5xXblLkE+BPOqsGk/UpQKADko5awwERJ HNc+WNcmL9MaIhFC4nAAY5e2uYWqIXDwDU4FqY5TqWnxCneHBUabuVvY4vw2tWH7oa6f GlfA== X-Gm-Message-State: AOAM530bJAYoPtwdiMzAGELP6m5Jq6F2aS1tvXv7IDinYU/JtLTgoawq Uu0NsXJDINnjn98kar9ypTi/nbqe4PaG X-Google-Smtp-Source: ABdhPJwNVTFkkqxdEn8Wn3ptjZ8V2Tx41+I9jG7A2tDSKfu5K7d5dH4nKTomyaojJkxdTnmw9aY94XoIplkM X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:ad4:4b25:: with SMTP id s5mr9077382qvw.52.1628223392975; Thu, 05 Aug 2021 21:16:32 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:27 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-12-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 11/14] media: mtk-vcodec: vdec: support stateless H.264 decoding From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211635_005677_01A23721 X-CRM114-Status: GOOD ( 22.15 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yunfei Dong Add support for H.264 decoding using the stateless API, as supported by MT8183. This support takes advantage of the V4L2 H.264 reference list builders. Signed-off-by: Yunfei Dong [acourbot: refactor, cleanup and split] Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot [tzungbi: fix missing kerneldoc issue] Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/Kconfig | 1 + drivers/media/platform/mtk-vcodec/Makefile | 1 + .../mtk-vcodec/vdec/vdec_h264_req_if.c | 774 ++++++++++++++++++ .../media/platform/mtk-vcodec/vdec_drv_if.c | 3 + .../media/platform/mtk-vcodec/vdec_drv_if.h | 1 + 5 files changed, 780 insertions(+) create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 157c924686e4..ae1468aa1b4e 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -314,6 +314,7 @@ config VIDEO_MEDIATEK_VCODEC select V4L2_MEM2MEM_DEV select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU select VIDEO_MEDIATEK_VCODEC_SCP if MTK_SCP + select V4L2_H264 help Mediatek video codec driver provides HW capability to encode and decode in a range of video formats on MT8173 diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile index 4ba93d838ab6..ca8e9e7a9c4e 100644 --- a/drivers/media/platform/mtk-vcodec/Makefile +++ b/drivers/media/platform/mtk-vcodec/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.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 \ 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 new file mode 100644 index 000000000000..2396b9a6d6e5 --- /dev/null +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c @@ -0,0 +1,774 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#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_param : 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%lx", 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 = (ctx->picinfo.pic_w + 15) & 0xFFFFFFF0; + ctx->picinfo.buf_h = (ctx->picinfo.pic_h + 31) & 0xFFFFFFE0; + 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 = %d,%d,%d,%d\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); + 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_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c index b18743b906ea..42008243ceac 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c @@ -19,6 +19,9 @@ 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; break; diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h index ec8f4e8d3d23..d467e8af4a84 100644 --- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h +++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h @@ -55,6 +55,7 @@ struct vdec_fb_node { }; 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; From patchwork Fri Aug 6 04:15:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422705 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D6E6C4338F for ; Fri, 6 Aug 2021 04:22:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BB22C611C5 for ; Fri, 6 Aug 2021 04:22:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BB22C611C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=S18Yuw84FniTzFfnqyN6L0gfWmyoIizv1FKiMZMba1E=; b=sqod1BB/K/bnQcGhsvqlwvWP5E jo1adk37gztLD5pFjCWKcjYOxIpGVhDbg94gG2rtncBU4wVBafJ9SPbMBuOB44Cm4Vg82ZBVv+O+1 q/fEh4p1YGRlUCAzOi7arZWmAvFsJJLmDlcAdjkFjZ7gWF43z8BxQ+basK+5b77Oah//578nw6kf0 rEtPbPC7mfTYc2hkoH2vJXaEOdZLwmkA/kjPnQqAz7ePYa3Duhyjx++KHiwt4Wsc/S091MUENHNHo LpsrBykQGZb6YoMoYO8OE9pW/TyKNzviCG+b+1lBEVvLy4f3nY2xmqxZLh0idu5w4PAL/8tyBbPyg CwjzvWbQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrNI-00BW4q-9x; Fri, 06 Aug 2021 04:22:24 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHi-00BT9Z-QC for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:41 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id f3-20020a25cf030000b029055a2303fc2dso8346644ybg.11 for ; Thu, 05 Aug 2021 21:16:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=oPE1v1kYszg9FU+kfYGAPyUdSszW/QUX8TrG+ItsMlc=; b=wRAmpjl5Tp1P0V4/0Qs40Z8RIx8HO8peuCxUkTEw7vDEqOCrwiCPA6gZgElPB66Zu8 DiYTMDT7MJz8qs0/0a3pAjaEaTiahRcoHEIBvZLClQvBViNQ/ooXSHaYTjpUdZNuQOTZ 7pRl7jPMdnHiSYLc4XwQDUJlIuhggLdHEDrBiVHLmYd7lKGMKmL5d9YKqpwtwQIRbGdK HqJaQgvzzab9C7FjnfggAUodA5WAIrLnQjlQ8NASjQNq4wYxmIDYPLWEjvtMgTooabTY BSZE+OqLjLuw4GUdAk1ZVhNNXfVdPj4ji2eSQ8UXLtUudY7j9djtOkjWAaG1KS+MsXzj s5iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=oPE1v1kYszg9FU+kfYGAPyUdSszW/QUX8TrG+ItsMlc=; b=DZ5I3H6mU7rV9qdrOMV8vum+Ohh4nJWC4zTgA8p2AqCE8kCeg3CHw5a7z2I8rE9JX9 1SxYJkJoSW38EXo+rnU8XXhN7E8z87ci+AYJ5hb2C1pClk4M+1RdlQ6SEwX2YjfNDy7N QdkCz0y9c0+DkCuI9nbVIfG6wvNr42+wSbyVGVp4cED4+fEcDcXa6LkNzUUH3aS+c85b Wnh0TPsJTk1qfK3OTdy0KnW/EfvBfwhxQgKVv476kh9qZa1+Ob6c80QB0DEmLhxhe8Rb cNyMioj/Th7hkAK46KyLEsPZwYSGRu4SbxCWuECtaWBvsPRAhLRBjcQDdoQfUdeOklax PwVw== X-Gm-Message-State: AOAM5336Xmo8bzZx3qVUnCxRkYrTk6KpLTSSkaX/x5ERzrvwZMzVnrrX Fy9XR9uqRxJ7SM6xiKi8uixGOJM1CDRR X-Google-Smtp-Source: ABdhPJzHv93sp38BXCMDnFkgYFIopCnlFNt4d9gy77XHq5f8skX6+aGKHwCmhbZiIiEDqty9RHDOn1a0J+A6 X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a25:1e89:: with SMTP id e131mr10513765ybe.90.1628223397026; Thu, 05 Aug 2021 21:16:37 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:28 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-13-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 12/14] media: mtk-vcodec: vdec: add media device if using stateless api From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211638_970873_71F5E880 X-CRM114-Status: GOOD ( 14.13 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yunfei Dong The stateless API requires a media device for issuing requests. Add one if we are being instantiated as a stateless decoder. Signed-off-by: Yunfei Dong [acourbot: refactor, cleanup and split] Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih [tzungbi: fix wrong device minor number reference] Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/Kconfig | 2 + .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 41 ++++++++++++++++++- .../platform/mtk-vcodec/mtk_vcodec_drv.h | 2 + 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index ae1468aa1b4e..aa277a19e275 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -315,6 +315,8 @@ config VIDEO_MEDIATEK_VCODEC 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 diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 1460951f302c..fe345aab9853 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "mtk_vcodec_drv.h" #include "mtk_vcodec_dec.h" @@ -316,18 +317,47 @@ static int mtk_vcodec_probe(struct platform_device *pdev) goto err_event_workq; } + 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_reg_cont; + } + + 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); + } ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0); if (ret) { mtk_v4l2_err("Failed to register video device"); goto err_dec_reg; } - mtk_v4l2_debug(0, "decoder registered as /dev/video%d", - vfd_dec->num); + mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor); return 0; err_dec_reg: + if (dev->vdec_pdata->uses_stateless_api) + media_device_unregister(&dev->mdev_dec); +err_media_reg: + if (dev->vdec_pdata->uses_stateless_api) + v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec); +err_reg_cont: destroy_workqueue(dev->decode_workqueue); err_event_workq: v4l2_m2m_release(dev->m2m_dev_dec); @@ -360,6 +390,13 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev) flush_workqueue(dev->decode_workqueue); 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); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index 8fb333a99a40..d4f840a7bbcb 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -389,6 +389,7 @@ struct mtk_vcodec_enc_pdata { * 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 @@ -426,6 +427,7 @@ struct mtk_vcodec_enc_pdata { 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; From patchwork Fri Aug 6 04:15:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422709 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DEA3C4338F for ; Fri, 6 Aug 2021 04:24:54 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C563961154 for ; Fri, 6 Aug 2021 04:24:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C563961154 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Tser7C4ZE3pNUxXl2YMk5+JHpZwsy/+MpKuFCHdHCQ8=; b=OhH001LjQ1fi3eYQSwKLpq+nkF 1rtfAB4MHscuTddcIW7czvr6IJaR5ktQ+PbuxaCFApp5OH5qDrRYL/EucJRaK7xqmhzCdRdqIE6I7 lpQJr3aM/zJUjwGdf/gX9BDlW5MCNE2VCZAgapjq0LuekGANfdbQBobevL/JCDXEAFphK0SD2q7dC lIk2Yc4ehHcDyPPsZf0J0Zx9WIoPqeIGXlRNToyLagC5Y//tgNWOobOgGowx1B/3C7/YrQ6AgzoNM 0/F1V0X2oBKm7wxLZSR0TZrHPZ8nhwUrVipDJxXJOT3EzH4aw1hhB1lVR3HTiSkF79KIzFE4JbhmM oD8vm4lQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrPZ-00BX1S-0D; Fri, 06 Aug 2021 04:24:45 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHm-00BTB8-3C for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:43 +0000 Received: by mail-yb1-xb49.google.com with SMTP id 203-20020a250bd40000b02905933fff7091so835231ybl.16 for ; Thu, 05 Aug 2021 21:16:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Q40VTyrZ8Jb3xiuLDWJt6+4MmyDxko7tqCpmYIXIET0=; b=KFfQ68eJZhEOu8WCeUjfFQd8FJzMNLuIbt1sBK+Zex7v8uDpxuX3qJAzY+rlDVkCzx ddgml7gc7yo115aJu0qJ7YFRhOH8EacWt4TFqPyugYmvZlkzGymGrEe78IRkuoTeAPIQ IGPEHz9/qYkpe4H4PMkNJ7jPaJ0WWG/RCMNa9z9wT7z0OXKaQksRDXFP+eeAGiunL1lE AxICXMcYN4tpXeX4HKJ2R6aQkGzjiINLeRiRMoQYibsJZEj1NKopEJ8EUIewwYLdidHt 24zi8T8Ovqs2psTayROx8d7JgvDSh+lbY1iEqTfFky4qIMSW5XhfN+nOgJIjVAKfIK2Y YFZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Q40VTyrZ8Jb3xiuLDWJt6+4MmyDxko7tqCpmYIXIET0=; b=dfmDi2UAniBQBZxzGP273u+Y0oVS3exo7OyXHst2vlpJU/krkpJfGb09q/xuiQW/cg SzDh0axFYHFe1rGOowvDOuVopNdBEHsQSQlE+Ak8gxzaxm7IiqE/B2w8hqXHS2xSlnCu Ltd+7ncMOu+AJofUiQYZhpLRzfWsy67uKU2QjbY8r7/XREh7AN134UR0nHO14cPCPV43 LUpui1zJwB5UT6VBUQT+5ldyn1jQXW9XdyHaSan58o+iFjCQdtEm04DCSL8aHhM2sBnc pgQAGS295z1jsUZ+K6luD9W3nkHutegzt9+h9l5hNsQbxQVMZhHV3TbpIkl/mqhJy9bX 7XNA== X-Gm-Message-State: AOAM531qaZ5UC4WhVqwDTqludvCk7OM9QID50QnsbXIOJzC+J8Y58kR9 JF2rP/rVm48zAko6RwmdsnhDpXWZ/rfa X-Google-Smtp-Source: ABdhPJy7KEPygmtbEYTAh7CaN/i2KocvupvFKwvGA77PqToujXIpHnTvPQ/IKCQ1AV7lU8YQE63ExtiPNS3T X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a25:bc02:: with SMTP id i2mr9968274ybh.98.1628223400442; Thu, 05 Aug 2021 21:16:40 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:29 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-14-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 13/14] dt-bindings: media: document mediatek, mt8183-vcodec-dec From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com, Rob Herring X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211642_214393_85A783E0 X-CRM114-Status: UNSURE ( 7.96 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Alexandre Courbot MT8183's decoder is instantiated similarly to MT8173's. Signed-off-by: Alexandre Courbot Acked-by: Rob Herring Signed-off-by: Tzung-Bi Shih --- Documentation/devicetree/bindings/media/mediatek-vcodec.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt index ad1321e5a22d..c44a6e6943af 100644 --- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt +++ b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt @@ -10,6 +10,7 @@ Required properties: "mediatek,mt8183-vcodec-enc" for MT8183 encoder. "mediatek,mt8173-vcodec-dec" for MT8173 decoder. "mediatek,mt8192-vcodec-enc" for MT8192 encoder. + "mediatek,mt8183-vcodec-dec" for MT8183 decoder. - reg : Physical base address of the video codec registers and length of memory mapped region. - interrupts : interrupt number to the cpu. From patchwork Fri Aug 6 04:15:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 12422711 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41329C4338F for ; Fri, 6 Aug 2021 04:24:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 00435611C5 for ; Fri, 6 Aug 2021 04:24:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 00435611C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=PNq8YoGQ16YmbWtENcBzhkDW/KzYIt6qwjp0/t9aYs8=; b=a1d82oCfYvOSzmDTQ4UVH8SlU7 cSHco9JVOlvUJ9R36Ua0LR9+328WbEeduPaZvnmDAeJCkDMsSlefKDly8VeBfegabILDRcl9bO6Xr eebU+TlkIS3aneg0PJD6DKgWbWBmLall5bu9uL1ETwnGLglV/JZSGUUkkxExyQaveqYJETFxwiaGX 736LC8gt+rWrfFux1jU+aQNME0U5ithdf+I2V2e4+wPvoYnKApbCGo6ekxW2bvRQXCVghOmDHhcLN u1qs+zta1W7LeP4bUPs+3We/Bn6YRrmpnovhL/8BjfRsxMmYWa72+QRp82IrwVg2yI89awwTTLVSc wuYbwlNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrPc-00BX2w-IM; Fri, 06 Aug 2021 04:24:48 +0000 Received: from mail-pj1-x104a.google.com ([2607:f8b0:4864:20::104a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mBrHp-00BTES-Gb for linux-mediatek@lists.infradead.org; Fri, 06 Aug 2021 04:16:46 +0000 Received: by mail-pj1-x104a.google.com with SMTP id q6-20020a17090aa006b02901779796d79eso1513133pjp.1 for ; Thu, 05 Aug 2021 21:16:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=VRCp1gt1+Tm8DKrP/bEBz4/wYC+uwc+iQhHn0pgVUPM=; b=qqjK53VfiiIyZXKieqMrPne4RfS+RoIGd+Vs+zgcRBTVQ2or7efv+fyQDpWwa/v6yc V2Nm8vCaiHPeMuv0tWK3acbZMTTGJDO2oJoTzidqaYzCZWcB7J2DhUhxwHKq53O8JkJj SK1Rbi6+5eeC95kPp0xm8PkPJ/3MiwEdsG0raX5T/LIC3AANrZBoQJC5bjEdBN19taKt 56LPVMFcKBRQ2XWEXM4WGz6TQAEbMHjUXAUGOaoupgKZGLBfCfCUN+ygKSi1umW+qeBT l4U4qvtDOxXKoCDa8E+CsPe6LE9rR/fz8oUc2TPmRpmzzPA2zYjWsQjq1ZWbd0GKvZTC WX+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=VRCp1gt1+Tm8DKrP/bEBz4/wYC+uwc+iQhHn0pgVUPM=; b=HovpWHHph/D8yoHca05steYSL/cafz0yi8vVPOoug2ZfUKdsW8ePQDn/k+eXtDzEIF NFnrXMKVolg5860bmVDQz8kU2Z92XVsWV8aTu7S8BnPMKnCl/5o5KyKV+zMnaJxyRfvs POnKeWis8MR7+0sdTNbkH5KSavk8bM7CtxidAlshJDe/xAW5f/V/OKCJepjKvtBPhmdA C8OTnKS6J07N+1HLoWdMQbjk868WZFFW0gMOmsgsWtbs826kuche8PBr+/54cA6IZ8Qh nJGdW14IDj5MV2GR823kbL/v0jHqekOlBuNQX5JUGNtJFKnkaWYJh9chufQ1+AV2NLMn bjqA== X-Gm-Message-State: AOAM532veVfMMD7QnwGJyGK9/XrjaGGJ/MZfI/sEmXZdKCgfEKxrQFfY t4vi+EuQ26AH920lwulvi+Dqi36Lp8mj X-Google-Smtp-Source: ABdhPJxYcHrjQQ4a3Sxpy0Mj49WvdIyMPVK6N5vcc2g+T/OMwr+DJisr+Meut0Leq4TWpLJPRTzKEAjWkSfK X-Received: from tzungbi-z840.tpe.corp.google.com ([2401:fa00:1:10:ebc2:859f:4153:773e]) (user=tzungbi job=sendgmr) by 2002:a17:902:d652:b029:12b:45c1:21ba with SMTP id y18-20020a170902d652b029012b45c121bamr4702610plh.9.1628223404249; Thu, 05 Aug 2021 21:16:44 -0700 (PDT) Date: Fri, 6 Aug 2021 12:15:30 +0800 In-Reply-To: <20210806041530.4170869-1-tzungbi@google.com> Message-Id: <20210806041530.4170869-15-tzungbi@google.com> Mime-Version: 1.0 References: <20210806041530.4170869-1-tzungbi@google.com> X-Mailer: git-send-email 2.32.0.605.g8dce9f2422-goog Subject: [PATCH v7 14/14] media: mtk-vcodec: enable MT8183 decoder From: Tzung-Bi Shih To: hverkuil-cisco@xs4all.nl, yunfei.dong@mediatek.com, acourbot@chromium.org Cc: tiffany.lin@mediatek.com, andrew-ct.chen@mediatek.com, dafna.hirschfeld@collabora.com, mchehab@kernel.org, linux-media@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, tzungbi@google.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210805_211645_622704_A1C6586F X-CRM114-Status: UNSURE ( 9.62 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yunfei Dong Now that all the supporting blocks are present, enable decoder for MT8183. Signed-off-by: Yunfei Dong [acourbot: refactor, cleanup and split] Co-developed-by: Alexandre Courbot Signed-off-by: Alexandre Courbot Reviewed-by: Tzung-Bi Shih Signed-off-by: Tzung-Bi Shih --- drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index fe345aab9853..36ae3e6017f0 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -373,12 +373,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata; +extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata; 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, + }, {}, };