mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -174,6 +174,13 @@ struct vpu_task_info {
|
||||
*/
|
||||
int reg_pps;
|
||||
|
||||
/*
|
||||
* soft reset register
|
||||
* special register for soft reset
|
||||
* valid on vpu & vpu2 & rkv
|
||||
*/
|
||||
int reg_reset;
|
||||
|
||||
/*
|
||||
* decoder pipeline mode register
|
||||
*
|
||||
@@ -200,6 +207,9 @@ struct vpu_task_info {
|
||||
/* task error bit mask for irq register */
|
||||
u32 error_mask;
|
||||
|
||||
/* task reset bit mask for reset register */
|
||||
u32 reset_mask;
|
||||
|
||||
enum FORMAT_TYPE (*get_fmt)(u32 *regs);
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
| RKV_DEC_BUFFER_EMPTY_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[] = {
|
||||
[0] = FMT_H265D,
|
||||
[1] = FMT_H264D,
|
||||
@@ -80,6 +84,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 0,
|
||||
.reg_dir_mv = 0,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = 0,
|
||||
.enable_mask = 0,
|
||||
.gating_mask = 0,
|
||||
@@ -87,6 +92,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.irq_mask = 0,
|
||||
.ready_mask = 0,
|
||||
.error_mask = 0,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = NULL,
|
||||
},
|
||||
{
|
||||
@@ -97,6 +103,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 4,
|
||||
.reg_dir_mv = 52,
|
||||
.reg_pps = 42,
|
||||
.reg_reset = RKV_REG_DEC_RESET,
|
||||
.reg_pipe = 0,
|
||||
.enable_mask = 0,
|
||||
.gating_mask = RKV_REG_DEC_GATING_BIT,
|
||||
@@ -104,6 +111,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.pipe_mask = 0,
|
||||
.ready_mask = HEVC_READY_BIT,
|
||||
.error_mask = HEVC_DEC_ERR_MASK,
|
||||
.reset_mask = RKV_REG_DEC_RESET_BIT,
|
||||
.get_fmt = rkv_dec_get_fmt,
|
||||
},
|
||||
{
|
||||
@@ -113,6 +121,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 0,
|
||||
.reg_dir_mv = 0,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = 0,
|
||||
.enable_mask = 0,
|
||||
.gating_mask = 0,
|
||||
@@ -120,6 +129,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.irq_mask = 0,
|
||||
.ready_mask = 0,
|
||||
.error_mask = 0,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = NULL,
|
||||
},
|
||||
{
|
||||
@@ -129,6 +139,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 0,
|
||||
.reg_dir_mv = 0,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = 0,
|
||||
.enable_mask = 0,
|
||||
.gating_mask = 0,
|
||||
@@ -136,6 +147,7 @@ static struct vpu_task_info task_rkv[TASK_TYPE_BUTT] = {
|
||||
.irq_mask = 0,
|
||||
.ready_mask = 0,
|
||||
.error_mask = 0,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = NULL,
|
||||
},};
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
| VPU_DEC_STREAM_ERROR_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_PIPELINE_MODE_BIT BIT(1)
|
||||
#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_dir_mv = -1,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = -1,
|
||||
.enable_mask = 0x6,
|
||||
.gating_mask = 0,
|
||||
@@ -139,6 +144,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
|
||||
.irq_mask = VPU_ENC_INTERRUPT_BIT,
|
||||
.ready_mask = VPU_ENC_READY_BIT,
|
||||
.error_mask = VPU_ENC_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = vpu_enc_get_fmt,
|
||||
},
|
||||
{
|
||||
@@ -149,6 +155,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 12,
|
||||
.reg_dir_mv = 41,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = VPU_REG_DEC_RESET,
|
||||
.reg_pipe = VPU_PP_INTERRUPT_REGISTER,
|
||||
.enable_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,
|
||||
.ready_mask = VPU_DEC_READY_BIT,
|
||||
.error_mask = VPU_DEC_ERR_MASK,
|
||||
.reset_mask = VPU_REG_DEC_RESET_BIT,
|
||||
.get_fmt = vpu_dec_get_fmt,
|
||||
},
|
||||
{
|
||||
@@ -165,6 +173,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
|
||||
.reg_len = -1,
|
||||
.reg_dir_mv = -1,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = VPU_PP_INTERRUPT_REGISTER,
|
||||
.enable_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,
|
||||
.ready_mask = VPU_PP_READY_BIT,
|
||||
.error_mask = VPU_PP_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = vpu_pp_get_fmt,
|
||||
},
|
||||
{
|
||||
@@ -182,6 +192,7 @@ static struct vpu_task_info task_vpu[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 12,
|
||||
.reg_dir_mv = 41,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = VPU_PP_INTERRUPT_REGISTER,
|
||||
.enable_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,
|
||||
.ready_mask = VPU_DEC_READY_BIT,
|
||||
.error_mask = VPU_DEC_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = vpu_dec_get_fmt,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
| VPU2_DEC_STREAM_ERROR_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_BIT BIT(0)
|
||||
#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_dir_mv = -1,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = -1,
|
||||
.reg_pipe = -1,
|
||||
.enable_mask = 0x30,
|
||||
.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,
|
||||
.ready_mask = VPU2_ENC_READY_BIT,
|
||||
.error_mask = VPU2_ENC_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = vpu2_enc_get_fmt,
|
||||
},
|
||||
{
|
||||
@@ -148,6 +154,7 @@ static struct vpu_task_info task_vpu2[TASK_TYPE_BUTT] = {
|
||||
.reg_len = 64,
|
||||
.reg_dir_mv = 62,
|
||||
.reg_pps = -1,
|
||||
.reg_reset = VPU2_REG_DEC_RESET,
|
||||
.reg_pipe = VPU2_PP_PIPELINE_REGISTER,
|
||||
.enable_mask = 0,
|
||||
.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,
|
||||
.ready_mask = VPU2_DEC_READY_BIT,
|
||||
.error_mask = VPU2_DEC_ERR_MASK,
|
||||
.reset_mask = VPU2_REG_DEC_RESET_BIT,
|
||||
.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,
|
||||
.ready_mask = VPU2_PP_READY_BIT,
|
||||
.error_mask = VPU2_PP_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.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,
|
||||
.ready_mask = VPU2_DEC_READY_BIT,
|
||||
.error_mask = VPU2_DEC_ERR_MASK,
|
||||
.reset_mask = 0,
|
||||
.get_fmt = vpu2_dec_get_fmt,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -461,14 +461,12 @@ struct compat_vpu_request {
|
||||
};
|
||||
#endif
|
||||
|
||||
#define VDPU_SOFT_RESET_REG 101
|
||||
#define VDPU_CLEAN_CACHE_REG 516
|
||||
#define VEPU_CLEAN_CACHE_REG 772
|
||||
#define HEVC_CLEAN_CACHE_REG 260
|
||||
|
||||
#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 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)
|
||||
@@ -755,6 +753,27 @@ static void vpu_reset(struct vpu_subdev_data *data)
|
||||
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 vpu_service_session_clear(struct vpu_subdev_data *data,
|
||||
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);
|
||||
/* avoid vpu timeout and can't recover problem */
|
||||
if (data->mode == VCODEC_RUNNING_MODE_VPU)
|
||||
VDPU_SOFT_RESET(data->regs);
|
||||
vpu_soft_reset(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user