video: rockchip: vpu: add soft reset for rkvdec

rkvdec dev status may wrong after irq, this may cause
next frame dec fail. so must add soft reset after irq

Change-Id: I8649206f353f5c3004b09f1255b50258afff1974
Signed-off-by: Siyong Chen <sayon.chen@rock-chips.com>
This commit is contained in:
Siyong Chen
2018-08-24 14:29:43 +08:00
committed by Tao Huang
parent 33cdb0cb52
commit d96ea9d580
5 changed files with 66 additions and 4 deletions

View File

@@ -174,6 +174,13 @@ struct vpu_task_info {
*/ */
int reg_pps; int reg_pps;
/*
* soft reset register
* special register for soft reset
* valid on vpu & vpu2 & rkv
*/
int reg_reset;
/* /*
* decoder pipeline mode register * decoder pipeline mode register
* *
@@ -200,6 +207,9 @@ struct vpu_task_info {
/* task error bit mask for irq register */ /* task error bit mask for irq register */
u32 error_mask; u32 error_mask;
/* task reset bit mask for reset register */
u32 reset_mask;
enum FORMAT_TYPE (*get_fmt)(u32 *regs); enum FORMAT_TYPE (*get_fmt)(u32 *regs);
}; };

View File

@@ -58,6 +58,10 @@
| RKV_DEC_BUFFER_EMPTY_BIT \ | RKV_DEC_BUFFER_EMPTY_BIT \
| RKV_DEC_COLMV_ERROR_BIT) | RKV_DEC_COLMV_ERROR_BIT)
/* enable and soft reset register */
#define RKV_REG_DEC_RESET 1
#define RKV_REG_DEC_RESET_BIT BIT(20)
static const enum FORMAT_TYPE rkv_dec_fmt_tbl[] = { static const enum FORMAT_TYPE rkv_dec_fmt_tbl[] = {
[0] = FMT_H265D, [0] = FMT_H265D,
[1] = FMT_H264D, [1] = FMT_H264D,
@@ -80,6 +84,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.reg_len = 0, .reg_len = 0,
.reg_dir_mv = 0, .reg_dir_mv = 0,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = 0, .reg_pipe = 0,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -87,6 +92,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.irq_mask = 0, .irq_mask = 0,
.ready_mask = 0, .ready_mask = 0,
.error_mask = 0, .error_mask = 0,
.reset_mask = 0,
.get_fmt = NULL, .get_fmt = NULL,
}, },
{ {
@@ -97,6 +103,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.reg_len = 4, .reg_len = 4,
.reg_dir_mv = 52, .reg_dir_mv = 52,
.reg_pps = 42, .reg_pps = 42,
.reg_reset = RKV_REG_DEC_RESET,
.reg_pipe = 0, .reg_pipe = 0,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = RKV_REG_DEC_GATING_BIT, .gating_mask = RKV_REG_DEC_GATING_BIT,
@@ -104,6 +111,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.pipe_mask = 0, .pipe_mask = 0,
.ready_mask = HEVC_READY_BIT, .ready_mask = HEVC_READY_BIT,
.error_mask = HEVC_DEC_ERR_MASK, .error_mask = HEVC_DEC_ERR_MASK,
.reset_mask = RKV_REG_DEC_RESET_BIT,
.get_fmt = rkv_dec_get_fmt, .get_fmt = rkv_dec_get_fmt,
}, },
{ {
@@ -113,6 +121,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.reg_len = 0, .reg_len = 0,
.reg_dir_mv = 0, .reg_dir_mv = 0,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = 0, .reg_pipe = 0,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -120,6 +129,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.irq_mask = 0, .irq_mask = 0,
.ready_mask = 0, .ready_mask = 0,
.error_mask = 0, .error_mask = 0,
.reset_mask = 0,
.get_fmt = NULL, .get_fmt = NULL,
}, },
{ {
@@ -129,6 +139,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.reg_len = 0, .reg_len = 0,
.reg_dir_mv = 0, .reg_dir_mv = 0,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = 0, .reg_pipe = 0,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -136,6 +147,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
.irq_mask = 0, .irq_mask = 0,
.ready_mask = 0, .ready_mask = 0,
.error_mask = 0, .error_mask = 0,
.reset_mask = 0,
.get_fmt = NULL, .get_fmt = NULL,
},}; },};

