Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 818cd91a authored by Pawel Osciak's avatar Pawel Osciak Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-mfc: Extract open/close MFC instance commands



This is in preparation for a new flow to fix issues with streamon, which
should not be allocating buffer memory.

Signed-off-by: default avatarPawel Osciak <posciak@chromium.org>
Signed-off-by: default avatarArun Kumar K <arun.kk@samsung.com>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 38beac65
Loading
Loading
Loading
Loading
+1 −18
Original line number Diff line number Diff line
@@ -877,24 +877,7 @@ static int s5p_mfc_release(struct file *file)
	 * return instance and free resources */
	if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
		mfc_debug(2, "Has to free instance\n");
		ctx->state = MFCINST_RETURN_INST;
		set_work_bit_irqsave(ctx);
		s5p_mfc_clean_ctx_int_flags(ctx);
		s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
		/* Wait until instance is returned or timeout occurred */
		if (s5p_mfc_wait_for_done_ctx
		    (ctx, S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
			s5p_mfc_clock_off();
			mfc_err("Err returning instance\n");
		}
		mfc_debug(2, "After free instance\n");
		/* Free resources */
		s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
		s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
		if (ctx->type == MFCINST_DECODER)
			s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer,
					ctx);

		s5p_mfc_close_mfc_inst(dev, ctx);
		ctx->inst_no = MFC_NO_INSTANCE_SET;
	}
	/* hardware locking scheme */
+61 −0
Original line number Diff line number Diff line
@@ -400,3 +400,64 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
	return 0;
}

int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
{
	int ret = 0;

	ret = s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
	if (ret) {
		mfc_err("Failed allocating instance buffer\n");
		goto err;
	}

	if (ctx->type == MFCINST_DECODER) {
		ret = s5p_mfc_hw_call(dev->mfc_ops,
					alloc_dec_temp_buffers, ctx);
		if (ret) {
			mfc_err("Failed allocating temporary buffers\n");
			goto err_free_inst_buf;
		}
	}

	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_OPEN_INSTANCE_RET, 0)) {
		/* Error or timeout */
		mfc_err("Error getting instance from hardware\n");
		ret = -EIO;
		goto err_free_desc_buf;
	}

	mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
	return ret;

err_free_desc_buf:
	if (ctx->type == MFCINST_DECODER)
		s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx);
err_free_inst_buf:
	s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
err:
	return ret;
}

void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
{
	ctx->state = MFCINST_RETURN_INST;
	set_work_bit_irqsave(ctx);
	s5p_mfc_clean_ctx_int_flags(ctx);
	s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
	/* Wait until instance is returned or timeout occurred */
	if (s5p_mfc_wait_for_done_ctx(ctx,
				S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
		mfc_err("Err returning instance\n");

	/* Free resources */
	s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
	s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer, ctx);
	if (ctx->type == MFCINST_DECODER)
		s5p_mfc_hw_call(dev->mfc_ops, release_dec_desc_buffer, ctx);

	ctx->state = MFCINST_FREE;
}
+3 −0
Original line number Diff line number Diff line
@@ -28,4 +28,7 @@ int s5p_mfc_wakeup(struct s5p_mfc_dev *dev);

int s5p_mfc_reset(struct s5p_mfc_dev *dev);

int s5p_mfc_open_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx);
void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx);

#endif /* S5P_MFC_CTRL_H */
+6 −22
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <media/v4l2-event.h>
#include <media/videobuf2-core.h>
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_dec.h"
#include "s5p_mfc_intr.h"
@@ -674,36 +675,19 @@ static int vidioc_streamon(struct file *file, void *priv,

	mfc_debug_enter();
	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {

		if (ctx->state == MFCINST_INIT) {
			ctx->dst_bufs_cnt = 0;
			ctx->src_bufs_cnt = 0;
			ctx->capture_state = QUEUE_FREE;
			ctx->output_state = QUEUE_FREE;
			s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer,
					ctx);
			s5p_mfc_hw_call(dev->mfc_ops, alloc_dec_temp_buffers,
					ctx);
			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_OPEN_INSTANCE_RET, 0)) {
				/* Error or timeout */
				mfc_err("Error getting instance from hardware\n");
				s5p_mfc_hw_call(dev->mfc_ops,
						release_instance_buffer, ctx);
				s5p_mfc_hw_call(dev->mfc_ops,
						release_dec_desc_buffer, ctx);
				return -EIO;
			}
			mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
			ret = s5p_mfc_open_mfc_inst(dev, ctx);
			if (ret)
				return ret;
		}
		ret = vb2_streamon(&ctx->vq_src, type);
		}
	else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
		ret = vb2_streamon(&ctx->vq_dst, type);
	}
	mfc_debug_leave();
	return ret;
}
+3 −15
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <media/v4l2-ctrls.h>
#include <media/videobuf2-core.h>
#include "s5p_mfc_common.h"
#include "s5p_mfc_ctrl.h"
#include "s5p_mfc_debug.h"
#include "s5p_mfc_enc.h"
#include "s5p_mfc_intr.h"
@@ -1106,20 +1107,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
		pix_fmt_mp->plane_fmt[0].bytesperline = 0;
		ctx->dst_bufs_cnt = 0;
		ctx->capture_state = QUEUE_FREE;
		s5p_mfc_hw_call(dev->mfc_ops, alloc_instance_buffer, ctx);
		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_OPEN_INSTANCE_RET, 1)) {
				/* Error or timeout */
			mfc_err("Error getting instance from hardware\n");
			s5p_mfc_hw_call(dev->mfc_ops, release_instance_buffer,
					ctx);
			ret = -EIO;
			goto out;
		}
		mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
		ret = s5p_mfc_open_mfc_inst(dev, ctx);
	} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		/* src_fmt is validated by call to vidioc_try_fmt */
		ctx->src_fmt = find_format(f, MFC_FMT_RAW);
@@ -1140,7 +1128,7 @@ static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
		ctx->output_state = QUEUE_FREE;
	} else {
		mfc_err("invalid buf type\n");
		return -EINVAL;
		ret = -EINVAL;
	}
out:
	mfc_debug_leave();