]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/media/platform/s5p-mfc/s5p_mfc.c
Merge remote-tracking branch 'v4l-dvb/master'
[karo-tx-linux.git] / drivers / media / platform / s5p-mfc / s5p_mfc.c
index 8de61dc1e142dd53d0638f65121e06a64b82800f..3ffe2ecfd5efe37649750c64636c91c042f57a47 100644 (file)
@@ -22,7 +22,7 @@
 #include <media/v4l2-event.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
-#include <media/videobuf2-core.h>
+#include <media/videobuf2-v4l2.h>
 #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,22 +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->v4l2_buf.flags |= V4L2_BUF_FLAG_LAST;
+                       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);
        }
 }
 
@@ -235,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:
@@ -296,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;
                }
@@ -395,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;
@@ -407,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:
@@ -510,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;
@@ -551,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);
@@ -573,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);
@@ -592,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);
 
@@ -640,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);
@@ -685,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: