10934d375SYunfei Dong /* SPDX-License-Identifier: GPL-2.0 */
20934d375SYunfei Dong /*
30934d375SYunfei Dong  * Copyright (c) 2021 MediaTek Inc.
40934d375SYunfei Dong  * Author: Yunfei Dong <[email protected]>
50934d375SYunfei Dong  */
60934d375SYunfei Dong 
70934d375SYunfei Dong #ifndef _VDEC_MSG_QUEUE_H_
80934d375SYunfei Dong #define _VDEC_MSG_QUEUE_H_
90934d375SYunfei Dong 
100934d375SYunfei Dong #include <linux/sched.h>
110934d375SYunfei Dong #include <linux/semaphore.h>
120934d375SYunfei Dong #include <linux/slab.h>
130934d375SYunfei Dong #include <media/videobuf2-v4l2.h>
140934d375SYunfei Dong 
150934d375SYunfei Dong #define NUM_BUFFER_COUNT 3
160934d375SYunfei Dong 
170934d375SYunfei Dong struct vdec_lat_buf;
180934d375SYunfei Dong struct mtk_vcodec_dec_ctx;
190934d375SYunfei Dong struct mtk_vcodec_dec_dev;
200934d375SYunfei Dong typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
210934d375SYunfei Dong 
220934d375SYunfei Dong /**
230934d375SYunfei Dong  * enum core_ctx_status - Context decode status for core hardwre.
240934d375SYunfei Dong  * @CONTEXT_LIST_EMPTY: No buffer queued on core hardware(must always be 0)
250934d375SYunfei Dong  * @CONTEXT_LIST_QUEUED: Buffer queued to core work list
260934d375SYunfei Dong  * @CONTEXT_LIST_DEC_DONE: context decode done
270934d375SYunfei Dong  */
280934d375SYunfei Dong enum core_ctx_status {
290934d375SYunfei Dong 	CONTEXT_LIST_EMPTY = 0,
300934d375SYunfei Dong 	CONTEXT_LIST_QUEUED,
310934d375SYunfei Dong 	CONTEXT_LIST_DEC_DONE,
320934d375SYunfei Dong };
330934d375SYunfei Dong 
340934d375SYunfei Dong /**
350934d375SYunfei Dong  * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed
360934d375SYunfei Dong  * @ready_to_use: ready used queue used to signalize when get a job queue
370934d375SYunfei Dong  * @ready_queue: list of ready lat buffer queues
380934d375SYunfei Dong  * @ready_lock: spin lock to protect the lat buffer usage
390934d375SYunfei Dong  * @ready_num: number of buffers ready to be processed
400934d375SYunfei Dong  * @hardware_index: hardware id that this queue is used for
410934d375SYunfei Dong  */
420934d375SYunfei Dong struct vdec_msg_queue_ctx {
430934d375SYunfei Dong 	wait_queue_head_t ready_to_use;
440934d375SYunfei Dong 	struct list_head ready_queue;
450934d375SYunfei Dong 	/* protect lat buffer */
460934d375SYunfei Dong 	spinlock_t ready_lock;
470934d375SYunfei Dong 	int ready_num;
480934d375SYunfei Dong 	int hardware_index;
490934d375SYunfei Dong };
500934d375SYunfei Dong 
510934d375SYunfei Dong /**
520934d375SYunfei Dong  * struct vdec_lat_buf - lat buffer message used to store lat info for core decode
530934d375SYunfei Dong  * @wdma_err_addr: wdma error address used for lat hardware
540934d375SYunfei Dong  * @slice_bc_addr: slice bc address used for lat hardware
550934d375SYunfei Dong  * @rd_mv_addr:	mv addr for av1 lat hardware output, core hardware input
560934d375SYunfei Dong  * @tile_addr:	tile buffer for av1 core input
570934d375SYunfei Dong  * @ts_info: need to set timestamp from output to capture
580934d375SYunfei Dong  * @src_buf_req: output buffer media request object
590934d375SYunfei Dong  *
600934d375SYunfei Dong  * @private_data: shared information used to lat and core hardware
610934d375SYunfei Dong  * @ctx: mtk vcodec context information
620934d375SYunfei Dong  * @core_decode: different codec use different decode callback function
630934d375SYunfei Dong  * @lat_list: add lat buffer to lat head list
640934d375SYunfei Dong  * @core_list: add lat buffer to core head list
650934d375SYunfei Dong  *
660934d375SYunfei Dong  * @is_last_frame: meaning this buffer is the last frame
670934d375SYunfei Dong  */
680934d375SYunfei Dong struct vdec_lat_buf {
690934d375SYunfei Dong 	struct mtk_vcodec_mem wdma_err_addr;
700934d375SYunfei Dong 	struct mtk_vcodec_mem slice_bc_addr;
710934d375SYunfei Dong 	struct mtk_vcodec_mem rd_mv_addr;
720934d375SYunfei Dong 	struct mtk_vcodec_mem tile_addr;
730934d375SYunfei Dong 	struct vb2_v4l2_buffer ts_info;
740934d375SYunfei Dong 	struct media_request *src_buf_req;
750934d375SYunfei Dong 
760934d375SYunfei Dong 	void *private_data;
770934d375SYunfei Dong 	struct mtk_vcodec_dec_ctx *ctx;
780934d375SYunfei Dong 	core_decode_cb_t core_decode;
790934d375SYunfei Dong 	struct list_head lat_list;
800934d375SYunfei Dong 	struct list_head core_list;
810934d375SYunfei Dong 
820934d375SYunfei Dong 	bool is_last_frame;
830934d375SYunfei Dong };
840934d375SYunfei Dong 
850934d375SYunfei Dong /**
860934d375SYunfei Dong  * struct vdec_msg_queue - used to store lat buffer message
870934d375SYunfei Dong  * @lat_buf: lat buffer used to store lat buffer information
880934d375SYunfei Dong  * @wdma_addr: wdma address used for ube
890934d375SYunfei Dong  * @wdma_rptr_addr: ube read point
900934d375SYunfei Dong  * @wdma_wptr_addr: ube write point
910934d375SYunfei Dong  * @core_work: core hardware work
920934d375SYunfei Dong  * @lat_ctx: used to store lat buffer list
930934d375SYunfei Dong  * @core_ctx: used to store core buffer list
940934d375SYunfei Dong  *
950934d375SYunfei Dong  * @lat_list_cnt: used to record each instance lat list count
960934d375SYunfei Dong  * @core_list_cnt: used to record each instance core list count
970934d375SYunfei Dong  * @flush_done: core flush done status
980934d375SYunfei Dong  * @empty_lat_buf: the last lat buf used to flush decode
990934d375SYunfei Dong  * @core_dec_done: core work queue decode done event
1000934d375SYunfei Dong  * @status: current context decode status for core hardware
1010934d375SYunfei Dong  * @ctx: mtk vcodec context information
1020934d375SYunfei Dong  */
1030934d375SYunfei Dong struct vdec_msg_queue {
1040934d375SYunfei Dong 	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
1050934d375SYunfei Dong 
1060934d375SYunfei Dong 	struct mtk_vcodec_mem wdma_addr;
1070934d375SYunfei Dong 	u64 wdma_rptr_addr;
1080934d375SYunfei Dong 	u64 wdma_wptr_addr;
1090934d375SYunfei Dong 
1100934d375SYunfei Dong 	struct work_struct core_work;
1110934d375SYunfei Dong 	struct vdec_msg_queue_ctx lat_ctx;
1120934d375SYunfei Dong 	struct vdec_msg_queue_ctx core_ctx;
1130934d375SYunfei Dong 
1140934d375SYunfei Dong 	atomic_t lat_list_cnt;
1150934d375SYunfei Dong 	atomic_t core_list_cnt;
1160934d375SYunfei Dong 	bool flush_done;
1170934d375SYunfei Dong 	struct vdec_lat_buf empty_lat_buf;
1180934d375SYunfei Dong 	wait_queue_head_t core_dec_done;
1190934d375SYunfei Dong 	int status;
1200934d375SYunfei Dong 	struct mtk_vcodec_dec_ctx *ctx;
1210934d375SYunfei Dong };
1220934d375SYunfei Dong 
1230934d375SYunfei Dong /**
1240934d375SYunfei Dong  * vdec_msg_queue_init - init lat buffer information.
1250934d375SYunfei Dong  * @msg_queue: used to store the lat buffer information
1260934d375SYunfei Dong  * @ctx: v4l2 ctx
1270934d375SYunfei Dong  * @core_decode: core decode callback for each codec
1280934d375SYunfei Dong  * @private_size: the private data size used to share with core
1290934d375SYunfei Dong  *
1300934d375SYunfei Dong  * Return: returns 0 if init successfully, or fail.
1310934d375SYunfei Dong  */
1320934d375SYunfei Dong int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
1330934d375SYunfei Dong 			struct mtk_vcodec_dec_ctx *ctx, core_decode_cb_t core_decode,
1340934d375SYunfei Dong 			int private_size);
1350934d375SYunfei Dong 
1360934d375SYunfei Dong /**
1370934d375SYunfei Dong  * vdec_msg_queue_init_ctx - used to init msg queue context information.
1380934d375SYunfei Dong  * @ctx: message queue context
1390934d375SYunfei Dong  * @hardware_index: hardware index
1400934d375SYunfei Dong  */
1410934d375SYunfei Dong void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index);
1420934d375SYunfei Dong 
1430934d375SYunfei Dong /**
1440934d375SYunfei Dong  * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
1450934d375SYunfei Dong  * @ctx: message queue context
1460934d375SYunfei Dong  * @buf: current lat buffer
1470934d375SYunfei Dong  *
1480934d375SYunfei Dong  * Return: returns 0 if qbuf successfully, or fail.
1490934d375SYunfei Dong  */
1500934d375SYunfei Dong int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx, struct vdec_lat_buf *buf);
1510934d375SYunfei Dong 
1520934d375SYunfei Dong /**
1530934d375SYunfei Dong  * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
1540934d375SYunfei Dong  * @ctx: message queue context
1550934d375SYunfei Dong  *
1560934d375SYunfei Dong  * Return: returns not null if dq successfully, or fail.
1570934d375SYunfei Dong  */
1580934d375SYunfei Dong struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
1590934d375SYunfei Dong 
1600934d375SYunfei Dong /**
161*64a2ade8SSebastian Fricke  * vdec_msg_queue_update_ube_rptr - used to update the ube read point.
1620934d375SYunfei Dong  * @msg_queue: used to store the lat buffer information
1630934d375SYunfei Dong  * @ube_rptr: current ube read point
1640934d375SYunfei Dong  */
1650934d375SYunfei Dong void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr);
1660934d375SYunfei Dong 
1670934d375SYunfei Dong /**
168*64a2ade8SSebastian Fricke  * vdec_msg_queue_update_ube_wptr - used to update the ube write point.
1690934d375SYunfei Dong  * @msg_queue: used to store the lat buffer information
1700934d375SYunfei Dong  * @ube_wptr: current ube write point
1710934d375SYunfei Dong  */
1720934d375SYunfei Dong void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr);
1730934d375SYunfei Dong 
1740934d375SYunfei Dong /**
1750934d375SYunfei Dong  * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
1760934d375SYunfei Dong  *                                    in lat list.
1770934d375SYunfei Dong  * @msg_queue: used to store the lat buffer information
1780934d375SYunfei Dong  *
1790934d375SYunfei Dong  * Return: returns true if successfully, or fail.
1800934d375SYunfei Dong  */
1810934d375SYunfei Dong bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
1820934d375SYunfei Dong 
1830934d375SYunfei Dong /**
1840934d375SYunfei Dong  * vdec_msg_queue_deinit - deinit lat buffer information.
1850934d375SYunfei Dong  * @msg_queue: used to store the lat buffer information
1860934d375SYunfei Dong  * @ctx: v4l2 ctx
1870934d375SYunfei Dong  */
1880934d375SYunfei Dong void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
1890934d375SYunfei Dong 			   struct mtk_vcodec_dec_ctx *ctx);
1900934d375SYunfei Dong 
1910934d375SYunfei Dong #endif
192