aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-01-30 07:54:06 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-05 14:52:41 -0500
commit81619ce1931a1d96e53b455ca2f35757f0c457a5 (patch)
tree2ec70dacd59aa087d9d8c13b2c22f8919959eb67 /drivers/media/platform
parent031f515b3d303eca80518ed9a71c79ed420b352a (diff)
[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: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.c20
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-core.h5
-rw-r--r--drivers/media/platform/s5p-fimc/fimc-m2m.c131
3 files changed, 75 insertions, 81 deletions
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.c b/drivers/media/platform/s5p-fimc/fimc-core.c
index a9625414ea95..29f7bb71c7e1 100644
--- a/drivers/media/platform/s5p-fimc/fimc-core.c
+++ b/drivers/media/platform/s5p-fimc/fimc-core.c
@@ -525,7 +525,6 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
525{ 525{
526 struct fimc_dev *fimc = ctx->fimc_dev; 526 struct fimc_dev *fimc = ctx->fimc_dev;
527 const struct fimc_variant *variant = fimc->variant; 527 const struct fimc_variant *variant = fimc->variant;
528 unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
529 int ret = 0; 528 int ret = 0;
530 529
531 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) 530 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 break; 540 break;
542 541
543 case V4L2_CID_ROTATE: 542 case V4L2_CID_ROTATE:
544 if (fimc_capture_pending(fimc) || 543 if (fimc_capture_pending(fimc)) {
545 (ctx->state & flags) == flags) {
546 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, 544 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
547 ctx->s_frame.height, ctx->d_frame.width, 545 ctx->s_frame.height, ctx->d_frame.width,
548 ctx->d_frame.height, ctrl->val); 546 ctx->d_frame.height, ctrl->val);
@@ -709,22 +707,6 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f)
709 } 707 }
710} 708}
711 709
712void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f)
713{
714 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
715
716 frame->f_width = pixm->plane_fmt[0].bytesperline;
717 if (frame->fmt->colplanes == 1)
718 frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0];
719 frame->f_height = pixm->height;
720 frame->width = pixm->width;
721 frame->height = pixm->height;
722 frame->o_width = pixm->width;
723 frame->o_height = pixm->height;
724 frame->offs_h = 0;
725 frame->offs_v = 0;
726}
727
728/** 710/**
729 * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane 711 * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
730 * @fmt: fimc pixel format description (input) 712 * @fmt: fimc pixel format description (input)
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h
index cf760c364099..412d50708f75 100644
--- a/drivers/media/platform/s5p-fimc/fimc-core.h
+++ b/drivers/media/platform/s5p-fimc/fimc-core.h
@@ -112,9 +112,7 @@ enum fimc_color_fmt {
112 112
113/* The hardware context state. */ 113/* The hardware context state. */
114#define FIMC_PARAMS (1 << 0) 114#define FIMC_PARAMS (1 << 0)
115#define FIMC_SRC_FMT (1 << 3) 115#define FIMC_COMPOSE (1 << 1)
116#define FIMC_DST_FMT (1 << 4)
117#define FIMC_COMPOSE (1 << 5)
118#define FIMC_CTX_M2M (1 << 16) 116#define FIMC_CTX_M2M (1 << 16)
119#define FIMC_CTX_CAP (1 << 17) 117#define FIMC_CTX_CAP (1 << 17)
120#define FIMC_CTX_SHUT (1 << 18) 118#define FIMC_CTX_SHUT (1 << 18)
@@ -654,7 +652,6 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
654 struct fimc_frame *frame, struct fimc_addr *paddr); 652 struct fimc_frame *frame, struct fimc_addr *paddr);
655void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); 653void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
656void fimc_set_yuv_order(struct fimc_ctx *ctx); 654void fimc_set_yuv_order(struct fimc_ctx *ctx);
657void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
658void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf); 655void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
659 656
660int fimc_register_m2m_device(struct fimc_dev *fimc, 657int fimc_register_m2m_device(struct fimc_dev *fimc,
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 1eabd7e74849..f3d535cdd87f 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver 2 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
3 * 3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@samsung.com> 5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published 8 * it under the terms of the GNU General Public License as published
@@ -160,8 +160,7 @@ static void fimc_device_run(void *priv)
160 fimc_hw_set_output_addr(fimc, &df->paddr, -1); 160 fimc_hw_set_output_addr(fimc, &df->paddr, -1);
161 161
162 fimc_activate_capture(ctx); 162 fimc_activate_capture(ctx);
163 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP | 163 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP);
164 FIMC_SRC_FMT | FIMC_DST_FMT);
165 fimc_hw_activate_input_dma(fimc, true); 164 fimc_hw_activate_input_dma(fimc, true);
166 165
167dma_unlock: 166dma_unlock:
@@ -309,8 +308,6 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
309 if (!IS_M2M(f->type)) 308 if (!IS_M2M(f->type))
310 return -EINVAL; 309 return -EINVAL;
311 310
312 dbg("w: %d, h: %d", pix->width, pix->height);
313
314 fmt = fimc_find_format(&pix->pixelformat, NULL, 311 fmt = fimc_find_format(&pix->pixelformat, NULL,
315 get_m2m_fmt_flags(f->type), 0); 312 get_m2m_fmt_flags(f->type), 0);
316 if (WARN(fmt == NULL, "Pixel format lookup failed")) 313 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 struct v4l2_format *f) 347 struct v4l2_format *f)
351{ 348{
352 struct fimc_ctx *ctx = fh_to_ctx(fh); 349 struct fimc_ctx *ctx = fh_to_ctx(fh);
353
354 return fimc_try_fmt_mplane(ctx, f); 350 return fimc_try_fmt_mplane(ctx, f);
355} 351}
356 352
353static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt,
354 struct v4l2_pix_format_mplane *pixm)
355{
356 int i;
357
358 for (i = 0; i < fmt->colplanes; i++) {
359 frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline;
360 frame->payload[i] = pixm->plane_fmt[i].sizeimage;
361 }
362
363 frame->f_width = pixm->width;
364 frame->f_height = pixm->height;
365 frame->o_width = pixm->width;
366 frame->o_height = pixm->height;
367 frame->width = pixm->width;
368 frame->height = pixm->height;
369 frame->offs_h = 0;
370 frame->offs_v = 0;
371 frame->fmt = fmt;
372}
373
357static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, 374static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
358 struct v4l2_format *f) 375 struct v4l2_format *f)
359{ 376{
360 struct fimc_ctx *ctx = fh_to_ctx(fh); 377 struct fimc_ctx *ctx = fh_to_ctx(fh);
361 struct fimc_dev *fimc = ctx->fimc_dev; 378 struct fimc_dev *fimc = ctx->fimc_dev;
379 struct fimc_fmt *fmt;
362 struct vb2_queue *vq; 380 struct vb2_queue *vq;
363 struct fimc_frame *frame; 381 struct fimc_frame *frame;
364 struct v4l2_pix_format_mplane *pix; 382 int ret;
365 int i, ret = 0;
366 383
367 ret = fimc_try_fmt_mplane(ctx, f); 384 ret = fimc_try_fmt_mplane(ctx, f);
368 if (ret) 385 if (ret)
@@ -380,31 +397,16 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
380 else 397 else
381 frame = &ctx->d_frame; 398 frame = &ctx->d_frame;
382 399
383 pix = &f->fmt.pix_mp; 400 fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL,
384 frame->fmt = fimc_find_format(&pix->pixelformat, NULL, 401 get_m2m_fmt_flags(f->type), 0);
385 get_m2m_fmt_flags(f->type), 0); 402 if (!fmt)
386 if (!frame->fmt)
387 return -EINVAL; 403 return -EINVAL;
388 404
405 __set_frame_format(frame, fmt, &f->fmt.pix_mp);
406
389 /* Update RGB Alpha control state and value range */ 407 /* Update RGB Alpha control state and value range */
390 fimc_alpha_ctrl_update(ctx); 408 fimc_alpha_ctrl_update(ctx);
391 409
392 for (i = 0; i < frame->fmt->colplanes; i++) {
393 frame->bytesperline[i] = pix->plane_fmt[i].bytesperline;
394 frame->payload[i] = pix->plane_fmt[i].sizeimage;
395 }
396
397 fimc_fill_frame(frame, f);
398
399 ctx->scaler.enabled = 1;
400
401 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
402 fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
403 else
404 fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
405
406 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
407
408 return 0; 410 return 0;
409} 411}
410 412
@@ -412,7 +414,6 @@ static int fimc_m2m_reqbufs(struct file *file, void *fh,
412 struct v4l2_requestbuffers *reqbufs) 414 struct v4l2_requestbuffers *reqbufs)
413{ 415{
414 struct fimc_ctx *ctx = fh_to_ctx(fh); 416 struct fimc_ctx *ctx = fh_to_ctx(fh);
415
416 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); 417 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
417} 418}
418 419
@@ -420,7 +421,6 @@ static int fimc_m2m_querybuf(struct file *file, void *fh,
420 struct v4l2_buffer *buf) 421 struct v4l2_buffer *buf)
421{ 422{
422 struct fimc_ctx *ctx = fh_to_ctx(fh); 423 struct fimc_ctx *ctx = fh_to_ctx(fh);
423
424 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); 424 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
425} 425}
426 426
@@ -428,7 +428,6 @@ static int fimc_m2m_qbuf(struct file *file, void *fh,
428 struct v4l2_buffer *buf) 428 struct v4l2_buffer *buf)
429{ 429{
430 struct fimc_ctx *ctx = fh_to_ctx(fh); 430 struct fimc_ctx *ctx = fh_to_ctx(fh);
431
432 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); 431 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
433} 432}
434 433
@@ -436,7 +435,6 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
436 struct v4l2_buffer *buf) 435 struct v4l2_buffer *buf)
437{ 436{
438 struct fimc_ctx *ctx = fh_to_ctx(fh); 437 struct fimc_ctx *ctx = fh_to_ctx(fh);
439
440 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); 438 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
441} 439}
442 440
@@ -444,7 +442,6 @@ static int fimc_m2m_expbuf(struct file *file, void *fh,
444 struct v4l2_exportbuffer *eb) 442 struct v4l2_exportbuffer *eb)
445{ 443{
446 struct fimc_ctx *ctx = fh_to_ctx(fh); 444 struct fimc_ctx *ctx = fh_to_ctx(fh);
447
448 return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); 445 return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
449} 446}
450 447
@@ -453,15 +450,6 @@ static int fimc_m2m_streamon(struct file *file, void *fh,
453 enum v4l2_buf_type type) 450 enum v4l2_buf_type type)
454{ 451{
455 struct fimc_ctx *ctx = fh_to_ctx(fh); 452 struct fimc_ctx *ctx = fh_to_ctx(fh);
456
457 /* The source and target color format need to be set */
458 if (V4L2_TYPE_IS_OUTPUT(type)) {
459 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
460 return -EINVAL;
461 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
462 return -EINVAL;
463 }
464
465 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 453 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
466} 454}
467 455
@@ -469,7 +457,6 @@ static int fimc_m2m_streamoff(struct file *file, void *fh,
469 enum v4l2_buf_type type) 457 enum v4l2_buf_type type)
470{ 458{
471 struct fimc_ctx *ctx = fh_to_ctx(fh); 459 struct fimc_ctx *ctx = fh_to_ctx(fh);
472
473 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); 460 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
474} 461}
475 462
@@ -577,20 +564,18 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *
577 &ctx->s_frame : &ctx->d_frame; 564 &ctx->s_frame : &ctx->d_frame;
578 565
579 /* Check to see if scaling ratio is within supported range */ 566 /* Check to see if scaling ratio is within supported range */
580 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) { 567 if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
581 if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 568 ret = fimc_check_scaler_ratio(ctx, cr.c.width,
582 ret = fimc_check_scaler_ratio(ctx, cr.c.width, 569 cr.c.height, ctx->d_frame.width,
583 cr.c.height, ctx->d_frame.width, 570 ctx->d_frame.height, ctx->rotation);
584 ctx->d_frame.height, ctx->rotation); 571 } else {
585 } else { 572 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
586 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, 573 ctx->s_frame.height, cr.c.width,
587 ctx->s_frame.height, cr.c.width, 574 cr.c.height, ctx->rotation);
588 cr.c.height, ctx->rotation); 575 }
589 } 576 if (ret) {
590 if (ret) { 577 v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
591 v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); 578 return -EINVAL;
592 return -EINVAL;
593 }
594 } 579 }
595 580
596 f->offs_h = cr.c.left; 581 f->offs_h = cr.c.left;
@@ -653,6 +638,29 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
653 return vb2_queue_init(dst_vq); 638 return vb2_queue_init(dst_vq);
654} 639}
655 640
641static int fimc_m2m_set_default_format(struct fimc_ctx *ctx)
642{
643 struct v4l2_pix_format_mplane pixm = {
644 .pixelformat = V4L2_PIX_FMT_RGB32,
645 .width = 800,
646 .height = 600,
647 .plane_fmt[0] = {
648 .bytesperline = 800 * 4,
649 .sizeimage = 800 * 4 * 600,
650 },
651 };
652 struct fimc_fmt *fmt;
653
654 fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0);
655 if (!fmt)
656 return -EINVAL;
657
658 __set_frame_format(&ctx->s_frame, fmt, &pixm);
659 __set_frame_format(&ctx->d_frame, fmt, &pixm);
660
661 return 0;
662}
663
656static int fimc_m2m_open(struct file *file) 664static int fimc_m2m_open(struct file *file)
657{ 665{
658 struct fimc_dev *fimc = video_drvdata(file); 666 struct fimc_dev *fimc = video_drvdata(file);
@@ -697,6 +705,7 @@ static int fimc_m2m_open(struct file *file)
697 ctx->flags = 0; 705 ctx->flags = 0;
698 ctx->in_path = FIMC_IO_DMA; 706 ctx->in_path = FIMC_IO_DMA;
699 ctx->out_path = FIMC_IO_DMA; 707 ctx->out_path = FIMC_IO_DMA;
708 ctx->scaler.enabled = 1;
700 709
701 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); 710 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
702 if (IS_ERR(ctx->m2m_ctx)) { 711 if (IS_ERR(ctx->m2m_ctx)) {
@@ -707,9 +716,15 @@ static int fimc_m2m_open(struct file *file)
707 if (fimc->m2m.refcnt++ == 0) 716 if (fimc->m2m.refcnt++ == 0)
708 set_bit(ST_M2M_RUN, &fimc->state); 717 set_bit(ST_M2M_RUN, &fimc->state);
709 718
719 ret = fimc_m2m_set_default_format(ctx);
720 if (ret < 0)
721 goto error_m2m_ctx;
722
710 mutex_unlock(&fimc->lock); 723 mutex_unlock(&fimc->lock);
711 return 0; 724 return 0;
712 725
726error_m2m_ctx:
727 v4l2_m2m_ctx_release(ctx->m2m_ctx);
713error_c: 728error_c:
714 fimc_ctrls_delete(ctx); 729 fimc_ctrls_delete(ctx);
715error_fh: 730error_fh: