summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/camss-8x16/camss-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/camss-8x16/camss-video.c')
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss-video.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/media/platform/qcom/camss-8x16/camss-video.c b/drivers/media/platform/qcom/camss-8x16/camss-video.c
index 8a45314c42c1..cf4219e871bd 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss-video.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss-video.c
@@ -150,6 +150,7 @@ static int video_find_format(u32 code, u32 pixelformat,
* @mbus: v4l2_mbus_framefmt format (input)
* @pix: v4l2_pix_format_mplane format (output)
* @f: a pointer to formats array element to be used for the conversion
+ * @alignment: bytesperline alignment value
*
* Fill the output pix structure with information from the input mbus format.
*
@@ -157,7 +158,8 @@ static int video_find_format(u32 code, u32 pixelformat,
*/
static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
struct v4l2_pix_format_mplane *pix,
- const struct camss_format_info *f)
+ const struct camss_format_info *f,
+ unsigned int alignment)
{
unsigned int i;
u32 bytesperline;
@@ -169,7 +171,7 @@ static int video_mbus_to_pix_mp(const struct v4l2_mbus_framefmt *mbus,
for (i = 0; i < pix->num_planes; i++) {
bytesperline = pix->width / f->hsub[i].numerator *
f->hsub[i].denominator * f->bpp[i] / 8;
- bytesperline = ALIGN(bytesperline, 8);
+ bytesperline = ALIGN(bytesperline, alignment);
pix->plane_fmt[i].bytesperline = bytesperline;
pix->plane_fmt[i].sizeimage = pix->height /
f->vsub[i].numerator * f->vsub[i].denominator *
@@ -223,7 +225,7 @@ static int video_get_subdev_format(struct camss_video *video,
format->type = video->type;
return video_mbus_to_pix_mp(&fmt.format, &format->fmt.pix_mp,
- &video->formats[ret]);
+ &video->formats[ret], video->bpl_alignment);
}
/* -----------------------------------------------------------------------------
@@ -323,7 +325,6 @@ static int video_check_format(struct camss_video *video)
struct v4l2_pix_format_mplane *pix = &video->active_fmt.fmt.pix_mp;
struct v4l2_format format;
struct v4l2_pix_format_mplane *sd_pix = &format.fmt.pix_mp;
- unsigned int i;
int ret;
sd_pix->pixelformat = pix->pixelformat;
@@ -338,13 +339,6 @@ static int video_check_format(struct camss_video *video)
pix->field != format.fmt.pix_mp.field)
return -EPIPE;
- for (i = 0; i < pix->num_planes; i++)
- if (pix->plane_fmt[i].bytesperline !=
- sd_pix->plane_fmt[i].bytesperline ||
- pix->plane_fmt[i].sizeimage !=
- sd_pix->plane_fmt[i].sizeimage)
- return -EINVAL;
-
return 0;
}
@@ -498,12 +492,25 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f)
{
struct v4l2_pix_format_mplane *pix_mp;
const struct camss_format_info *fi;
+ struct v4l2_plane_pix_format *p;
+ u32 bytesperline[3] = { 0 };
+ u32 sizeimage[3] = { 0 };
u32 width, height;
- u32 bpl;
+ u32 bpl, lines;
int i, j;
pix_mp = &f->fmt.pix_mp;
+ if (video->line_based)
+ for (i = 0; i < pix_mp->num_planes && i < 3; i++) {
+ p = &pix_mp->plane_fmt[i];
+ bytesperline[i] = clamp_t(u32, p->bytesperline,
+ 1, 65528);
+ sizeimage[i] = clamp_t(u32, p->sizeimage,
+ bytesperline[i],
+ bytesperline[i] * 4096);
+ }
+
for (j = 0; j < video->nformats; j++)
if (pix_mp->pixelformat == video->formats[j].pixelformat)
break;
@@ -524,7 +531,7 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f)
for (i = 0; i < pix_mp->num_planes; i++) {
bpl = pix_mp->width / fi->hsub[i].numerator *
fi->hsub[i].denominator * fi->bpp[i] / 8;
- bpl = ALIGN(bpl, 8);
+ bpl = ALIGN(bpl, video->bpl_alignment);
pix_mp->plane_fmt[i].bytesperline = bpl;
pix_mp->plane_fmt[i].sizeimage = pix_mp->height /
fi->vsub[i].numerator * fi->vsub[i].denominator * bpl;
@@ -538,6 +545,26 @@ static int __video_try_fmt(struct camss_video *video, struct v4l2_format *f)
pix_mp->colorspace, pix_mp->ycbcr_enc);
pix_mp->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix_mp->colorspace);
+ if (video->line_based)
+ for (i = 0; i < pix_mp->num_planes; i++) {
+ p = &pix_mp->plane_fmt[i];
+ p->bytesperline = clamp_t(u32, p->bytesperline,
+ 1, 65528);
+ p->sizeimage = clamp_t(u32, p->sizeimage,
+ p->bytesperline,
+ p->bytesperline * 4096);
+ lines = p->sizeimage / p->bytesperline;
+
+ if (p->bytesperline < bytesperline[i])
+ p->bytesperline = ALIGN(bytesperline[i], 8);
+
+ if (p->sizeimage < p->bytesperline * lines)
+ p->sizeimage = p->bytesperline * lines;
+
+ if (p->sizeimage < sizeimage[i])
+ p->sizeimage = sizeimage[i];
+ }
+
return 0;
}