[media] s5p-mfc: Flush DPB buffers during stream off
Flushing of delay DPB buffers have to be done during stream off. In MFC v6, it is done with a risc to host command. Signed-off-by: Arun Kumar K <arun.kk@samsung.com> Signed-off-by: Arun Mankuzhi <arun.m@samsung.com> Acked-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:

committed by
Mauro Carvalho Chehab

parent
20fe1cf081
commit
8f23cc0222
@@ -686,6 +686,12 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv)
|
|||||||
s5p_mfc_handle_stream_complete(ctx, reason, err);
|
s5p_mfc_handle_stream_complete(ctx, reason, err);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case S5P_MFC_R2H_CMD_DPB_FLUSH_RET:
|
||||||
|
clear_work_bit(ctx);
|
||||||
|
ctx->state = MFCINST_RUNNING;
|
||||||
|
wake_up(&ctx->queue);
|
||||||
|
goto irq_cleanup_hw;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mfc_debug(2, "Unknown int reason\n");
|
mfc_debug(2, "Unknown int reason\n");
|
||||||
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
|
s5p_mfc_hw_call(dev->mfc_ops, clear_int_flags, dev);
|
||||||
|
@@ -145,6 +145,7 @@ enum s5p_mfc_inst_state {
|
|||||||
MFCINST_RETURN_INST,
|
MFCINST_RETURN_INST,
|
||||||
MFCINST_ERROR,
|
MFCINST_ERROR,
|
||||||
MFCINST_ABORT,
|
MFCINST_ABORT,
|
||||||
|
MFCINST_FLUSH,
|
||||||
MFCINST_RES_CHANGE_INIT,
|
MFCINST_RES_CHANGE_INIT,
|
||||||
MFCINST_RES_CHANGE_FLUSH,
|
MFCINST_RES_CHANGE_FLUSH,
|
||||||
MFCINST_RES_CHANGE_END,
|
MFCINST_RES_CHANGE_END,
|
||||||
|
@@ -991,24 +991,35 @@ static int s5p_mfc_stop_streaming(struct vb2_queue *q)
|
|||||||
S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0);
|
S5P_MFC_R2H_CMD_FRAME_DONE_RET, 0);
|
||||||
aborted = 1;
|
aborted = 1;
|
||||||
}
|
}
|
||||||
spin_lock_irqsave(&dev->irqlock, flags);
|
|
||||||
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||||
|
spin_lock_irqsave(&dev->irqlock, flags);
|
||||||
s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
|
s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->dst_queue,
|
||||||
&ctx->vq_dst);
|
&ctx->vq_dst);
|
||||||
INIT_LIST_HEAD(&ctx->dst_queue);
|
INIT_LIST_HEAD(&ctx->dst_queue);
|
||||||
ctx->dst_queue_cnt = 0;
|
ctx->dst_queue_cnt = 0;
|
||||||
ctx->dpb_flush_flag = 1;
|
ctx->dpb_flush_flag = 1;
|
||||||
ctx->dec_dst_flag = 0;
|
ctx->dec_dst_flag = 0;
|
||||||
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
||||||
|
if (IS_MFCV6(dev) && (ctx->state == MFCINST_RUNNING)) {
|
||||||
|
ctx->state = MFCINST_FLUSH;
|
||||||
|
set_work_bit_irqsave(ctx);
|
||||||
|
s5p_mfc_clean_ctx_int_flags(ctx);
|
||||||
|
s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
|
||||||
|
if (s5p_mfc_wait_for_done_ctx(ctx,
|
||||||
|
S5P_MFC_R2H_CMD_DPB_FLUSH_RET, 0))
|
||||||
|
mfc_err("Err flushing buffers\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
|
||||||
|
spin_lock_irqsave(&dev->irqlock, flags);
|
||||||
s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
|
s5p_mfc_hw_call(dev->mfc_ops, cleanup_queue, &ctx->src_queue,
|
||||||
&ctx->vq_src);
|
&ctx->vq_src);
|
||||||
INIT_LIST_HEAD(&ctx->src_queue);
|
INIT_LIST_HEAD(&ctx->src_queue);
|
||||||
ctx->src_queue_cnt = 0;
|
ctx->src_queue_cnt = 0;
|
||||||
|
spin_unlock_irqrestore(&dev->irqlock, flags);
|
||||||
}
|
}
|
||||||
if (aborted)
|
if (aborted)
|
||||||
ctx->state = MFCINST_RUNNING;
|
ctx->state = MFCINST_RUNNING;
|
||||||
spin_unlock_irqrestore(&dev->irqlock, flags);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1253,12 +1253,14 @@ int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx)
|
|||||||
static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
|
static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
|
||||||
{
|
{
|
||||||
struct s5p_mfc_dev *dev = ctx->dev;
|
struct s5p_mfc_dev *dev = ctx->dev;
|
||||||
unsigned int dpb;
|
|
||||||
if (flush)
|
if (flush) {
|
||||||
dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (1 << 14);
|
dev->curr_ctx = ctx->num;
|
||||||
else
|
s5p_mfc_clean_ctx_int_flags(ctx);
|
||||||
dpb = READL(S5P_FIMV_SI_CH0_DPB_CONF_CTRL) & ~(1 << 14);
|
WRITEL(ctx->inst_no, S5P_FIMV_INSTANCE_ID_V6);
|
||||||
WRITEL(dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
|
s5p_mfc_hw_call(dev->mfc_cmds, cmd_host2risc, dev,
|
||||||
|
S5P_FIMV_H2R_CMD_FLUSH_V6, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decode a single frame */
|
/* Decode a single frame */
|
||||||
@@ -1650,6 +1652,9 @@ void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev)
|
|||||||
case MFCINST_HEAD_PARSED:
|
case MFCINST_HEAD_PARSED:
|
||||||
ret = s5p_mfc_run_init_dec_buffers(ctx);
|
ret = s5p_mfc_run_init_dec_buffers(ctx);
|
||||||
break;
|
break;
|
||||||
|
case MFCINST_FLUSH:
|
||||||
|
s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);
|
||||||
|
break;
|
||||||
case MFCINST_RES_CHANGE_INIT:
|
case MFCINST_RES_CHANGE_INIT:
|
||||||
s5p_mfc_run_dec_last_frames(ctx);
|
s5p_mfc_run_dec_last_frames(ctx);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user