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 <sayon.chen@rock-chips.com>
Change-Id: Ieffd91cf356fa3d682aeb20a7a445de0596fec79
This commit is contained in:
Sayon Chen
2022-07-19 14:25:16 +08:00
committed by Tao Huang
parent ed7ebdb2a0
commit 3318f0eac0

View File

@@ -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);