media: mediatek: vcodec: using empty lat buffer as the last one

Adding one empty lat buffer with parameter 'is_empty_flag = true'
used to flush core work queue decode.

Queue the empty lat buffer to core list when driver need to flush decode.
It's mean core already decode all existed lat buffer when get empty lat
buffer, then wake up core decode done event, the driver will exit when
getting core dec done event.

Fixes: d227af847a ("media: mediatek: vcodec: add core decode done event")
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>
This commit is contained in:
Yunfei Dong 2023-05-25 02:40:09 +01:00 committed by Mauro Carvalho Chehab
parent 297160d411
commit 962508e31c
2 changed files with 28 additions and 15 deletions

View File

@ -177,9 +177,6 @@ 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)
{
int ret;
long timeout_jiff;
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),
@ -189,19 +186,14 @@ bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
return true;
}
timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
ret = wait_event_timeout(msg_queue->core_dec_done,
msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
timeout_jiff);
if (ret) {
mtk_v4l2_debug(3, "success to get lat buf: %d",
msg_queue->lat_ctx.ready_num);
return true;
}
msg_queue->flush_done = false;
vdec_msg_queue_qbuf(&msg_queue->core_ctx, &msg_queue->empty_lat_buf);
wait_event(msg_queue->core_dec_done, msg_queue->flush_done);
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));
mtk_v4l2_debug(3, "flush done => ready_num:%d status:%d list(%d %d)",
msg_queue->lat_ctx.ready_num, msg_queue->status,
atomic_read(&msg_queue->lat_list_cnt),
atomic_read(&msg_queue->core_list_cnt));
return false;
}
@ -250,6 +242,14 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
if (!lat_buf)
return;
if (lat_buf->is_last_frame) {
ctx->msg_queue.status = CONTEXT_LIST_DEC_DONE;
msg_queue->flush_done = true;
wake_up(&ctx->msg_queue.core_dec_done);
return;
}
ctx = lat_buf->ctx;
mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
@ -300,6 +300,10 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
msg_queue->empty_lat_buf.ctx = ctx;
msg_queue->empty_lat_buf.core_decode = NULL;
msg_queue->empty_lat_buf.is_last_frame = true;
for (i = 0; i < NUM_BUFFER_COUNT; i++) {
lat_buf = &msg_queue->lat_buf[i];
@ -325,6 +329,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
lat_buf->ctx = ctx;
lat_buf->core_decode = core_decode;
lat_buf->is_last_frame = false;
err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
if (err) {
mtk_v4l2_err("failed to qbuf buf[%d]", i);

View File

@ -62,6 +62,8 @@ struct vdec_msg_queue_ctx {
* @core_decode: different codec use different decode callback function
* @lat_list: add lat buffer to lat head list
* @core_list: add lat buffer to core head list
*
* @is_last_frame: meaning this buffer is the last frame
*/
struct vdec_lat_buf {
struct mtk_vcodec_mem wdma_err_addr;
@ -74,6 +76,8 @@ struct vdec_lat_buf {
core_decode_cb_t core_decode;
struct list_head lat_list;
struct list_head core_list;
bool is_last_frame;
};
/**
@ -88,6 +92,8 @@ struct vdec_lat_buf {
*
* @lat_list_cnt: used to record each instance lat list count
* @core_list_cnt: used to record each instance core list count
* @flush_done: core flush done status
* @empty_lat_buf: the last lat buf used to flush decode
* @core_dec_done: core work queue decode done event
* @status: current context decode status for core hardware
*/
@ -104,6 +110,8 @@ struct vdec_msg_queue {
atomic_t lat_list_cnt;
atomic_t core_list_cnt;
bool flush_done;
struct vdec_lat_buf empty_lat_buf;
wait_queue_head_t core_dec_done;
int status;
};