diff mbox series

[v2,17/34] media: iris: implement vb2_ops queue setup

Message ID 1702899149-21321-18-git-send-email-quic_dikshita@quicinc.com (mailing list archive)
State New, archived
Headers show
Series Qualcomm video encoder and decoder driver | expand

Commit Message

Dikshita Agarwal Dec. 18, 2023, 11:32 a.m. UTC
Implement queue_setup vb2_ops.
Calculate the buffer count and buffer size as par video
hardware requirement and updates to client.
Also, allocate the video driver buffers for output and
capture plane.

Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
---
 drivers/media/platform/qcom/vcodec/iris/Makefile   |   4 +-
 .../media/platform/qcom/vcodec/iris/iris_buffer.c  | 179 +++++++++++++++++++++
 .../media/platform/qcom/vcodec/iris/iris_buffer.h  |  49 ++++++
 .../media/platform/qcom/vcodec/iris/iris_common.h  |  71 +++++++-
 .../media/platform/qcom/vcodec/iris/iris_helpers.c |  24 +++
 .../media/platform/qcom/vcodec/iris/iris_helpers.h |   4 +-
 .../platform/qcom/vcodec/iris/iris_instance.h      |   6 +
 drivers/media/platform/qcom/vcodec/iris/iris_vb2.c |  71 ++++++++
 drivers/media/platform/qcom/vcodec/iris/iris_vb2.h |  15 ++
 .../media/platform/qcom/vcodec/iris/iris_vdec.c    |   5 +-
 .../media/platform/qcom/vcodec/iris/iris_vidc.c    |  19 ++-
 .../platform/qcom/vcodec/iris/platform_common.h    |  16 +-
 12 files changed, 442 insertions(+), 21 deletions(-)
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_buffer.c
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_buffer.h
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
 create mode 100644 drivers/media/platform/qcom/vcodec/iris/iris_vb2.h

Comments

Konrad Dybcio Dec. 19, 2023, 11:56 a.m. UTC | #1
On 18.12.2023 12:32, Dikshita Agarwal wrote:
> Implement queue_setup vb2_ops.
> Calculate the buffer count and buffer size as par video
> hardware requirement and updates to client.
> Also, allocate the video driver buffers for output and
> capture plane.
> 
> Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
> ---
[...]

> +static int input_min_count(struct iris_inst *inst)
> +{
> +	return MIN_BUFFERS;
> +}
Why is this a function?

