From nobody Mon Sep 29 20:12:06 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11ADAC3F6B0 for ; Mon, 15 Aug 2022 23:37:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346267AbiHOXhU (ORCPT ); Mon, 15 Aug 2022 19:37:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353651AbiHOXcK (ORCPT ); Mon, 15 Aug 2022 19:32:10 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 105DC150B81; Mon, 15 Aug 2022 13:08:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F0BE160DEB; Mon, 15 Aug 2022 20:08:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ECAA9C433D6; Mon, 15 Aug 2022 20:08:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1660594102; bh=+3E+NhvBufXGI/SnEC2niRAaLRAmDGmZRXWc+haofkQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jgg8likHLBKLe+k7iyRNqlfWyWTMFitAlm6v98hHjtqX9U3Kq5Ad6YOYPWBP+IHg5 TMG3CM06/rMt9agqey1VLKnkrBZO4W097qrcu8YLNEHsI6vjKgDSqCR3LcMi9Wx5O/ mwh5JDZ2QWj+GoyonhRoqoHzGhkykRmTvn8EpYYg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ming Qian , Hans Verkuil , Mauro Carvalho Chehab , Sasha Levin Subject: [PATCH 5.19 0379/1157] media: imx-jpeg: Implement drain using v4l2-mem2mem helpers Date: Mon, 15 Aug 2022 19:55:35 +0200 Message-Id: <20220815180454.896574356@linuxfoundation.org> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815180439.416659447@linuxfoundation.org> References: <20220815180439.416659447@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Ming Qian [ Upstream commit 4911c5acf9351c4caf692895c7cf6a4fa46c26b0 ] v4l2 m2m has supplied some helper function to handle drain, so the driver can use the helper function directly. Fixes: d8ebe298d008c ("media: imx-jpeg: Set V4L2_BUF_FLAG_LAST at eos") Signed-off-by: Ming Qian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- .../media/platform/nxp/imx-jpeg/mxc-jpeg.c | 155 +++++++++--------- .../media/platform/nxp/imx-jpeg/mxc-jpeg.h | 2 - 2 files changed, 73 insertions(+), 84 deletions(-) diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media= /platform/nxp/imx-jpeg/mxc-jpeg.c index 9b8451b56657..9a2fb0dc77a4 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -559,6 +559,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_de= v *jpeg, jpeg->slot_data[slot].used =3D false; } =20 +static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, + struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf) +{ + if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { + dst_buf->flags |=3D V4L2_BUF_FLAG_LAST; + v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); + notify_eos(ctx); + ctx->header_parsed =3D false; + } +} + static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) { struct mxc_jpeg_dev *jpeg =3D priv; @@ -633,6 +645,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n"); goto job_unlock; } + if (jpeg->mode =3D=3D MXC_JPEG_ENCODE) { payload =3D readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR)); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); @@ -661,6 +674,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) =20 buffers_done: jpeg->slot_data[slot].used =3D false; /* unused, but don't free */ + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, buf_state); @@ -1034,6 +1048,7 @@ static void mxc_jpeg_device_run(void *priv) jpeg_src_buf->jpeg_parse_error =3D true; } if (jpeg_src_buf->jpeg_parse_error) { + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); @@ -1084,45 +1099,33 @@ static void mxc_jpeg_device_run(void *priv) spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); } =20 -static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx) -{ - struct vb2_queue *q; - - ctx->stopped =3D 1; - q =3D v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx); - if (!list_empty(&q->done_list)) - return; - - q->last_buffer_dequeued =3D true; - wake_up(&q->done_wq); - ctx->stopped =3D 0; - ctx->header_parsed =3D false; -} - static int mxc_jpeg_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { struct v4l2_fh *fh =3D file->private_data; struct mxc_jpeg_ctx *ctx =3D mxc_jpeg_fh_to_ctx(fh); - struct device *dev =3D ctx->mxc_jpeg->dev; int ret; =20 ret =3D v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); if (ret < 0) return ret; =20 - if (cmd->cmd =3D=3D V4L2_DEC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_DEC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) =3D=3D 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping =3D 1; - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) + return 0; + + ret =3D v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd); + if (ret < 0) + return ret; + + if (cmd->cmd =3D=3D V4L2_DEC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed =3D false; } =20 + if (cmd->cmd =3D=3D V4L2_DEC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); return 0; } =20 @@ -1131,24 +1134,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, = void *priv, { struct v4l2_fh *fh =3D file->private_data; struct mxc_jpeg_ctx *ctx =3D mxc_jpeg_fh_to_ctx(fh); - struct device *dev =3D ctx->mxc_jpeg->dev; int ret; =20 ret =3D v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); if (ret < 0) return ret; =20 - if (cmd->cmd =3D=3D V4L2_ENC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_ENC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) =3D=3D 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping =3D 1; - } - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || + !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) + return 0; + + ret =3D v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd); + if (ret < 0) + return 0; + + if (cmd->cmd =3D=3D V4L2_ENC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + notify_eos(ctx); + + if (cmd->cmd =3D=3D V4L2_ENC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); =20 return 0; } @@ -1204,6 +1210,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue = *q, unsigned int count) struct mxc_jpeg_q_data *q_data =3D mxc_jpeg_get_q_data(ctx, q->type); int ret; =20 + v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); + if (ctx->mxc_jpeg->mode =3D=3D MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q-= >type)) ctx->source_change =3D 0; dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=3D%p", ctx); @@ -1235,11 +1243,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queu= e *q) break; v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); } - pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); - if (V4L2_TYPE_IS_OUTPUT(q->type)) { - ctx->stopping =3D 0; - ctx->stopped =3D 0; + + v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); + if (V4L2_TYPE_IS_OUTPUT(q->type) && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed =3D false; } + + pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); } =20 static int mxc_jpeg_valid_comp_id(struct device *dev, @@ -1438,6 +1450,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) struct mxc_jpeg_ctx *ctx =3D vb2_get_drv_priv(vb->vb2_queue); struct mxc_jpeg_src_buf *jpeg_src_buf; =20 + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && + vb2_is_streaming(vb->vb2_queue) && + v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { + struct mxc_jpeg_q_data *q_data; + + q_data =3D mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); + vbuf->field =3D V4L2_FIELD_NONE; + vbuf->sequence =3D q_data->sequence++; + v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); + notify_eos(ctx); + ctx->header_parsed =3D false; + return; + } + if (vb->vb2_queue->type =3D=3D V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) goto end; =20 @@ -1486,24 +1512,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *= vb) return -EINVAL; } } - return 0; -} - -static void mxc_jpeg_buf_finish(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf =3D to_vb2_v4l2_buffer(vb); - struct mxc_jpeg_ctx *ctx =3D vb2_get_drv_priv(vb->vb2_queue); - struct vb2_queue *q =3D vb->vb2_queue; - - if (V4L2_TYPE_IS_OUTPUT(vb->type)) - return; - if (!ctx->stopped) - return; - if (list_empty(&q->done_list)) { - vbuf->flags |=3D V4L2_BUF_FLAG_LAST; - ctx->stopped =3D 0; - ctx->header_parsed =3D false; + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { + vb2_set_plane_payload(vb, 0, 0); + vb2_set_plane_payload(vb, 1, 0); } + return 0; } =20 static const struct vb2_ops mxc_jpeg_qops =3D { @@ -1512,7 +1525,6 @@ static const struct vb2_ops mxc_jpeg_qops =3D { .wait_finish =3D vb2_ops_wait_finish, .buf_out_validate =3D mxc_jpeg_buf_out_validate, .buf_prepare =3D mxc_jpeg_buf_prepare, - .buf_finish =3D mxc_jpeg_buf_finish, .start_streaming =3D mxc_jpeg_start_streaming, .stop_streaming =3D mxc_jpeg_stop_streaming, .buf_queue =3D mxc_jpeg_buf_queue, @@ -1956,27 +1968,6 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *= fh, } } =20 -static int mxc_jpeg_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct v4l2_fh *fh =3D file->private_data; - struct mxc_jpeg_ctx *ctx =3D mxc_jpeg_fh_to_ctx(priv); - struct device *dev =3D ctx->mxc_jpeg->dev; - int num_src_ready =3D v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx); - int ret; - - dev_dbg(dev, "DQBUF type=3D%d, index=3D%d", buf->type, buf->index); - if (ctx->stopping =3D=3D 1 && num_src_ready =3D=3D 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - ctx->stopping =3D 0; - mxc_jpeg_set_last_buffer_dequeued(ctx); - } - - ret =3D v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf); - return ret; -} - static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops =3D { .vidioc_querycap =3D mxc_jpeg_querycap, .vidioc_enum_fmt_vid_cap =3D mxc_jpeg_enum_fmt_vid_cap, @@ -2000,7 +1991,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops= =3D { .vidioc_encoder_cmd =3D mxc_jpeg_encoder_cmd, =20 .vidioc_qbuf =3D v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf =3D mxc_jpeg_dqbuf, + .vidioc_dqbuf =3D v4l2_m2m_ioctl_dqbuf, =20 .vidioc_create_bufs =3D v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf =3D v4l2_m2m_ioctl_prepare_buf, diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media= /platform/nxp/imx-jpeg/mxc-jpeg.h index 760eaf5387a1..1d41cb8ffb6c 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -92,8 +92,6 @@ struct mxc_jpeg_ctx { struct mxc_jpeg_q_data cap_q; struct v4l2_fh fh; enum mxc_jpeg_enc_state enc_state; - unsigned int stopping; - unsigned int stopped; unsigned int slot; unsigned int source_change; bool header_parsed; --=20 2.35.1