diff --git a/drivers/video/rockchip/mpp/mpp_av1dec.c b/drivers/video/rockchip/mpp/mpp_av1dec.c index 797f2a870b0c..26ef14a3fe79 100644 --- a/drivers/video/rockchip/mpp/mpp_av1dec.c +++ b/drivers/video/rockchip/mpp/mpp_av1dec.c @@ -652,6 +652,7 @@ static int av1dec_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) struct av1dec_dev *dec = to_av1dec_dev(mpp); struct av1dec_hw_info *hw = dec->hw_info; struct av1dec_task *task = to_av1dec_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); mpp_iommu_flush_tlb(mpp->iommu_info); @@ -687,10 +688,15 @@ static int av1dec_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, hw->en_base, en_val); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; @@ -879,6 +885,10 @@ static int av1dec_procfs_init(struct mpp_dev *mpp) dec->procfs = NULL; return -EIO; } + + /* for common mpp_dev options */ + mpp_procfs_create_common(dec->procfs, mpp); + /* for debug */ mpp_procfs_create_u32("aclk", 0644, dec->procfs, &dec->aclk_info.debug_rate_hz); diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index 295a6caec33c..3565926e64c1 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -36,7 +36,6 @@ #include "mpp_common.h" #include "mpp_iommu.h" -#define MPP_WORK_TIMEOUT_DELAY (500) #define MPP_WAIT_TIMEOUT_DELAY (2000) /* Use 'v' as magic number */ @@ -751,6 +750,35 @@ int mpp_dev_reset(struct mpp_dev *mpp) return 0; } +void mpp_task_run_begin(struct mpp_task *task, u32 timing_en, u32 timeout) +{ + preempt_disable(); + + set_bit(TASK_STATE_START, &task->state); + + mpp_time_record(task); + schedule_delayed_work(&task->timeout_work, msecs_to_jiffies(timeout)); + + if (timing_en) { + task->on_sched_timeout = ktime_get(); + set_bit(TASK_TIMING_TO_SCHED, &task->state); + } +} + +void mpp_task_run_end(struct mpp_task *task, u32 timing_en) +{ + if (timing_en) { + task->on_run_end = ktime_get(); + set_bit(TASK_TIMING_RUN_END, &task->state); + } + +#ifdef MODULE + preempt_enable(); +#else + preempt_enable_no_resched(); +#endif +} + static int mpp_task_run(struct mpp_dev *mpp, struct mpp_task *task) { @@ -791,23 +819,9 @@ static int mpp_task_run(struct mpp_dev *mpp, */ mpp_reset_down_read(mpp->reset_group); - set_bit(TASK_STATE_START, &task->state); - mpp_time_record(task); - schedule_delayed_work(&task->timeout_work, - msecs_to_jiffies(MPP_WORK_TIMEOUT_DELAY)); - - if (timing_en) { - task->on_sched_timeout = ktime_get(); - set_bit(TASK_TIMING_TO_SCHED, &task->state); - } - if (mpp->dev_ops->run) mpp->dev_ops->run(mpp, task); - if (timing_en) { - task->on_run_end = ktime_get(); - set_bit(TASK_TIMING_RUN_END, &task->state); - } mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 2a40521cdcad..cf62cc396dcf 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -25,7 +25,8 @@ #include #include -#define MHZ (1000 * 1000) +#define MHZ (1000 * 1000) +#define MPP_WORK_TIMEOUT_DELAY (500) #define MPP_MAX_MSG_NUM (16) #define MPP_MAX_REG_TRANS_NUM (60) @@ -662,6 +663,8 @@ int mpp_task_init(struct mpp_session *session, struct mpp_task *task); int mpp_task_finish(struct mpp_session *session, struct mpp_task *task); +void mpp_task_run_begin(struct mpp_task *task, u32 timing_en, u32 timeout); +void mpp_task_run_end(struct mpp_task *task, u32 timing_en); int mpp_task_finalize(struct mpp_session *session, struct mpp_task *task); int mpp_task_dump_mem_region(struct mpp_dev *mpp, diff --git a/drivers/video/rockchip/mpp/mpp_iep2.c b/drivers/video/rockchip/mpp/mpp_iep2.c index e92c68827704..74a72540a854 100644 --- a/drivers/video/rockchip/mpp/mpp_iep2.c +++ b/drivers/video/rockchip/mpp/mpp_iep2.c @@ -578,6 +578,7 @@ static int iep2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) { struct iep_task *task = NULL; + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -598,11 +599,15 @@ static int iep2_run(struct mpp_dev *mpp, | IEP2_REG_OSD_MAX_EN | IEP2_REG_BUS_ERROR_EN); + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Last, flush the registers */ wmb(); /* start iep2 */ mpp_write(mpp, IEP2_REG_FRM_START, 1); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; @@ -767,6 +772,10 @@ static int iep2_procfs_init(struct mpp_dev *mpp) iep->procfs = NULL; return -EIO; } + + /* for common mpp_dev options */ + mpp_procfs_create_common(iep->procfs, mpp); + mpp_procfs_create_u32("aclk", 0644, iep->procfs, &iep->aclk_info.debug_rate_hz); mpp_procfs_create_u32("session_buffers", 0644, diff --git a/drivers/video/rockchip/mpp/mpp_jpgdec.c b/drivers/video/rockchip/mpp/mpp_jpgdec.c index 58e8b16222ec..4cdbceb22250 100644 --- a/drivers/video/rockchip/mpp/mpp_jpgdec.c +++ b/drivers/video/rockchip/mpp/mpp_jpgdec.c @@ -251,6 +251,7 @@ static int jpgdec_run(struct mpp_dev *mpp, u32 i; u32 reg_en; struct jpgdec_task *task = to_jpgdec_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -265,11 +266,16 @@ static int jpgdec_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, JPGDEC_REG_INT_EN_BASE, task->reg[reg_en] | JPGDEC_START_EN); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 5acc6049b562..5c5ca8f38c90 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -318,6 +318,7 @@ static void *rkvdec2_rk3568_alloc_task(struct mpp_session *session, static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) { struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; u32 reg_en = mpp_task->hw_info->reg_en; /* set cache size */ u32 reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS | @@ -352,10 +353,15 @@ static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, RKVDEC_REG_START_EN_BASE, task->reg[reg_en] | RKVDEC_START_EN); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 8396cb4622d6..0dd7c21d85af 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -458,6 +458,7 @@ static int rkvdec_link_send_task_to_hw(struct rkvdec_link_dev *dev, } if (!resend) { + u32 timing_en = dev->mpp->srv->timing_en; u32 i; for (i = 0; i < task_to_run; i++) { @@ -467,9 +468,8 @@ static int rkvdec_link_send_task_to_hw(struct rkvdec_link_dev *dev, if (!task_ddr) continue; - set_bit(TASK_STATE_START, &task_ddr->state); - schedule_delayed_work(&task_ddr->timeout_work, - msecs_to_jiffies(200)); + mpp_task_run_begin(task_ddr, timing_en, WORK_TIMEOUT_MS); + mpp_task_run_end(task_ddr, timing_en); } } else { if (task_total) @@ -1826,6 +1826,7 @@ static int rkvdec2_soft_ccu_enqueue(struct mpp_dev *mpp, struct mpp_task *mpp_ta u32 i, reg_en, reg; struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -1865,12 +1866,17 @@ static int rkvdec2_soft_ccu_enqueue(struct mpp_dev *mpp, struct mpp_task *mpp_ta } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + mpp->irq_status = 0; writel_relaxed(dec->core_mask, dec->ccu->reg_base + RKVDEC_CCU_CORE_STA_BASE); /* Flush the register before the start the device */ wmb(); mpp_write(mpp, RKVDEC_REG_START_EN_BASE, task->reg[reg_en] | RKVDEC_START_EN); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; @@ -1998,26 +2004,13 @@ get_task: mutex_unlock(&queue->pending_lock); set_bit(TASK_STATE_RUNNING, &mpp_task->state); - mpp_time_record(mpp_task); mpp_debug(DEBUG_TASK_INFO, "pid %d, start hw %s\n", mpp_task->session->pid, dev_name(mpp->dev)); - set_bit(TASK_STATE_START, &mpp_task->state); INIT_DELAYED_WORK(&mpp_task->timeout_work, rkvdec2_ccu_link_timeout_work); - schedule_delayed_work(&mpp_task->timeout_work, msecs_to_jiffies(WORK_TIMEOUT_MS)); - - if (timing_en) { - mpp_task->on_sched_timeout = ktime_get(); - set_bit(TASK_TIMING_TO_SCHED, &mpp_task->state); - } rkvdec2_ccu_power_on(queue, dec->ccu); rkvdec2_soft_ccu_enqueue(mpp, mpp_task); - if (timing_en) { - mpp_task->on_run_end = ktime_get(); - set_bit(TASK_TIMING_RUN_END, &mpp_task->state); - } - done: if (list_empty(&queue->running_list) && list_empty(&queue->pending_list)) diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index e5370cd50071..3d142a05e8c9 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -439,6 +439,7 @@ static int rkvenc_run(struct mpp_dev *mpp, int i; struct mpp_request *req; u32 reg_en = mpp_task->hw_info->reg_en; + u32 timing_en = mpp->srv->timing_en; /* * Tips: ensure osd plt clock is 0 before setting register, @@ -468,9 +469,14 @@ static int rkvenc_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, RKVENC_ENC_START_BASE, task->reg[reg_en]); + + mpp_task_run_end(mpp_task, timing_en); } break; case RKVENC_MODE_LINKTABLE_FIX: case RKVENC_MODE_LINKTABLE_UPDATE: diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 0358e5ca9c1c..8b2c2d4516a7 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -1019,6 +1019,7 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) struct rkvenc_dev *enc = to_rkvenc_dev(mpp); struct rkvenc_task *task = to_rkvenc_task(mpp_task); struct rkvenc_hw_info *hw = enc->hw_info; + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -1067,10 +1068,15 @@ static int rkvenc_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) /* init current task */ mpp->cur_task = mpp_task; + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); + mpp_write(mpp, enc->hw_info->enc_start_base, start_val); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_vdpu1.c b/drivers/video/rockchip/mpp/mpp_vdpu1.c index 0d4bb9ee8c79..926be9d7834f 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu1.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu1.c @@ -390,6 +390,7 @@ static int vdpu_run(struct mpp_dev *mpp, u32 i; u32 reg_en; struct vdpu_task *task = to_vdpu_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -406,11 +407,16 @@ static int vdpu_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the register before the start the device */ wmb(); mpp_write(mpp, VDPU1_REG_DEC_INT_EN, task->reg[reg_en] | VDPU1_DEC_START); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_vdpu2.c b/drivers/video/rockchip/mpp/mpp_vdpu2.c index e3d78d710f59..b63fc48c4568 100644 --- a/drivers/video/rockchip/mpp/mpp_vdpu2.c +++ b/drivers/video/rockchip/mpp/mpp_vdpu2.c @@ -343,6 +343,7 @@ static int vdpu_run(struct mpp_dev *mpp, u32 i; u32 reg_en; struct vdpu_task *task = to_vdpu_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -359,11 +360,16 @@ static int vdpu_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Flush the registers */ wmb(); mpp_write(mpp, VDPU2_REG_DEC_EN, task->reg[reg_en] | VDPU2_DEC_START); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_vepu1.c b/drivers/video/rockchip/mpp/mpp_vepu1.c index 3bb51c963939..8c9782d78a1b 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu1.c +++ b/drivers/video/rockchip/mpp/mpp_vepu1.c @@ -264,6 +264,7 @@ static int vepu_run(struct mpp_dev *mpp, u32 i; u32 reg_en; struct vepu_task *task = to_vepu_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -284,11 +285,16 @@ static int vepu_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Last, flush start registers */ wmb(); mpp_write(mpp, VEPU1_REG_ENC_EN, task->reg[reg_en] | VEPU1_ENC_START); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0; diff --git a/drivers/video/rockchip/mpp/mpp_vepu2.c b/drivers/video/rockchip/mpp/mpp_vepu2.c index 02797ba1b182..cb61fc044b6a 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu2.c +++ b/drivers/video/rockchip/mpp/mpp_vepu2.c @@ -352,6 +352,7 @@ static int vepu_run(struct mpp_dev *mpp, u32 i; u32 reg_en; struct vepu_task *task = to_vepu_task(mpp_task); + u32 timing_en = mpp->srv->timing_en; mpp_debug_enter(); @@ -372,11 +373,16 @@ static int vepu_run(struct mpp_dev *mpp, } /* init current task */ mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + /* Last, flush the registers */ wmb(); mpp_write(mpp, VEPU2_REG_ENC_EN, task->reg[reg_en] | VEPU2_ENC_START); + mpp_task_run_end(mpp_task, timing_en); + mpp_debug_leave(); return 0;