video: rockchip: mpp: Add run begin/end

Disable preempt when schedule task timeout work and start hardware.

On heavy system burden case the kthread may be switched out between
starting timeout work and real hardware starting operation and do not
come back for a long time. This will cause unexpected task timeout.

Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: I636c80d5230eedd8ef98e1fd3219b83a0b99614a
This commit is contained in:
Herman Chen
2022-09-01 11:25:17 +08:00
committed by Tao Huang
parent f56620d9d7
commit 18cd4a3e70
13 changed files with 109 additions and 32 deletions

View File

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

View File

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

View File

@@ -25,7 +25,8 @@
#include <linux/platform_device.h>
#include <soc/rockchip/pm_domains.h>
#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,

View File

@@ -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,

View File

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

View File

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

View File

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

View File

@@ -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:

View File

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

View File

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

View File

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

View File

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

View File

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