View File

@@ -61,6 +61,10 @@
| VPU_DEC_STREAM_ERROR_BIT \ | VPU_DEC_STREAM_ERROR_BIT \
| VPU_DEC_TIMEOUT_BIT) | VPU_DEC_TIMEOUT_BIT)
/* enable and soft reset register*/
#define VPU_REG_DEC_RESET 101
#define VPU_REG_DEC_RESET_BIT BIT(0)
#define VPU_PP_INTERRUPT_REGISTER 60 #define VPU_PP_INTERRUPT_REGISTER 60
#define VPU_PP_PIPELINE_MODE_BIT BIT(1) #define VPU_PP_PIPELINE_MODE_BIT BIT(1)
#define VPU_PP_INTERRUPT_BIT BIT(8) #define VPU_PP_INTERRUPT_BIT BIT(8)
@@ -132,6 +136,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.reg_len = -1, .reg_len = -1,
.reg_dir_mv = -1, .reg_dir_mv = -1,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = -1, .reg_pipe = -1,
.enable_mask = 0x6, .enable_mask = 0x6,
.gating_mask = 0, .gating_mask = 0,
@@ -139,6 +144,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.irq_mask = VPU_ENC_INTERRUPT_BIT, .irq_mask = VPU_ENC_INTERRUPT_BIT,
.ready_mask = VPU_ENC_READY_BIT, .ready_mask = VPU_ENC_READY_BIT,
.error_mask = VPU_ENC_ERR_MASK, .error_mask = VPU_ENC_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu_enc_get_fmt, .get_fmt = vpu_enc_get_fmt,
}, },
{ {
@@ -149,6 +155,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.reg_len = 12, .reg_len = 12,
.reg_dir_mv = 41, .reg_dir_mv = 41,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = VPU_REG_DEC_RESET,
.reg_pipe = VPU_PP_INTERRUPT_REGISTER, .reg_pipe = VPU_PP_INTERRUPT_REGISTER,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -156,6 +163,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.irq_mask = VPU_DEC_INTERRUPT_BIT, .irq_mask = VPU_DEC_INTERRUPT_BIT,
.ready_mask = VPU_DEC_READY_BIT, .ready_mask = VPU_DEC_READY_BIT,
.error_mask = VPU_DEC_ERR_MASK, .error_mask = VPU_DEC_ERR_MASK,
.reset_mask = VPU_REG_DEC_RESET_BIT,
.get_fmt = vpu_dec_get_fmt, .get_fmt = vpu_dec_get_fmt,
}, },
{ {
@@ -165,6 +173,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.reg_len = -1, .reg_len = -1,
.reg_dir_mv = -1, .reg_dir_mv = -1,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = VPU_PP_INTERRUPT_REGISTER, .reg_pipe = VPU_PP_INTERRUPT_REGISTER,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -172,6 +181,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.irq_mask = VPU_PP_INTERRUPT_BIT, .irq_mask = VPU_PP_INTERRUPT_BIT,
.ready_mask = VPU_PP_READY_BIT, .ready_mask = VPU_PP_READY_BIT,
.error_mask = VPU_PP_ERR_MASK, .error_mask = VPU_PP_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu_pp_get_fmt, .get_fmt = vpu_pp_get_fmt,
}, },
{ {
@@ -182,6 +192,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.reg_len = 12, .reg_len = 12,
.reg_dir_mv = 41, .reg_dir_mv = 41,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = VPU_PP_INTERRUPT_REGISTER, .reg_pipe = VPU_PP_INTERRUPT_REGISTER,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = 0, .gating_mask = 0,
@@ -189,6 +200,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
.irq_mask = VPU_DEC_INTERRUPT_BIT, .irq_mask = VPU_DEC_INTERRUPT_BIT,
.ready_mask = VPU_DEC_READY_BIT, .ready_mask = VPU_DEC_READY_BIT,
.error_mask = VPU_DEC_ERR_MASK, .error_mask = VPU_DEC_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu_dec_get_fmt, .get_fmt = vpu_dec_get_fmt,
}, },
}; };

