video: rockchip: mpp: rkvdec issue for rk3399 that 264 switch vp9
in rk3399 rkvdec, after 264 task run, 264 hardware may remain state, and it cannot clear completely. Case this, when last task is 264 and current is vp9, vp9 affect decode error. Thus, it should reset hardware before task run, when 264 switch vp9. Change-Id: Ie038f9de8533d15cd828f5fdde7634f278fbd061 Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
parent
25bb952677
commit
bd1bd4072a
3 changed files with 64 additions and 6 deletions
|
|
@ -57,7 +57,6 @@ struct mpp_msg_v1 {
|
|||
};
|
||||
|
||||
static void mpp_free_task(struct kref *ref);
|
||||
static int mpp_dev_reset(struct mpp_dev *mpp);
|
||||
|
||||
/* task queue schedule */
|
||||
static int
|
||||
|
|
@ -181,7 +180,7 @@ mpp_taskqueue_trigger_work(struct mpp_taskqueue *queue,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mpp_power_on(struct mpp_dev *mpp)
|
||||
int mpp_power_on(struct mpp_dev *mpp)
|
||||
{
|
||||
pm_runtime_get_sync(mpp->dev);
|
||||
pm_stay_awake(mpp->dev);
|
||||
|
|
@ -192,7 +191,7 @@ static int mpp_power_on(struct mpp_dev *mpp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mpp_power_off(struct mpp_dev *mpp)
|
||||
int mpp_power_off(struct mpp_dev *mpp)
|
||||
{
|
||||
if (mpp->hw_ops->power_off)
|
||||
mpp->hw_ops->power_off(mpp);
|
||||
|
|
@ -466,7 +465,7 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int mpp_dev_reset(struct mpp_dev *mpp)
|
||||
int mpp_dev_reset(struct mpp_dev *mpp)
|
||||
{
|
||||
dev_info(mpp->dev, "resetting...\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -419,6 +419,10 @@ int mpp_dev_probe(struct mpp_dev *mpp,
|
|||
struct platform_device *pdev);
|
||||
int mpp_dev_remove(struct mpp_dev *mpp);
|
||||
|
||||
int mpp_power_on(struct mpp_dev *mpp);
|
||||
int mpp_power_off(struct mpp_dev *mpp);
|
||||
int mpp_dev_reset(struct mpp_dev *mpp);
|
||||
|
||||
irqreturn_t mpp_dev_irq(int irq, void *param);
|
||||
irqreturn_t mpp_dev_isr_sched(int irq, void *param);
|
||||
|
||||
|
|
|
|||
|
|
@ -199,6 +199,9 @@ struct rkvdec_dev {
|
|||
unsigned long aclk_devf;
|
||||
unsigned long clk_core_devf;
|
||||
unsigned long clk_cabac_devf;
|
||||
/* record last infos */
|
||||
u32 last_fmt;
|
||||
bool had_reset;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -852,6 +855,34 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void *rkvdec_prepare_with_reset(struct mpp_dev *mpp,
|
||||
struct mpp_task *mpp_task)
|
||||
{
|
||||
struct mpp_task *out_task = NULL;
|
||||
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
|
||||
|
||||
mutex_lock(&mpp->queue->running_lock);
|
||||
out_task = list_empty(&mpp->queue->running_list) ? mpp_task : NULL;
|
||||
mutex_unlock(&mpp->queue->running_lock);
|
||||
|
||||
if (out_task && !dec->had_reset) {
|
||||
struct rkvdec_task *task = to_rkvdec_task(out_task);
|
||||
u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_SYS_CTRL_INDEX]);
|
||||
|
||||
/* in 3399 3228 and 3229 chips, when 264 switch vp9,
|
||||
* hardware will timeout, and can't recover problem.
|
||||
* so reset it when 264 switch vp9, before hardware run.
|
||||
*/
|
||||
if (dec->last_fmt == RKVDEC_FMT_H264D && fmt == RKVDEC_FMT_VP9D) {
|
||||
mpp_power_on(mpp);
|
||||
mpp_dev_reset(mpp);
|
||||
mpp_power_off(mpp);
|
||||
}
|
||||
}
|
||||
|
||||
return out_task;
|
||||
}
|
||||
|
||||
static int rkvdec_run(struct mpp_dev *mpp,
|
||||
struct mpp_task *mpp_task)
|
||||
{
|
||||
|
|
@ -1028,6 +1059,19 @@ static int rkvdec_finish(struct mpp_dev *mpp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_finish_with_record_info(struct mpp_dev *mpp,
|
||||
struct mpp_task *mpp_task)
|
||||
{
|
||||
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
|
||||
struct rkvdec_task *task = to_rkvdec_task(mpp_task);
|
||||
|
||||
rkvdec_finish(mpp, mpp_task);
|
||||
dec->last_fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_SYS_CTRL_INDEX]);
|
||||
dec->had_reset = (atomic_read(&mpp->reset_request) > 0) ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rkvdec_result(struct mpp_dev *mpp,
|
||||
struct mpp_task *mpp_task,
|
||||
struct mpp_task_msgs *msgs)
|
||||
|
|
@ -1588,7 +1632,7 @@ static struct mpp_hw_ops rkvdec_3399_hw_ops = {
|
|||
.get_freq = rkvdec_get_freq,
|
||||
.set_freq = rkvdec_set_freq,
|
||||
.reduce_freq = rkvdec_reduce_freq,
|
||||
.reset = rkvdec_sip_reset,
|
||||
.reset = rkvdec_reset,
|
||||
};
|
||||
|
||||
static struct mpp_hw_ops rkvdec_3368_hw_ops = {
|
||||
|
|
@ -1632,6 +1676,17 @@ static struct mpp_dev_ops rkvdec_3328_dev_ops = {
|
|||
.free_task = rkvdec_free_task,
|
||||
};
|
||||
|
||||
static struct mpp_dev_ops rkvdec_3399_dev_ops = {
|
||||
.alloc_task = rkvdec_alloc_task,
|
||||
.prepare = rkvdec_prepare_with_reset,
|
||||
.run = rkvdec_run,
|
||||
.irq = rkvdec_irq,
|
||||
.isr = rkvdec_isr,
|
||||
.finish = rkvdec_finish_with_record_info,
|
||||
.result = rkvdec_result,
|
||||
.free_task = rkvdec_free_task,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rk_hevcdec_data = {
|
||||
.device_type = MPP_DEVICE_HEVC_DEC,
|
||||
.hw_info = &rk_hevcdec_hw_info,
|
||||
|
|
@ -1669,7 +1724,7 @@ static const struct mpp_dev_var rkvdec_3399_data = {
|
|||
.hw_info = &rkvdec_v1_hw_info,
|
||||
.trans_info = rkvdec_v1_trans,
|
||||
.hw_ops = &rkvdec_3399_hw_ops,
|
||||
.dev_ops = &rkvdec_v1_dev_ops,
|
||||
.dev_ops = &rkvdec_3399_dev_ops,
|
||||
};
|
||||
|
||||
static const struct mpp_dev_var rkvdec_3328_data = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue