From nobody Thu Oct 2 18:08:01 2025 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) (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 9821C2264CC; Mon, 15 Sep 2025 03:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=60.244.123.138 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757905358; cv=none; b=LQfK/zXYCnRXgAxbt/Lbgf/TkdzDWy5b8GeKST6SmZl0PmmCY2xf8m/Ka8axP2h9t3J/EEm/Rg0dXFohyancbOvmW7a+5CC3NXbfTd6ldmtR8124iiUN1AJ4afFk35kj14BcN94r4rd37YRp8No4vjLWjG60GlO5kA1LErtkjks= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757905358; c=relaxed/simple; bh=+nfiWvvmOUMiFK9sBCXhYClLQCLsWIvnx7kuGFPwNuM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LpDlQxJRox3tDbHePAS9hgNU/M9nm3jaHGSuAY/h+5SVqLreyd/Q0AqMMHcv9eaPCVjvt+UTgb2PMDYWujNj7iUNVx+4Vy2cy/aML2kcrJ9kKyU9MPN5hXe8FbYBu0WAZNYQbIzfOyXtuKJZCCTnstZYMNLFfOz7LTV2bUiTxxo= 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=lCUPh0mq; arc=none smtp.client-ip=60.244.123.138 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="lCUPh0mq" X-UUID: 6a0540fa91e011f0bd5779446731db89-20250915 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:To:From; bh=jfVe+xmA/JLODmPzk8Gu1TpfHlupl/a+noyHBp4nNgY=; b=lCUPh0mqRAYjrdt3eKmBexCx2K7AQO5M/o8Xrc+EqNxhm2ufeweB2JihpWnIPbC7ET7a6NiSoiuvRR5QCxWXfTew362ppuGNx5mTcuSfvVbwpGUPoBF5oDL6ernTqiVuPEe31Ii3oN7HWXrt5kvowUXRhaSPnX2RNEkIiNbkR7w=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.4,REQID:14d930d3-3b62-401a-b891-ff1b02086689,IP:0,UR L:0,TC:0,Content:0,EDM:25,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:25 X-CID-META: VersionHash:1ca6b93,CLOUDID:d4da50a9-24df-464e-9c88-e53ab7cf7153,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102,TC:-5,Content:0|15|50,EDM: 5,IP:nil,URL:0,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,A V:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 6a0540fa91e011f0bd5779446731db89-20250915 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 946505029; Mon, 15 Sep 2025 11:02:28 +0800 Received: from mtkmbs11n2.mediatek.inc (172.21.101.187) by mtkmbs11n1.mediatek.inc (172.21.101.185) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.39; Mon, 15 Sep 2025 11:02:22 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs11n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1258.39 via Frontend Transport; Mon, 15 Sep 2025 11:02:25 +0800 From: Kyrie Wu To: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Kyrie Wu , , , , , Subject: [PATCH v9 04/12] media: mediatek: jpeg: fix stop streaming flow for multi-core Date: Mon, 15 Sep 2025 11:02:03 +0800 Message-ID: <20250915030212.22078-5-kyrie.wu@mediatek.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20250915030212.22078-1-kyrie.wu@mediatek.com> References: <20250915030212.22078-1-kyrie.wu@mediatek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Content-Type: text/plain; charset="utf-8" For jpeg multi-core architecture, if all hardware run at the same time, some input and output buffers are occupied. If one hardware is completed firstly, while other hardwares are still running. The decoding completion signal calls mtk_jpeg_dec_stop_streaming, and the function of v4l2_m2m_buf_done is called in mtk_jpeg_dec_stop_streaming to complete all input/output buffers. However, some buffers are occupied by other hardwares, resulting in errors. It needs to add a counter to calculate the used decoding buffer counts, it will increase 1 when the buffer set to hardware and decrease to 0 until the all buffers decoded and the function could continue to be executed. Fixes: 0fa49df4222f ("media: mtk-jpegdec: support jpegdec multi-hardware") Fixes: dedc21500334 ("media: mtk-jpegdec: add jpeg decode worker interface") Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware") Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface") Signed-off-by: Kyrie Wu --- .../media/platform/mediatek/jpeg/mtk_jpeg_core.c | 16 ++++++++++++++++ .../media/platform/mediatek/jpeg/mtk_jpeg_core.h | 2 ++ .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 9 +++++++++ .../platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers= /media/platform/mediatek/jpeg/mtk_jpeg_core.c index fff8c12421af..0d379a01f9a7 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -857,8 +857,12 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(str= uct mtk_jpeg_ctx *ctx, static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx =3D vb2_get_drv_priv(q); + struct mtk_jpeg_dev *jpeg =3D ctx->jpeg; struct vb2_v4l2_buffer *vb; =20 + if (jpeg->variant->multi_core) + wait_event(jpeg->hw_wq, (atomic_read(&ctx->buf_list_cnt) =3D=3D 0)); + while ((vb =3D mtk_jpeg_buf_remove(ctx, q->type))) v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); } @@ -866,6 +870,7 @@ static void mtk_jpeg_enc_stop_streaming(struct vb2_queu= e *q) static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) { struct mtk_jpeg_ctx *ctx =3D vb2_get_drv_priv(q); + struct mtk_jpeg_dev *jpeg =3D ctx->jpeg; struct vb2_v4l2_buffer *vb; =20 /* @@ -873,6 +878,9 @@ static void mtk_jpeg_dec_stop_streaming(struct vb2_queu= e *q) * Before STREAMOFF, we still have to return the old resolution and * subsampling. Update capture queue when the stream is off. */ + if (jpeg->variant->multi_core) + wait_event(jpeg->hw_wq, (atomic_read(&ctx->buf_list_cnt) =3D=3D 0)); + if (ctx->state =3D=3D MTK_JPEG_SOURCE_CHANGE && V4L2_TYPE_IS_CAPTURE(q->type)) { struct mtk_jpeg_src_buf *src_buf; @@ -1182,6 +1190,7 @@ static int mtk_jpeg_open(struct file *file) v4l2_fh_init(&ctx->fh, vfd); file->private_data =3D &ctx->fh; v4l2_fh_add(&ctx->fh); + atomic_set(&ctx->buf_list_cnt, 0); =20 ctx->jpeg =3D jpeg; ctx->fh.m2m_ctx =3D v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, @@ -1564,6 +1573,11 @@ static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_= ctx *ctx, return 0; } =20 +static void jpeg_buf_queue_inc(struct mtk_jpeg_ctx *ctx) +{ + atomic_inc(&ctx->buf_list_cnt); +} + static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg) { struct mtk_jpeg_ctx *ctx; @@ -1672,6 +1686,7 @@ static void mtk_jpegenc_worker(struct work_struct *wo= rk) &src_buf->vb2_buf); mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base); mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base); + jpeg_buf_queue_inc(ctx); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); =20 @@ -1787,6 +1802,7 @@ static void mtk_jpegdec_worker(struct work_struct *wo= rk) &bs, &fb); mtk_jpeg_dec_start(comp_jpeg[hw_id]->reg_base); + jpeg_buf_queue_inc(ctx); v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags); =20 diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers= /media/platform/mediatek/jpeg/mtk_jpeg_core.h index 148fd41759b7..33f7fbc4ca5e 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -288,6 +288,7 @@ struct mtk_jpeg_q_data { * @dst_done_queue: encoded frame buffer queue * @done_queue_lock: encoded frame operation spinlock * @last_done_frame_num: the last encoded frame number + * @buf_list_cnt: the frame buffer count own by jpeg driver */ struct mtk_jpeg_ctx { struct mtk_jpeg_dev *jpeg; @@ -306,6 +307,7 @@ struct mtk_jpeg_ctx { /* spinlock protecting the encode done buffer */ spinlock_t done_queue_lock; u32 last_done_frame_num; + atomic_t buf_list_cnt; }; =20 #endif /* _MTK_JPEG_CORE_H */ diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drive= rs/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index a1e54715cb7e..84d12eea35f7 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -519,6 +519,11 @@ static void mtk_jpegdec_put_buf(struct mtk_jpegdec_com= p_dev *jpeg) spin_unlock_irqrestore(&ctx->done_queue_lock, flags); } =20 +static void jpeg_buf_queue_dec(struct mtk_jpeg_ctx *ctx) +{ + atomic_dec(&ctx->buf_list_cnt); +} + static void mtk_jpegdec_timeout_work(struct work_struct *work) { enum vb2_buffer_state buf_state =3D VB2_BUF_STATE_ERROR; @@ -527,9 +532,11 @@ static void mtk_jpegdec_timeout_work(struct work_struc= t *work) job_timeout_work.work); struct mtk_jpeg_dev *master_jpeg =3D cjpeg->master_dev; struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_ctx *ctx; =20 src_buf =3D cjpeg->hw_param.src_buffer; dst_buf =3D cjpeg->hw_param.dst_buffer; + ctx =3D cjpeg->hw_param.curr_ctx; v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); =20 mtk_jpeg_dec_reset(cjpeg->reg_base); @@ -540,6 +547,7 @@ static void mtk_jpegdec_timeout_work(struct work_struct= *work) wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(cjpeg); + jpeg_buf_queue_dec(ctx); } =20 static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) @@ -580,6 +588,7 @@ static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, = void *priv) buf_state =3D VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegdec_put_buf(jpeg); + jpeg_buf_queue_dec(ctx); pm_runtime_put(ctx->jpeg->dev); clk_disable_unprepare(jpeg->jdec_clk.clks->clk); =20 diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drive= rs/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 28d05909c96f..625a0d350348 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -248,6 +248,11 @@ static void mtk_jpegenc_put_buf(struct mtk_jpegenc_com= p_dev *jpeg) spin_unlock_irqrestore(&ctx->done_queue_lock, flags); } =20 +static void jpeg_buf_queue_dec(struct mtk_jpeg_ctx *ctx) +{ + atomic_dec(&ctx->buf_list_cnt); +} + static void mtk_jpegenc_timeout_work(struct work_struct *work) { struct delayed_work *dly_work =3D to_delayed_work(work); @@ -258,9 +263,11 @@ static void mtk_jpegenc_timeout_work(struct work_struc= t *work) struct mtk_jpeg_dev *master_jpeg =3D cjpeg->master_dev; enum vb2_buffer_state buf_state =3D VB2_BUF_STATE_ERROR; struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_ctx *ctx; =20 src_buf =3D cjpeg->hw_param.src_buffer; dst_buf =3D cjpeg->hw_param.dst_buffer; + ctx =3D cjpeg->hw_param.curr_ctx; v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); =20 mtk_jpeg_enc_reset(cjpeg->reg_base); @@ -271,6 +278,7 @@ static void mtk_jpegenc_timeout_work(struct work_struct= *work) wake_up(&master_jpeg->hw_wq); v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(cjpeg); + jpeg_buf_queue_dec(ctx); } =20 static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv) @@ -304,6 +312,7 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, = void *priv) buf_state =3D VB2_BUF_STATE_DONE; v4l2_m2m_buf_done(src_buf, buf_state); mtk_jpegenc_put_buf(jpeg); + jpeg_buf_queue_dec(ctx); pm_runtime_put(ctx->jpeg->dev); clk_disable_unprepare(jpeg->venc_clk.clks->clk); =20 --=20 2.45.2