> +
> +static int output_min_count(struct iris_inst *inst)
> +{
> +	int output_min_count;
> +
> +	switch (inst->codec) {
> +	case H264:
> +	case HEVC:
> +		output_min_count = 4;
> +		break;
> +	case VP9:
> +		output_min_count = 9;
> +		break;
> +	default:
> +		output_min_count = 4;
> +		break;
> +	}

switch (inst->codec) {
case VP9:
	return 9;
case H264:
case HEVC:
default:
	return 4;
}

> +
> +	return output_min_count;
> +}
> +
> +int iris_get_buf_min_count(struct iris_inst *inst,
> +			   enum iris_buffer_type buffer_type)
> +{
> +	switch (buffer_type) {
> +	case BUF_INPUT:
> +		return input_min_count(inst);
> +	case BUF_OUTPUT:
> +		return output_min_count(inst);
> +	default:
> +		return 0;
> +	}
> +}
> +
> +static u32 input_buffer_size(struct iris_inst *inst)
> +{
> +	u32 base_res_mbs = NUM_MBS_4k;
> +	u32 frame_size, num_mbs;
> +	struct v4l2_format *f;
> +	u32 div_factor = 1;
> +	u32 codec;
> +
> +	f = inst->fmt_src;
> +	codec = f->fmt.pix_mp.pixelformat;
> +
> +	num_mbs = get_mbpf(inst);
> +	if (num_mbs > NUM_MBS_4k) {
> +		div_factor = 4;
> +		base_res_mbs = inst->cap[MBPF].value;
> +	} else {
> +		base_res_mbs = NUM_MBS_4k;
> +		if (codec == V4L2_PIX_FMT_VP9)
> +			div_factor = 1;
> +		else
> +			div_factor = 2;
> +	}
> +
> +	frame_size = base_res_mbs * MB_IN_PIXEL * 3 / 2 / div_factor;
that's a bit magic..

> +
> +	 /* multiply by 10/8 (1.25) to get size for 10 bit case */
misaligned


Konrad
Dikshita Agarwal Dec. 20, 2023, 8:37 a.m. UTC | #2
On 12/19/2023 5:26 PM, Konrad Dybcio wrote:
> On 18.12.2023 12:32, Dikshita Agarwal wrote:
>> Implement queue_setup vb2_ops.
>> Calculate the buffer count and buffer size as par video
>> hardware requirement and updates to client.
>> Also, allocate the video driver buffers for output and
>> capture plane.
>>
>> Signed-off-by: Dikshita Agarwal <quic_dikshita@quicinc.com>
>> ---
> [...]
> 
>> +static int input_min_count(struct iris_inst *inst)
>> +{
>> +	return MIN_BUFFERS;
>> +}
> Why is this a function?
> 
Some extra checks will be performed to calculate the input buffers for
encoder, hence it was made a function. May be I can directly use the macro
at this point and introduce the function later in the patch with encoder
patches.
>> +
>> +static int output_min_count(struct iris_inst *inst)
>> +{
>> +	int output_min_count;
>> +
>> +	switch (inst->codec) {
>> +	case H264:
>> +	case HEVC:
>> +		output_min_count = 4;
>> +		break;
>> +	case VP9:
>> +		output_min_count = 9;
>> +		break;
>> +	default:
>> +		output_min_count = 4;
>> +		break;
>> +	}
> 
> switch (inst->codec) {
> case VP9:
> 	return 9;
> case H264:
> case HEVC:
> default:
> 	return 4;
> }
> 
Right, this is better, will make the change.
>> +
>> +	return output_min_count;
>> +}
>> +
>> +int iris_get_buf_min_count(struct iris_inst *inst,
>> +			   enum iris_buffer_type buffer_type)
>> +{
>> +	switch (buffer_type) {
>> +	case BUF_INPUT:
>> +		return input_min_count(inst);
>> +	case BUF_OUTPUT:
>> +		return output_min_count(inst);
>> +	default:
>> +		return 0;
>> +	}
>> +}
>> +
>> +static u32 input_buffer_size(struct iris_inst *inst)
>> +{
>> +	u32 base_res_mbs = NUM_MBS_4k;
>> +	u32 frame_size, num_mbs;
>> +	struct v4l2_format *f;
>> +	u32 div_factor = 1;
>> +	u32 codec;
>> +
>> +	f = inst->fmt_src;
>> +	codec = f->fmt.pix_mp.pixelformat;
>> +
>> +	num_mbs = get_mbpf(inst);
>> +	if (num_mbs > NUM_MBS_4k) {
>> +		div_factor = 4;
>> +		base_res_mbs = inst->cap[MBPF].value;
>> +	} else {
>> +		base_res_mbs = NUM_MBS_4k;
>> +		if (codec == V4L2_PIX_FMT_VP9)
>> +			div_factor = 1;
>> +		else
>> +			div_factor = 2;
>> +	}
>> +
>> +	frame_size = base_res_mbs * MB_IN_PIXEL * 3 / 2 / div_factor;
> that's a bit magic..
> 
This is the formula to calculate video frame size, no magic here :)
>> +
>> +	 /* multiply by 10/8 (1.25) to get size for 10 bit case */
> misaligned
> 
Oh! wasn't caught by check-patch.
Thanks for pointing this, Will fix.
> 
> Konrad
diff mbox series

Patch

diff --git a/drivers/media/platform/qcom/vcodec/iris/Makefile b/drivers/media/platform/qcom/vcodec/iris/Makefile
index 7fdee5b..a94e36b 100644
--- a/drivers/media/platform/qcom/vcodec/iris/Makefile
+++ b/drivers/media/platform/qcom/vcodec/iris/Makefile
@@ -1,9 +1,10 @@ 
-iris-objs += ../hfi_queue.o ../firmware.o
+iris-objs += ../hfi_queue.o ../firmware.o ../buffers.o
 
 iris-objs += iris_probe.o \
              iris_state.o \
              iris_core.o \
              iris_vidc.o \
+             iris_vb2.o \
              iris_vdec.o \
              iris_state.o \
              iris_ctrls.o \
@@ -11,6 +12,7 @@  iris-objs += iris_probe.o \
              iris_hfi.o \
              iris_hfi_response.o \
              iris_hfi_packet.o \
+             iris_buffer.o \
              resources.o \
              vpu_common.o \
              vpu_iris3.o \
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_buffer.c b/drivers/media/platform/qcom/vcodec/iris/iris_buffer.c
new file mode 100644
index 0000000..b9cffbf
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_buffer.c
@@ -0,0 +1,179 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "../buffers.h"
+#include "iris_buffer.h"
+#include "iris_helpers.h"
+#include "iris_instance.h"
+
+static int input_min_count(struct iris_inst *inst)
+{
+	return MIN_BUFFERS;
+}
+
+static int output_min_count(struct iris_inst *inst)
+{
+	int output_min_count;
+
+	switch (inst->codec) {
+	case H264:
+	case HEVC:
+		output_min_count = 4;
+		break;
+	case VP9:
+		output_min_count = 9;
+		break;
+	default:
+		output_min_count = 4;
+		break;
+	}
+
+	return output_min_count;
+}
+
+int iris_get_buf_min_count(struct iris_inst *inst,
+			   enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return input_min_count(inst);
+	case BUF_OUTPUT:
+		return output_min_count(inst);
+	default:
+		return 0;
+	}
+}
+
+static u32 input_buffer_size(struct iris_inst *inst)
+{
+	u32 base_res_mbs = NUM_MBS_4k;
+	u32 frame_size, num_mbs;
+	struct v4l2_format *f;
+	u32 div_factor = 1;
+	u32 codec;
+
+	f = inst->fmt_src;
+	codec = f->fmt.pix_mp.pixelformat;
+
+	num_mbs = get_mbpf(inst);
+	if (num_mbs > NUM_MBS_4k) {
+		div_factor = 4;
+		base_res_mbs = inst->cap[MBPF].value;
+	} else {
+		base_res_mbs = NUM_MBS_4k;
+		if (codec == V4L2_PIX_FMT_VP9)
+			div_factor = 1;
+		else
+			div_factor = 2;
+	}
+
+	frame_size = base_res_mbs * MB_IN_PIXEL * 3 / 2 / div_factor;
+
+	 /* multiply by 10/8 (1.25) to get size for 10 bit case */
+	if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC)
+		frame_size = frame_size + (frame_size >> 2);
+
+	return ALIGN(frame_size, SZ_4K);
+}
+
+static u32 output_buffer_size(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	u32 size;
+
+	f = inst->fmt_dst;
+
+	size = video_raw_buffer_size(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
+				     f->fmt.pix_mp.height);
+	return size;
+}
+
+int iris_get_buffer_size(struct iris_inst *inst,
+			 enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return input_buffer_size(inst);
+	case BUF_OUTPUT:
+		return output_buffer_size(inst);
+	default:
+		return 0;
+	}
+}
+
+struct iris_buffers *iris_get_buffer_list(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return &inst->buffers.input;
+	case BUF_OUTPUT:
+		return &inst->buffers.output;
+	case BUF_READ_ONLY:
+		return &inst->buffers.read_only;
+	case BUF_BIN:
+		return &inst->buffers.bin;
+	case BUF_ARP:
+		return &inst->buffers.arp;
+	case BUF_COMV:
+		return &inst->buffers.comv;
+	case BUF_NON_COMV:
+		return &inst->buffers.non_comv;
+	case BUF_LINE:
+		return &inst->buffers.line;
+	case BUF_DPB:
+		return &inst->buffers.dpb;
+	case BUF_PERSIST:
+		return &inst->buffers.persist;
+	case BUF_VPSS:
+		return &inst->buffers.vpss;
+	default:
+		return NULL;
+	}
+}
+
+int iris_allocate_buffers(struct iris_inst *inst,
+			  enum iris_buffer_type buf_type,
+			  u32 num_buffers)
+{
+	struct iris_buffer *buf = NULL;
+	struct iris_buffers *buffers;
+	int idx = 0;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return -EINVAL;
+
+	for (idx = 0; idx < num_buffers; idx++) {
+		buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+		if (!buf)
+			return -EINVAL;
+
+		INIT_LIST_HEAD(&buf->list);
+		list_add_tail(&buf->list, &buffers->list);
+		buf->type = buf_type;
+		buf->index = idx;
+	}
+
+	return 0;
+}
+
+int iris_free_buffers(struct iris_inst *inst,
+		      enum iris_buffer_type buf_type)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+		list_del_init(&buf->list);
+		kfree(buf);
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_buffer.h b/drivers/media/platform/qcom/vcodec/iris/iris_buffer.h
new file mode 100644
index 0000000..1cd76a9
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_buffer.h
@@ -0,0 +1,49 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_BUFFER_H_
+#define _IRIS_BUFFER_H_
+
+#define MIN_BUFFERS  4
+
+#include "iris_common.h"
+
+struct iris_inst;
+
+struct iris_buffers {
+	struct list_head	list; // list of "struct iris_buffer"
+	u32			min_count;
+	u32			actual_count;
+	u32			size;
+	bool			reuse;
+};
+
+struct iris_buffers_info {
+	struct iris_buffers	input;
+	struct iris_buffers	output;
+	struct iris_buffers	read_only;
+	struct iris_buffers	bin;
+	struct iris_buffers	arp;
+	struct iris_buffers	comv;
+	struct iris_buffers	non_comv;
+	struct iris_buffers	line;
+	struct iris_buffers	dpb;
+	struct iris_buffers	persist;
+	struct iris_buffers	vpss;
+};
+
+int iris_get_buf_min_count(struct iris_inst *inst,
+			   enum iris_buffer_type buffer_type);
+int iris_get_buffer_size(struct iris_inst *inst,
+			 enum iris_buffer_type buffer_type);
+struct iris_buffers *iris_get_buffer_list(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type);
+int iris_allocate_buffers(struct iris_inst *inst,
+			  enum iris_buffer_type buf_type,
+			  u32 num_buffers);
+int iris_free_buffers(struct iris_inst *inst,
+		      enum iris_buffer_type buf_type);
+
+#endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_common.h b/drivers/media/platform/qcom/vcodec/iris/iris_common.h
index 3e4dd71..4edadc3 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_common.h
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_common.h
@@ -5,6 +5,7 @@ 
 #ifndef _IRIS_COMMON_H_
 #define _IRIS_COMMON_H_
 