View File

@@ -58,6 +58,10 @@
| VPU2_DEC_STREAM_ERROR_BIT \ | VPU2_DEC_STREAM_ERROR_BIT \
| VPU2_DEC_TIMEOUT_BIT) | VPU2_DEC_TIMEOUT_BIT)
/*enable and soft reset register*/
#define VPU2_REG_DEC_RESET 58
#define VPU2_REG_DEC_RESET_BIT BIT(0)
#define VPU2_PP_INTERRUPT_REGISTER 40 #define VPU2_PP_INTERRUPT_REGISTER 40
#define VPU2_PP_INTERRUPT_BIT BIT(0) #define VPU2_PP_INTERRUPT_BIT BIT(0)
#define VPU2_PP_READY_BIT BIT(2) #define VPU2_PP_READY_BIT BIT(2)
@@ -131,6 +135,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.reg_len = -1, .reg_len = -1,
.reg_dir_mv = -1, .reg_dir_mv = -1,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = -1,
.reg_pipe = -1, .reg_pipe = -1,
.enable_mask = 0x30, .enable_mask = 0x30,
.gating_mask = VPU2_REG_ENC_GATE_BIT, .gating_mask = VPU2_REG_ENC_GATE_BIT,
@@ -138,6 +143,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.irq_mask = VPU2_ENC_INTERRUPT_BIT, .irq_mask = VPU2_ENC_INTERRUPT_BIT,
.ready_mask = VPU2_ENC_READY_BIT, .ready_mask = VPU2_ENC_READY_BIT,
.error_mask = VPU2_ENC_ERR_MASK, .error_mask = VPU2_ENC_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu2_enc_get_fmt, .get_fmt = vpu2_enc_get_fmt,
}, },
{ {
@@ -148,6 +154,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.reg_len = 64, .reg_len = 64,
.reg_dir_mv = 62, .reg_dir_mv = 62,
.reg_pps = -1, .reg_pps = -1,
.reg_reset = VPU2_REG_DEC_RESET,
.reg_pipe = VPU2_PP_PIPELINE_REGISTER, .reg_pipe = VPU2_PP_PIPELINE_REGISTER,
.enable_mask = 0, .enable_mask = 0,
.gating_mask = VPU2_REG_DEC_GATE_BIT, .gating_mask = VPU2_REG_DEC_GATE_BIT,
@@ -155,6 +162,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.irq_mask = VPU2_DEC_INTERRUPT_BIT, .irq_mask = VPU2_DEC_INTERRUPT_BIT,
.ready_mask = VPU2_DEC_READY_BIT, .ready_mask = VPU2_DEC_READY_BIT,
.error_mask = VPU2_DEC_ERR_MASK, .error_mask = VPU2_DEC_ERR_MASK,
.reset_mask = VPU2_REG_DEC_RESET_BIT,
.get_fmt = vpu2_dec_get_fmt, .get_fmt = vpu2_dec_get_fmt,
}, },
{ {
@@ -171,6 +179,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.irq_mask = VPU2_PP_INTERRUPT_BIT, .irq_mask = VPU2_PP_INTERRUPT_BIT,
.ready_mask = VPU2_PP_READY_BIT, .ready_mask = VPU2_PP_READY_BIT,
.error_mask = VPU2_PP_ERR_MASK, .error_mask = VPU2_PP_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu2_pp_get_fmt, .get_fmt = vpu2_pp_get_fmt,
}, },
{ {
@@ -188,6 +197,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
.irq_mask = VPU2_DEC_INTERRUPT_BIT, .irq_mask = VPU2_DEC_INTERRUPT_BIT,
.ready_mask = VPU2_DEC_READY_BIT, .ready_mask = VPU2_DEC_READY_BIT,
.error_mask = VPU2_DEC_ERR_MASK, .error_mask = VPU2_DEC_ERR_MASK,
.reset_mask = 0,
.get_fmt = vpu2_dec_get_fmt, .get_fmt = vpu2_dec_get_fmt,
}, },
}; };

