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

[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
...@@ -525,7 +525,6 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) ...@@ -525,7 +525,6 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
{ {
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
const struct fimc_variant *variant = fimc->variant; const struct fimc_variant *variant = fimc->variant;
unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
int ret = 0; int ret = 0;
if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
...@@ -541,8 +540,7 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) ...@@ -541,8 +540,7 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
break; break;
case V4L2_CID_ROTATE: case V4L2_CID_ROTATE:
if (fimc_capture_pending(fimc) || if (fimc_capture_pending(fimc)) {
(ctx->state & flags) == flags) {
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ctx->s_frame.height, ctx->d_frame.width, ctx->s_frame.height, ctx->d_frame.width,
ctx->d_frame.height, ctrl->val); ctx->d_frame.height, ctrl->val);
...@@ -709,22 +707,6 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f) ...@@ -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 * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
* @fmt: fimc pixel format description (input) * @fmt: fimc pixel format description (input)
......
...@@ -112,9 +112,7 @@ enum fimc_color_fmt { ...@@ -112,9 +112,7 @@ enum fimc_color_fmt {
/* The hardware context state. */ /* The hardware context state. */
#define FIMC_PARAMS (1 << 0) #define FIMC_PARAMS (1 << 0)
#define FIMC_SRC_FMT (1 << 3) #define FIMC_COMPOSE (1 << 1)
#define FIMC_DST_FMT (1 << 4)
#define FIMC_COMPOSE (1 << 5)
#define FIMC_CTX_M2M (1 << 16) #define FIMC_CTX_M2M (1 << 16)
#define FIMC_CTX_CAP (1 << 17) #define FIMC_CTX_CAP (1 << 17)
#define FIMC_CTX_SHUT (1 << 18) #define FIMC_CTX_SHUT (1 << 18)
...@@ -654,7 +652,6 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, ...@@ -654,7 +652,6 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
struct fimc_frame *frame, struct fimc_addr *paddr); struct fimc_frame *frame, struct fimc_addr *paddr);
void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
void fimc_set_yuv_order(struct fimc_ctx *ctx); 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); void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
int fimc_register_m2m_device(struct fimc_dev *fimc, int fimc_register_m2m_device(struct fimc_dev *fimc,
......
/* /*
* Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
* *
* Copyright (C) 2012 Samsung Electronics Co., Ltd. * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
* Sylwester Nawrocki, <s.nawrocki@samsung.com> * Sylwester Nawrocki <s.nawrocki@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published * it under the terms of the GNU General Public License as published
...@@ -160,8 +160,7 @@ static void fimc_device_run(void *priv) ...@@ -160,8 +160,7 @@ static void fimc_device_run(void *priv)
fimc_hw_set_output_addr(fimc, &df->paddr, -1); fimc_hw_set_output_addr(fimc, &df->paddr, -1);
fimc_activate_capture(ctx); fimc_activate_capture(ctx);
ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP);
FIMC_SRC_FMT | FIMC_DST_FMT);
fimc_hw_activate_input_dma(fimc, true); fimc_hw_activate_input_dma(fimc, true);
dma_unlock: dma_unlock:
...@@ -309,8 +308,6 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) ...@@ -309,8 +308,6 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
if (!IS_M2M(f->type)) if (!IS_M2M(f->type))
return -EINVAL; return -EINVAL;
dbg("w: %d, h: %d", pix->width, pix->height);
fmt = fimc_find_format(&pix->pixelformat, NULL, fmt = fimc_find_format(&pix->pixelformat, NULL,
get_m2m_fmt_flags(f->type), 0); get_m2m_fmt_flags(f->type), 0);
if (WARN(fmt == NULL, "Pixel format lookup failed")) if (WARN(fmt == NULL, "Pixel format lookup failed"))
...@@ -350,19 +347,39 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh, ...@@ -350,19 +347,39 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return fimc_try_fmt_mplane(ctx, f); 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, static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
struct v4l2_format *f) struct v4l2_format *f)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_fmt *fmt;
struct vb2_queue *vq; struct vb2_queue *vq;
struct fimc_frame *frame; struct fimc_frame *frame;
struct v4l2_pix_format_mplane *pix; int ret;
int i, ret = 0;
ret = fimc_try_fmt_mplane(ctx, f); ret = fimc_try_fmt_mplane(ctx, f);
if (ret) if (ret)
...@@ -380,31 +397,16 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, ...@@ -380,31 +397,16 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
else else
frame = &ctx->d_frame; frame = &ctx->d_frame;
pix = &f->fmt.pix_mp; fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL,
frame->fmt = fimc_find_format(&pix->pixelformat, NULL, get_m2m_fmt_flags(f->type), 0);
get_m2m_fmt_flags(f->type), 0); if (!fmt)
if (!frame->fmt)
return -EINVAL; return -EINVAL;
__set_frame_format(frame, fmt, &f->fmt.pix_mp);
/* Update RGB Alpha control state and value range */ /* Update RGB Alpha control state and value range */
fimc_alpha_ctrl_update(ctx); 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; return 0;
} }
...@@ -412,7 +414,6 @@ static int fimc_m2m_reqbufs(struct file *file, void *fh, ...@@ -412,7 +414,6 @@ static int fimc_m2m_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *reqbufs) struct v4l2_requestbuffers *reqbufs)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
} }
...@@ -420,7 +421,6 @@ static int fimc_m2m_querybuf(struct file *file, void *fh, ...@@ -420,7 +421,6 @@ static int fimc_m2m_querybuf(struct file *file, void *fh,
struct v4l2_buffer *buf) struct v4l2_buffer *buf)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
} }
...@@ -428,7 +428,6 @@ static int fimc_m2m_qbuf(struct file *file, void *fh, ...@@ -428,7 +428,6 @@ static int fimc_m2m_qbuf(struct file *file, void *fh,
struct v4l2_buffer *buf) struct v4l2_buffer *buf)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
} }
...@@ -436,7 +435,6 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh, ...@@ -436,7 +435,6 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
struct v4l2_buffer *buf) struct v4l2_buffer *buf)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
} }
...@@ -444,7 +442,6 @@ static int fimc_m2m_expbuf(struct file *file, void *fh, ...@@ -444,7 +442,6 @@ static int fimc_m2m_expbuf(struct file *file, void *fh,
struct v4l2_exportbuffer *eb) struct v4l2_exportbuffer *eb)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
} }
...@@ -453,15 +450,6 @@ static int fimc_m2m_streamon(struct file *file, void *fh, ...@@ -453,15 +450,6 @@ static int fimc_m2m_streamon(struct file *file, void *fh,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); 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); return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
} }
...@@ -469,7 +457,6 @@ static int fimc_m2m_streamoff(struct file *file, void *fh, ...@@ -469,7 +457,6 @@ static int fimc_m2m_streamoff(struct file *file, void *fh,
enum v4l2_buf_type type) enum v4l2_buf_type type)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
} }
...@@ -577,20 +564,18 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop * ...@@ -577,20 +564,18 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *
&ctx->s_frame : &ctx->d_frame; &ctx->s_frame : &ctx->d_frame;
/* Check to see if scaling ratio is within supported range */ /* 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) {
if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { ret = fimc_check_scaler_ratio(ctx, cr.c.width,
ret = fimc_check_scaler_ratio(ctx, cr.c.width, cr.c.height, ctx->d_frame.width,
cr.c.height, ctx->d_frame.width, ctx->d_frame.height, ctx->rotation);
ctx->d_frame.height, ctx->rotation); } else {
} else { ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, ctx->s_frame.height, cr.c.width,
ctx->s_frame.height, cr.c.width, cr.c.height, ctx->rotation);
cr.c.height, ctx->rotation); }
} if (ret) {
if (ret) { v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); return -EINVAL;
return -EINVAL;
}
} }
f->offs_h = cr.c.left; f->offs_h = cr.c.left;
...@@ -653,6 +638,29 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, ...@@ -653,6 +638,29 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
return vb2_queue_init(dst_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) static int fimc_m2m_open(struct file *file)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
...@@ -697,6 +705,7 @@ static int fimc_m2m_open(struct file *file) ...@@ -697,6 +705,7 @@ static int fimc_m2m_open(struct file *file)
ctx->flags = 0; ctx->flags = 0;
ctx->in_path = FIMC_IO_DMA; ctx->in_path = FIMC_IO_DMA;
ctx->out_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); ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
if (IS_ERR(ctx->m2m_ctx)) { if (IS_ERR(ctx->m2m_ctx)) {
...@@ -707,9 +716,15 @@ static int fimc_m2m_open(struct file *file) ...@@ -707,9 +716,15 @@ static int fimc_m2m_open(struct file *file)
if (fimc->m2m.refcnt++ == 0) if (fimc->m2m.refcnt++ == 0)
set_bit(ST_M2M_RUN, &fimc->state); 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); mutex_unlock(&fimc->lock);
return 0; return 0;
error_m2m_ctx:
v4l2_m2m_ctx_release(ctx->m2m_ctx);
error_c: error_c:
fimc_ctrls_delete(ctx); fimc_ctrls_delete(ctx);
error_fh: error_fh:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment