X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fmedia%2Fplatform%2Fs5p-mfc%2Fs5p_mfc.c;fp=kernel%2Fdrivers%2Fmedia%2Fplatform%2Fs5p-mfc%2Fs5p_mfc.c;h=3ffe2ecfd5efe37649750c64636c91c042f57a47;hb=e09b41010ba33a20a87472ee821fa407a5b8da36;hp=8333fbc2fe96c18c66f2e17c1949874001821ab3;hpb=f93b97fd65072de626c074dbe099a1fff05ce060;p=kvmfornfv.git diff --git a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c index 8333fbc2f..3ffe2ecfd 100644 --- a/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/kernel/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "s5p_mfc_common.h" #include "s5p_mfc_ctrl.h" #include "s5p_mfc_debug.h" @@ -181,13 +181,6 @@ unlock: mutex_unlock(&dev->mfc_mutex); } -static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev) -{ - mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT); - mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD); - mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID); -} - static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_buf *dst_buf; @@ -199,21 +192,23 @@ static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx) dst_buf = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); mfc_debug(2, "Cleaning up buffer: %d\n", - dst_buf->b->v4l2_buf.index); - vb2_set_plane_payload(dst_buf->b, 0, 0); - vb2_set_plane_payload(dst_buf->b, 1, 0); + dst_buf->b->vb2_buf.index); + vb2_set_plane_payload(&dst_buf->b->vb2_buf, 0, 0); + vb2_set_plane_payload(&dst_buf->b->vb2_buf, 1, 0); list_del(&dst_buf->list); + dst_buf->flags |= MFC_BUF_FLAG_EOS; ctx->dst_queue_cnt--; - dst_buf->b->v4l2_buf.sequence = (ctx->sequence++); + dst_buf->b->sequence = (ctx->sequence++); if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) == s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx)) - dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; + dst_buf->b->field = V4L2_FIELD_NONE; else - dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED; + dst_buf->b->field = V4L2_FIELD_INTERLACED; + dst_buf->b->flags |= V4L2_BUF_FLAG_LAST; - ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index); - vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE); + ctx->dec_dst_flag &= ~(1 << dst_buf->b->vb2_buf.index); + vb2_buffer_done(&dst_buf->b->vb2_buf, VB2_BUF_STATE_DONE); } } @@ -234,27 +229,28 @@ static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx) appropriate flags. */ src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); list_for_each_entry(dst_buf, &ctx->dst_queue, list) { - if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) { - dst_buf->b->v4l2_buf.timecode = - src_buf->b->v4l2_buf.timecode; - dst_buf->b->v4l2_buf.timestamp = - src_buf->b->v4l2_buf.timestamp; - dst_buf->b->v4l2_buf.flags &= + if (vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0) + == dec_y_addr) { + dst_buf->b->timecode = + src_buf->b->timecode; + dst_buf->b->timestamp = + src_buf->b->timestamp; + dst_buf->b->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; - dst_buf->b->v4l2_buf.flags |= - src_buf->b->v4l2_buf.flags + dst_buf->b->flags |= + src_buf->b->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; switch (frame_type) { case S5P_FIMV_DECODE_FRAME_I_FRAME: - dst_buf->b->v4l2_buf.flags |= + dst_buf->b->flags |= V4L2_BUF_FLAG_KEYFRAME; break; case S5P_FIMV_DECODE_FRAME_P_FRAME: - dst_buf->b->v4l2_buf.flags |= + dst_buf->b->flags |= V4L2_BUF_FLAG_PFRAME; break; case S5P_FIMV_DECODE_FRAME_B_FRAME: - dst_buf->b->v4l2_buf.flags |= + dst_buf->b->flags |= V4L2_BUF_FLAG_BFRAME; break; default: @@ -295,25 +291,28 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err) * check which videobuf does it correspond to */ list_for_each_entry(dst_buf, &ctx->dst_queue, list) { /* Check if this is the buffer we're looking for */ - if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dspl_y_addr) { + if (vb2_dma_contig_plane_dma_addr(&dst_buf->b->vb2_buf, 0) + == dspl_y_addr) { list_del(&dst_buf->list); ctx->dst_queue_cnt--; - dst_buf->b->v4l2_buf.sequence = ctx->sequence; + dst_buf->b->sequence = ctx->sequence; if (s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_top, ctx) == s5p_mfc_hw_call(dev->mfc_ops, get_pic_type_bot, ctx)) - dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE; + dst_buf->b->field = V4L2_FIELD_NONE; else - dst_buf->b->v4l2_buf.field = + dst_buf->b->field = V4L2_FIELD_INTERLACED; - vb2_set_plane_payload(dst_buf->b, 0, ctx->luma_size); - vb2_set_plane_payload(dst_buf->b, 1, ctx->chroma_size); - clear_bit(dst_buf->b->v4l2_buf.index, + vb2_set_plane_payload(&dst_buf->b->vb2_buf, 0, + ctx->luma_size); + vb2_set_plane_payload(&dst_buf->b->vb2_buf, 1, + ctx->chroma_size); + clear_bit(dst_buf->b->vb2_buf.index, &ctx->dec_dst_flag); - vb2_buffer_done(dst_buf->b, - err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); + vb2_buffer_done(&dst_buf->b->vb2_buf, err ? + VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); break; } @@ -394,7 +393,7 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && ctx->codec_mode != S5P_MFC_CODEC_VP8_DEC && ctx->consumed_stream + STUFF_BYTE < - src_buf->b->v4l2_planes[0].bytesused) { + src_buf->b->vb2_buf.planes[0].bytesused) { /* Run MFC again on the same buffer */ mfc_debug(2, "Running again the same buffer\n"); ctx->after_packed_pb = 1; @@ -406,9 +405,11 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, list_del(&src_buf->list); ctx->src_queue_cnt--; if (s5p_mfc_hw_call(dev->mfc_ops, err_dec, err) > 0) - vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&src_buf->b->vb2_buf, + VB2_BUF_STATE_ERROR); else - vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE); + vb2_buffer_done(&src_buf->b->vb2_buf, + VB2_BUF_STATE_DONE); } } leave_handle_frame: @@ -509,7 +510,7 @@ static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf, list); if (s5p_mfc_hw_call(dev->mfc_ops, get_consumed_stream, dev) < - src_buf->b->v4l2_planes[0].bytesused) + src_buf->b->vb2_buf.planes[0].bytesused) ctx->head_processed = 0; else ctx->head_processed = 1; @@ -550,7 +551,7 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, struct s5p_mfc_buf, list); list_del(&src_buf->list); ctx->src_queue_cnt--; - vb2_buffer_done(src_buf->b, + vb2_buffer_done(&src_buf->b->vb2_buf, VB2_BUF_STATE_DONE); } spin_unlock_irqrestore(&dev->irqlock, flags); @@ -572,17 +573,13 @@ static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx, } } -static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx, - unsigned int reason, unsigned int err) +static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; struct s5p_mfc_buf *mb_entry; mfc_debug(2, "Stream completed\n"); - s5p_mfc_clear_int_flags(dev); - ctx->int_type = reason; - ctx->int_err = err; ctx->state = MFCINST_FINISHED; spin_lock(&dev->irqlock); @@ -591,8 +588,8 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx, list); list_del(&mb_entry->list); ctx->dst_queue_cnt--; - vb2_set_plane_payload(mb_entry->b, 0, 0); - vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE); + vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, 0); + vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE); } spin_unlock(&dev->irqlock); @@ -639,6 +636,13 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) if (ctx->c_ops->post_frame_start) { if (ctx->c_ops->post_frame_start(ctx)) mfc_err("post_frame_start() failed\n"); + + if (ctx->state == MFCINST_FINISHING && + list_empty(&ctx->ref_queue)) { + s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); + s5p_mfc_handle_stream_complete(ctx); + break; + } s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); wake_up_ctx(ctx, reason, err); WARN_ON(test_and_clear_bit(0, &dev->hw_lock) == 0); @@ -684,7 +688,10 @@ static irqreturn_t s5p_mfc_irq(int irq, void *priv) break; case S5P_MFC_R2H_CMD_COMPLETE_SEQ_RET: - s5p_mfc_handle_stream_complete(ctx, reason, err); + s5p_mfc_hw_call_void(dev->mfc_ops, clear_int_flags, dev); + ctx->int_type = reason; + ctx->int_err = err; + s5p_mfc_handle_stream_complete(ctx); break; case S5P_MFC_R2H_CMD_DPB_FLUSH_RET: @@ -1337,8 +1344,6 @@ static int s5p_mfc_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev); - if (!m_dev->alloc_ctx) - return 0; atomic_set(&m_dev->pm.power, 1); return 0; } @@ -1463,7 +1468,7 @@ static struct s5p_mfc_variant mfc_drvdata_v8 = { .fw_name[0] = "s5p-mfc-v8.fw", }; -static struct platform_device_id mfc_driver_ids[] = { +static const struct platform_device_id mfc_driver_ids[] = { { .name = "s5p-mfc", .driver_data = (unsigned long)&mfc_drvdata_v5,