media: mediatek: vcodec: move lat_buf to the top of core list
authorYunfei Dong <yunfei.dong@mediatek.com>
Wed, 1 Feb 2023 07:33:12 +0000 (07:33 +0000)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 10 Apr 2023 13:11:27 +0000 (14:11 +0100)
Current instance will decode done when begin to wait lat buf full,
move the lat_buf of current instance to the top of core list to make
sure current instance's lat_buf will be used firstly.

Fixes: 365e4ba01df4 ("media: mtk-vcodec: Add work queue for core hardware decode")
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/vdec_msg_queue.c
drivers/media/platform/mediatek/vcodec/vdec_msg_queue.h

index ad5002ca953e0a86d55a468639321ccb9d6acf73..0da6e3e2ef0b320e60ec4601dca6e90cfdffb502 100644 (file)
@@ -174,8 +174,26 @@ 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;
        long timeout_jiff;
-       int ret;
+
+       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);
+       }
+       spin_unlock(&core_ctx->ready_lock);
 
        timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
        ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
@@ -257,6 +275,7 @@ 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);
        INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
 
index b1aa5572ba49f99a33e8ded079ede4de899a35a7..56280d6682c5ac10472fa1c7fd907bca4daaace1 100644 (file)
@@ -72,6 +72,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
  *
  * @lat_list_cnt: used to record each instance lat list count
  * @core_list_cnt: used to record each instance core list count
@@ -85,6 +86,7 @@ struct vdec_msg_queue {
 
        struct work_struct core_work;
        struct vdec_msg_queue_ctx lat_ctx;
+       struct mtk_vcodec_ctx *ctx;
 
        atomic_t lat_list_cnt;
        atomic_t core_list_cnt;