Skip to content

Commit b1d2dc5

Browse files
Sylwester NawrockiMauro Carvalho Chehab
authored andcommitted
[media] exynos4-is: Fix format propagation on FIMC-LITE.n subdevs
FIMC-LITE subdevs have one sink pad and two source pads on which the image formats are always same. This patch implements missing format propagation from the sink pad to the source pads, to allow user space to negotiate TRY format on whole media pipeline involving FIMC-LITE.n subdevs. The subdev try_fmt helper is simplified. Signed-off-by: Sylwester Nawrocki <[email protected]> Signed-off-by: Jacek Anaszewski <[email protected]> Signed-off-by: Kyungmin Park <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 038f5c4 commit b1d2dc5

File tree

1 file changed

+59
-33
lines changed

1 file changed

+59
-33
lines changed

drivers/media/platform/exynos4-is/fimc-lite.c

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -560,37 +560,51 @@ static const struct v4l2_file_operations fimc_lite_fops = {
560560
* Format and crop negotiation helpers
561561
*/
562562

563-
static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
564-
u32 *width, u32 *height,
565-
u32 *code, u32 *fourcc, int pad)
563+
static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
564+
struct v4l2_subdev_fh *fh,
565+
struct v4l2_subdev_format *format)
566566
{
567567
struct flite_drvdata *dd = fimc->dd;
568-
const struct fimc_fmt *fmt;
569-
unsigned int flags = 0;
568+
struct v4l2_mbus_framefmt *mf = &format->format;
569+
const struct fimc_fmt *fmt = NULL;
570+
571+
if (format->pad == FLITE_SD_PAD_SINK) {
572+
v4l_bound_align_image(&mf->width, 8, dd->max_width,
573+
ffs(dd->out_width_align) - 1,
574+
&mf->height, 0, dd->max_height, 0, 0);
570575

571-
if (pad == FLITE_SD_PAD_SINK) {
572-
v4l_bound_align_image(width, 8, dd->max_width,
573-
ffs(dd->out_width_align) - 1,
574-
height, 0, dd->max_height, 0, 0);
576+
fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
577+
if (WARN_ON(!fmt))
578+
return NULL;
579+
580+
mf->code = fmt->mbus_code;
575581
} else {
576-
v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
577-
ffs(dd->out_width_align) - 1,
578-
height, 0, fimc->inp_frame.rect.height,
579-
0, 0);
580-
flags = fimc->inp_frame.fmt->flags;
581-
}
582+
struct flite_frame *sink = &fimc->inp_frame;
583+
struct v4l2_mbus_framefmt *sink_fmt;
584+
struct v4l2_rect *rect;
582585

583-
fmt = fimc_lite_find_format(fourcc, code, flags, 0);
584-
if (WARN_ON(!fmt))
585-
return NULL;
586+
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
587+
sink_fmt = v4l2_subdev_get_try_format(fh,
588+
FLITE_SD_PAD_SINK);
586589

587-
if (code)
588-
*code = fmt->mbus_code;
589-
if (fourcc)
590-
*fourcc = fmt->fourcc;
590+
mf->code = sink_fmt->code;
591+
592+
rect = v4l2_subdev_get_try_crop(fh,
593+
FLITE_SD_PAD_SINK);
594+
} else {
595+
mf->code = sink->fmt->mbus_code;
596+
rect = &sink->rect;
597+
}
598+
599+
/* Allow changing format only on sink pad */
600+
mf->width = rect->width;
601+
mf->height = rect->height;
602+
}
591603

592-
v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
593-
code ? *code : 0, *width, *height);
604+
mf->field = V4L2_FIELD_NONE;
605+
606+
v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
607+
mf->code, mf->colorspace, mf->width, mf->height);
594608

595609
return fmt;
596610
}
@@ -1035,6 +1049,15 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
10351049
return 0;
10361050
}
10371051

1052+
static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
1053+
struct v4l2_subdev_fh *fh, unsigned int pad)
1054+
{
1055+
if (pad != FLITE_SD_PAD_SINK)
1056+
pad = FLITE_SD_PAD_SOURCE_DMA;
1057+
1058+
return v4l2_subdev_get_try_format(fh, pad);
1059+
}
1060+
10381061
static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
10391062
struct v4l2_subdev_fh *fh,
10401063
struct v4l2_subdev_format *fmt)
@@ -1044,7 +1067,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
10441067
struct flite_frame *f = &fimc->inp_frame;
10451068

10461069
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1047-
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1070+
mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
10481071
fmt->format = *mf;
10491072
return 0;
10501073
}
@@ -1090,12 +1113,20 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
10901113
return -EBUSY;
10911114
}
10921115

1093-
ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
1094-
&mf->code, NULL, fmt->pad);
1116+
ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
10951117

10961118
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1097-
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1119+
struct v4l2_mbus_framefmt *src_fmt;
1120+
1121+
mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
10981122
*mf = fmt->format;
1123+
1124+
if (fmt->pad == FLITE_SD_PAD_SINK) {
1125+
unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
1126+
src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
1127+
*src_fmt = *mf;
1128+
}
1129+
10991130
mutex_unlock(&fimc->lock);
11001131
return 0;
11011132
}
@@ -1113,11 +1144,6 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
11131144
source->rect = sink->rect;
11141145
source->f_width = mf->width;
11151146
source->f_height = mf->height;
1116-
} else {
1117-
/* Allow changing format only on sink pad */
1118-
mf->code = sink->fmt->mbus_code;
1119-
mf->width = sink->rect.width;
1120-
mf->height = sink->rect.height;
11211147
}
11221148

11231149
mutex_unlock(&fimc->lock);

0 commit comments

Comments
 (0)