mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +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;
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
},};
|
},};
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user