From 3318f0eac05fbeefe4d9e2b45e452dd816925f5b Mon Sep 17 00:00:00 2001 From: Sayon Chen Date: Tue, 19 Jul 2022 14:25:16 +0800 Subject: [PATCH] video: rockchip: mpp: rkvenc2: Improve slice mode Slice mode now will poll wait and read slice length until max return number is reached. Signed-off-by: Sayon Chen Change-Id: Ieffd91cf356fa3d682aeb20a7a445de0596fec79 --- drivers/video/rockchip/mpp/mpp_rkvenc2.c | 95 +++++++++--------------- 1 file changed, 37 insertions(+), 58 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 44bfab9735a7..7415e07a7afa 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -42,6 +42,7 @@ #define RKVENC_SESSION_MAX_BUFFERS 40 #define RKVENC_MAX_CORE_NUM 4 #define RKVENC_MAX_DCHS_ID 4 +#define RKVENC_MAX_SLICE_FIFO_LEN 256 #define to_rkvenc_info(info) \ container_of(info, struct rkvenc_hw_info, hw) @@ -217,7 +218,7 @@ struct rkvenc_task { u32 last_slice_found; u32 slice_wr_cnt; u32 slice_rd_cnt; - DECLARE_KFIFO(slice_info, union rkvenc2_slice_len_info, 64); + DECLARE_KFIFO(slice_info, union rkvenc2_slice_len_info, RKVENC_MAX_SLICE_FIFO_LEN); }; #define RKVENC_MAX_RCB_NUM (4) @@ -708,40 +709,14 @@ static void rkvenc2_setup_task_id(u32 session_id, struct rkvenc_task *task) static int rkvenc2_is_split_task(struct rkvenc_task *task) { - u32 slc_done_en; - u32 slc_done_msk; - u32 slen_fifo_en; - u32 sli_split_en; - u32 sli_flsh_en; - - if (task->reg[RKVENC_CLASS_BASE].valid) { - u32 *reg = task->reg[RKVENC_CLASS_BASE].data; - - slc_done_en = (reg[RKVENC2_REG_INT_EN] & RKVENC2_BIT_SLICE_DONE_EN) ? 1 : 0; - slc_done_msk = (reg[RKVENC2_REG_INT_MASK] & RKVENC2_BIT_SLICE_DONE_MASK) ? 1 : 0; - } else { - slc_done_en = 0; - slc_done_msk = 0; - } - if (task->reg[RKVENC_CLASS_PIC].valid) { u32 *reg = task->reg[RKVENC_CLASS_PIC].data; + u32 slen_fifo_en = (reg[RKVENC2_REG_ENC_PIC] & RKVENC2_BIT_SLEN_FIFO) ? 1 : 0; + u32 sli_split_en = (reg[RKVENC2_REG_SLI_SPLIT] & RKVENC2_BIT_SLI_SPLIT) ? 1 : 0; + u32 sli_flsh_en = (reg[RKVENC2_REG_SLI_SPLIT] & RKVENC2_BIT_SLI_FLUSH) ? 1 : 0; - slen_fifo_en = (reg[RKVENC2_REG_ENC_PIC] & RKVENC2_BIT_SLEN_FIFO) ? 1 : 0; - sli_split_en = (reg[RKVENC2_REG_SLI_SPLIT] & RKVENC2_BIT_SLI_SPLIT) ? 1 : 0; - sli_flsh_en = (reg[RKVENC2_REG_SLI_SPLIT] & RKVENC2_BIT_SLI_FLUSH) ? 1 : 0; - } else { - slen_fifo_en = 0; - sli_split_en = 0; - sli_flsh_en = 0; - } - - if (sli_split_en && slen_fifo_en && sli_flsh_en) { - if (!slc_done_en || slc_done_msk) - mpp_dbg_slice("task %d slice output enabled but irq disabled!\n", - task->mpp_task.task_id); - - return 1; + if (sli_split_en && slen_fifo_en && sli_flsh_en) + return 1; } return 0; @@ -1735,37 +1710,41 @@ task_done_ret: cfg.count_ret = 0; /* handle slice mode poll return */ - ret = wait_event_timeout(task->wait, - kfifo_out(&enc_task->slice_info, &slice_info, 1), - msecs_to_jiffies(RKVENC2_WORK_TIMEOUT_DELAY)); - if (ret > 0) { - mpp_dbg_slice("task %d rd %3d len %d %s\n", task_id, - enc_task->slice_rd_cnt, slice_info.slice_len, - slice_info.last ? "last" : ""); + do { + ret = wait_event_timeout(task->wait, + kfifo_out(&enc_task->slice_info, &slice_info, 1), + msecs_to_jiffies(RKVENC2_WORK_TIMEOUT_DELAY)); + if (ret > 0) { + mpp_dbg_slice("core %d task %d rd %3d len %d %s\n", task_id, + mpp->core_id, enc_task->slice_rd_cnt, slice_info.slice_len, + slice_info.last ? "last" : ""); + enc_task->slice_rd_cnt++; + if (cfg.count_ret < cfg.count_max) { + struct rkvenc_poll_slice_cfg __user *ucfg = + (struct rkvenc_poll_slice_cfg __user *)(req->data); + u32 __user *dst = (u32 __user *)(ucfg + 1); - enc_task->slice_rd_cnt++; + /* Do NOT return here when put_user error. Just continue */ + if (put_user(slice_info.val, dst + cfg.count_ret)) + ret = -EFAULT; - if (cfg.count_ret < cfg.count_max) { - struct rkvenc_poll_slice_cfg __user *ucfg = - (struct rkvenc_poll_slice_cfg __user *)(req->data); - u32 __user *dst = (u32 __user *)(ucfg + 1); + cfg.count_ret++; + if (put_user(cfg.count_ret, &ucfg->count_ret)) + ret = -EFAULT; + } - /* Do NOT return here when put_user error. Just continue */ - if (put_user(slice_info.val, dst + cfg.count_ret)) - ret = -EFAULT; + if (slice_info.last) { + enc_task->task_split_done = 1; + goto task_done_ret; + } - cfg.count_ret++; - if (put_user(cfg.count_ret, &ucfg->count_ret)) - ret = -EFAULT; + if (cfg.count_ret >= cfg.count_max) + return 0; + + if (ret < 0) + return ret; } - - if (slice_info.last) { - enc_task->task_split_done = 1; - goto task_done_ret; - } - - return ret < 0 ? ret : 0; - } + } while (ret > 0); rkvenc2_task_timeout_process(session, task);