aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch')
-rw-r--r--target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch387
1 files changed, 0 insertions, 387 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch b/target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch
deleted file mode 100644
index 3a638710f7..0000000000
--- a/target/linux/bcm27xx/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch
+++ /dev/null
@@ -1,387 +0,0 @@
-From 2c51b8e533a8b43bde18072c9dbbd0fc5084bbe7 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.org>
-Date: Wed, 2 Oct 2019 17:40:38 +0100
-Subject: [PATCH] media: bcm2835-unicam: Rework to not cache the list
- of active fmts
-
-Some sensors will change Bayer order based on H & V flips,
-therefore collecting the list of formats at async_bound has
-problems.
-
-Enumerate the formats from the sensor every time.
-
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
----
- .../media/platform/bcm2835/bcm2835-unicam.c | 246 ++++++++++--------
- 1 file changed, 136 insertions(+), 110 deletions(-)
-
---- a/drivers/media/platform/bcm2835/bcm2835-unicam.c
-+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
-@@ -363,8 +363,6 @@ struct unicam_device {
- /* Used to store current mbus frame format */
- struct v4l2_mbus_framefmt m_fmt;
-
-- struct unicam_fmt active_fmts[MAX_POSSIBLE_PIX_FMTS];
-- int num_active_fmt;
- unsigned int virtual_channel;
- enum v4l2_mbus_type bus_type;
- /*
-@@ -455,48 +453,30 @@ static int find_mbus_depth_by_code(u32 c
- return 0;
- }
-
--static const struct unicam_fmt *find_format_by_code(struct unicam_device *dev,
-- u32 code)
-+static const struct unicam_fmt *find_format_by_code(u32 code)
- {
-- const struct unicam_fmt *fmt;
- unsigned int k;
-
-- for (k = 0; k < dev->num_active_fmt; k++) {
-- fmt = &dev->active_fmts[k];
-- if (fmt->code == code)
-- return fmt;
-+ for (k = 0; k < ARRAY_SIZE(formats); k++) {
-+ if (formats[k].code == code)
-+ return &formats[k];
- }
-
- return NULL;
- }
-
--static const struct unicam_fmt *find_format_by_pix(struct unicam_device *dev,
-- u32 pixelformat)
-+static const struct unicam_fmt *find_format_by_pix(u32 pixelformat)
- {
-- const struct unicam_fmt *fmt;
- unsigned int k;
-
-- for (k = 0; k < dev->num_active_fmt; k++) {
-- fmt = &dev->active_fmts[k];
-- if (fmt->fourcc == pixelformat)
-- return fmt;
-+ for (k = 0; k < ARRAY_SIZE(formats); k++) {
-+ if (formats[k].fourcc == pixelformat)
-+ return &formats[k];
- }
-
- return NULL;
- }
-
--static void dump_active_formats(struct unicam_device *dev)
--{
-- int i;
--
-- for (i = 0; i < dev->num_active_fmt; i++) {
-- unicam_dbg(3, dev, "active_fmt[%d] (%p) is code %04x, fourcc " V4L2_FOURCC_CONV ", depth %d\n",
-- i, &dev->active_fmts[i], dev->active_fmts[i].code,
-- V4L2_FOURCC_CONV_ARGS(dev->active_fmts[i].fourcc),
-- dev->active_fmts[i].depth);
-- }
--}
--
- static inline unsigned int bytes_per_line(u32 width,
- const struct unicam_fmt *fmt)
- {
-@@ -726,14 +706,40 @@ static int unicam_enum_fmt_vid_cap(struc
- struct v4l2_fmtdesc *f)
- {
- struct unicam_device *dev = video_drvdata(file);
-+ struct v4l2_subdev_mbus_code_enum mbus_code;
- const struct unicam_fmt *fmt = NULL;
-+ int index = 0;
-+ int ret = 0;
-+ int i;
-
-- if (f->index >= dev->num_active_fmt)
-- return -EINVAL;
-+ /* Loop whilst the sensor driver says it has more formats, but add a
-+ * failsafe against a dodgy driver at 128 (more than any sensor will
-+ * ever sensibly advertise)
-+ */
-+ for (i = 0; !ret && i < 128 ; i++) {
-+ memset(&mbus_code, 0, sizeof(mbus_code));
-+ mbus_code.index = i;
-
-- fmt = &dev->active_fmts[f->index];
-+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code,
-+ NULL, &mbus_code);
-+ if (ret < 0) {
-+ unicam_dbg(2, dev,
-+ "subdev->enum_mbus_code idx %d returned %d - index invalid\n",
-+ i, ret);
-+ return -EINVAL;
-+ }
-
-- f->pixelformat = fmt->fourcc;
-+ fmt = find_format_by_code(mbus_code.code);
-+ if (fmt) {
-+ if (fmt->fourcc) {
-+ if (index == f->index) {
-+ f->pixelformat = fmt->fourcc;
-+ break;
-+ }
-+ index++;
-+ }
-+ }
-+ }
-
- return 0;
- }
-@@ -748,6 +754,39 @@ static int unicam_g_fmt_vid_cap(struct f
- return 0;
- }
-
-+static
-+const struct unicam_fmt *get_first_supported_format(struct unicam_device *dev)
-+{
-+ struct v4l2_subdev_mbus_code_enum mbus_code;
-+ const struct unicam_fmt *fmt = NULL;
-+ int ret;
-+ int j;
-+
-+ for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) {
-+ memset(&mbus_code, 0, sizeof(mbus_code));
-+ mbus_code.index = j;
-+ ret = v4l2_subdev_call(dev->sensor, pad, enum_mbus_code, NULL,
-+ &mbus_code);
-+ if (ret < 0) {
-+ unicam_dbg(2, dev,
-+ "subdev->enum_mbus_code idx %d returned %d - continue\n",
-+ j, ret);
-+ continue;
-+ }
-+
-+ unicam_dbg(2, dev, "subdev %s: code: %04x idx: %d\n",
-+ dev->sensor->name, mbus_code.code, j);
-+
-+ fmt = find_format_by_code(mbus_code.code);
-+ unicam_dbg(2, dev, "fmt %04x returned as %p, V4L2 FOURCC %04x, csi_dt %02X\n",
-+ mbus_code.code, fmt, fmt ? fmt->fourcc : 0,
-+ fmt ? fmt->csi_dt : 0);
-+ if (fmt)
-+ return fmt;
-+ }
-+
-+ return NULL;
-+}
- static int unicam_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
- {
-@@ -759,13 +798,15 @@ static int unicam_try_fmt_vid_cap(struct
- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
- int ret;
-
-- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
-+ fmt = find_format_by_pix(f->fmt.pix.pixelformat);
- if (!fmt) {
-- unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use default of %08X\n",
-- f->fmt.pix.pixelformat, dev->active_fmts[0].fourcc);
-+ /* Pixel format not supported by unicam. Choose the first
-+ * supported format, and let the sensor choose something else.
-+ */
-+ unicam_dbg(3, dev, "Fourcc format (0x%08x) not found. Use first format.\n",
-+ f->fmt.pix.pixelformat);
-
-- /* Just get the first one enumerated */
-- fmt = &dev->active_fmts[0];
-+ fmt = &formats[0];
- f->fmt.pix.pixelformat = fmt->fourcc;
- }
-
-@@ -785,6 +826,40 @@ static int unicam_try_fmt_vid_cap(struct
- unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
-
- v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
-+ if (mbus_fmt->code != fmt->code) {
-+ /* Sensor has returned an alternate format */
-+ fmt = find_format_by_code(mbus_fmt->code);
-+ if (!fmt) {
-+ /* The alternate format is one unicam can't support.
-+ * Find the first format that is supported by both, and
-+ * then set that.
-+ */
-+ fmt = get_first_supported_format(dev);
-+ mbus_fmt->code = fmt->code;
-+
-+ ret = v4l2_subdev_call(dev->sensor, pad, set_fmt,
-+ dev->sensor_config, &sd_fmt);
-+ if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV)
-+ return ret;
-+
-+ if (mbus_fmt->field != V4L2_FIELD_NONE)
-+ unicam_info(dev, "Sensor trying to send interlaced video - results may be unpredictable\n");
-+
-+ v4l2_fill_pix_format(&f->fmt.pix, &sd_fmt.format);
-+
-+ if (mbus_fmt->code != fmt->code) {
-+ /* We've set a format that the sensor reports
-+ * as being supported, but it refuses to set it.
-+ * Not much else we can do.
-+ * Assume that the sensor driver may accept the
-+ * format when it is set (rather than tried).
-+ */
-+ unicam_err(dev, "Sensor won't accept default format, and Unicam can't support sensor default\n");
-+ }
-+ }
-+
-+ f->fmt.pix.pixelformat = fmt->fourcc;
-+ }
-
- return unicam_calc_format_size_bpl(dev, fmt, f);
- }
-@@ -805,10 +880,18 @@ static int unicam_s_fmt_vid_cap(struct f
- if (ret < 0)
- return ret;
-
-- fmt = find_format_by_pix(dev, f->fmt.pix.pixelformat);
-+ fmt = find_format_by_pix(f->fmt.pix.pixelformat);
- if (!fmt) {
-- /* Unknown pixel format - adopt a default */
-- fmt = &dev->active_fmts[0];
-+ /* Unknown pixel format - adopt a default.
-+ * This shouldn't happen as try_fmt should have resolved any
-+ * issues first.
-+ */
-+ fmt = get_first_supported_format(dev);
-+ if (!fmt)
-+ /* It shouldn't be possible to get here with no
-+ * supported formats
-+ */
-+ return -EINVAL;
- f->fmt.pix.pixelformat = fmt->fourcc;
- return -EINVAL;
- }
-@@ -944,6 +1027,7 @@ static void unicam_set_packing_config(st
- unpack = UNICAM_PUM_NONE;
- break;
- }
-+
- switch (v4l2_depth) {
- case 8:
- pack = UNICAM_PPM_PACK8;
-@@ -1439,7 +1523,7 @@ static int unicam_enum_framesizes(struct
- int ret;
-
- /* check for valid format */
-- fmt = find_format_by_pix(dev, fsize->pixel_format);
-+ fmt = find_format_by_pix(fsize->pixel_format);
- if (!fmt) {
- unicam_dbg(3, dev, "Invalid pixel code: %x\n",
- fsize->pixel_format);
-@@ -1478,7 +1562,7 @@ static int unicam_enum_frameintervals(st
- };
- int ret;
-
-- fmt = find_format_by_pix(dev, fival->pixel_format);
-+ fmt = find_format_by_pix(fival->pixel_format);
- if (!fmt)
- return -EINVAL;
-
-@@ -1742,27 +1826,6 @@ static const struct v4l2_ioctl_ops unica
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- };
-
--/*
-- * Adds an entry to the active_fmts array
-- * Returns non-zero if attempting to write off the end of the array.
-- */
--static int unicam_add_active_format(struct unicam_device *unicam,
-- const struct unicam_fmt *fmt)
--{
-- //Ensure we don't run off the end of the array.
-- if (unicam->num_active_fmt >= MAX_POSSIBLE_PIX_FMTS)
-- return 1;
--
-- unicam->active_fmts[unicam->num_active_fmt] = *fmt;
-- unicam_dbg(2, unicam,
-- "matched fourcc: " V4L2_FOURCC_CONV ": code: %04x idx: %d\n",
-- V4L2_FOURCC_CONV_ARGS(fmt->fourcc),
-- fmt->code, unicam->num_active_fmt);
-- unicam->num_active_fmt++;
--
-- return 0;
--}
--
- static int
- unicam_async_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *subdev,
-@@ -1770,9 +1833,6 @@ unicam_async_bound(struct v4l2_async_not
- {
- struct unicam_device *unicam = container_of(notifier->v4l2_dev,
- struct unicam_device, v4l2_dev);
-- struct v4l2_subdev_mbus_code_enum mbus_code;
-- int ret = 0;
-- int j;
-
- if (unicam->sensor) {
- unicam_info(unicam, "Rejecting subdev %s (Already set!!)",
-@@ -1783,47 +1843,6 @@ unicam_async_bound(struct v4l2_async_not
- unicam->sensor = subdev;
- unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name);
-
-- /* Enumerate sub device formats and enable all matching local formats */
-- unicam->num_active_fmt = 0;
-- unicam_dbg(2, unicam, "Get supported formats...\n");
-- for (j = 0; ret != -EINVAL && ret != -ENOIOCTLCMD; ++j) {
-- const struct unicam_fmt *fmt = NULL;
-- int k;
--
-- memset(&mbus_code, 0, sizeof(mbus_code));
-- mbus_code.index = j;
-- ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
-- NULL, &mbus_code);
-- if (ret < 0) {
-- unicam_dbg(2, unicam,
-- "subdev->enum_mbus_code idx %d returned %d - continue\n",
-- j, ret);
-- continue;
-- }
--
-- unicam_dbg(2, unicam, "subdev %s: code: %04x idx: %d\n",
-- subdev->name, mbus_code.code, j);
--
-- for (k = 0; k < ARRAY_SIZE(formats); k++) {
-- if (mbus_code.code == formats[k].code) {
-- fmt = &formats[k];
-- break;
-- }
-- }
-- unicam_dbg(2, unicam, "fmt %04x returned as %p, V4L2 FOURCC %04x, csi_dt %02X\n",
-- mbus_code.code, fmt, fmt ? fmt->fourcc : 0,
-- fmt ? fmt->csi_dt : 0);
-- if (fmt) {
-- if (unicam_add_active_format(unicam, fmt)) {
-- unicam_dbg(1, unicam, "Active fmt list truncated\n");
-- break;
-- }
-- }
-- }
-- unicam_dbg(2, unicam,
-- "Done all formats\n");
-- dump_active_formats(unicam);
--
- return 0;
- }
-
-@@ -1849,10 +1868,17 @@ static int unicam_probe_complete(struct
- return ret;
- }
-
-- fmt = find_format_by_code(unicam, mbus_fmt.code);
-+ fmt = find_format_by_code(mbus_fmt.code);
- if (!fmt) {
-- /* Default image format not valid. Choose first active fmt. */
-- fmt = &unicam->active_fmts[0];
-+ /* Find the first format that the sensor and unicam both
-+ * support
-+ */
-+ fmt = get_first_supported_format(unicam);
-+
-+ if (!fmt)
-+ /* No compatible formats */
-+ return -EINVAL;
-+
- mbus_fmt.code = fmt->code;
- ret = __subdev_set_format(unicam, &mbus_fmt);
- if (ret)