View File

@@ -461,14 +461,12 @@ struct compat_vpu_request {
}; };
#endif #endif
#define VDPU_SOFT_RESET_REG 101
#define VDPU_CLEAN_CACHE_REG 516 #define VDPU_CLEAN_CACHE_REG 516
#define VEPU_CLEAN_CACHE_REG 772 #define VEPU_CLEAN_CACHE_REG 772
#define HEVC_CLEAN_CACHE_REG 260 #define HEVC_CLEAN_CACHE_REG 260
#define VPU_REG_ENABLE(base, reg) writel_relaxed(1, base + reg) #define VPU_REG_ENABLE(base, reg) writel_relaxed(1, base + reg)
#define VDPU_SOFT_RESET(base) VPU_REG_ENABLE(base, VDPU_SOFT_RESET_REG)
#define VDPU_CLEAN_CACHE(base) VPU_REG_ENABLE(base, VDPU_CLEAN_CACHE_REG) #define VDPU_CLEAN_CACHE(base) VPU_REG_ENABLE(base, VDPU_CLEAN_CACHE_REG)
#define VEPU_CLEAN_CACHE(base) VPU_REG_ENABLE(base, VEPU_CLEAN_CACHE_REG) #define VEPU_CLEAN_CACHE(base) VPU_REG_ENABLE(base, VEPU_CLEAN_CACHE_REG)
#define HEVC_CLEAN_CACHE(base) VPU_REG_ENABLE(base, HEVC_CLEAN_CACHE_REG) #define HEVC_CLEAN_CACHE(base) VPU_REG_ENABLE(base, HEVC_CLEAN_CACHE_REG)
@@ -755,6 +753,27 @@ static void vpu_reset(struct vpu_subdev_data *data)
dev_info(pservice->dev, "reset done\n"); dev_info(pservice->dev, "reset done\n");
} }
static void vpu_soft_reset(struct vpu_subdev_data *data)
{
struct vpu_device *dev = &data->dec_dev;
struct vpu_service_info *pservice = data->pservice;
struct vpu_task_info *task = &data->task_info[TASK_DEC];
if (task->reg_reset < 0)
return;
writel(task->reset_mask, dev->regs + task->reg_reset);
if (data->mmu_dev && test_bit(MMU_ACTIVATED, &data->state)) {
clear_bit(MMU_ACTIVATED, &data->state);
clear_bit(MMU_PAGEFAULT, &data->state);
if (atomic_read(&pservice->enabled))
/* Need to reset iommu */
vcodec_iommu_detach(data->iommu_info);
else
WARN_ON(!atomic_read(&pservice->enabled));
}
}
static void reg_deinit(struct vpu_subdev_data *data, struct vpu_reg *reg); static void reg_deinit(struct vpu_subdev_data *data, struct vpu_reg *reg);
static void vpu_service_session_clear(struct vpu_subdev_data *data, static void vpu_service_session_clear(struct vpu_subdev_data *data,
struct vpu_session *session) struct vpu_session *session)
@@ -3798,8 +3817,7 @@ static irqreturn_t vdpu_isr(int irq, void *dev_id)
} }
reg_from_run_to_done(data, pservice->reg_codec); reg_from_run_to_done(data, pservice->reg_codec);
/* avoid vpu timeout and can't recover problem */ /* avoid vpu timeout and can't recover problem */
if (data->mode == VCODEC_RUNNING_MODE_VPU) vpu_soft_reset(data);
VDPU_SOFT_RESET(data->regs);
} }
} }