From 1765ef7906a19eb403adf58f77dbec3217aca686 Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Wed, 8 Feb 2023 17:27:37 +0800 Subject: [PATCH] video: rockchip: mpp: fix get hw time error issue Use aclk to calculate hw time. Signed-off-by: Yandong Lin Change-Id: Ic2d218531ae03583e51f6b8016832ca9d2ff3c2d --- drivers/video/rockchip/mpp/mpp_rkvdec2.c | 3 ++- drivers/video/rockchip/mpp/mpp_rkvdec2.h | 2 ++ drivers/video/rockchip/mpp/mpp_rkvdec2_link.c | 12 ++++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index d30f157a23ef..780e2a364030 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -422,7 +422,7 @@ static int rkvdec2_isr(struct mpp_dev *mpp) return IRQ_HANDLED; } 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_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz); mpp->cur_task = NULL; task = to_rkvdec2_task(mpp_task); task->irq_status = mpp->irq_status; @@ -1005,6 +1005,7 @@ static int rkvdec2_init(struct mpp_dev *mpp) mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ); mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ); + dec->cycle_clk = &dec->aclk_info; /* Get normal max workload from dtsi */ of_property_read_u32(mpp->dev->of_node, "rockchip,default-max-load", &dec->default_max_load); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.h b/drivers/video/rockchip/mpp/mpp_rkvdec2.h index 58eb8f7869e9..be89535e6217 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.h @@ -178,6 +178,8 @@ struct rkvdec2_dev { struct mpp_clk_info core_clk_info; struct mpp_clk_info cabac_clk_info; struct mpp_clk_info hevc_cabac_clk_info; + struct mpp_clk_info *cycle_clk; + u32 default_max_load; #ifdef CONFIG_ROCKCHIP_MPP_PROC_FS struct proc_dir_entry *procfs; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 58bba121bdc7..41a4d9089aeb 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -190,6 +190,7 @@ struct rkvdec_link_info rkvdec_link_vdpu382_hw_info = { }, .tb_reg_int = 180, .hack_setup = 0, + .tb_reg_cycle = 197, .reg_status = { .dec_num_mask = 0x000fffff, .err_flag_base = 0x024, @@ -674,7 +675,7 @@ static int rkvdec_link_isr_recv_task(struct mpp_dev *mpp, 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_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz); mpp_dbg_link_flow("slot %d rd task %d\n", idx, mpp_task->task_id); @@ -1684,12 +1685,19 @@ static int rkvdec2_ccu_power_on(struct mpp_taskqueue *queue, mpp_clk_safe_enable(ccu->aclk_info.clk); /* core pd and clk on */ for (i = 0; i < queue->core_count; i++) { + struct rkvdec2_dev *dec; + mpp = queue->cores[i]; + dec = to_rkvdec2_dev(mpp); pm_runtime_get_sync(mpp->dev); pm_stay_awake(mpp->dev); if (mpp->hw_ops->clk_on) mpp->hw_ops->clk_on(mpp); + mpp_clk_set_rate(&dec->aclk_info, CLK_MODE_NORMAL); + mpp_clk_set_rate(&dec->cabac_clk_info, CLK_MODE_NORMAL); + mpp_clk_set_rate(&dec->hevc_cabac_clk_info, CLK_MODE_NORMAL); + mpp_devfreq_set_core_rate(mpp, CLK_MODE_NORMAL); mpp_iommu_dev_activate(mpp->iommu_info, mpp); } mpp_debug(DEBUG_CCU, "power on\n"); @@ -1760,7 +1768,7 @@ 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_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_time_diff_with_hw_time(mpp_task, dec->cycle_clk->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);