aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch
diff options
context:
space:
mode:
authorAdrian Schmutzler <freifunk@adrianschmutzler.de>2020-02-08 21:58:55 +0100
committerAdrian Schmutzler <freifunk@adrianschmutzler.de>2020-02-14 14:10:51 +0100
commit7d7aa2fd924c27829ec25f825481554dd81bce97 (patch)
tree658b87b89331670266163e522ea5fb52535633cb /target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch
parente7bfda2c243e66a75ff966ba04c28b1590b5d24c (diff)
downloadupstream-7d7aa2fd924c27829ec25f825481554dd81bce97.tar.gz
upstream-7d7aa2fd924c27829ec25f825481554dd81bce97.tar.bz2
upstream-7d7aa2fd924c27829ec25f825481554dd81bce97.zip
brcm2708: rename target to bcm27xx
This change makes the names of Broadcom targets consistent by using the common notation based on SoC/CPU ID (which is used internally anyway), bcmXXXX instead of brcmXXXX. This is even used for target TITLE in make menuconfig already, only the short target name used brcm so far. Despite, since subtargets range from bcm2708 to bcm2711, it seems appropriate to use bcm27xx instead of bcm2708 (again, as already done for BOARDNAME). This also renames the packages brcm2708-userland and brcm2708-gpu-fw. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Acked-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch')
-rw-r--r--target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch727
1 files changed, 727 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch
new file mode 100644
index 0000000000..5eec74e42a
--- /dev/null
+++ b/target/linux/bcm27xx/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch
@@ -0,0 +1,727 @@
+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;
+ }