X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch;fp=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch;h=0000000000000000000000000000000000000000;hb=7d7aa2fd924c27829ec25f825481554dd81bce97;hp=5eec74e42ac789ed3a5b9badfbb47f81bb601089;hpb=e7bfda2c243e66a75ff966ba04c28b1590b5d24c;p=openwrt%2Fstaging%2Fchunkeey.git diff --git a/target/linux/brcm2708/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch b/target/linux/brcm2708/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch deleted file mode 100644 index 5eec74e42a..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0307-staging-bcm2835_codec-Query-supported-formats-from-t.patch +++ /dev/null @@ -1,727 +0,0 @@ -From ce8cc7a85839af588b753ce4af0832db9c467f45 Mon Sep 17 00:00:00 2001 -From: Dave Stevenson -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 ---- - .../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, -+ ¶m_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, -+ ¶m_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; - }