mtk-jpegenc: add output pic reorder interface
authorkyrie wu <kyrie.wu@mediatek.com>
Thu, 29 Sep 2022 09:08:08 +0000 (17:08 +0800)
committerHans Verkuil <hverkuil-cisco@xs4all.nl>
Fri, 30 Sep 2022 14:39:28 +0000 (16:39 +0200)
There are two HWs in mt8195. Since the two HWs run
in parallel, it is necessary to reorder the output images
to ensure that the order is consistent with the input images.

Signed-off-by: kyrie wu <kyrie.wu@mediatek.com>
Signed-off-by: irui wang <irui.wang@mediatek.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.h
drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c

index 930384531259923fc5a3914a957f493d7c2f332d..9a99460ec1e2fc8a9f161a060e6b2dd9f461706d 100644 (file)
@@ -111,15 +111,6 @@ enum {
        MTK_JPEG_BUF_FLAGS_LAST_FRAME           = 1,
 };
 
-struct mtk_jpeg_src_buf {
-       u32 frame_num;
-       struct vb2_v4l2_buffer b;
-       struct list_head list;
-       struct mtk_jpeg_dec_param dec_param;
-
-       struct mtk_jpeg_ctx *curr_ctx;
-};
-
 static int debug;
 module_param(debug, int, 0644);
 
@@ -1375,6 +1366,8 @@ static int mtk_jpeg_open(struct file *file)
        if (jpeg->is_jpgenc_multihw)
                INIT_WORK(&ctx->jpeg_work, mtk_jpegenc_worker);
 
+       INIT_LIST_HEAD(&ctx->dst_done_queue);
+       spin_lock_init(&ctx->done_queue_lock);
        v4l2_fh_init(&ctx->fh, vfd);
        file->private_data = &ctx->fh;
        v4l2_fh_add(&ctx->fh);
index cbc6fbc216818fc7d7a3c4b820d370adf687f2e0..0f69402ffce67912e19e6e1532f6e37016f7366f 100644 (file)
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fh.h>
+#include <media/videobuf2-v4l2.h>
 
-#define MTK_JPEG_NAME          "mtk-jpeg"
+#include "mtk_jpeg_dec_hw.h"
 
-#define MTK_JPEG_COMP_MAX              3
+#define MTK_JPEG_NAME          "mtk-jpeg"
 
 #define MTK_JPEG_FMT_FLAG_OUTPUT       BIT(0)
 #define MTK_JPEG_FMT_FLAG_CAPTURE      BIT(1)
@@ -75,6 +76,15 @@ struct mtk_jpeg_variant {
        u32 cap_q_default_fourcc;
 };
 