+#include <media/v4l2-dev.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
@@ -14,7 +15,31 @@ 
 #define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
 #define DEFAULT_WIDTH 320
 #define DEFAULT_HEIGHT 240
-#define DEFAULT_BUF_SIZE 115200
+
+#define MB_IN_PIXEL (16 * 16)
+
+#define NUM_MBS_4k (((4096 + 15) >> 4) * ((2304 + 15) >> 4))
+
+enum codec_type {
+	H264	= BIT(0),
+	HEVC	= BIT(1),
+	VP9	= BIT(2),
+};
+
+enum colorformat_type {
+	FMT_NONE	= 0,
+	FMT_NV12C	= BIT(0),
+	FMT_NV12	= BIT(1),
+	FMT_NV21	= BIT(2),
+	FMT_TP10C	= BIT(3),
+};
+
+struct rect_desc {
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+};
 
 enum signal_session_response {
 	SIGNAL_CMD_STOP_INPUT = 0,
@@ -23,4 +48,48 @@  enum signal_session_response {
 	MAX_SIGNAL,
 };
 
+enum iris_buffer_type {
+	BUF_NONE,
+	BUF_INPUT,
+	BUF_OUTPUT,
+	BUF_READ_ONLY,
+	BUF_BIN,
+	BUF_ARP,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+	BUF_DPB,
+	BUF_PERSIST,
+	BUF_VPSS,
+};
+
+enum iris_buffer_attributes {
+	BUF_ATTR_DEFERRED		= BIT(0),
+	BUF_ATTR_READ_ONLY		= BIT(1),
+	BUF_ATTR_PENDING_RELEASE	= BIT(2),
+	BUF_ATTR_QUEUED			= BIT(3),
+	BUF_ATTR_DEQUEUED		= BIT(4),
+	BUF_ATTR_BUFFER_DONE		= BIT(5),
+};
+
+struct iris_buffer {
+	struct list_head		list;
+	struct iris_inst		*inst;
+	enum iris_buffer_type		type;
+	u32				index;
+	int				fd;
+	u32				buffer_size;
+	u32				data_offset;
+	u32				data_size;
+	u64				device_addr;
+	void				*kvaddr;
+	unsigned long			dma_attrs;
+	u32				flags;
+	u64				timestamp;
+	enum iris_buffer_attributes	attr;
+	void				*dmabuf;
+	struct sg_table			*sg_table;
+	struct dma_buf_attachment	*attach;
+};
+
 #endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_helpers.c b/drivers/media/platform/qcom/vcodec/iris/iris_helpers.c
index 8d8bc3a..54a7851 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_helpers.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_helpers.c
@@ -42,6 +42,30 @@  u32 get_port_info(struct iris_inst *inst,
 	return HFI_PORT_NONE;
 }
 
+enum iris_buffer_type v4l2_type_to_driver(u32 type)
+{
+	switch (type) {
+	case INPUT_MPLANE:
+		return BUF_INPUT;
+	case OUTPUT_MPLANE:
+		return BUF_OUTPUT;
+	default:
+		return 0;
+	}
+}
+
+int get_mbpf(struct iris_inst *inst)
+{
+	int height = 0, width = 0;
+	struct v4l2_format *inp_f;
+
+	inp_f = inst->fmt_src;
+	width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
+	height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+	return NUM_MBS_PER_FRAME(height, width);
+}
+
 static int process_inst_timeout(struct iris_inst *inst)
 {
 	struct iris_inst *instance;
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_helpers.h b/drivers/media/platform/qcom/vcodec/iris/iris_helpers.h
index 60c79124..3bae969 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_helpers.h
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_helpers.h
@@ -11,6 +11,7 @@ 
 
 #include "iris_core.h"
 #include "iris_instance.h"
+#include "iris_buffer.h"
 #include "platform_common.h"
 
 #define NUM_MBS_PER_FRAME(__height, __width) \
@@ -21,7 +22,8 @@  bool res_is_less_than(u32 width, u32 height,
 		      u32 ref_width, u32 ref_height);
 u32 get_port_info(struct iris_inst *inst,
 		  enum plat_inst_cap_type cap_id);
-
+enum iris_buffer_type v4l2_type_to_driver(u32 type);
+int get_mbpf(struct iris_inst *inst);
 int close_session(struct iris_inst *inst);
 
 #endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_instance.h b/drivers/media/platform/qcom/vcodec/iris/iris_instance.h
index f6a3066..a5c6cb48 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_instance.h
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_instance.h
@@ -8,6 +8,8 @@ 
 
 #include <media/v4l2-ctrls.h>
 
+#include "iris_buffer.h"
+#include "iris_common.h"
 #include "iris_core.h"
 #include "iris_common.h"
 #include "platform_common.h"
@@ -25,6 +27,7 @@ 
  * @fmt_src: structure of v4l2_format for source
  * @fmt_dst: structure of v4l2_format for destination
  * @ctrl_handler: reference of v4l2 ctrl handler
+ * @crop: structure of crop info
  * @packet: HFI packet
  * @packet_size: HFI packet size
  * @completions: structure of signal completions
@@ -32,6 +35,7 @@ 
  * @num_ctrls: supported number of controls
  * @caps_list: list head of capability
  * @codec: codec type
+ * @buffers: structure of buffer info
  */
 
 struct iris_inst {
@@ -45,6 +49,7 @@  struct iris_inst {
 	struct v4l2_format		*fmt_src;
 	struct v4l2_format		*fmt_dst;
 	struct v4l2_ctrl_handler	ctrl_handler;
+	struct rect_desc		crop;
 	void				*packet;
 	u32				packet_size;
 	struct completion		completions[MAX_SIGNAL];
@@ -52,6 +57,7 @@  struct iris_inst {
 	u32				num_ctrls;
 	struct list_head		caps_list;
 	enum codec_type			codec;
+	struct iris_buffers_info	buffers;
 };
 
 #endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
new file mode 100644
index 0000000..b040d27
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.c
@@ -0,0 +1,71 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_buffer.h"
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_instance.h"
+#include "iris_vb2.h"
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[])
+{
+	enum iris_buffer_type buffer_type = 0;
+	struct iris_buffers *buffers;
+	struct iris_inst *inst;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	int ret;
+
+	if (!q || !num_buffers || !num_planes || !sizes)
+		return -EINVAL;
+
+	inst = vb2_get_drv_priv(q);
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		f = inst->fmt_src;
+	else
+		f = inst->fmt_dst;
+
+	if (*num_planes) {
+		if (*num_planes != f->fmt.pix_mp.num_planes ||
+		    sizes[0] < f->fmt.pix_mp.plane_fmt[0].sizeimage)
+			return -EINVAL;
+	}
+
+	buffer_type = v4l2_type_to_driver(q->type);
+	if (!buffer_type)
+		return -EINVAL;
+
+	ret = iris_free_buffers(inst, buffer_type);
+	if (ret)
+		return ret;
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	buffers->min_count = iris_get_buf_min_count(inst, buffer_type);
+	if (*num_buffers < buffers->min_count)
+		*num_buffers = buffers->min_count;
+	buffers->actual_count = *num_buffers;
+	*num_planes = 1;
+
+	buffers->size = iris_get_buffer_size(inst, buffer_type);
+
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = buffers->size;
+	sizes[0] = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	ret = iris_allocate_buffers(inst, buffer_type, *num_buffers);
+
+	q->dev = core->dev;
+
+	return ret;
+}
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h
new file mode 100644
index 0000000..8a8e1039
--- /dev/null
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vb2.h
@@ -0,0 +1,15 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VB2_H_
+#define _IRIS_VB2_H_
+
+#include <media/videobuf2-v4l2.h>
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[]);
+
+#endif
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vdec.c b/drivers/media/platform/qcom/vcodec/iris/iris_vdec.c
index 984be34..1b957a13 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_vdec.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vdec.c
@@ -3,6 +3,7 @@ 
  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
+#include "iris_buffer.h"
 #include "iris_common.h"
 #include "iris_vdec.h"
 
@@ -22,7 +23,7 @@  void vdec_inst_init(struct iris_inst *inst)
 	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
 	f->fmt.pix_mp.num_planes = 1;
 	f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
-	f->fmt.pix_mp.plane_fmt[0].sizeimage = DEFAULT_BUF_SIZE;
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
 	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
 
 	f = inst->fmt_dst;
@@ -32,7 +33,7 @@  void vdec_inst_init(struct iris_inst *inst)
 	f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
 	f->fmt.pix_mp.num_planes = 1;
 	f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
-	f->fmt.pix_mp.plane_fmt[0].sizeimage = DEFAULT_BUF_SIZE;
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
 	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
 	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
 	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
diff --git a/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c b/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
index 3a26edb..410de720 100644
--- a/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
+++ b/drivers/media/platform/qcom/vcodec/iris/iris_vidc.c
@@ -10,6 +10,7 @@ 
 #include "iris_vdec.h"
 #include "iris_vidc.h"
 #include "iris_ctrls.h"
+#include "iris_vb2.h"
 
 static int vidc_v4l2_fh_init(struct iris_inst *inst)
 {
@@ -168,13 +169,22 @@  int vidc_open(struct file *filp)
 	inst->core = core;
 	inst->session_id = hash32_ptr(inst);
 	mutex_init(&inst->ctx_q_lock);
-	for (i = 0; i < MAX_SIGNAL; i++)
-		init_completion(&inst->completions[i]);
 
 	ret = vidc_add_session(inst);
 	if (ret)
 		goto fail_free_inst;
 
+	INIT_LIST_HEAD(&inst->buffers.input.list);
+	INIT_LIST_HEAD(&inst->buffers.output.list);
+	INIT_LIST_HEAD(&inst->buffers.read_only.list);
+	INIT_LIST_HEAD(&inst->buffers.bin.list);
+	INIT_LIST_HEAD(&inst->buffers.arp.list);
+	INIT_LIST_HEAD(&inst->buffers.comv.list);
+	INIT_LIST_HEAD(&inst->buffers.non_comv.list);
+	INIT_LIST_HEAD(&inst->buffers.line.list);
+	INIT_LIST_HEAD(&inst->buffers.dpb.list);
+	INIT_LIST_HEAD(&inst->buffers.persist.list);
+	INIT_LIST_HEAD(&inst->buffers.vpss.list);
 	INIT_LIST_HEAD(&inst->caps_list);
 	for (i = 0; i < MAX_SIGNAL; i++)
 		init_completion(&inst->completions[i]);
@@ -306,9 +316,14 @@  static const struct v4l2_file_operations v4l2_file_ops = {
 	.poll                           = vidc_poll,
 };
 
+static const struct vb2_ops iris_vb2_ops = {
+	.queue_setup                    = iris_vb2_queue_setup,
+};
+
 int init_ops(struct iris_core *core)
 {
 	core->v4l2_file_ops = &v4l2_file_ops;
+	core->vb2_ops = &iris_vb2_ops;
 
 	return 0;
 }
diff --git a/drivers/media/platform/qcom/vcodec/iris/platform_common.h b/drivers/media/platform/qcom/vcodec/iris/platform_common.h
index 8305c65..e242614 100644
--- a/drivers/media/platform/qcom/vcodec/iris/platform_common.h
+++ b/drivers/media/platform/qcom/vcodec/iris/platform_common.h
@@ -9,6 +9,8 @@ 
 #include <linux/bits.h>
 #include <media/v4l2-ctrls.h>
 
+#include "iris_common.h"
+
 struct iris_core;
 struct iris_inst;
 
@@ -35,20 +37,6 @@  struct iris_inst;
 	.bank_spreading = bsp,                           \
 }
 
-enum codec_type {
-	H264	= BIT(0),
-	HEVC	= BIT(1),
-	VP9	= BIT(2),
-};
-
-enum colorformat_type {
-	FMT_NONE	= 0,
-	FMT_NV12C	= BIT(0),
-	FMT_NV12	= BIT(1),
-	FMT_NV21	= BIT(2),
-	FMT_TP10C	= BIT(3),
-};
-
 enum stage_type {
 	STAGE_NONE = 0,
 	STAGE_1 = 1,