media: mediatek: vcodec: move core context from device to each instance
authorYunfei Dong <yunfei.dong@mediatek.com>
Thu, 25 May 2023 01:40:08 +0000 (02:40 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 26 May 2023 09:55:30 +0000 (10:55 +0100)
There are so many lat buffer in core context list, some instances
maybe be scheduled for a very long time. Moving the core context to
each instance, it only be used to control lat buffer of each instance.
And the core work queue of each instance is scheduled by system.

Fixes: 2cfca6c1bf80 ("media: mediatek: vcodec: move lat_buf to the top of core list")
Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c
drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h
drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
drivers/media/platform/mediatek/vcodec/vdec/vdec_hevc_req_multi_if.c
drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h

index 9c652beb3f193bc2226ae0678a92eff1df68e2bc..7bd300341cf09b5649afc3be8ad0e8f1f2f5ea63 100644 (file)
@@ -310,7 +310,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
        }
 
        if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
-               vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE);
                dev->core_workqueue =
                        alloc_ordered_workqueue("core-decoder",
                                                WQ_MEM_RECLAIM | WQ_FREEZABLE);
index 144252fa8bea432d6de3d152c4bfd70d20be8ce6..1f4c5774ec473e794585821241afbfdd0f903853 100644 (file)
@@ -462,7 +462,6 @@ struct mtk_vcodec_enc_pdata {
  * @enc_capability: used to identify encode capability
  *
  * @core_workqueue: queue used for core hardware decode
- * @msg_queue_core_ctx: msg queue context used for core workqueue
  *
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
@@ -511,7 +510,6 @@ struct mtk_vcodec_dev {
        unsigned int enc_capability;
 
        struct workqueue_struct *core_workqueue;
-       struct vdec_msg_queue_ctx msg_queue_core_ctx;
 
        void *subdev_dev[MTK_VDEC_HW_MAX];
        int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
index 181cc52e084723e9b6fff8c93915751d0f2e6ca2..a7e8e3257b7fcca23383a4191ee136937c84c302 100644 (file)
@@ -672,7 +672,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
        if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
                memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
                       sizeof(share_info->h264_slice_params));
-               vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+               vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
        }
 
        /* wait decoder done interrupt */
@@ -698,7 +698,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
        if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
                memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
                       sizeof(share_info->h264_slice_params));
-               vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+               vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
        }
        mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num,
                         inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]);
index e8758e5db961b2cd1fc3b9cc17471e0d2d4b86e9..1e6ab138b0bbe247d971db8d59475267a9e4b5c2 100644 (file)
@@ -1017,7 +1017,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
        if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
                memcpy(&share_info->hevc_slice_params, &inst->vsi->hevc_slice_params,
                       sizeof(share_info->hevc_slice_params));
-               vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+               vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
        }
 
        /* wait decoder done interrupt */
@@ -1043,7 +1043,7 @@ static int vdec_hevc_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
        if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
                memcpy(&share_info->hevc_slice_params, &inst->vsi->hevc_slice_params,
                       sizeof(share_info->hevc_slice_params));
-               vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+               vdec_msg_queue_qbuf(&inst->ctx->msg_queue.core_ctx, lat_buf);
        }
        mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num,
                         inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]);
index 6d981d7341d2f93ef8b70df113ffdb0e73ea570a..c2f90848f4984e5534b56bc0cc564974842418de 100644 (file)
@@ -2119,7 +2119,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
        vdec_msg_queue_update_ube_wptr(&ctx->msg_queue,
                                       vsi->trans.dma_addr_end +
                                       ctx->msg_queue.wdma_addr.dma_addr);
-       vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+       vdec_msg_queue_qbuf(&ctx->msg_queue.core_ctx, lat_buf);
 
        return 0;
 err_free_fb_out:
