From patchwork Tue Aug 14 15:34:41 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Stanislawski X-Patchwork-Id: 1321251 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 9DF21DF215 for ; Tue, 14 Aug 2012 15:36:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755049Ab2HNPgq (ORCPT ); Tue, 14 Aug 2012 11:36:46 -0400 Received: from mailout3.samsung.com ([203.254.224.33]:51012 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751785Ab2HNPgo (ORCPT ); Tue, 14 Aug 2012 11:36:44 -0400 Received: from epcpsbgm1.samsung.com (mailout3.samsung.com [203.254.224.33]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M8R00IQ94OUO320@mailout3.samsung.com> for linux-media@vger.kernel.org; Wed, 15 Aug 2012 00:36:39 +0900 (KST) X-AuditID: cbfee61a-b7fc66d0000043b7-23-502a7086e010 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id DB.6D.17335.6807A205; Wed, 15 Aug 2012 00:36:38 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0M8R004J44MBC810@mmp1.samsung.com> for linux-media@vger.kernel.org; Wed, 15 Aug 2012 00:36:38 +0900 (KST) From: Tomasz Stanislawski To: linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org Cc: airlied@redhat.com, m.szyprowski@samsung.com, t.stanislaws@samsung.com, kyungmin.park@samsung.com, laurent.pinchart@ideasonboard.com, sumit.semwal@ti.com, daeinki@gmail.com, daniel.vetter@ffwll.ch, robdclark@gmail.com, pawel@osciak.com, linaro-mm-sig@lists.linaro.org, hverkuil@xs4all.nl, remi@remlab.net, subashrp@gmail.com, mchehab@redhat.com, g.liakhovetski@gmx.de, dmitriyz@google.com, s.nawrocki@samsung.com, k.debski@samsung.com, Sumit Semwal Subject: [PATCHv8 11/26] v4l: vb2-dma-contig: add support for dma_buf importing Date: Tue, 14 Aug 2012 17:34:41 +0200 Message-id: <1344958496-9373-12-git-send-email-t.stanislaws@samsung.com> X-Mailer: git-send-email 1.7.10 In-reply-to: <1344958496-9373-1-git-send-email-t.stanislaws@samsung.com> References: <1344958496-9373-1-git-send-email-t.stanislaws@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrAJMWRmVeSWpSXmKPExsVy+t9jAd22Aq0Ag2MtZhY9G7ayOjB6fN4k F8AYxWWTkpqTWZZapG+XwJVx7N9m9oLtmhWdvzexNTD2KHUxcnBICJhIrNwa2sXICWSKSVy4 t56ti5GLQ0hgEaPEjIZ17BDOKiaJx3snsINUsQE1HFvymRHEFhFwkDh9dxYzSBGzwCtmie1T 1rKCTBUW8Jc43KEOUsMioCqx6cwFsHpeAQ+Jro61bBDb5CWe3u8DszmB4i83dTOCtAoJuEss /Ok/gZF3ASPDKkbR1ILkguKk9FxDveLE3OLSvHS95PzcTYxgfz+T2sG4ssHiEKMAB6MSD69C mmaAEGtiWXFl7iFGCQ5mJRHeoiCtACHelMTKqtSi/Pii0pzU4kOM0hwsSuK8xt5f/YUE0hNL UrNTUwtSi2CyTBycUg2MLid33z7NdXolf2bzxgOqhpzbWr4vXh24ocqiKvDn0kd5Hky+QRre B23Zv+Z9q4nX+j3RoXKjvFbftsWTfDKKRP4GzZ45efmiWLVXv3t0nH85nlBPuCmffVeSe4fq 2us3z1012PxG3dlOI31OzJTV62YsLOD9+G2KiHTV7uBLK0sCXqwz+fNCU4mlOCPRUIu5qDgR ANydUuDzAQAA X-TM-AS-MML: No Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Sumit Semwal This patch makes changes for adding dma-contig as a dma_buf user. It provides function implementations for the {attach, detach, map, unmap}_dmabuf() mem_ops of DMABUF memory type. Signed-off-by: Sumit Semwal Signed-off-by: Sumit Semwal [author of the original patch] Signed-off-by: Tomasz Stanislawski [integration with refactored dma-contig allocator] Acked-by: Laurent Pinchart --- drivers/media/video/videobuf2-dma-contig.c | 120 +++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c index 494a824..a5804cf 100644 --- a/drivers/media/video/videobuf2-dma-contig.c +++ b/drivers/media/video/videobuf2-dma-contig.c @@ -10,6 +10,7 @@ * the Free Software Foundation. */ +#include #include #include #include @@ -38,6 +39,9 @@ struct vb2_dc_buf { /* USERPTR related */ struct vm_area_struct *vma; + + /* DMABUF related */ + struct dma_buf_attachment *db_attach; }; /*********************************************/ @@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - if (!sgt) + /* DMABUF exporter will flush the cache for us */ + if (!sgt || buf->db_attach) return; dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir); @@ -377,6 +383,112 @@ fail_buf: } /*********************************************/ +/* callbacks for DMABUF buffers */ +/*********************************************/ + +static int vb2_dc_map_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt; + unsigned long contig_size; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to pin a non attached buffer\n"); + return -EINVAL; + } + + if (WARN_ON(buf->dma_sgt)) { + pr_err("dmabuf buffer is already pinned\n"); + return 0; + } + + /* get the associated scatterlist for this buffer */ + sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir); + if (IS_ERR_OR_NULL(sgt)) { + pr_err("Error getting dmabuf scatterlist\n"); + return -EINVAL; + } + + /* checking if dmabuf is big enough to store contiguous chunk */ + contig_size = vb2_dc_get_contiguous_size(sgt); + if (contig_size < buf->size) { + pr_err("contiguous chunk is too small %lu/%lu b\n", + contig_size, buf->size); + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + return -EFAULT; + } + + buf->dma_addr = sg_dma_address(sgt->sgl); + buf->dma_sgt = sgt; + + return 0; +} + +static void vb2_dc_unmap_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + struct sg_table *sgt = buf->dma_sgt; + + if (WARN_ON(!buf->db_attach)) { + pr_err("trying to unpin a not attached buffer\n"); + return; + } + + if (WARN_ON(!sgt)) { + pr_err("dmabuf buffer is already unpinned\n"); + return; + } + + dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir); + + buf->dma_addr = 0; + buf->dma_sgt = NULL; +} + +static void vb2_dc_detach_dmabuf(void *mem_priv) +{ + struct vb2_dc_buf *buf = mem_priv; + + /* if vb2 works correctly you should never detach mapped buffer */ + if (WARN_ON(buf->dma_addr)) + vb2_dc_unmap_dmabuf(buf); + + /* detach this attachment */ + dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach); + kfree(buf); +} + +static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write) +{ + struct vb2_dc_conf *conf = alloc_ctx; + struct vb2_dc_buf *buf; + struct dma_buf_attachment *dba; + + if (dbuf->size < size) + return ERR_PTR(-EFAULT); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + buf->dev = conf->dev; + /* create attachment for the dmabuf with the user device */ + dba = dma_buf_attach(dbuf, buf->dev); + if (IS_ERR(dba)) { + pr_err("failed to attach dmabuf\n"); + kfree(buf); + return dba; + } + + buf->dma_dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + buf->size = size; + buf->db_attach = dba; + + return buf; +} + +/*********************************************/ /* DMA CONTIG exported functions */ /*********************************************/ @@ -390,6 +502,10 @@ const struct vb2_mem_ops vb2_dma_contig_memops = { .put_userptr = vb2_dc_put_userptr, .prepare = vb2_dc_prepare, .finish = vb2_dc_finish, + .map_dmabuf = vb2_dc_map_dmabuf, + .unmap_dmabuf = vb2_dc_unmap_dmabuf, + .attach_dmabuf = vb2_dc_attach_dmabuf, + .detach_dmabuf = vb2_dc_detach_dmabuf, .num_users = vb2_dc_num_users, }; EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);