summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2023-06-01 15:58:57 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2023-06-09 15:41:11 +0100
commit0f417dc1b7330aae06f155ea505899fa74b2eabe (patch)
tree4223905a1d89c392933daa32b7348f39d3a0f0a8
parent72f0ba79a063ec2b21d5874e41c6d82193100515 (diff)
downloadlinux-stable-0f417dc1b7330aae06f155ea505899fa74b2eabe.tar.gz
linux-stable-0f417dc1b7330aae06f155ea505899fa74b2eabe.tar.bz2
linux-stable-0f417dc1b7330aae06f155ea505899fa74b2eabe.zip
media: atomisp: Make atomisp_enum_framesizes_crop() check resolution fits with padding
Now that atomisp_get_padding() takes minimum padding requirements on BYT/ISP2400 into account, it is possible for a resolution which fits in the active area of the sensor to not fit in the native area once padding is added. For example on the ov2680 which has a native resolution of 1616x1216 the max active resolution of 1600x1200 leaves 16x16 for padding which meets the worst-case minimum padding requirement of 14x14 on BYT. But after binning we are left with an native area of 808x608 and an active area of 800x600. This leaves 8x8 for padding which is not enough. So on BYT 800x600 is not a valid resolution (it could be made by lots of cropping without binning but then the remaining field of view is no good). Modify atomisp_enum_framesizes_crop() to check the resolution + padding fits in the native rectangle, removing 800x600 from the list of valid modes on BYT. Link: https://lore.kernel.org/r/20230601145858.59652-3-hdegoede@redhat.com Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.c5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_cmd.h4
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp_ioctl.c18
3 files changed, 19 insertions, 8 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 5c984edfb3fc..68550cd49a83 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -3691,9 +3691,8 @@ static void atomisp_fill_pix_format(struct v4l2_pix_format *f,
}
/* Get sensor padding values for the non padded width x height resolution */
-static void atomisp_get_padding(struct atomisp_device *isp,
- u32 width, u32 height,
- u32 *padding_w, u32 *padding_h)
+void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height,
+ u32 *padding_w, u32 *padding_h)
{
struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr];
struct v4l2_rect native_rect = input->native_rect;
diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
index c9a587b34e70..8305161d2062 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h
@@ -250,6 +250,10 @@ int atomisp_makeup_css_parameters(struct atomisp_sub_device *asd,
int atomisp_compare_grid(struct atomisp_sub_device *asd,
struct atomisp_grid_info *atomgrid);
+/* Get sensor padding values for the non padded width x height resolution */
+void atomisp_get_padding(struct atomisp_device *isp, u32 width, u32 height,
+ u32 *padding_w, u32 *padding_h);
+
/* This function looks up the closest available resolution. */
int atomisp_try_fmt(struct atomisp_device *isp, struct v4l2_pix_format *f,
const struct atomisp_format_bridge **fmt_ret,
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 279493af6e0d..d2174156573a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -703,7 +703,8 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
*/
static int atomisp_enum_framesizes_crop_inner(struct atomisp_device *isp,
struct v4l2_frmsizeenum *fsize,
- struct v4l2_rect *active,
+ const struct v4l2_rect *active,
+ const struct v4l2_rect *native,
int *valid_sizes)
{
static const struct v4l2_frmsize_discrete frame_sizes[] = {
@@ -716,11 +717,15 @@ static int atomisp_enum_framesizes_crop_inner(struct atomisp_device *isp,
{ 800, 600 },
{ 640, 480 },
};
+ u32 padding_w, padding_h;
int i;
for (i = 0; i < ARRAY_SIZE(frame_sizes); i++) {
- if (frame_sizes[i].width > active->width ||
- frame_sizes[i].height > active->height)
+ atomisp_get_padding(isp, frame_sizes[i].width, frame_sizes[i].height,
+ &padding_w, &padding_h);
+
+ if ((frame_sizes[i].width + padding_w) > native->width ||
+ (frame_sizes[i].height + padding_h) > native->height)
continue;
/*
@@ -748,9 +753,10 @@ static int atomisp_enum_framesizes_crop(struct atomisp_device *isp,
{
struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr];
struct v4l2_rect active = input->active_rect;
+ struct v4l2_rect native = input->native_rect;
int ret, valid_sizes = 0;
- ret = atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &valid_sizes);
+ ret = atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &native, &valid_sizes);
if (ret == 0)
return 0;
@@ -759,8 +765,10 @@ static int atomisp_enum_framesizes_crop(struct atomisp_device *isp,
active.width /= 2;
active.height /= 2;
+ native.width /= 2;
+ native.height /= 2;
- return atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &valid_sizes);
+ return atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &native, &valid_sizes);
}
static int atomisp_enum_framesizes(struct file *file, void *priv,