Message ID | 20240516122102.16379-13-yunfei.dong@mediatek.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Sebastian Fricke |
Headers |
Received: from am.mirrors.kernel.org ([147.75.80.249]) by linuxtv.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from <linux-media+bounces-11538-patchwork=linuxtv.org@vger.kernel.org>) id 1s7a9c-0003a9-1t for patchwork@linuxtv.org; Thu, 16 May 2024 12:24:13 +0000 Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 5A5111F22865 for <patchwork@linuxtv.org>; Thu, 16 May 2024 12:24:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B19A146581; Thu, 16 May 2024 12:21:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="G93Y/p7U" X-Original-To: linux-media@vger.kernel.org Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9004014E2DA; Thu, 16 May 2024 12:21:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.61.82.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715862092; cv=none; b=OKWWQrpz1RvqY7xiHQpgSRCvqt+JhTV90JYBxGVf3dSRuDHoW+mS4LGrKS8ZL5FGb04893aXsHnMaU1D5zGRky10xBYK0/5gsVx1EsGpqv3OF3Nb+EEMsKhEm6v7sBFHNOtbcaz82Bwr1oqQOidnBhKYHFKoUvTONzfjaiK9W5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715862092; c=relaxed/simple; bh=/uEO+lD5EPzBWP+go2HidO0zaCfj6lmraYjanZvxFVI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GyUzLwgMU2XiALNVkvIGH69UnPI3wWvssWKUC7It6Tsce/hHmwcjZCSeqpQLW+ld6jBaJej0ZvUCDvqD+w8e1ihbaTWzo17Rgn3YwrAmgweFsu4vwU23n0mRqYBR8ayUQ62upqCe4GZ6o03KdMHEzkEckdkAg4nlEz2wQs8zwIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com; spf=pass smtp.mailfrom=mediatek.com; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b=G93Y/p7U; arc=none smtp.client-ip=210.61.82.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mediatek.com X-UUID: d1078984137e11ef8065b7b53f7091ad-20240516 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=/xKPtK+eSyCFTpdeW0Z+gbZ1CA9J+Sm7RjZuCyigMlY=; b=G93Y/p7Uz8mHj1SMTz34tROjm2IrR2rwKkLpRtxMacf2PSs9gaD2hWHjwbKpdBNKl9OV1dbhMEPXHBfULEn2XMCDnpCvKQd39DRB8hgDLI2TxnooCoUQ1OK290VVKl4KLPbtGSzDuMSniQaU51w9QVk90QlH7FpPanX1QcHKGXw=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.38,REQID:f806f9a1-1ba4-4476-8c46-f40f4576d4de,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:82c5f88,CLOUDID:bb537087-8d4f-477b-89d2-1e3bdbef96d1,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1, SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-UUID: d1078984137e11ef8065b7b53f7091ad-20240516 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw02.mediatek.com (envelope-from <yunfei.dong@mediatek.com>) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1144441362; Thu, 16 May 2024 20:21:26 +0800 Received: from mtkmbs13n1.mediatek.inc (172.21.101.193) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Thu, 16 May 2024 20:21:24 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs13n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Thu, 16 May 2024 20:21:23 +0800 From: Yunfei Dong <yunfei.dong@mediatek.com> To: Jeffrey Kardatzke <jkardatzke@google.com>, =?utf-8?q?N=C3=ADcolas_F_=2E_?= =?utf-8?q?R_=2E_A_=2E_Prado?= <nfraprado@collabora.com>, Nathan Hebert <nhebert@chromium.org>, "Nicolas Dufresne" <nicolas.dufresne@collabora.com>, Hans Verkuil <hverkuil-cisco@xs4all.nl>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, Benjamin Gaignard <benjamin.gaignard@collabora.com>, Sebastian Fricke <sebastian.fricke@collabora.com>, Tomasz Figa <tfiga@chromium.org>, "Mauro Carvalho Chehab" <mchehab@kernel.org>, Marek Szyprowski <m.szyprowski@samsung.com> CC: Chen-Yu Tsai <wenst@chromium.org>, Yong Wu <yong.wu@mediatek.com>, "Hsin-Yi Wang" <hsinyi@chromium.org>, Fritz Koenig <frkoenig@chromium.org>, "Daniel Vetter" <daniel@ffwll.ch>, Steve Cho <stevecho@chromium.org>, Yunfei Dong <yunfei.dong@mediatek.com>, Sumit Semwal <sumit.semwal@linaro.org>, "Brian Starkey" <Brian.Starkey@arm.com>, John Stultz <jstultz@google.com>, "T . J . Mercier" <tjmercier@google.com>, =?utf-8?q?Christian_K=C3=B6nig?= <christian.koenig@amd.com>, Matthias Brugger <matthias.bgg@gmail.com>, <linux-media@vger.kernel.org>, <dri-devel@lists.freedesktop.org>, <linux-kernel@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <linux-mediatek@lists.infradead.org>, <Project_Global_Chrome_Upstream_Group@mediatek.com> Subject: [PATCH v6,12/24] media: mediatek: vcodec: add interface to allocate/free secure memory Date: Thu, 16 May 2024 20:20:50 +0800 Message-ID: <20240516122102.16379-13-yunfei.dong@mediatek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240516122102.16379-1-yunfei.dong@mediatek.com> References: <20240516122102.16379-1-yunfei.dong@mediatek.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: <linux-media.vger.kernel.org> List-Subscribe: <mailto:linux-media+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-media+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-TM-AS-Product-Ver: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-AS-Result: No-10--7.939000-8.000000 X-TMASE-MatchedRID: zw7qKAGHZJaVUgVEUxWI0M36paW7ZnFoqQ9UezeTkTjK99fyOVK2z8Rr vjvFKTaxvl8gwRzU3uXUaxsqcNeOOm8aeniRmKw1oMfp2vHck9W7nrAU9KQxUbXvDHySC+eUd/f gGgoXNwfBfR/WU+6YOCtvlgVfOuhgVo9xxUteKStEtgfzRzMa1+WNJG9Iamrch5Q1ArtCPlyu01 fPRCxAIkGUQBmB+AgBkDfm1zFLejyR9GF2J2xqMxRFJJyf5BJe3QfwsVk0UbvWxQsAIHSpEkz29 EGOOh8zNZJDhfepoARgMZrm/uWkK33YvSZTn/tqleXDE6E+NjKUTGVAhB5EbQ== X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--7.939000-8.000000 X-TMASE-Version: SMEX-14.0.0.3152-9.1.1006-23728.005 X-TM-SNTS-SMTP: 730FA7EDCD17DC9FE1E4D47EF8D3412BFA3083AD50317C2B294A9CF2025C8FCF2000:8 X-MTK: N X-LSpam-Score: -2.6 (--) X-LSpam-Report: No, score=-2.6 required=5.0 tests=ARC_SIGNED=0.001,ARC_VALID=-0.1,BAYES_00=-1.9,DKIM_SIGNED=0.1,DKIM_VALID=-0.1,DKIM_VALID_AU=-0.1,DMARC_PASS=-0.001,HEADER_FROM_DIFFERENT_DOMAINS=0.5,MAILING_LIST_MULTI=-1,SPF_HELO_NONE=0.001,SPF_PASS=-0.001,UNPARSEABLE_RELAY=0.001 autolearn=ham autolearn_force=no |
Series |
[v6,01/24] v4l2: add restricted memory flags
|
|
Commit Message
Yunfei Dong (董云飞)
May 16, 2024, 12:20 p.m. UTC
Need to call dma heap interface to allocate/free secure memory when playing
secure video.
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
---
.../media/platform/mediatek/vcodec/Kconfig | 1 +
.../mediatek/vcodec/common/mtk_vcodec_util.c | 122 +++++++++++++++++-
.../mediatek/vcodec/common/mtk_vcodec_util.h | 3 +
3 files changed, 123 insertions(+), 3 deletions(-)
Comments
Hi Yunfei, W dniu 16.05.2024 o 14:20, Yunfei Dong pisze: > Need to call dma heap interface to allocate/free secure memory when playing > secure video. > > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> > --- > .../media/platform/mediatek/vcodec/Kconfig | 1 + > .../mediatek/vcodec/common/mtk_vcodec_util.c | 122 +++++++++++++++++- > .../mediatek/vcodec/common/mtk_vcodec_util.h | 3 + > 3 files changed, 123 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig b/drivers/media/platform/mediatek/vcodec/Kconfig > index bc8292232530..707865703e61 100644 > --- a/drivers/media/platform/mediatek/vcodec/Kconfig > +++ b/drivers/media/platform/mediatek/vcodec/Kconfig > @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC > depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU > depends on MTK_SCP || !MTK_SCP > depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n) > + depends on DMABUF_HEAPS > select VIDEOBUF2_DMA_CONTIG > select V4L2_MEM2MEM_DEV > select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU > diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > index c60e4c193b25..5958dcd7965a 100644 > --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > @@ -5,9 +5,11 @@ > * Tiffany Lin <tiffany.lin@mediatek.com> > */ > > +#include <linux/dma-heap.h> > #include <linux/module.h> > #include <linux/of.h> > #include <linux/regmap.h> > +#include <uapi/linux/dma-heap.h> > > #include "../decoder/mtk_vcodec_dec_drv.h" > #include "../encoder/mtk_vcodec_enc_drv.h" > @@ -45,7 +47,7 @@ int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, unsigned int reg, > } > EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); > > -int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > +static int mtk_vcodec_mem_alloc_nor(void *priv, struct mtk_vcodec_mem *mem) > { > enum mtk_instance_type inst_type = *((unsigned int *)priv); > struct platform_device *plat_dev; > @@ -75,9 +77,71 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > > return 0; > } > -EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > > -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *mem) > +{ > + struct device *dev = &ctx->dev->plat_dev->dev; > + struct dma_buf *dma_buffer; > + struct dma_heap *vdec_heap; > + struct dma_buf_attachment *attach; > + struct sg_table *sgt; > + unsigned long size = mem->size; > + int ret = 0; > + > + if (!size) > + return -EINVAL; > + > + vdec_heap = dma_heap_find("restricted_mtk_cma"); > + if (!vdec_heap) { > + mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); > + return -EPERM; > + } > + > + dma_buffer = dma_heap_buffer_alloc(vdec_heap, size, DMA_HEAP_VALID_FD_FLAGS, > + DMA_HEAP_VALID_HEAP_FLAGS); > + if (IS_ERR_OR_NULL(dma_buffer)) { > + mtk_v4l2_vdec_err(ctx, "dma heap alloc size=0x%lx failed!", size); > + return PTR_ERR(dma_buffer); > + } > + > + attach = dma_buf_attach(dma_buffer, dev); > + if (IS_ERR_OR_NULL(attach)) { > + mtk_v4l2_vdec_err(ctx, "dma attach size=0x%lx failed!", size); > + ret = PTR_ERR(attach); > + goto err_attach; > + } > + > + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); > + if (IS_ERR_OR_NULL(sgt)) { > + mtk_v4l2_vdec_err(ctx, "dma map attach size=0x%lx failed!", size); > + ret = PTR_ERR(sgt); > + goto err_sgt; > + } > + > + mem->va = dma_buffer; > + mem->dma_addr = (dma_addr_t)sg_dma_address((sgt)->sgl); > + > + if (!mem->va || !mem->dma_addr) { > + mtk_v4l2_vdec_err(ctx, "dma buffer size=0x%lx failed!", size); > + ret = -EPERM; > + goto err_addr; > + } > + > + mem->attach = attach; > + mem->sgt = sgt; > + > + return 0; > +err_addr: > + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); > +err_sgt: > + dma_buf_detach(dma_buffer, attach); > +err_attach: > + dma_buf_put(dma_buffer); > + > + return ret; > +} > + > +static void mtk_vcodec_mem_free_nor(void *priv, struct mtk_vcodec_mem *mem) > { > enum mtk_instance_type inst_type = *((unsigned int *)priv); > struct platform_device *plat_dev; > @@ -110,6 +174,57 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > mem->dma_addr = 0; > mem->size = 0; > } > + > +static void mtk_vcodec_mem_free_sec(struct mtk_vcodec_mem *mem) > +{ > + if (mem->sgt) > + dma_buf_unmap_attachment(mem->attach, mem->sgt, DMA_BIDIRECTIONAL); is (!mem->sgt) possible at all here? In mtk_vcodec_mem_alloc_sec() "if (IS_ERR_OR_NULL(sgt))" triggers an error recovery path and the allocation fails. Do you ever try to free_sec() a failed allocation? > + dma_buf_detach((struct dma_buf *)mem->va, mem->attach); > + dma_buf_put((struct dma_buf *)mem->va); > + > + mem->attach = NULL; > + mem->sgt = NULL; > + mem->va = NULL; > + mem->dma_addr = 0; > + mem->size = 0; > +} > + > +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > +{ > + enum mtk_instance_type inst_type = *((unsigned int *)priv); > + int ret; > + > + if (inst_type == MTK_INST_DECODER) { > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > + > + if (dec_ctx->is_secure_playback) { > + ret = mtk_vcodec_mem_alloc_sec(dec_ctx, mem); > + goto alloc_end; > + } > + } > + > + ret = mtk_vcodec_mem_alloc_nor(priv, mem); > +alloc_end: > + again maybe it's just my personal preference, but I'd have no goto (not because goto is prohibited, but because maybe it's not really justified here), fewer curly braces and no label: int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) { struct mtk_vcodec_dec_ctx *dec_ctx = priv; if (dec_ctx->inst_type == MTK_INST_DECODER && dec_ctx->is_secure_playback) return mtk_vcodec_mem_alloc_sec(dec_ctx, mem); return mtk_vcodec_mem_alloc_nor(priv, mem); } To me it makes no sense to cast priv to inst_type _and_ to dec_ctx given that dec_ctx's first member _is_ inst_type. > + return ret; > +} > +EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > + > +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > +{ > + enum mtk_instance_type inst_type = *((unsigned int *)priv); ditto here. Regards, Andrzej > + > + if (inst_type == MTK_INST_DECODER) { > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > + > + if (dec_ctx->is_secure_playback) { > + mtk_vcodec_mem_free_sec(mem); > + return; > + } > + } > + > + mtk_vcodec_mem_free_nor(priv, mem); > +} > EXPORT_SYMBOL(mtk_vcodec_mem_free); > > void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx) > @@ -171,3 +286,4 @@ EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx); > > MODULE_LICENSE("GPL v2"); > MODULE_DESCRIPTION("Mediatek video codec driver"); > +MODULE_IMPORT_NS(DMA_BUF); > diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > index 85f615cdd4d3..22078e757ed0 100644 > --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > @@ -18,6 +18,9 @@ struct mtk_vcodec_mem { > size_t size; > void *va; > dma_addr_t dma_addr; > + > + struct dma_buf_attachment *attach; > + struct sg_table *sgt; > }; > > struct mtk_vcodec_fb {
On Thu, May 16, 2024 at 08:20:50PM +0800, Yunfei Dong wrote: > Need to call dma heap interface to allocate/free secure memory when playing > secure video. > > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> > --- > .../media/platform/mediatek/vcodec/Kconfig | 1 + > .../mediatek/vcodec/common/mtk_vcodec_util.c | 122 +++++++++++++++++- > .../mediatek/vcodec/common/mtk_vcodec_util.h | 3 + > 3 files changed, 123 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig b/drivers/media/platform/mediatek/vcodec/Kconfig > index bc8292232530..707865703e61 100644 > --- a/drivers/media/platform/mediatek/vcodec/Kconfig > +++ b/drivers/media/platform/mediatek/vcodec/Kconfig > @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC > depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU > depends on MTK_SCP || !MTK_SCP > depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n) > + depends on DMABUF_HEAPS > select VIDEOBUF2_DMA_CONTIG > select V4L2_MEM2MEM_DEV > select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU > diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > index c60e4c193b25..5958dcd7965a 100644 > --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > @@ -5,9 +5,11 @@ > * Tiffany Lin <tiffany.lin@mediatek.com> > */ > > +#include <linux/dma-heap.h> > #include <linux/module.h> > #include <linux/of.h> > #include <linux/regmap.h> > +#include <uapi/linux/dma-heap.h> > > #include "../decoder/mtk_vcodec_dec_drv.h" > #include "../encoder/mtk_vcodec_enc_drv.h" > @@ -45,7 +47,7 @@ int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, unsigned int reg, > } > EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); > > -int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > +static int mtk_vcodec_mem_alloc_nor(void *priv, struct mtk_vcodec_mem *mem) > { > enum mtk_instance_type inst_type = *((unsigned int *)priv); > struct platform_device *plat_dev; > @@ -75,9 +77,71 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > > return 0; > } > -EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > > -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *mem) > +{ > + struct device *dev = &ctx->dev->plat_dev->dev; > + struct dma_buf *dma_buffer; > + struct dma_heap *vdec_heap; > + struct dma_buf_attachment *attach; > + struct sg_table *sgt; > + unsigned long size = mem->size; > + int ret = 0; > + > + if (!size) > + return -EINVAL; > + > + vdec_heap = dma_heap_find("restricted_mtk_cma"); > + if (!vdec_heap) { > + mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); > + return -EPERM; > + } How is the heap name determined here? My recollection is that the heap name comes from the heap node in the DT, so it may vary depending on the board. Is the heap name documented anywhere in the DT bindings? Shouldn't we rather query DT for a phandle to the right heap? > + > + dma_buffer = dma_heap_buffer_alloc(vdec_heap, size, DMA_HEAP_VALID_FD_FLAGS, > + DMA_HEAP_VALID_HEAP_FLAGS); > + if (IS_ERR_OR_NULL(dma_buffer)) { > + mtk_v4l2_vdec_err(ctx, "dma heap alloc size=0x%lx failed!", size); > + return PTR_ERR(dma_buffer); This will be incorrect if NULL was returned, because the function will return 0. Does dma_heap_buffer_alloc() actually return NULL? > + } > + > + attach = dma_buf_attach(dma_buffer, dev); > + if (IS_ERR_OR_NULL(attach)) { > + mtk_v4l2_vdec_err(ctx, "dma attach size=0x%lx failed!", size); > + ret = PTR_ERR(attach); Ditto. > + goto err_attach; > + } > + > + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); > + if (IS_ERR_OR_NULL(sgt)) { > + mtk_v4l2_vdec_err(ctx, "dma map attach size=0x%lx failed!", size); > + ret = PTR_ERR(sgt); Ditto. > + goto err_sgt; > + } > + > + mem->va = dma_buffer; Isn't this field supposed to point to the kernel mapping of the buffer itself? If we need to store the dma_buf pointer, we should probably add a separate field to avoid (potentially serious) bugs. > + mem->dma_addr = (dma_addr_t)sg_dma_address((sgt)->sgl); Why is this type cast necessary here? > + > + if (!mem->va || !mem->dma_addr) { I don't think any of these 2 conditions are possible, since we already checked for successful completion of the functions above. Also 0 is a valid DMA address, so it shouldn't be considered an error. > + mtk_v4l2_vdec_err(ctx, "dma buffer size=0x%lx failed!", size); > + ret = -EPERM; > + goto err_addr; > + } > + > + mem->attach = attach; > + mem->sgt = sgt; > + > + return 0; > +err_addr: Please name the labels according to the clean-up step they perform first, because it will make it much easier to validate at the goto point whether it jumps to the right place. > + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); > +err_sgt: > + dma_buf_detach(dma_buffer, attach); > +err_attach: > + dma_buf_put(dma_buffer); > + > + return ret; > +} > + > +static void mtk_vcodec_mem_free_nor(void *priv, struct mtk_vcodec_mem *mem) > { > enum mtk_instance_type inst_type = *((unsigned int *)priv); > struct platform_device *plat_dev; > @@ -110,6 +174,57 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > mem->dma_addr = 0; > mem->size = 0; > } > + > +static void mtk_vcodec_mem_free_sec(struct mtk_vcodec_mem *mem) > +{ > + if (mem->sgt) > + dma_buf_unmap_attachment(mem->attach, mem->sgt, DMA_BIDIRECTIONAL); > + dma_buf_detach((struct dma_buf *)mem->va, mem->attach); > + dma_buf_put((struct dma_buf *)mem->va); > + > + mem->attach = NULL; > + mem->sgt = NULL; > + mem->va = NULL; > + mem->dma_addr = 0; > + mem->size = 0; > +} > + > +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > +{ > + enum mtk_instance_type inst_type = *((unsigned int *)priv); > + int ret; > + > + if (inst_type == MTK_INST_DECODER) { > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > + > + if (dec_ctx->is_secure_playback) { > + ret = mtk_vcodec_mem_alloc_sec(dec_ctx, mem); > + goto alloc_end; Why not just return here directly? Best regards, Tomasz > + } > + } > + > + ret = mtk_vcodec_mem_alloc_nor(priv, mem); > +alloc_end: > + > + return ret; > +} > +EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > + > +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > +{ > + enum mtk_instance_type inst_type = *((unsigned int *)priv); > + > + if (inst_type == MTK_INST_DECODER) { > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > + > + if (dec_ctx->is_secure_playback) { > + mtk_vcodec_mem_free_sec(mem); > + return; > + } > + } > + > + mtk_vcodec_mem_free_nor(priv, mem); > +} > EXPORT_SYMBOL(mtk_vcodec_mem_free); > > void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx) > @@ -171,3 +286,4 @@ EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx); > > MODULE_LICENSE("GPL v2"); > MODULE_DESCRIPTION("Mediatek video codec driver"); > +MODULE_IMPORT_NS(DMA_BUF); > diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > index 85f615cdd4d3..22078e757ed0 100644 > --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > @@ -18,6 +18,9 @@ struct mtk_vcodec_mem { > size_t size; > void *va; > dma_addr_t dma_addr; > + > + struct dma_buf_attachment *attach; > + struct sg_table *sgt; > }; > > struct mtk_vcodec_fb { > -- > 2.25.1 >
On Wed, 2024-06-12 at 14:22 +0900, Tomasz Figa wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > On Thu, May 16, 2024 at 08:20:50PM +0800, Yunfei Dong wrote: > > Need to call dma heap interface to allocate/free secure memory when > playing > > secure video. > > > > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> > > --- > > .../media/platform/mediatek/vcodec/Kconfig | 1 + > > .../mediatek/vcodec/common/mtk_vcodec_util.c | 122 > +++++++++++++++++- > > .../mediatek/vcodec/common/mtk_vcodec_util.h | 3 + > > 3 files changed, 123 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig > b/drivers/media/platform/mediatek/vcodec/Kconfig > > index bc8292232530..707865703e61 100644 > > --- a/drivers/media/platform/mediatek/vcodec/Kconfig > > +++ b/drivers/media/platform/mediatek/vcodec/Kconfig > > @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC [snip] > > -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > > +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx > *ctx, struct mtk_vcodec_mem *mem) > > +{ > > +struct device *dev = &ctx->dev->plat_dev->dev; > > +struct dma_buf *dma_buffer; > > +struct dma_heap *vdec_heap; > > +struct dma_buf_attachment *attach; > > +struct sg_table *sgt; > > +unsigned long size = mem->size; > > +int ret = 0; > > + > > +if (!size) > > +return -EINVAL; > > + > > +vdec_heap = dma_heap_find("restricted_mtk_cma"); > > +if (!vdec_heap) { > > +mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); > > +return -EPERM; > > +} > > How is the heap name determined here? My recollection is that the > heap > name comes from the heap node in the DT, so it may vary depending on > the > board. > > Is the heap name documented anywhere in the DT bindings? > > Shouldn't we rather query DT for a phandle to the right heap? > Hi Tomasz, This heap name does not come from dt-binding. It is hard-coded in the driver[1]. Because the heap driver is a pure SW driver, there is no corresponding HW unit, and there is no way to add a dtsi node. [1] https://lore.kernel.org/linux-mediatek/20240515112308.10171-10-yong.wu@mediatek.com/ Thanks.
Hi Andrzej, Thanks for your help to review this patch. On Wed, 2024-05-22 at 14:25 +0200, Andrzej Pietrasiewicz wrote: > Hi Yunfei, > > W dniu 16.05.2024 o 14:20, Yunfei Dong pisze: > > Need to call dma heap interface to allocate/free secure memory when > > playing > > secure video. > > > > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> > > --- > > .../media/platform/mediatek/vcodec/Kconfig | 1 + > > .../mediatek/vcodec/common/mtk_vcodec_util.c | 122 > > +++++++++++++++++- > > .../mediatek/vcodec/common/mtk_vcodec_util.h | 3 + > > 3 files changed, 123 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig > > b/drivers/media/platform/mediatek/vcodec/Kconfig > > index bc8292232530..707865703e61 100644 > > --- a/drivers/media/platform/mediatek/vcodec/Kconfig > > +++ b/drivers/media/platform/mediatek/vcodec/Kconfig > > @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC > > depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU > > depends on MTK_SCP || !MTK_SCP > > depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n) > > + depends on DMABUF_HEAPS > > select VIDEOBUF2_DMA_CONTIG > > select V4L2_MEM2MEM_DEV > > select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU > > diff --git > > a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > > b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > > index c60e4c193b25..5958dcd7965a 100644 > > --- > > a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > > +++ > > b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c > > @@ -5,9 +5,11 @@ > > * Tiffany Lin <tiffany.lin@mediatek.com> > > */ > > > > +#include <linux/dma-heap.h> > > #include <linux/module.h> > > #include <linux/of.h> > > #include <linux/regmap.h> > > +#include <uapi/linux/dma-heap.h> > > > > #include "../decoder/mtk_vcodec_dec_drv.h" > > #include "../encoder/mtk_vcodec_enc_drv.h" > > @@ -45,7 +47,7 @@ int mtk_vcodec_write_vdecsys(struct > > mtk_vcodec_dec_ctx *ctx, unsigned int reg, > > } > > EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); > > > > -int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > > +static int mtk_vcodec_mem_alloc_nor(void *priv, struct > > mtk_vcodec_mem *mem) > > { > > enum mtk_instance_type inst_type = *((unsigned int *)priv); > > struct platform_device *plat_dev; > > @@ -75,9 +77,71 @@ int mtk_vcodec_mem_alloc(void *priv, struct > > mtk_vcodec_mem *mem) > > > > return 0; > > } > > -EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > > > > -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > > +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx > > *ctx, struct mtk_vcodec_mem *mem) > > +{ > > + struct device *dev = &ctx->dev->plat_dev->dev; > > + struct dma_buf *dma_buffer; > > + struct dma_heap *vdec_heap; > > + struct dma_buf_attachment *attach; > > + struct sg_table *sgt; > > + unsigned long size = mem->size; > > + int ret = 0; > > + > > + if (!size) > > + return -EINVAL; > > + > > + vdec_heap = dma_heap_find("restricted_mtk_cma"); > > + if (!vdec_heap) { > > + mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); > > + return -EPERM; > > + } > > + > > + dma_buffer = dma_heap_buffer_alloc(vdec_heap, size, > > DMA_HEAP_VALID_FD_FLAGS, > > + DMA_HEAP_VALID_HEAP_FLAGS); > > + if (IS_ERR_OR_NULL(dma_buffer)) { > > + mtk_v4l2_vdec_err(ctx, "dma heap alloc size=0x%lx > > failed!", size); > > + return PTR_ERR(dma_buffer); > > + } > > + > > + attach = dma_buf_attach(dma_buffer, dev); > > + if (IS_ERR_OR_NULL(attach)) { > > + mtk_v4l2_vdec_err(ctx, "dma attach size=0x%lx failed!", > > size); > > + ret = PTR_ERR(attach); > > + goto err_attach; > > + } > > + > > + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); > > + if (IS_ERR_OR_NULL(sgt)) { > > + mtk_v4l2_vdec_err(ctx, "dma map attach size=0x%lx > > failed!", size); > > + ret = PTR_ERR(sgt); > > + goto err_sgt; > > + } > > + > > + mem->va = dma_buffer; > > + mem->dma_addr = (dma_addr_t)sg_dma_address((sgt)->sgl); > > + > > + if (!mem->va || !mem->dma_addr) { > > + mtk_v4l2_vdec_err(ctx, "dma buffer size=0x%lx failed!", > > size); > > + ret = -EPERM; > > + goto err_addr; > > + } > > + > > + mem->attach = attach; > > + mem->sgt = sgt; > > + > > + return 0; > > +err_addr: > > + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); > > +err_sgt: > > + dma_buf_detach(dma_buffer, attach); > > +err_attach: > > + dma_buf_put(dma_buffer); > > + > > + return ret; > > +} > > + > > +static void mtk_vcodec_mem_free_nor(void *priv, struct > > mtk_vcodec_mem *mem) > > { > > enum mtk_instance_type inst_type = *((unsigned int *)priv); > > struct platform_device *plat_dev; > > @@ -110,6 +174,57 @@ void mtk_vcodec_mem_free(void *priv, struct > > mtk_vcodec_mem *mem) > > mem->dma_addr = 0; > > mem->size = 0; > > } > > + > > +static void mtk_vcodec_mem_free_sec(struct mtk_vcodec_mem *mem) > > +{ > > + if (mem->sgt) > > + dma_buf_unmap_attachment(mem->attach, mem->sgt, > > DMA_BIDIRECTIONAL); > > is (!mem->sgt) possible at all here? > > In mtk_vcodec_mem_alloc_sec() "if (IS_ERR_OR_NULL(sgt))" triggers an > error recovery path and the allocation fails. Do you ever try to > free_sec() > a failed allocation? Looks using 'if (!IS_ERR_OR_NULL(mem->sgt))' is much more reasonable. Best Regards, Yunfei Dong > > > + dma_buf_detach((struct dma_buf *)mem->va, mem->attach); > > + dma_buf_put((struct dma_buf *)mem->va); > > + > > + mem->attach = NULL; > > + mem->sgt = NULL; > > + mem->va = NULL; > > + mem->dma_addr = 0; > > + mem->size = 0; > > +} > > + > > +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > > +{ > > + enum mtk_instance_type inst_type = *((unsigned int *)priv); > > + int ret; > > + > > + if (inst_type == MTK_INST_DECODER) { > > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > > + > > + if (dec_ctx->is_secure_playback) { > > + ret = mtk_vcodec_mem_alloc_sec(dec_ctx, mem); > > + goto alloc_end; > > + } > > + } > > + > > + ret = mtk_vcodec_mem_alloc_nor(priv, mem); > > +alloc_end: > > + > > again maybe it's just my personal preference, but I'd have no goto > (not because goto is prohibited, but because maybe it's not really > justified here), fewer curly braces and no label: > > int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) > { > struct mtk_vcodec_dec_ctx *dec_ctx = priv; > > if (dec_ctx->inst_type == MTK_INST_DECODER && dec_ctx- > >is_secure_playback) > return mtk_vcodec_mem_alloc_sec(dec_ctx, mem); > > return mtk_vcodec_mem_alloc_nor(priv, mem); > } > > To me it makes no sense to cast priv to inst_type _and_ to dec_ctx > given that dec_ctx's first member _is_ inst_type. > > > + return ret; > > +} > > +EXPORT_SYMBOL(mtk_vcodec_mem_alloc); > > + > > +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > > +{ > > + enum mtk_instance_type inst_type = *((unsigned int *)priv); > > > ditto here. > > Regards, > > Andrzej > > > + > > + if (inst_type == MTK_INST_DECODER) { > > + struct mtk_vcodec_dec_ctx *dec_ctx = priv; > > + > > + if (dec_ctx->is_secure_playback) { > > + mtk_vcodec_mem_free_sec(mem); > > + return; > > + } > > + } > > + > > + mtk_vcodec_mem_free_nor(priv, mem); > > +} > > EXPORT_SYMBOL(mtk_vcodec_mem_free); > > > > void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int > > hw_idx) > > @@ -171,3 +286,4 @@ EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx); > > > > MODULE_LICENSE("GPL v2"); > > MODULE_DESCRIPTION("Mediatek video codec driver"); > > +MODULE_IMPORT_NS(DMA_BUF); > > diff --git > > a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > > b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > > index 85f615cdd4d3..22078e757ed0 100644 > > --- > > a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > > +++ > > b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h > > @@ -18,6 +18,9 @@ struct mtk_vcodec_mem { > > size_t size; > > void *va; > > dma_addr_t dma_addr; > > + > > + struct dma_buf_attachment *attach; > > + struct sg_table *sgt; > > }; > > > > struct mtk_vcodec_fb { > >
On Mon, Jun 17, 2024 at 3:53 PM Yong Wu (吴勇) <Yong.Wu@mediatek.com> wrote: > > On Wed, 2024-06-12 at 14:22 +0900, Tomasz Figa wrote: > > > > External email : Please do not click links or open attachments until > > you have verified the sender or the content. > > On Thu, May 16, 2024 at 08:20:50PM +0800, Yunfei Dong wrote: > > > Need to call dma heap interface to allocate/free secure memory when > > playing > > > secure video. > > > > > > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com> > > > --- > > > .../media/platform/mediatek/vcodec/Kconfig | 1 + > > > .../mediatek/vcodec/common/mtk_vcodec_util.c | 122 > > +++++++++++++++++- > > > .../mediatek/vcodec/common/mtk_vcodec_util.h | 3 + > > > 3 files changed, 123 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig > > b/drivers/media/platform/mediatek/vcodec/Kconfig > > > index bc8292232530..707865703e61 100644 > > > --- a/drivers/media/platform/mediatek/vcodec/Kconfig > > > +++ b/drivers/media/platform/mediatek/vcodec/Kconfig > > > @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC > > [snip] > > > > -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) > > > +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx > > *ctx, struct mtk_vcodec_mem *mem) > > > +{ > > > +struct device *dev = &ctx->dev->plat_dev->dev; > > > +struct dma_buf *dma_buffer; > > > +struct dma_heap *vdec_heap; > > > +struct dma_buf_attachment *attach; > > > +struct sg_table *sgt; > > > +unsigned long size = mem->size; > > > +int ret = 0; > > > + > > > +if (!size) > > > +return -EINVAL; > > > + > > > +vdec_heap = dma_heap_find("restricted_mtk_cma"); > > > +if (!vdec_heap) { > > > +mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); > > > +return -EPERM; > > > +} > > > > How is the heap name determined here? My recollection is that the > > heap > > name comes from the heap node in the DT, so it may vary depending on > > the > > board. > > > > Is the heap name documented anywhere in the DT bindings? > > > > Shouldn't we rather query DT for a phandle to the right heap? > > > > Hi Tomasz, > > This heap name does not come from dt-binding. It is hard-coded in the > driver[1]. Because the heap driver is a pure SW driver, there is no > corresponding HW unit, and there is no way to add a dtsi node. > > [1] > https://lore.kernel.org/linux-mediatek/20240515112308.10171-10-yong.wu@mediatek.com/ Okay, I see. Thanks for clarifying. Best regards, Tomasz
diff --git a/drivers/media/platform/mediatek/vcodec/Kconfig b/drivers/media/platform/mediatek/vcodec/Kconfig index bc8292232530..707865703e61 100644 --- a/drivers/media/platform/mediatek/vcodec/Kconfig +++ b/drivers/media/platform/mediatek/vcodec/Kconfig @@ -17,6 +17,7 @@ config VIDEO_MEDIATEK_VCODEC depends on VIDEO_MEDIATEK_VPU || !VIDEO_MEDIATEK_VPU depends on MTK_SCP || !MTK_SCP depends on MTK_SMI || (COMPILE_TEST && MTK_SMI=n) + depends on DMABUF_HEAPS select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV select VIDEO_MEDIATEK_VCODEC_VPU if VIDEO_MEDIATEK_VPU diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c index c60e4c193b25..5958dcd7965a 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.c @@ -5,9 +5,11 @@ * Tiffany Lin <tiffany.lin@mediatek.com> */ +#include <linux/dma-heap.h> #include <linux/module.h> #include <linux/of.h> #include <linux/regmap.h> +#include <uapi/linux/dma-heap.h> #include "../decoder/mtk_vcodec_dec_drv.h" #include "../encoder/mtk_vcodec_enc_drv.h" @@ -45,7 +47,7 @@ int mtk_vcodec_write_vdecsys(struct mtk_vcodec_dec_ctx *ctx, unsigned int reg, } EXPORT_SYMBOL(mtk_vcodec_write_vdecsys); -int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) +static int mtk_vcodec_mem_alloc_nor(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; @@ -75,9 +77,71 @@ int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) return 0; } -EXPORT_SYMBOL(mtk_vcodec_mem_alloc); -void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) +static int mtk_vcodec_mem_alloc_sec(struct mtk_vcodec_dec_ctx *ctx, struct mtk_vcodec_mem *mem) +{ + struct device *dev = &ctx->dev->plat_dev->dev; + struct dma_buf *dma_buffer; + struct dma_heap *vdec_heap; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + unsigned long size = mem->size; + int ret = 0; + + if (!size) + return -EINVAL; + + vdec_heap = dma_heap_find("restricted_mtk_cma"); + if (!vdec_heap) { + mtk_v4l2_vdec_err(ctx, "dma heap find failed!"); + return -EPERM; + } + + dma_buffer = dma_heap_buffer_alloc(vdec_heap, size, DMA_HEAP_VALID_FD_FLAGS, + DMA_HEAP_VALID_HEAP_FLAGS); + if (IS_ERR_OR_NULL(dma_buffer)) { + mtk_v4l2_vdec_err(ctx, "dma heap alloc size=0x%lx failed!", size); + return PTR_ERR(dma_buffer); + } + + attach = dma_buf_attach(dma_buffer, dev); + if (IS_ERR_OR_NULL(attach)) { + mtk_v4l2_vdec_err(ctx, "dma attach size=0x%lx failed!", size); + ret = PTR_ERR(attach); + goto err_attach; + } + + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(sgt)) { + mtk_v4l2_vdec_err(ctx, "dma map attach size=0x%lx failed!", size); + ret = PTR_ERR(sgt); + goto err_sgt; + } + + mem->va = dma_buffer; + mem->dma_addr = (dma_addr_t)sg_dma_address((sgt)->sgl); + + if (!mem->va || !mem->dma_addr) { + mtk_v4l2_vdec_err(ctx, "dma buffer size=0x%lx failed!", size); + ret = -EPERM; + goto err_addr; + } + + mem->attach = attach; + mem->sgt = sgt; + + return 0; +err_addr: + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); +err_sgt: + dma_buf_detach(dma_buffer, attach); +err_attach: + dma_buf_put(dma_buffer); + + return ret; +} + +static void mtk_vcodec_mem_free_nor(void *priv, struct mtk_vcodec_mem *mem) { enum mtk_instance_type inst_type = *((unsigned int *)priv); struct platform_device *plat_dev; @@ -110,6 +174,57 @@ void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) mem->dma_addr = 0; mem->size = 0; } + +static void mtk_vcodec_mem_free_sec(struct mtk_vcodec_mem *mem) +{ + if (mem->sgt) + dma_buf_unmap_attachment(mem->attach, mem->sgt, DMA_BIDIRECTIONAL); + dma_buf_detach((struct dma_buf *)mem->va, mem->attach); + dma_buf_put((struct dma_buf *)mem->va); + + mem->attach = NULL; + mem->sgt = NULL; + mem->va = NULL; + mem->dma_addr = 0; + mem->size = 0; +} + +int mtk_vcodec_mem_alloc(void *priv, struct mtk_vcodec_mem *mem) +{ + enum mtk_instance_type inst_type = *((unsigned int *)priv); + int ret; + + if (inst_type == MTK_INST_DECODER) { + struct mtk_vcodec_dec_ctx *dec_ctx = priv; + + if (dec_ctx->is_secure_playback) { + ret = mtk_vcodec_mem_alloc_sec(dec_ctx, mem); + goto alloc_end; + } + } + + ret = mtk_vcodec_mem_alloc_nor(priv, mem); +alloc_end: + + return ret; +} +EXPORT_SYMBOL(mtk_vcodec_mem_alloc); + +void mtk_vcodec_mem_free(void *priv, struct mtk_vcodec_mem *mem) +{ + enum mtk_instance_type inst_type = *((unsigned int *)priv); + + if (inst_type == MTK_INST_DECODER) { + struct mtk_vcodec_dec_ctx *dec_ctx = priv; + + if (dec_ctx->is_secure_playback) { + mtk_vcodec_mem_free_sec(mem); + return; + } + } + + mtk_vcodec_mem_free_nor(priv, mem); +} EXPORT_SYMBOL(mtk_vcodec_mem_free); void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dec_dev *dev, int hw_idx) @@ -171,3 +286,4 @@ EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Mediatek video codec driver"); +MODULE_IMPORT_NS(DMA_BUF); diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h index 85f615cdd4d3..22078e757ed0 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_util.h @@ -18,6 +18,9 @@ struct mtk_vcodec_mem { size_t size; void *va; dma_addr_t dma_addr; + + struct dma_buf_attachment *attach; + struct sg_table *sgt; }; struct mtk_vcodec_fb {