brcm2708: rename target to bcm27xx
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch b/target/linux/brcm2708/patches-4.19/950-0727-media-bcm2835-unicam-Rework-to-not-cache-the-list-of.patch
deleted file mode 100644 (file)
index 3a63871..0000000
+++ /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)