index 03f8d7cd8eddccb107c90371283d54cadb72b6ef..3f571cbc83316349c2136a0ecea96ed834106a36 100644 (file)
@@ -177,29 +177,20 @@ void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t u
 
 bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
 {
-       struct vdec_lat_buf *buf, *tmp;
-       struct list_head *list_core[3];
-       struct vdec_msg_queue_ctx *core_ctx;
-       int ret, i, in_core_count = 0, count = 0;
+       int ret;
        long timeout_jiff;
 
-       core_ctx = &msg_queue->ctx->dev->msg_queue_core_ctx;
-       spin_lock(&core_ctx->ready_lock);
-       list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) {
-               if (buf && buf->ctx == msg_queue->ctx) {
-                       list_core[in_core_count++] = &buf->core_list;
-                       list_del(&buf->core_list);
-               }
-       }
-
-       for (i = 0; i < in_core_count; i++) {
-               list_add(list_core[in_core_count - (1 + i)], &core_ctx->ready_queue);
-               queue_work(msg_queue->ctx->dev->core_workqueue, &msg_queue->core_work);
+       if (atomic_read(&msg_queue->lat_list_cnt) == NUM_BUFFER_COUNT) {
+               mtk_v4l2_debug(3, "wait buf full: list(%d %d) ready_num:%d status:%d",
+                              atomic_read(&msg_queue->lat_list_cnt),
+                              atomic_read(&msg_queue->core_list_cnt),
+                              msg_queue->lat_ctx.ready_num,
+                              msg_queue->status);
+               return true;
        }
-       spin_unlock(&core_ctx->ready_lock);
 
        timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
-       ret = wait_event_timeout(msg_queue->ctx->msg_queue.core_dec_done,
+       ret = wait_event_timeout(msg_queue->core_dec_done,
                                 msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
                                 timeout_jiff);
        if (ret) {
@@ -208,18 +199,9 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
                return true;
        }
 
-       spin_lock(&core_ctx->ready_lock);
-       list_for_each_entry_safe(buf, tmp, &core_ctx->ready_queue, core_list) {
-               if (buf && buf->ctx == msg_queue->ctx) {
-                       count++;
-                       list_del(&buf->core_list);
-               }
-       }
-       spin_unlock(&core_ctx->ready_lock);
-
-       mtk_v4l2_err("failed with lat buf isn't full: list(%d %d) count:%d",
+       mtk_v4l2_err("failed with lat buf isn't full: list(%d %d)",
                     atomic_read(&msg_queue->lat_list_cnt),
-                    atomic_read(&msg_queue->core_list_cnt), count);
+                    atomic_read(&msg_queue->core_list_cnt));
 
        return false;
 }
@@ -247,6 +229,8 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
 
                kfree(lat_buf->private_data);
        }
+
+       cancel_work_sync(&msg_queue->core_work);
 }
 
 static void vdec_msg_queue_core_work(struct work_struct *work)
@@ -258,11 +242,11 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
        struct mtk_vcodec_dev *dev = ctx->dev;
        struct vdec_lat_buf *lat_buf;
 
-       spin_lock(&ctx->dev->msg_queue_core_ctx.ready_lock);
+       spin_lock(&msg_queue->core_ctx.ready_lock);
        ctx->msg_queue.status &= ~CONTEXT_LIST_QUEUED;
-       spin_unlock(&ctx->dev->msg_queue_core_ctx.ready_lock);
+       spin_unlock(&msg_queue->core_ctx.ready_lock);
 
-       lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+       lat_buf = vdec_msg_queue_dqbuf(&msg_queue->core_ctx);
        if (!lat_buf)
                return;
 
@@ -276,12 +260,11 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
        mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
        vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
 
-       wake_up_all(&ctx->msg_queue.core_dec_done);
        if (!(ctx->msg_queue.status & CONTEXT_LIST_QUEUED) &&
            atomic_read(&msg_queue->core_list_cnt)) {
-               spin_lock(&ctx->dev->msg_queue_core_ctx.ready_lock);
+               spin_lock(&msg_queue->core_ctx.ready_lock);
                ctx->msg_queue.status |= CONTEXT_LIST_QUEUED;
-               spin_unlock(&ctx->dev->msg_queue_core_ctx.ready_lock);
+               spin_unlock(&msg_queue->core_ctx.ready_lock);
                queue_work(ctx->dev->core_workqueue, &msg_queue->core_work);
        }
 }
@@ -297,8 +280,8 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
        if (msg_queue->wdma_addr.size)
                return 0;
 
-       msg_queue->ctx = ctx;
        vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+       vdec_msg_queue_init_ctx(&msg_queue->core_ctx, MTK_VDEC_CORE);
        INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
 
        atomic_set(&msg_queue->lat_list_cnt, 0);
index 8f82d148477266d67eab077624edabdad86d81e6..efc94165e016c7734e4411ad7dcc75b73c041521 100644 (file)
@@ -84,7 +84,7 @@ struct vdec_lat_buf {
  * @wdma_wptr_addr: ube write point
  * @core_work: core hardware work
  * @lat_ctx: used to store lat buffer list
- * @ctx: point to mtk_vcodec_ctx
+ * @core_ctx: used to store core buffer list
  *
  * @lat_list_cnt: used to record each instance lat list count
  * @core_list_cnt: used to record each instance core list count
@@ -100,7 +100,7 @@ struct vdec_msg_queue {
 
        struct work_struct core_work;
        struct vdec_msg_queue_ctx lat_ctx;
-       struct mtk_vcodec_ctx *ctx;
+       struct vdec_msg_queue_ctx core_ctx;
 
        atomic_t lat_list_cnt;
        atomic_t core_list_cnt;