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

Commit 81619ce1 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab
Browse files

[media] s5p-fimc: Set default image format at device open()



Make sure a valid image format is initially set on both the CAPTURE
and the OUTPUT buffer queue.

Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 031f515b
Loading
Loading
Loading
Loading
+1 −19
Original line number Diff line number Diff line
@@ -525,7 +525,6 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
{
	struct fimc_dev *fimc = ctx->fimc_dev;
	const struct fimc_variant *variant = fimc->variant;
	unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
	int ret = 0;

	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
@@ -541,8 +540,7 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
		break;

	case V4L2_CID_ROTATE:
		if (fimc_capture_pending(fimc) ||
		    (ctx->state & flags) == flags) {
		if (fimc_capture_pending(fimc)) {
			ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
					ctx->s_frame.height, ctx->d_frame.width,
					ctx->d_frame.height, ctrl->val);
@@ -709,22 +707,6 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f)
	}
}

void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f)
{
	struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;

	frame->f_width  = pixm->plane_fmt[0].bytesperline;
	if (frame->fmt->colplanes == 1)
		frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0];
	frame->f_height	= pixm->height;
	frame->width    = pixm->width;
	frame->height   = pixm->height;
	frame->o_width  = pixm->width;
	frame->o_height = pixm->height;
	frame->offs_h   = 0;
	frame->offs_v   = 0;
}

/**
 * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
 * @fmt: fimc pixel format description (input)
+1 −4
Original line number Diff line number Diff line
@@ -112,9 +112,7 @@ enum fimc_color_fmt {

/* The hardware context state. */
#define	FIMC_PARAMS		(1 << 0)
#define	FIMC_SRC_FMT		(1 << 3)
#define	FIMC_DST_FMT		(1 << 4)
#define	FIMC_COMPOSE		(1 << 5)
#define	FIMC_COMPOSE		(1 << 1)
#define	FIMC_CTX_M2M		(1 << 16)
#define	FIMC_CTX_CAP		(1 << 17)
#define	FIMC_CTX_SHUT		(1 << 18)
@@ -654,7 +652,6 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
		      struct fimc_frame *frame, struct fimc_addr *paddr);
void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
void fimc_set_yuv_order(struct fimc_ctx *ctx);
void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);

int fimc_register_m2m_device(struct fimc_dev *fimc,
+73 −58
Original line number Diff line number Diff line
/*
 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
 *
 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
 * Sylwester Nawrocki <s.nawrocki@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
@@ -160,8 +160,7 @@ static void fimc_device_run(void *priv)
	fimc_hw_set_output_addr(fimc, &df->paddr, -1);

	fimc_activate_capture(ctx);
	ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
		       FIMC_SRC_FMT | FIMC_DST_FMT);
	ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP);
	fimc_hw_activate_input_dma(fimc, true);

dma_unlock:
@@ -309,8 +308,6 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
	if (!IS_M2M(f->type))
		return -EINVAL;

	dbg("w: %d, h: %d", pix->width, pix->height);

	fmt = fimc_find_format(&pix->pixelformat, NULL,
			       get_m2m_fmt_flags(f->type), 0);
	if (WARN(fmt == NULL, "Pixel format lookup failed"))
@@ -350,19 +347,39 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
				   struct v4l2_format *f)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return fimc_try_fmt_mplane(ctx, f);
}

static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt,
			       struct v4l2_pix_format_mplane *pixm)
{
	int i;

	for (i = 0; i < fmt->colplanes; i++) {
		frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline;
		frame->payload[i] = pixm->plane_fmt[i].sizeimage;
	}

	frame->f_width = pixm->width;
	frame->f_height	= pixm->height;
	frame->o_width = pixm->width;
	frame->o_height = pixm->height;
	frame->width = pixm->width;
	frame->height = pixm->height;
	frame->offs_h = 0;
	frame->offs_v = 0;
	frame->fmt = fmt;
}

static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
				 struct v4l2_format *f)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);
	struct fimc_dev *fimc = ctx->fimc_dev;
	struct fimc_fmt *fmt;
	struct vb2_queue *vq;
	struct fimc_frame *frame;
	struct v4l2_pix_format_mplane *pix;
	int i, ret = 0;
	int ret;

	ret = fimc_try_fmt_mplane(ctx, f);
	if (ret)
@@ -380,31 +397,16 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
	else
		frame = &ctx->d_frame;

	pix = &f->fmt.pix_mp;
	frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
	fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL,
			       get_m2m_fmt_flags(f->type), 0);
	if (!frame->fmt)
	if (!fmt)
		return -EINVAL;

	__set_frame_format(frame, fmt, &f->fmt.pix_mp);

	/* Update RGB Alpha control state and value range */
	fimc_alpha_ctrl_update(ctx);

	for (i = 0; i < frame->fmt->colplanes; i++) {
		frame->bytesperline[i] = pix->plane_fmt[i].bytesperline;
		frame->payload[i] = pix->plane_fmt[i].sizeimage;
	}

	fimc_fill_frame(frame, f);

	ctx->scaler.enabled = 1;

	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
	else
		fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);

	dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);

	return 0;
}

