diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index d167f837c508..c129eec91c11 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -2351,6 +2351,28 @@ int mpp_time_diff(struct mpp_task *task) return 0; } +int mpp_time_diff_with_hw_time(struct mpp_task *task, u32 clk_hz) +{ + if (mpp_debug_unlikely(DEBUG_TIMING)) { + ktime_t end; + struct mpp_dev *mpp = mpp_get_task_used_device(task, task->session); + + end = ktime_get(); + + if (clk_hz) + mpp_debug(DEBUG_TIMING, "%s:%d session %d:%d time: %lld us hw %d us\n", + dev_name(mpp->dev), task->core_id, task->session->pid, + task->session->index, ktime_us_delta(end, task->start), + task->hw_cycles / (clk_hz / 1000000)); + else + mpp_debug(DEBUG_TIMING, "%s:%d session %d:%d time: %lld us\n", + dev_name(mpp->dev), task->core_id, task->session->pid, + task->session->index, ktime_us_delta(end, task->start)); + } + + return 0; +} + #define LOG_TIMING(state, id, stage, time, base) \ do { \ if (test_bit(id, &state)) \ @@ -2512,6 +2534,7 @@ int mpp_clk_set_rate(struct mpp_clk_info *clk_info, if (clk_rate_hz) { clk_info->used_rate_hz = clk_rate_hz; clk_set_rate(clk_info->clk, clk_rate_hz); + clk_info->real_rate_hz = clk_get_rate(clk_info->clk); } return 0; diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 9d6289baf739..f4bf8f21b887 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -285,6 +285,7 @@ struct mpp_clk_info { u32 reduce_rate_hz; /* record last used rate */ u32 used_rate_hz; + u32 real_rate_hz; }; struct mpp_dev_var { @@ -493,6 +494,8 @@ struct mpp_task { /* for multi-core */ struct mpp_dev *mpp; s32 core_id; + /* hw cycles */ + u32 hw_cycles; }; struct mpp_taskqueue { @@ -707,6 +710,7 @@ int mpp_set_grf(struct mpp_grf_info *grf_info); int mpp_time_record(struct mpp_task *task); int mpp_time_diff(struct mpp_task *task); +int mpp_time_diff_with_hw_time(struct mpp_task *task, u32 clk_hz); int mpp_time_part_diff(struct mpp_task *task); int mpp_write_req(struct mpp_dev *mpp, u32 *regs, diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 0ce4324796c6..bb2ee3452e50 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -404,13 +404,15 @@ static int rkvdec2_isr(struct mpp_dev *mpp) u32 err_mask; struct rkvdec2_task *task = NULL; struct mpp_task *mpp_task = mpp->cur_task; + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); /* FIXME use a spin lock here */ if (!mpp_task) { dev_err(mpp->dev, "no current task\n"); return IRQ_HANDLED; } - mpp_time_diff(mpp_task); + mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT); + mpp_time_diff_with_hw_time(mpp_task, dec->core_clk_info.real_rate_hz); mpp->cur_task = NULL; task = to_rkvdec2_task(mpp_task); task->irq_status = mpp->irq_status; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.h b/drivers/video/rockchip/mpp/mpp_rkvdec2.h index ee0d5696b8c0..bf237ca7fd9b 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.h @@ -73,6 +73,7 @@ RKVDEC_BUF_EMPTY_STA |\ RKVDEC_TIMEOUT_STA |\ RKVDEC_ERROR_STA) +#define RKVDEC_PERF_WORKING_CNT 0x41c /* perf sel reference register */ #define RKVDEC_PERF_SEL_OFFSET 0x20000 diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 03dba0e20376..d79045b866de 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -71,6 +71,7 @@ struct rkvdec_link_info rkvdec_link_v2_hw_info = { .reg_num = 28, }, .tb_reg_int = 180, + .tb_reg_cycle = 195, .hack_setup = 0, }; @@ -124,6 +125,7 @@ struct rkvdec_link_info rkvdec_link_rk356x_hw_info = { .reg_num = 28, }, .tb_reg_int = 164, + .tb_reg_cycle = 179, .hack_setup = 1, }; @@ -538,6 +540,7 @@ static int rkvdec_link_isr_recv_task(struct mpp_dev *mpp, struct rkvdec_link_info *info = link_dec->info; u32 *table_base = (u32 *)link_dec->table->vaddr; int i; + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); for (i = 0; i < count; i++) { int idx = rkvdec_link_get_task_read(link_dec); @@ -598,6 +601,8 @@ static int rkvdec_link_isr_recv_task(struct mpp_dev *mpp, task = to_rkvdec2_task(mpp_task); regs = table_base + idx * link_dec->link_reg_count; irq_status = regs[info->tb_reg_int]; + mpp_task->hw_cycles = regs[info->tb_reg_cycle]; + mpp_time_diff_with_hw_time(mpp_task, dec->core_clk_info.real_rate_hz); mpp_dbg_link_flow("slot %d rd task %d\n", idx, mpp_task->task_id); @@ -1207,7 +1212,6 @@ static int mpp_task_queue(struct mpp_dev *mpp, struct mpp_task *task) mpp_debug_enter(); rkvdec2_link_power_on(mpp); - mpp_time_record(task); mpp_debug(DEBUG_TASK_INFO, "pid %d, start hw %s\n", task->session->pid, dev_name(mpp->dev)); @@ -1664,6 +1668,7 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) &queue->running_list, queue_link) { struct mpp_dev *mpp = mpp_get_task_used_device(mpp_task, mpp_task->session); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); u32 irq_status = mpp->irq_status; u32 timeout_flag = test_bit(TASK_STATE_TIMEOUT, &mpp_task->state); u32 abort_flag = test_bit(TASK_STATE_ABORT, &mpp_task->state); @@ -1685,7 +1690,8 @@ static int rkvdec2_soft_ccu_dequeue(struct mpp_taskqueue *queue) set_bit(TASK_STATE_HANDLE, &mpp_task->state); cancel_delayed_work(&mpp_task->timeout_work); - mpp_time_diff(mpp_task); + mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT); + mpp_time_diff_with_hw_time(mpp_task, dec->core_clk_info.real_rate_hz); task->irq_status = irq_status; mpp_debug(DEBUG_IRQ_CHECK, "irq_status=%08x, timeout=%u, abort=%u\n", irq_status, timeout_flag, abort_flag); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h index 635516ae3262..b2e20015a630 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h @@ -112,6 +112,7 @@ struct rkvdec_link_info { /* interrupt read back in table buffer */ u32 tb_reg_int; + u32 tb_reg_cycle; bool hack_setup; };