+struct mtk_jpeg_src_buf {
+       u32 frame_num;
+       struct vb2_v4l2_buffer b;
+       struct list_head list;
+       struct mtk_jpeg_dec_param dec_param;
+
+       struct mtk_jpeg_ctx *curr_ctx;
+};
+
 enum mtk_jpeg_hw_state {
        MTK_JPEG_HW_IDLE = 0,
        MTK_JPEG_HW_BUSY = 1,
@@ -205,17 +215,20 @@ struct mtk_jpeg_q_data {
 
 /**
  * struct mtk_jpeg_ctx - the device context data
- * @jpeg:              JPEG IP device for this context
- * @out_q:             source (output) queue information
- * @cap_q:             destination (capture) queue queue information
- * @fh:                        V4L2 file handle
- * @state:             state of the context
- * @enable_exif:       enable exif mode of jpeg encoder
- * @enc_quality:       jpeg encoder quality
- * @restart_interval:  jpeg encoder restart interval
- * @ctrl_hdl:          controls handler
- * @jpeg_work:         jpeg encoder workqueue
- * @total_frame_num:   encoded frame number
+ * @jpeg:                      JPEG IP device for this context
+ * @out_q:                     source (output) queue information
+ * @cap_q:                     destination queue information
+ * @fh:                                V4L2 file handle
+ * @state:                     state of the context
+ * @enable_exif:               enable exif mode of jpeg encoder
+ * @enc_quality:               jpeg encoder quality
+ * @restart_interval:          jpeg encoder restart interval
+ * @ctrl_hdl:                  controls handler
+ * @jpeg_work:                 jpeg encoder workqueue
+ * @total_frame_num:           encoded frame number
+ * @dst_done_queue:            encoded frame buffer queue
+ * @done_queue_lock:           encoded frame operation spinlock
+ * @last_done_frame_num:       the last encoded frame number
  */
 struct mtk_jpeg_ctx {
        struct mtk_jpeg_dev             *jpeg;
@@ -230,6 +243,10 @@ struct mtk_jpeg_ctx {
 
        struct work_struct jpeg_work;
        u32 total_frame_num;
+       struct list_head dst_done_queue;
+       /* spinlock protecting the encode done buffer */
+       spinlock_t done_queue_lock;
+       u32 last_done_frame_num;
 };
 
 #endif /* _MTK_JPEG_CORE_H */
index afbbfd5d02bccab825b1ed1f8fe4cd483fc01f60..1e3852295f2f95fa02823dfe75b358020d84b740 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <media/videobuf2-core.h>
 
+#include "mtk_jpeg_core.h"
 #include "mtk_jpeg_dec_hw.h"
 
 #define MTK_JPEG_DUNUM_MASK(val)       (((val) - 1) & 0x3)
index fa0d45fd7c343e9a3e84fdcaeec46d686f4bddb2..87aaa5c9082b372592a89ffe1208431f91b12631 100644 (file)
 
 #include <media/videobuf2-core.h>
 
-#include "mtk_jpeg_core.h"
 #include "mtk_jpeg_dec_reg.h"
 
+#define MTK_JPEG_COMP_MAX              3
+
 enum {
        MTK_JPEG_DEC_RESULT_EOF_DONE            = 0,
        MTK_JPEG_DEC_RESULT_PAUSE               = 1,
index 02d6c49936530b33654c6a33e2620e2f8a4c04da..1bbb712d78d0e64057e7ac13502958a11b508c24 100644 (file)
@@ -185,6 +185,50 @@ void mtk_jpeg_set_enc_params(struct mtk_jpeg_ctx *ctx,  void __iomem *base)
 }
 EXPORT_SYMBOL_GPL(mtk_jpeg_set_enc_params);
 
+static void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg)
+{
+       struct mtk_jpeg_ctx *ctx;
+       struct vb2_v4l2_buffer *dst_buffer;
+       struct list_head *temp_entry;
+       struct list_head *pos = NULL;
+       struct mtk_jpeg_src_buf *dst_done_buf, *tmp_dst_done_buf;
+       unsigned long flags;
+
+       ctx = jpeg->hw_param.curr_ctx;
+       if (!ctx) {
+               dev_err(jpeg->dev, "comp_jpeg ctx fail !!!\n");
+               return;
+       }
+
+       dst_buffer = jpeg->hw_param.dst_buffer;
+       if (!dst_buffer) {
+               dev_err(jpeg->dev, "comp_jpeg dst_buffer fail !!!\n");
+               return;
+       }
+
+       dst_done_buf = container_of(dst_buffer,
+                                   struct mtk_jpeg_src_buf, b);
+
+       spin_lock_irqsave(&ctx->done_queue_lock, flags);
+       list_add_tail(&dst_done_buf->list, &ctx->dst_done_queue);
+       while (!list_empty(&ctx->dst_done_queue) &&
+              (pos != &ctx->dst_done_queue)) {
+               list_for_each_prev_safe(pos, temp_entry, &ctx->dst_done_queue) {
+                       tmp_dst_done_buf = list_entry(pos,
+                                                     struct mtk_jpeg_src_buf,
+                                                     list);
+                       if (tmp_dst_done_buf->frame_num ==
+                               ctx->last_done_frame_num) {
+                               list_del(&tmp_dst_done_buf->list);
+                               v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
+                                                 VB2_BUF_STATE_DONE);
+                               ctx->last_done_frame_num++;
+                       }
+               }
+       }
+       spin_unlock_irqrestore(&ctx->done_queue_lock, flags);
+}
+
 static void mtk_jpegenc_timeout_work(struct work_struct *work)
 {
        struct delayed_work *dly_work = to_delayed_work(work);
@@ -207,6 +251,7 @@ static void mtk_jpegenc_timeout_work(struct work_struct *work)
        atomic_inc(&master_jpeg->enchw_rdy);
        wake_up(&master_jpeg->enc_hw_wq);
        v4l2_m2m_buf_done(src_buf, buf_state);
+       mtk_jpegenc_put_buf(cjpeg);
 }
 
 static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
@@ -238,7 +283,7 @@ static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
        vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
        buf_state = VB2_BUF_STATE_DONE;
        v4l2_m2m_buf_done(src_buf, buf_state);
-       v4l2_m2m_buf_done(dst_buf, buf_state);
+       mtk_jpegenc_put_buf(jpeg);
        pm_runtime_put(ctx->jpeg->dev);
        clk_disable_unprepare(jpeg->venc_clk.clks->clk);
        if (!list_empty(&ctx->fh.m2m_ctx->out_q_ctx.rdy_queue) ||