@@ -412,7 +414,6 @@ static int fimc_m2m_reqbufs(struct file *file, void *fh,
			    struct v4l2_requestbuffers *reqbufs)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
}

@@ -420,7 +421,6 @@ static int fimc_m2m_querybuf(struct file *file, void *fh,
			     struct v4l2_buffer *buf)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
}

@@ -428,7 +428,6 @@ static int fimc_m2m_qbuf(struct file *file, void *fh,
			 struct v4l2_buffer *buf)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
}

@@ -436,7 +435,6 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
			  struct v4l2_buffer *buf)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
}

@@ -444,7 +442,6 @@ static int fimc_m2m_expbuf(struct file *file, void *fh,
			    struct v4l2_exportbuffer *eb)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
}

@@ -453,15 +450,6 @@ static int fimc_m2m_streamon(struct file *file, void *fh,
			     enum v4l2_buf_type type)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	/* The source and target color format need to be set */
	if (V4L2_TYPE_IS_OUTPUT(type)) {
		if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
			return -EINVAL;
	} else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
		return -EINVAL;
	}

	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
}

@@ -469,7 +457,6 @@ static int fimc_m2m_streamoff(struct file *file, void *fh,
			    enum v4l2_buf_type type)
{
	struct fimc_ctx *ctx = fh_to_ctx(fh);

	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
}

@@ -577,7 +564,6 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *
		&ctx->s_frame : &ctx->d_frame;

	/* Check to see if scaling ratio is within supported range */
	if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
	if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		ret = fimc_check_scaler_ratio(ctx, cr.c.width,
				cr.c.height, ctx->d_frame.width,
@@ -591,7 +577,6 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *
		v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
		return -EINVAL;
	}
	}

	f->offs_h = cr.c.left;
	f->offs_v = cr.c.top;
@@ -653,6 +638,29 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
	return vb2_queue_init(dst_vq);
}

static int fimc_m2m_set_default_format(struct fimc_ctx *ctx)
{
	struct v4l2_pix_format_mplane pixm = {
		.pixelformat	= V4L2_PIX_FMT_RGB32,
		.width		= 800,
		.height		= 600,
		.plane_fmt[0]	= {
			.bytesperline = 800 * 4,
			.sizeimage = 800 * 4 * 600,
		},
	};
	struct fimc_fmt *fmt;

	fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0);
	if (!fmt)
		return -EINVAL;

	__set_frame_format(&ctx->s_frame, fmt, &pixm);
	__set_frame_format(&ctx->d_frame, fmt, &pixm);

	return 0;
}

static int fimc_m2m_open(struct file *file)
{
	struct fimc_dev *fimc = video_drvdata(file);
@@ -697,6 +705,7 @@ static int fimc_m2m_open(struct file *file)
	ctx->flags = 0;
	ctx->in_path = FIMC_IO_DMA;
	ctx->out_path = FIMC_IO_DMA;
	ctx->scaler.enabled = 1;

	ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
	if (IS_ERR(ctx->m2m_ctx)) {
@@ -707,9 +716,15 @@ static int fimc_m2m_open(struct file *file)
	if (fimc->m2m.refcnt++ == 0)
		set_bit(ST_M2M_RUN, &fimc->state);

	ret = fimc_m2m_set_default_format(ctx);
	if (ret < 0)
		goto error_m2m_ctx;

	mutex_unlock(&fimc->lock);
	return 0;

error_m2m_ctx:
	v4l2_m2m_ctx_release(ctx->m2m_ctx);
error_c:
	fimc_ctrls_delete(ctx);
error_fh: