From patchwork Fri Oct 20 10:14:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 10019467 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D7C8D60211 for ; Fri, 20 Oct 2017 10:15:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C7E0C28E7B for ; Fri, 20 Oct 2017 10:15:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BCAD028EE1; Fri, 20 Oct 2017 10:15:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B85528E7B for ; Fri, 20 Oct 2017 10:15:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752643AbdJTKPB (ORCPT ); Fri, 20 Oct 2017 06:15:01 -0400 Received: from mailout2.w1.samsung.com ([210.118.77.12]:48677 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752603AbdJTKO7 (ORCPT ); Fri, 20 Oct 2017 06:14:59 -0400 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20171020101457euoutp02b0ea868b30b061e716374198429c97b8~vP8C7gmMy0746107461euoutp029; Fri, 20 Oct 2017 10:14:57 +0000 (GMT) Received: from eusmges3.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20171020101456eucas1p235a2511e35f3ecf1af6daf7e66c1823f~vP8CR4Wn41608716087eucas1p2-; Fri, 20 Oct 2017 10:14:56 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3.samsung.com (EUCPMTA) with SMTP id E3.5C.12867.0ACC9E95; Fri, 20 Oct 2017 11:14:56 +0100 (BST) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20171020101455eucas1p1ad826b685fab9d93bb5f12b2b27096c6~vP8BkQs7A1295012950eucas1p1S; Fri, 20 Oct 2017 10:14:55 +0000 (GMT) X-AuditID: cbfec7f2-f793b6d000003243-7f-59e9cca027ba Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 7F.1D.18832.F9CC9E95; Fri, 20 Oct 2017 11:14:55 +0100 (BST) Received: from AMDC2765.digital.local ([106.116.147.25]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OY400M7E9SPGF40@eusync3.samsung.com>; Fri, 20 Oct 2017 11:14:55 +0100 (BST) From: Marek Szyprowski To: linux-media@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: Marek Szyprowski , Sylwester Nawrocki , Andrzej Hajda , Marian Mihailescu , Chanwoo Choi , JaeChul Lee , Krzysztof Kozlowski , Seung-Woo Kim Subject: [PATCH] media: s5p-mfc: Add support for V4L2_MEMORY_DMABUF type Date: Fri, 20 Oct 2017 12:14:33 +0200 Message-id: <20171020101433.30119-1-m.szyprowski@samsung.com> X-Mailer: git-send-email 2.14.2 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrFIsWRmVeSWpSXmKPExsWy7djP87oLzryMNDhwhM/i1rpzrBbXvzxn tXi7v5vZ4vz5DewWPRu2slrMOL+PyWLtkbvsFuun/WS1OPymHSg2+SWbA5fHzll32T02repk 8+jbsorR4/MmuQCWKC6blNSczLLUIn27BK6MAwtqCw54VVxZfZWpgfGqTRcjJ4eEgIlE0+v1 rBC2mMSFe+vZuhi5OIQEljJKHJz6gx3C+cwoceL5VHaYjv8955lAbCGBZYwS59aLQhQ1MEnc v7wUrIhNwFCi620XG4gtIuAksXDWX7BJzAIXmCRW9PwC2ycs4CEx90gfC4jNIqAq8XPlNUYQ m1fAVuLOmhksENvkJd4vuM8I0iwh0MEm0XnkKhNEwkVi4tePjBC2sMSr41ugzpOR6Ow4CFXT zyjR1KoNYc8AOvUtL4RtLXH4+EWwI5gF+CQmbZvO3MXIARTnlehoE4Io8ZD4dPEZ1A2OEu/m HGWF+DhWYv6Xj2wTGKUWMDKsYhRJLS3OTU8tNtYrTswtLs1L10vOz93ECIzR0/+Of9rB+PWE 1SFGAQ5GJR7eDRdeRAqxJpYVV+YeYpTgYFYS4TXc/zJSiDclsbIqtSg/vqg0J7X4EKM0B4uS OK9tVFukkEB6YklqdmpqQWoRTJaJg1OqgXF3wevd7TM+GLNN/P7MadrL7jX7D0YvixVIKq0y 5F52fmbalQel546ur8h092pf4jltqcnaDe4n05SkMs98bnA+F1zZ8l+W5YlCorXMD+4KzqKw tLV9W+9/e71r5kGDKocHL5l/NgeaCywonq4lZWR2frfhtfP+LjPDNicWasl+lTtyoyAsZYoS S3FGoqEWc1FxIgCYJD+7zQIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpmluLIzCtJLcpLzFFi42I5/e/4Vd35Z15GGizeqG1xa905VovrX56z Wrzd381scf78BnaLng1bWS1mnN/HZLH2yF12i/XTfrJaHH7TDhSb/JLNgctj56y77B6bVnWy efRtWcXo8XmTXABLFJdNSmpOZllqkb5dAlfGgQW1BQe8Kq6svsrUwHjVpouRk0NCwETif895 JghbTOLCvfVsXYxcHEICSxglvr+7xQKSEBJoYpKY9pcRxGYTMJToetvFBmKLCDhJLJz1lx3E Zha4xCRxbaI3iC0s4CEx90gfWC+LgKrEz5XXwHp5BWwl7qyZwQKxTF7i/YL7jBMYuRcwMqxi FEktLc5Nzy021CtOzC0uzUvXS87P3cQIDJptx35u3sF4aWPwIUYBDkYlHt4NF15ECrEmlhVX 5h5ilOBgVhLhNdz/MlKINyWxsiq1KD++qDQntfgQozQHi5I4b++e1ZFCAumJJanZqakFqUUw WSYOTqkGRsnPu+Z5bpuaxHHr7J6/0y3Lr1s/0Sh8LDSj9aj78vfFpcHpW6QFl9bHRpjVpu1a uvjaXvfpSe1if8r/sMqtPHul5V2/aeXOYhWBTYHfKnPOcB2qeZBpscx0mafroYQPs68eNplx 9piUXMQNtS3HpnWnhplZJRR/vn072edAuJnC7/ijlseZJyixFGckGmoxFxUnAgB5h7DlFgIA AA== X-CMS-MailID: 20171020101455eucas1p1ad826b685fab9d93bb5f12b2b27096c6 X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRs=?= =?UTF-8?B?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRtT?= =?UTF-8?B?YW1zdW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-CMS-RootMailID: 20171020101455eucas1p1ad826b685fab9d93bb5f12b2b27096c6 X-RootMTR: 20171020101455eucas1p1ad826b685fab9d93bb5f12b2b27096c6 References: Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Seung-Woo Kim There is memory constraint for the buffers in V5 of the MFC hardware, but when IOMMU is used, then this constraint is meaningless. Other version of the MFC hardware don't have such limitations. So in such cases the driver is able to use buffers placed anywhere in the system memory, thus USERPTR and DMABUF operation modes can be also enabled. This patch also removes USERPTR operation mode from encoder node, as it doesn't work with v5 MFC hardware without IOMMU being enabled. Signed-off-by: Seung-Woo Kim [mszyprow: adapted to v4.14 code base and updated commit message] Signed-off-by: Marek Szyprowski --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 14 ++++-- drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 73 ++++++++++++++++++++++++---- drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 24 ++++++--- 3 files changed, 89 insertions(+), 22 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index cf68aed59e0d..f975523dc040 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -754,6 +754,7 @@ static int s5p_mfc_open(struct file *file) struct s5p_mfc_dev *dev = video_drvdata(file); struct s5p_mfc_ctx *ctx = NULL; struct vb2_queue *q; + unsigned int io_modes; int ret = 0; mfc_debug_enter(); @@ -839,16 +840,21 @@ static int s5p_mfc_open(struct file *file) if (ret) goto err_init_hw; } + + io_modes = VB2_MMAP; + if (exynos_is_iommu_available(&dev->plat_dev->dev) || !IS_TWOPORT(dev)) + io_modes |= VB2_USERPTR | VB2_DMABUF; + /* Init videobuf2 queue for CAPTURE */ q = &ctx->vq_dst; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->drv_priv = &ctx->fh; q->lock = &dev->mfc_mutex; if (vdev == dev->vfd_dec) { - q->io_modes = VB2_MMAP; + q->io_modes = io_modes; q->ops = get_dec_queue_ops(); } else if (vdev == dev->vfd_enc) { - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = io_modes; q->ops = get_enc_queue_ops(); } else { ret = -ENOENT; @@ -872,10 +878,10 @@ static int s5p_mfc_open(struct file *file) q->drv_priv = &ctx->fh; q->lock = &dev->mfc_mutex; if (vdev == dev->vfd_dec) { - q->io_modes = VB2_MMAP; + q->io_modes = io_modes; q->ops = get_dec_queue_ops(); } else if (vdev == dev->vfd_enc) { - q->io_modes = VB2_MMAP | VB2_USERPTR; + q->io_modes = io_modes; q->ops = get_enc_queue_ops(); } else { ret = -ENOENT; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 8937b0af7cb3..efe65fce4880 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -546,14 +546,27 @@ static int reqbufs_capture(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx, goto out; } - WARN_ON(ctx->dst_bufs_cnt != ctx->total_dpb_count); - ctx->capture_state = QUEUE_BUFS_MMAPED; + if (reqbufs->memory == V4L2_MEMORY_MMAP) { + if (ctx->dst_bufs_cnt == ctx->total_dpb_count) { + ctx->capture_state = QUEUE_BUFS_MMAPED; + } else { + mfc_err("Not all buffers passed to buf_init\n"); + reqbufs->count = 0; + ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); + s5p_mfc_hw_call(dev->mfc_ops, + release_codec_buffers, ctx); + ret = -ENOMEM; + goto out; + } + } if (s5p_mfc_ctx_ready(ctx)) set_work_bit_irqsave(ctx); s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); - s5p_mfc_wait_for_done_ctx(ctx, S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, - 0); + if (reqbufs->memory == V4L2_MEMORY_MMAP) { + s5p_mfc_wait_for_done_ctx(ctx, + S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0); + } } else { mfc_err("Buffers have already been requested\n"); ret = -EINVAL; @@ -571,15 +584,19 @@ static int vidioc_reqbufs(struct file *file, void *priv, { struct s5p_mfc_dev *dev = video_drvdata(file); struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); - - if (reqbufs->memory != V4L2_MEMORY_MMAP) { - mfc_debug(2, "Only V4L2_MEMORY_MMAP is supported\n"); - return -EINVAL; - } + int ret; if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_src, reqbufs->memory, + reqbufs->type); + if (ret) + return ret; return reqbufs_output(dev, ctx, reqbufs); } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_dst, reqbufs->memory, + reqbufs->type); + if (ret) + return ret; return reqbufs_capture(dev, ctx, reqbufs); } else { mfc_err("Invalid type requested\n"); @@ -998,6 +1015,27 @@ static int s5p_mfc_buf_init(struct vb2_buffer *vb) return 0; } +static int s5p_mfc_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb->vb2_queue; + struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); + + if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + if (vb2_plane_size(vb, 0) < ctx->luma_size || + vb2_plane_size(vb, 1) < ctx->chroma_size) { + mfc_err("Plane buffer (CAPTURE) is too small.\n"); + return -EINVAL; + } + } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + if (vb2_plane_size(vb, 0) < ctx->dec_src_buf_size) { + mfc_err("Plane buffer (OUTPUT) is too small.\n"); + return -EINVAL; + } + } + + return 0; +} + static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count) { struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv); @@ -1066,6 +1104,7 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) struct s5p_mfc_dev *dev = ctx->dev; unsigned long flags; struct s5p_mfc_buf *mfc_buf; + int wait_flag = 0; if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { mfc_buf = &ctx->src_bufs[vb->index]; @@ -1083,12 +1122,25 @@ static void s5p_mfc_buf_queue(struct vb2_buffer *vb) list_add_tail(&mfc_buf->list, &ctx->dst_queue); ctx->dst_queue_cnt++; spin_unlock_irqrestore(&dev->irqlock, flags); + if ((vq->memory == V4L2_MEMORY_USERPTR || + vq->memory == V4L2_MEMORY_DMABUF) && + ctx->dst_queue_cnt == ctx->total_dpb_count) + ctx->capture_state = QUEUE_BUFS_MMAPED; } else { mfc_err("Unsupported buffer type (%d)\n", vq->type); } - if (s5p_mfc_ctx_ready(ctx)) + if (s5p_mfc_ctx_ready(ctx)) { set_work_bit_irqsave(ctx); + if ((vq->memory == V4L2_MEMORY_USERPTR || + vq->memory == V4L2_MEMORY_DMABUF) && + ctx->state == MFCINST_HEAD_PARSED && + ctx->capture_state == QUEUE_BUFS_MMAPED) + wait_flag = 1; + } s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); + if (wait_flag) + s5p_mfc_wait_for_done_ctx(ctx, + S5P_MFC_R2H_CMD_INIT_BUFFERS_RET, 0); } static struct vb2_ops s5p_mfc_dec_qops = { @@ -1096,6 +1148,7 @@ static struct vb2_ops s5p_mfc_dec_qops = { .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, .buf_init = s5p_mfc_buf_init, + .buf_prepare = s5p_mfc_buf_prepare, .start_streaming = s5p_mfc_start_streaming, .stop_streaming = s5p_mfc_stop_streaming, .buf_queue = s5p_mfc_buf_queue, diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 2a5fd7c42cd5..63a2cb3c7555 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1130,11 +1130,11 @@ static int vidioc_reqbufs(struct file *file, void *priv, struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret = 0; - /* if memory is not mmp or userptr return error */ - if ((reqbufs->memory != V4L2_MEMORY_MMAP) && - (reqbufs->memory != V4L2_MEMORY_USERPTR)) - return -EINVAL; if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_dst, reqbufs->memory, + reqbufs->type); + if (ret) + return ret; if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers\n"); ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); @@ -1164,6 +1164,10 @@ static int vidioc_reqbufs(struct file *file, void *priv, return -ENOMEM; } } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_dst, reqbufs->memory, + reqbufs->type); + if (ret) + return ret; if (reqbufs->count == 0) { mfc_debug(2, "Freeing buffers\n"); ret = vb2_reqbufs(&ctx->vq_src, reqbufs); @@ -1209,11 +1213,11 @@ static int vidioc_querybuf(struct file *file, void *priv, struct s5p_mfc_ctx *ctx = fh_to_ctx(priv); int ret = 0; - /* if memory is not mmp or userptr return error */ - if ((buf->memory != V4L2_MEMORY_MMAP) && - (buf->memory != V4L2_MEMORY_USERPTR)) - return -EINVAL; if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_dst, buf->memory, + buf->type); + if (ret) + return ret; if (ctx->state != MFCINST_GOT_INST) { mfc_err("invalid context state: %d\n", ctx->state); return -EINVAL; @@ -1225,6 +1229,10 @@ static int vidioc_querybuf(struct file *file, void *priv, } buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE; } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + ret = vb2_verify_memory_type(&ctx->vq_src, buf->memory, + buf->type); + if (ret) + return ret; ret = vb2_querybuf(&ctx->vq_src, buf); if (ret != 0) { mfc_err("error in vb2_querybuf() for E(S)\n");