brcm2708: update to latest patches from RPi foundation
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0309-staging-bcm2835_codec-Query-supported-formats-from-t.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0309-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/brcm2708/patches-4.19/950-0309-staging-bcm2835_codec-Query-supported-formats-from-t.patch
deleted file mode 100644 (file)
index 5eec74e..0000000
+++ /dev/null
@@ -1,727 +0,0 @@
-From ce8cc7a85839af588b753ce4af0832db9c467f45 Mon Sep 17 00:00:00 2001
-From: Dave Stevenson <dave.stevenson@raspberrypi.org>
-Date: Wed, 13 Feb 2019 13:44:00 +0000
-Subject: [PATCH] staging: bcm2835_codec: Query supported formats from
- the component
-
-The driver was previously working with hard coded tables of
-which video formats were supported by each component.
-The components advertise this information via a MMAL parameter,
-so retrieve the information from there during probe, and store
-in the state structure for that device.
-
-Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
----
- .../bcm2835-codec/bcm2835-v4l2-codec.c        | 455 +++++++++++++-----
- 1 file changed, 327 insertions(+), 128 deletions(-)
-
---- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
-+++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c
-@@ -88,17 +88,12 @@ struct bcm2835_codec_fmt {
-       int     bytesperline_align;
-       u32     flags;
-       u32     mmal_fmt;
--      bool    decode_only;
--      bool    encode_only;
-       int     size_multiplier_x2;
- };
--/* Supported raw pixel formats. Those supported for both encode and decode
-- * must come first, with those only supported for decode coming after (there
-- * are no formats supported for encode only).
-- */
--static struct bcm2835_codec_fmt raw_formats[] = {
-+static const struct bcm2835_codec_fmt supported_formats[] = {
-       {
-+              /* YUV formats */
-               .fourcc                 = V4L2_PIX_FMT_YUV420,
-               .depth                  = 8,
-               .bytesperline_align     = 32,
-@@ -139,7 +134,6 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_YUYV,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_UYVY,
-@@ -147,7 +141,6 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_UYVY,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_YVYU,
-@@ -155,7 +148,6 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_YVYU,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_VYUY,
-@@ -163,15 +155,14 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_VYUY,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-+              /* RGB formats */
-               .fourcc                 = V4L2_PIX_FMT_RGB24,
-               .depth                  = 24,
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_RGB24,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_BGR24,
-@@ -179,7 +170,6 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_BGR24,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_BGR32,
-@@ -187,17 +177,126 @@ static struct bcm2835_codec_fmt raw_form
-               .bytesperline_align     = 32,
-               .flags                  = 0,
-               .mmal_fmt               = MMAL_ENCODING_BGRA,
--              .encode_only            = true,
-               .size_multiplier_x2     = 2,
--      },
--};
--
--/* Supported encoded formats. Those supported for both encode and decode
-- * must come first, with those only supported for decode coming after (there
-- * are no formats supported for encode only).
-- */
--static struct bcm2835_codec_fmt encoded_formats[] = {
--      {
-+      }, {
-+              /* Bayer formats */
-+              /* 8 bit */
-+              .fourcc                 = V4L2_PIX_FMT_SRGGB8,
-+              .depth                  = 8,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SRGGB8,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SBGGR8,
-+              .depth                  = 8,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SBGGR8,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGRBG8,
-+              .depth                  = 8,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGRBG8,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGBRG8,
-+              .depth                  = 8,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGBRG8,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              /* 10 bit */
-+              .fourcc                 = V4L2_PIX_FMT_SRGGB10P,
-+              .depth                  = 10,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SRGGB10P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SBGGR10P,
-+              .depth                  = 10,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SBGGR10P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGRBG10P,
-+              .depth                  = 10,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGRBG10P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGBRG10P,
-+              .depth                  = 10,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGBRG10P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              /* 12 bit */
-+              .fourcc                 = V4L2_PIX_FMT_SRGGB12P,
-+              .depth                  = 12,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SRGGB12P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SBGGR12P,
-+              .depth                  = 12,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SBGGR12P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGRBG12P,
-+              .depth                  = 12,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGRBG12P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGBRG12P,
-+              .depth                  = 12,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGBRG12P,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              /* 16 bit */
-+              .fourcc                 = V4L2_PIX_FMT_SRGGB16,
-+              .depth                  = 16,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SRGGB16,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SBGGR16,
-+              .depth                  = 16,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SBGGR16,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGRBG16,
-+              .depth                  = 16,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGRBG16,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              .fourcc                 = V4L2_PIX_FMT_SGBRG16,
-+              .depth                  = 16,
-+              .bytesperline_align     = 32,
-+              .flags                  = 0,
-+              .mmal_fmt               = MMAL_ENCODING_BAYER_SGBRG16,
-+              .size_multiplier_x2     = 2,
-+      }, {
-+              /* Compressed formats */
-               .fourcc                 = V4L2_PIX_FMT_H264,
-               .depth                  = 0,
-               .flags                  = V4L2_FMT_FLAG_COMPRESSED,
-@@ -212,30 +311,22 @@ static struct bcm2835_codec_fmt encoded_
-               .depth                  = 0,
-               .flags                  = V4L2_FMT_FLAG_COMPRESSED,
-               .mmal_fmt               = MMAL_ENCODING_MP4V,
--              .decode_only            = true,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_H263,
-               .depth                  = 0,
-               .flags                  = V4L2_FMT_FLAG_COMPRESSED,
-               .mmal_fmt               = MMAL_ENCODING_H263,
--              .decode_only            = true,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_MPEG2,
-               .depth                  = 0,
-               .flags                  = V4L2_FMT_FLAG_COMPRESSED,
-               .mmal_fmt               = MMAL_ENCODING_MP2V,
--              .decode_only            = true,
-       }, {
-               .fourcc                 = V4L2_PIX_FMT_VP8,
-               .depth                  = 0,
-               .flags                  = V4L2_FMT_FLAG_COMPRESSED,
-               .mmal_fmt               = MMAL_ENCODING_VP8,
--              .decode_only            = true,
-       },
--      /*
--       * This list couold include VP6 and Theorafor decode, but V4L2 doesn't
--       * support them.
--       */
- };
- struct bcm2835_codec_fmt_list {
-@@ -243,19 +334,6 @@ struct bcm2835_codec_fmt_list {
-       unsigned int num_entries;
- };
--#define RAW_LIST      0
--#define ENCODED_LIST  1
--
--struct bcm2835_codec_fmt_list formats[] = {
--      {
--              .list = raw_formats,
--              .num_entries = ARRAY_SIZE(raw_formats),
--      }, {
--              .list = encoded_formats,
--              .num_entries = ARRAY_SIZE(encoded_formats),
--      },
--};
--
- struct m2m_mmal_buffer {
-       struct v4l2_m2m_buffer  m2m;
-       struct mmal_buffer      mmal;
-@@ -284,52 +362,6 @@ struct bcm2835_codec_q_data {
-       bool                    eos_buffer_in_use;      /* debug only */
- };
--enum {
--      V4L2_M2M_SRC = 0,
--      V4L2_M2M_DST = 1,
--};
--
--static inline struct bcm2835_codec_fmt_list *get_format_list(bool decode,
--                                                           bool capture)
--{
--      return decode ^ capture ? &formats[ENCODED_LIST] : &formats[RAW_LIST];
--}
--
--static struct bcm2835_codec_fmt *get_default_format(bool decode, bool capture)
--{
--      return &get_format_list(decode, capture)->list[0];
--}
--
--static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f, bool decode,
--                                           bool capture)
--{
--      struct bcm2835_codec_fmt *fmt;
--      unsigned int k;
--      struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture);
--
--      for (k = 0; k < fmts->num_entries; k++) {
--              fmt = &fmts->list[k];
--              if (fmt->fourcc == f->fmt.pix.pixelformat)
--                      break;
--      }
--
--      /*
--       * Some compressed formats are only supported for decoding, not
--       * encoding.
--       */
--      if (!decode && fmts->list[k].decode_only)
--              return NULL;
--
--      /* Some pixel formats are only supported for encoding, not decoding. */
--      if (decode && fmts->list[k].encode_only)
--              return NULL;
--
--      if (k == fmts->num_entries)
--              return NULL;
--
--      return &fmts->list[k];
--}
--
- struct bcm2835_codec_dev {
-       struct platform_device *pdev;
-@@ -342,6 +374,9 @@ struct bcm2835_codec_dev {
-       /* allocated mmal instance and components */
-       bool                    decode;  /* Is this instance a decoder? */
-+      /* The list of formats supported on input and output queues. */
-+      struct bcm2835_codec_fmt_list   supported_fmts[2];
-+
-       struct vchiq_mmal_instance      *instance;
-       struct v4l2_m2m_dev     *m2m_dev;
-@@ -374,8 +409,59 @@ struct bcm2835_codec_ctx {
- struct bcm2835_codec_driver {
-       struct bcm2835_codec_dev *encode;
-       struct bcm2835_codec_dev *decode;
-+      struct bcm2835_codec_dev *isp;
-+};
-+
-+enum {
-+      V4L2_M2M_SRC = 0,
-+      V4L2_M2M_DST = 1,
- };
-+static const struct bcm2835_codec_fmt *get_fmt(u32 mmal_fmt)
-+{
-+      unsigned int i;
-+
-+      for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
-+              if (supported_formats[i].mmal_fmt == mmal_fmt)
-+                      return &supported_formats[i];
-+      }
-+      return NULL;
-+}
-+
-+static inline
-+struct bcm2835_codec_fmt_list *get_format_list(struct bcm2835_codec_dev *dev,
-+                                             bool capture)
-+{
-+      return &dev->supported_fmts[capture ? 1 : 0];
-+}
-+
-+static
-+struct bcm2835_codec_fmt *get_default_format(struct bcm2835_codec_dev *dev,
-+                                           bool capture)
-+{
-+      return &dev->supported_fmts[capture ? 1 : 0].list[0];
-+}
-+
-+static struct bcm2835_codec_fmt *find_format(struct v4l2_format *f,
-+                                           struct bcm2835_codec_dev *dev,
-+                                           bool capture)
-+{
-+      struct bcm2835_codec_fmt *fmt;
-+      unsigned int k;
-+      struct bcm2835_codec_fmt_list *fmts =
-+                                      &dev->supported_fmts[capture ? 1 : 0];
-+
-+      for (k = 0; k < fmts->num_entries; k++) {
-+              fmt = &fmts->list[k];
-+              if (fmt->fourcc == f->fmt.pix.pixelformat)
-+                      break;
-+      }
-+      if (k == fmts->num_entries)
-+              return NULL;
-+
-+      return &fmts->list[k];
-+}
-+
- static inline struct bcm2835_codec_ctx *file2ctx(struct file *file)
- {
-       return container_of(file->private_data, struct bcm2835_codec_ctx, fh);
-@@ -456,7 +542,6 @@ static inline unsigned int get_bytesperl
- }
- static void setup_mmal_port_format(struct bcm2835_codec_ctx *ctx,
--                                 bool decode,
-                                  struct bcm2835_codec_q_data *q_data,
-                                  struct vchiq_mmal_port *port)
- {
-@@ -473,7 +558,7 @@ static void setup_mmal_port_format(struc
-               port->es.video.frame_rate.den = 1;
-       } else {
-               /* Compressed format - leave resolution as 0 for decode */
--              if (decode) {
-+              if (ctx->dev->decode) {
-                       port->es.video.width = 0;
-                       port->es.video.height = 0;
-                       port->es.video.crop.width = 0;
-@@ -802,22 +887,15 @@ static int vidioc_querycap(struct file *
-       return 0;
- }
--static int enum_fmt(struct v4l2_fmtdesc *f, bool decode, bool capture)
-+static int enum_fmt(struct v4l2_fmtdesc *f, struct bcm2835_codec_ctx *ctx,
-+                  bool capture)
- {
-       struct bcm2835_codec_fmt *fmt;
--      struct bcm2835_codec_fmt_list *fmts = get_format_list(decode, capture);
-+      struct bcm2835_codec_fmt_list *fmts =
-+                                      get_format_list(ctx->dev, capture);
-       if (f->index < fmts->num_entries) {
-               /* Format found */
--              /* Check format isn't a decode only format when encoding */
--              if (!decode &&
--                  fmts->list[f->index].decode_only)
--                      return -EINVAL;
--              /* Check format isn't a decode only format when encoding */
--              if (decode &&
--                  fmts->list[f->index].encode_only)
--                      return -EINVAL;
--
-               fmt = &fmts->list[f->index];
-               f->pixelformat = fmt->fourcc;
-               f->flags = fmt->flags;
-@@ -833,7 +911,7 @@ static int vidioc_enum_fmt_vid_cap(struc
- {
-       struct bcm2835_codec_ctx *ctx = file2ctx(file);
--      return enum_fmt(f, ctx->dev->decode, true);
-+      return enum_fmt(f, ctx, true);
- }
- static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
-@@ -841,7 +919,7 @@ static int vidioc_enum_fmt_vid_out(struc
- {
-       struct bcm2835_codec_ctx *ctx = file2ctx(file);
--      return enum_fmt(f, ctx->dev->decode, false);
-+      return enum_fmt(f, ctx, false);
- }
- static int vidioc_g_fmt(struct bcm2835_codec_ctx *ctx, struct v4l2_format *f)
-@@ -933,11 +1011,11 @@ static int vidioc_try_fmt_vid_cap(struct
-       struct bcm2835_codec_fmt *fmt;
-       struct bcm2835_codec_ctx *ctx = file2ctx(file);
--      fmt = find_format(f, ctx->dev->decode, true);
-+      fmt = find_format(f, ctx->dev, true);
-       if (!fmt) {
--              f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode,
-+              f->fmt.pix.pixelformat = get_default_format(ctx->dev,
-                                                           true)->fourcc;
--              fmt = find_format(f, ctx->dev->decode, true);
-+              fmt = find_format(f, ctx->dev, true);
-       }
-       return vidioc_try_fmt(f, fmt);
-@@ -949,11 +1027,11 @@ static int vidioc_try_fmt_vid_out(struct
-       struct bcm2835_codec_fmt *fmt;
-       struct bcm2835_codec_ctx *ctx = file2ctx(file);
--      fmt = find_format(f, ctx->dev->decode, false);
-+      fmt = find_format(f, ctx->dev, false);
-       if (!fmt) {
--              f->fmt.pix.pixelformat = get_default_format(ctx->dev->decode,
-+              f->fmt.pix.pixelformat = get_default_format(ctx->dev,
-                                                           false)->fourcc;
--              fmt = find_format(f, ctx->dev->decode, false);
-+              fmt = find_format(f, ctx->dev, false);
-       }
-       if (!f->fmt.pix.colorspace)
-@@ -988,7 +1066,7 @@ static int vidioc_s_fmt(struct bcm2835_c
-               return -EBUSY;
-       }
--      q_data->fmt = find_format(f, ctx->dev->decode,
-+      q_data->fmt = find_format(f, ctx->dev,
-                                 f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE);
-       q_data->crop_width = f->fmt.pix.width;
-       q_data->height = f->fmt.pix.height;
-@@ -1041,7 +1119,7 @@ static int vidioc_s_fmt(struct bcm2835_c
-       if (!port)
-               return 0;
--      setup_mmal_port_format(ctx, ctx->dev->decode, q_data, port);
-+      setup_mmal_port_format(ctx, q_data, port);
-       ret = vchiq_mmal_port_set_format(ctx->dev->instance, port);
-       if (ret) {
-               v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on port, ret %d\n",
-@@ -1064,8 +1142,7 @@ static int vidioc_s_fmt(struct bcm2835_c
-               struct bcm2835_codec_q_data *q_data_dst =
-                                               &ctx->q_data[V4L2_M2M_DST];
--              setup_mmal_port_format(ctx, ctx->dev->decode, q_data_dst,
--                                     port_dst);
-+              setup_mmal_port_format(ctx, q_data_dst, port_dst);
-               ret = vchiq_mmal_port_set_format(ctx->dev->instance, port_dst);
-               if (ret) {
-                       v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed vchiq_mmal_port_set_format on output port, ret %d\n",
-@@ -1636,10 +1713,10 @@ static int bcm2835_codec_create_componen
-                                     MMAL_PARAMETER_ZERO_COPY, &enable,
-                                     sizeof(enable));
--      setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_SRC],
-+      setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_SRC],
-                              &ctx->component->input[0]);
--      setup_mmal_port_format(ctx, dev->decode, &ctx->q_data[V4L2_M2M_DST],
-+      setup_mmal_port_format(ctx, &ctx->q_data[V4L2_M2M_DST],
-                              &ctx->component->output[0]);
-       ret = vchiq_mmal_port_set_format(dev->instance,
-@@ -2025,8 +2102,8 @@ static int bcm2835_codec_open(struct fil
-               goto open_unlock;
-       }
--      ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev->decode, false);
--      ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev->decode, true);
-+      ctx->q_data[V4L2_M2M_SRC].fmt = get_default_format(dev, false);
-+      ctx->q_data[V4L2_M2M_DST].fmt = get_default_format(dev, true);
-       if (dev->decode) {
-               /*
-                * Input width and height are irrelevant as they will be defined
-@@ -2209,13 +2286,130 @@ static const struct v4l2_m2m_ops m2m_ops
-       .job_abort      = job_abort,
- };
-+/* Size of the array to provide to the VPU when asking for the list of supported
-+ * formats.
-+ * The ISP component currently advertises 33 input formats, so add a small
-+ * overhead on that.
-+ */
-+#define MAX_SUPPORTED_ENCODINGS 40
-+
-+/* Populate dev->supported_fmts with the formats supported by those ports. */
-+static int bcm2835_codec_get_supported_fmts(struct bcm2835_codec_dev *dev)
-+{
-+      struct bcm2835_codec_fmt *list;
-+      struct vchiq_mmal_component *component;
-+      u32 fourccs[MAX_SUPPORTED_ENCODINGS];
-+      u32 param_size = sizeof(fourccs);
-+      unsigned int i, j, num_encodings;
-+      int ret;
-+
-+      ret = vchiq_mmal_component_init(dev->instance,
-+                                      dev->decode ?
-+                                              "ril.video_decode" :
-+                                              "ril.video_encode",
-+                                      &component);
-+      if (ret < 0) {
-+              v4l2_err(&dev->v4l2_dev, "%s: failed to create component\n",
-+                       __func__);
-+              return -ENOMEM;
-+      }
-+
-+      ret = vchiq_mmal_port_parameter_get(dev->instance,
-+                                          &component->input[0],
-+                                          MMAL_PARAMETER_SUPPORTED_ENCODINGS,
-+                                          &fourccs,
-+                                          &param_size);
-+
-+      if (ret) {
-+              if (ret == MMAL_MSG_STATUS_ENOSPC) {
-+                      v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n",
-+                               __func__);
-+                      num_encodings = MAX_SUPPORTED_ENCODINGS;
-+              } else {
-+                      v4l2_err(&dev->v4l2_dev, "%s: get_param ret %u.\n",
-+                               __func__, ret);
-+                      ret = -EINVAL;
-+                      goto destroy_component;
-+              }
-+      } else {
-+              num_encodings = param_size / sizeof(u32);
-+      }
-+
-+      /* Assume at this stage that all encodings will be supported in V4L2.
-+       * Any that aren't supported will waste a very small amount of memory.
-+       */
-+      list = devm_kzalloc(&dev->pdev->dev,
-+                          sizeof(struct bcm2835_codec_fmt) * num_encodings,
-+                          GFP_KERNEL);
-+      if (!list) {
-+              ret = -ENOMEM;
-+              goto destroy_component;
-+      }
-+      dev->supported_fmts[0].list = list;
-+
-+      for (i = 0, j = 0; i < num_encodings; i++) {
-+              const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]);
-+
-+              if (fmt) {
-+                      list[j] = *fmt;
-+                      j++;
-+              }
-+      }
-+      dev->supported_fmts[0].num_entries = j;
-+
-+      param_size = sizeof(fourccs);
-+      ret = vchiq_mmal_port_parameter_get(dev->instance,
-+                                          &component->output[0],
-+                                          MMAL_PARAMETER_SUPPORTED_ENCODINGS,
-+                                          &fourccs,
-+                                          &param_size);
-+
-+      if (ret) {
-+              if (ret == MMAL_MSG_STATUS_ENOSPC) {
-+                      v4l2_err(&dev->v4l2_dev, "%s: port has more encoding than we provided space for. Some are dropped.\n",
-+                               __func__);
-+                      num_encodings = MAX_SUPPORTED_ENCODINGS;
-+              } else {
-+                      ret = -EINVAL;
-+                      goto destroy_component;
-+              }
-+      } else {
-+              num_encodings = param_size / sizeof(u32);
-+      }
-+      /* Assume at this stage that all encodings will be supported in V4L2. */
-+      list = devm_kzalloc(&dev->pdev->dev,
-+                          sizeof(struct bcm2835_codec_fmt) * num_encodings,
-+                          GFP_KERNEL);
-+      if (!list) {
-+              ret = -ENOMEM;
-+              goto destroy_component;
-+      }
-+      dev->supported_fmts[1].list = list;
-+
-+      for (i = 0, j = 0; i < num_encodings; i++) {
-+              const struct bcm2835_codec_fmt *fmt = get_fmt(fourccs[i]);
-+
-+              if (fmt) {
-+                      list[j] = *fmt;
-+                      j++;
-+              }
-+      }
-+      dev->supported_fmts[1].num_entries = j;
-+
-+      ret = 0;
-+
-+destroy_component:
-+      vchiq_mmal_component_finalise(dev->instance, component);
-+
-+      return ret;
-+}
-+
- static int bcm2835_codec_create(struct platform_device *pdev,
-                               struct bcm2835_codec_dev **new_dev,
-                               bool decode)
- {
-       struct bcm2835_codec_dev *dev;
-       struct video_device *vfd;
--      struct vchiq_mmal_instance *instance = NULL;
-       int video_nr;
-       int ret;
-@@ -2227,10 +2421,18 @@ static int bcm2835_codec_create(struct p
-       dev->decode = decode;
--      ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-+      ret = vchiq_mmal_init(&dev->instance);
-       if (ret)
-               return ret;
-+      ret = bcm2835_codec_get_supported_fmts(dev);
-+      if (ret)
-+              goto vchiq_finalise;
-+
-+      ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
-+      if (ret)
-+              goto vchiq_finalise;
-+
-       atomic_set(&dev->num_inst, 0);
-       mutex_init(&dev->dev_mutex);
-@@ -2270,12 +2472,7 @@ static int bcm2835_codec_create(struct p
-               goto err_m2m;
-       }
--      ret = vchiq_mmal_init(&instance);
--      if (ret < 0)
--              goto err_m2m;
--      dev->instance = instance;
--
--      v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s codec\n",
-+      v4l2_info(&dev->v4l2_dev, "Loaded V4L2 %s\n",
-                 dev->decode ? "decode" : "encode");
-       return 0;
-@@ -2284,7 +2481,8 @@ err_m2m:
-       video_unregister_device(&dev->vfd);
- unreg_dev:
-       v4l2_device_unregister(&dev->v4l2_dev);
--
-+vchiq_finalise:
-+      vchiq_mmal_finalise(dev->instance);
-       return ret;
- }
-@@ -2297,6 +2495,7 @@ static int bcm2835_codec_destroy(struct
-       v4l2_m2m_release(dev->m2m_dev);
-       video_unregister_device(&dev->vfd);
-       v4l2_device_unregister(&dev->v4l2_dev);
-+      vchiq_mmal_finalise(dev->instance);
-       return 0;
- }