[media] s5p-fimc: Set default image format at device open()
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Wed, 30 Jan 2013 12:54:06 +0000 (09:54 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 5 Feb 2013 19:52:41 +0000 (17:52 -0200)
Make sure a valid image format is initially set on both the CAPTURE
and the OUTPUT buffer queue.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/platform/s5p-fimc/fimc-core.c
drivers/media/platform/s5p-fimc/fimc-core.h
drivers/media/platform/s5p-fimc/fimc-m2m.c

index a9625414ea95a536db8650502b8b5f0d32428241..29f7bb71c7e18ed3bbd46361775414aca6f9093b 100644 (file)
@@ -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)
index cf760c364099c48b970b057d692f2ef2be2cf4e1..412d50708f757a7af7678865ee272e288dd45c4d 100644 (file)
@@ -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,
index 1eabd7e74849312026a45651065c092302928a5e..f3d535cdd87fe66e8eddffc2d8fad79649ff2c2b 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * 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,
-                                     get_m2m_fmt_flags(f->type), 0);
-       if (!frame->fmt)
+       fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL,
+                              get_m2m_fmt_flags(f->type), 0);
+       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,20 +564,18 @@ 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,
-                                       ctx->d_frame.height, ctx->rotation);
-               } else {
-                       ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
-                                       ctx->s_frame.height, cr.c.width,
-                                       cr.c.height, ctx->rotation);
-               }
-               if (ret) {
-                       v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
-                       return -EINVAL;
-               }
+       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,
+                               ctx->d_frame.height, ctx->rotation);
+       } else {
+               ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
+                               ctx->s_frame.height, cr.c.width,
+                               cr.c.height, ctx->rotation);
+       }
+       if (ret) {
+               v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
+               return -EINVAL;
        }
 
        f->offs_h = cr.c.left;
@@ -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: