xref: /linux/drivers/media/platform/qcom/venus/helpers.c (revision bbfc89e6f67ccb1ddefc3e8a284248bcfea58544)
197fb5e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2af2c3834SStanimir Varbanov /*
3af2c3834SStanimir Varbanov  * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
4af2c3834SStanimir Varbanov  * Copyright (C) 2017 Linaro Ltd.
5af2c3834SStanimir Varbanov  */
640d87aafSMansur Alisha Shaik #include <linux/idr.h>
7af2c3834SStanimir Varbanov #include <linux/list.h>
8af2c3834SStanimir Varbanov #include <linux/mutex.h>
9af2c3834SStanimir Varbanov #include <linux/slab.h>
102c2dc2fdSStanimir Varbanov #include <linux/kernel.h>
11cc82fd69SAlexandre Courbot #include <media/videobuf2-dma-contig.h>
12af2c3834SStanimir Varbanov #include <media/v4l2-mem2mem.h>
13af2c3834SStanimir Varbanov #include <asm/div64.h>
14af2c3834SStanimir Varbanov 
15af2c3834SStanimir Varbanov #include "core.h"
16af2c3834SStanimir Varbanov #include "helpers.h"
17af2c3834SStanimir Varbanov #include "hfi_helper.h"
187482a983SStanimir Varbanov #include "pm_helpers.h"
19aa603389SStanimir Varbanov #include "hfi_platform.h"
207371093fSStanimir Varbanov #include "hfi_parser.h"
21af2c3834SStanimir Varbanov 
22fa622c3dSDikshita Agarwal #define NUM_MBS_720P	(((ALIGN(1280, 16)) >> 4) * ((ALIGN(736, 16)) >> 4))
23fa622c3dSDikshita Agarwal #define NUM_MBS_4K	(((ALIGN(4096, 16)) >> 4) * ((ALIGN(2304, 16)) >> 4))
241ad17595SDikshita Agarwal 
2540d87aafSMansur Alisha Shaik enum dpb_buf_owner {
2640d87aafSMansur Alisha Shaik 	DRIVER,
2740d87aafSMansur Alisha Shaik 	FIRMWARE,
2840d87aafSMansur Alisha Shaik };
2940d87aafSMansur Alisha Shaik 
30af2c3834SStanimir Varbanov struct intbuf {
31af2c3834SStanimir Varbanov 	struct list_head list;
32af2c3834SStanimir Varbanov 	u32 type;
33af2c3834SStanimir Varbanov 	size_t size;
34af2c3834SStanimir Varbanov 	void *va;
35af2c3834SStanimir Varbanov 	dma_addr_t da;
36af2c3834SStanimir Varbanov 	unsigned long attrs;
3740d87aafSMansur Alisha Shaik 	enum dpb_buf_owner owned_by;
3840d87aafSMansur Alisha Shaik 	u32 dpb_out_tag;
39af2c3834SStanimir Varbanov };
40af2c3834SStanimir Varbanov 
41d8db57c2SStanimir Varbanov bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt)
42d8db57c2SStanimir Varbanov {
43d8db57c2SStanimir Varbanov 	struct venus_core *core = inst->core;
44d8db57c2SStanimir Varbanov 	u32 session_type = inst->session_type;
45d8db57c2SStanimir Varbanov 	u32 codec;
46d8db57c2SStanimir Varbanov 
47d8db57c2SStanimir Varbanov 	switch (v4l2_pixfmt) {
48d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_H264:
49d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_H264;
50d8db57c2SStanimir Varbanov 		break;
51d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_H263:
52d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_H263;
53d8db57c2SStanimir Varbanov 		break;
54d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_MPEG1:
55d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_MPEG1;
56d8db57c2SStanimir Varbanov 		break;
57d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_MPEG2:
58d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_MPEG2;
59d8db57c2SStanimir Varbanov 		break;
60d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_MPEG4:
61d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_MPEG4;
62d8db57c2SStanimir Varbanov 		break;
63d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_G:
64d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_L:
65d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_VC1;
66d8db57c2SStanimir Varbanov 		break;
67d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_VP8:
68d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_VP8;
69d8db57c2SStanimir Varbanov 		break;
70d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_VP9:
71d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_VP9;
72d8db57c2SStanimir Varbanov 		break;
73d8db57c2SStanimir Varbanov 	case V4L2_PIX_FMT_XVID:
74d8db57c2SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_DIVX;
75d8db57c2SStanimir Varbanov 		break;
761fb9a605SStanimir Varbanov 	case V4L2_PIX_FMT_HEVC:
771fb9a605SStanimir Varbanov 		codec = HFI_VIDEO_CODEC_HEVC;
781fb9a605SStanimir Varbanov 		break;
79d8db57c2SStanimir Varbanov 	default:
80d8db57c2SStanimir Varbanov 		return false;
81d8db57c2SStanimir Varbanov 	}
82d8db57c2SStanimir Varbanov 
83d8db57c2SStanimir Varbanov 	if (session_type == VIDC_SESSION_TYPE_ENC && core->enc_codecs & codec)
84d8db57c2SStanimir Varbanov 		return true;
85d8db57c2SStanimir Varbanov 
86d8db57c2SStanimir Varbanov 	if (session_type == VIDC_SESSION_TYPE_DEC && core->dec_codecs & codec)
87d8db57c2SStanimir Varbanov 		return true;
88d8db57c2SStanimir Varbanov 
89d8db57c2SStanimir Varbanov 	return false;
90d8db57c2SStanimir Varbanov }
91d8db57c2SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_check_codec);
92d8db57c2SStanimir Varbanov 
9373664f10SVikash Garodia static void free_dpb_buf(struct venus_inst *inst, struct intbuf *buf)
9473664f10SVikash Garodia {
9573664f10SVikash Garodia 	ida_free(&inst->dpb_ids, buf->dpb_out_tag);
9673664f10SVikash Garodia 
9773664f10SVikash Garodia 	list_del_init(&buf->list);
9873664f10SVikash Garodia 	dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
9973664f10SVikash Garodia 		       buf->attrs);
10073664f10SVikash Garodia 	kfree(buf);
10173664f10SVikash Garodia }
10273664f10SVikash Garodia 
1031e485ee5SStanimir Varbanov int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
104f012b23dSStanimir Varbanov {
10573664f10SVikash Garodia 	struct intbuf *buf, *next;
10673664f10SVikash Garodia 	unsigned int dpb_size = 0;
107f012b23dSStanimir Varbanov 	int ret = 0;
108f012b23dSStanimir Varbanov 
10973664f10SVikash Garodia 	if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
11073664f10SVikash Garodia 		dpb_size = inst->output_buf_size;
11173664f10SVikash Garodia 	else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
11273664f10SVikash Garodia 		dpb_size = inst->output2_buf_size;
11373664f10SVikash Garodia 
11473664f10SVikash Garodia 	list_for_each_entry_safe(buf, next, &inst->dpbbufs, list) {
115f012b23dSStanimir Varbanov 		struct hfi_frame_data fdata;
116f012b23dSStanimir Varbanov 
117f012b23dSStanimir Varbanov 		memset(&fdata, 0, sizeof(fdata));
118f012b23dSStanimir Varbanov 		fdata.alloc_len = buf->size;
119f012b23dSStanimir Varbanov 		fdata.device_addr = buf->da;
120f012b23dSStanimir Varbanov 		fdata.buffer_type = buf->type;
121f012b23dSStanimir Varbanov 
12240d87aafSMansur Alisha Shaik 		if (buf->owned_by == FIRMWARE)
12340d87aafSMansur Alisha Shaik 			continue;
12440d87aafSMansur Alisha Shaik 
12573664f10SVikash Garodia 		/* free buffer from previous sequence which was released later */
12673664f10SVikash Garodia 		if (dpb_size > buf->size) {
12773664f10SVikash Garodia 			free_dpb_buf(inst, buf);
12873664f10SVikash Garodia 			continue;
12973664f10SVikash Garodia 		}
13073664f10SVikash Garodia 
13140d87aafSMansur Alisha Shaik 		fdata.clnt_data = buf->dpb_out_tag;
13240d87aafSMansur Alisha Shaik 
133f012b23dSStanimir Varbanov 		ret = hfi_session_process_buf(inst, &fdata);
134f012b23dSStanimir Varbanov 		if (ret)
135f012b23dSStanimir Varbanov 			goto fail;
13640d87aafSMansur Alisha Shaik 
13740d87aafSMansur Alisha Shaik 		buf->owned_by = FIRMWARE;
138f012b23dSStanimir Varbanov 	}
139f012b23dSStanimir Varbanov 
140f012b23dSStanimir Varbanov fail:
141f012b23dSStanimir Varbanov 	return ret;
142f012b23dSStanimir Varbanov }
1431e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs);
144f012b23dSStanimir Varbanov 
145f012b23dSStanimir Varbanov int venus_helper_free_dpb_bufs(struct venus_inst *inst)
146f012b23dSStanimir Varbanov {
147f012b23dSStanimir Varbanov 	struct intbuf *buf, *n;
148f012b23dSStanimir Varbanov 
149f012b23dSStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) {
15040d87aafSMansur Alisha Shaik 		if (buf->owned_by == FIRMWARE)
15140d87aafSMansur Alisha Shaik 			continue;
15273664f10SVikash Garodia 		free_dpb_buf(inst, buf);
153f012b23dSStanimir Varbanov 	}
154f012b23dSStanimir Varbanov 
15540d87aafSMansur Alisha Shaik 	if (list_empty(&inst->dpbbufs))
156f012b23dSStanimir Varbanov 		INIT_LIST_HEAD(&inst->dpbbufs);
157f012b23dSStanimir Varbanov 
158f012b23dSStanimir Varbanov 	return 0;
159f012b23dSStanimir Varbanov }
160f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs);
161f012b23dSStanimir Varbanov 
162f012b23dSStanimir Varbanov int venus_helper_alloc_dpb_bufs(struct venus_inst *inst)
163f012b23dSStanimir Varbanov {
164f012b23dSStanimir Varbanov 	struct venus_core *core = inst->core;
165f012b23dSStanimir Varbanov 	struct device *dev = core->dev;
166f012b23dSStanimir Varbanov 	enum hfi_version ver = core->res->hfi_version;
167f012b23dSStanimir Varbanov 	struct hfi_buffer_requirements bufreq;
168f012b23dSStanimir Varbanov 	u32 buftype = inst->dpb_buftype;
169f012b23dSStanimir Varbanov 	unsigned int dpb_size = 0;
170f012b23dSStanimir Varbanov 	struct intbuf *buf;
171f012b23dSStanimir Varbanov 	unsigned int i;
172f012b23dSStanimir Varbanov 	u32 count;
173f012b23dSStanimir Varbanov 	int ret;
17440d87aafSMansur Alisha Shaik 	int id;
175f012b23dSStanimir Varbanov 
176f012b23dSStanimir Varbanov 	/* no need to allocate dpb buffers */
177f012b23dSStanimir Varbanov 	if (!inst->dpb_fmt)
178f012b23dSStanimir Varbanov 		return 0;
179f012b23dSStanimir Varbanov 
180f012b23dSStanimir Varbanov 	if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
181f012b23dSStanimir Varbanov 		dpb_size = inst->output_buf_size;
182f012b23dSStanimir Varbanov 	else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
183f012b23dSStanimir Varbanov 		dpb_size = inst->output2_buf_size;
184f012b23dSStanimir Varbanov 
185f012b23dSStanimir Varbanov 	if (!dpb_size)
186f012b23dSStanimir Varbanov 		return 0;
187f012b23dSStanimir Varbanov 
188f012b23dSStanimir Varbanov 	ret = venus_helper_get_bufreq(inst, buftype, &bufreq);
189f012b23dSStanimir Varbanov 	if (ret)
190f012b23dSStanimir Varbanov 		return ret;
191f012b23dSStanimir Varbanov 
192*bbfc89e6SKonrad Dybcio 	count = hfi_bufreq_get_count_min(&bufreq, ver);
193f012b23dSStanimir Varbanov 
194f012b23dSStanimir Varbanov 	for (i = 0; i < count; i++) {
195f012b23dSStanimir Varbanov 		buf = kzalloc(sizeof(*buf), GFP_KERNEL);
196f012b23dSStanimir Varbanov 		if (!buf) {
197f012b23dSStanimir Varbanov 			ret = -ENOMEM;
198f012b23dSStanimir Varbanov 			goto fail;
199f012b23dSStanimir Varbanov 		}
200f012b23dSStanimir Varbanov 
201f012b23dSStanimir Varbanov 		buf->type = buftype;
202f012b23dSStanimir Varbanov 		buf->size = dpb_size;
203f012b23dSStanimir Varbanov 		buf->attrs = DMA_ATTR_WRITE_COMBINE |
204f012b23dSStanimir Varbanov 			     DMA_ATTR_NO_KERNEL_MAPPING;
205f012b23dSStanimir Varbanov 		buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL,
206f012b23dSStanimir Varbanov 					  buf->attrs);
207f012b23dSStanimir Varbanov 		if (!buf->va) {
208f012b23dSStanimir Varbanov 			ret = -ENOMEM;
209f012b23dSStanimir Varbanov 			goto fail;
210f012b23dSStanimir Varbanov 		}
21140d87aafSMansur Alisha Shaik 		buf->owned_by = DRIVER;
21240d87aafSMansur Alisha Shaik 
21340d87aafSMansur Alisha Shaik 		id = ida_alloc_min(&inst->dpb_ids, VB2_MAX_FRAME, GFP_KERNEL);
21440d87aafSMansur Alisha Shaik 		if (id < 0) {
21540d87aafSMansur Alisha Shaik 			ret = id;
21640d87aafSMansur Alisha Shaik 			goto fail;
21740d87aafSMansur Alisha Shaik 		}
21840d87aafSMansur Alisha Shaik 
21940d87aafSMansur Alisha Shaik 		buf->dpb_out_tag = id;
220f012b23dSStanimir Varbanov 
221f012b23dSStanimir Varbanov 		list_add_tail(&buf->list, &inst->dpbbufs);
222f012b23dSStanimir Varbanov 	}
223f012b23dSStanimir Varbanov 
224f012b23dSStanimir Varbanov 	return 0;
225f012b23dSStanimir Varbanov 
226f012b23dSStanimir Varbanov fail:
2278403fdd7SAmeer Hamza 	kfree(buf);
228f012b23dSStanimir Varbanov 	venus_helper_free_dpb_bufs(inst);
229f012b23dSStanimir Varbanov 	return ret;
230f012b23dSStanimir Varbanov }
231f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs);
232f012b23dSStanimir Varbanov 
233af2c3834SStanimir Varbanov static int intbufs_set_buffer(struct venus_inst *inst, u32 type)
234af2c3834SStanimir Varbanov {
235af2c3834SStanimir Varbanov 	struct venus_core *core = inst->core;
236af2c3834SStanimir Varbanov 	struct device *dev = core->dev;
237af2c3834SStanimir Varbanov 	struct hfi_buffer_requirements bufreq;
238af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd;
239af2c3834SStanimir Varbanov 	struct intbuf *buf;
240af2c3834SStanimir Varbanov 	unsigned int i;
241af2c3834SStanimir Varbanov 	int ret;
242af2c3834SStanimir Varbanov 
243af2c3834SStanimir Varbanov 	ret = venus_helper_get_bufreq(inst, type, &bufreq);
244af2c3834SStanimir Varbanov 	if (ret)
245af2c3834SStanimir Varbanov 		return 0;
246af2c3834SStanimir Varbanov 
247af2c3834SStanimir Varbanov 	if (!bufreq.size)
248af2c3834SStanimir Varbanov 		return 0;
249af2c3834SStanimir Varbanov 
250af2c3834SStanimir Varbanov 	for (i = 0; i < bufreq.count_actual; i++) {
251af2c3834SStanimir Varbanov 		buf = kzalloc(sizeof(*buf), GFP_KERNEL);
252af2c3834SStanimir Varbanov 		if (!buf) {
253af2c3834SStanimir Varbanov 			ret = -ENOMEM;
254af2c3834SStanimir Varbanov 			goto fail;
255af2c3834SStanimir Varbanov 		}
256af2c3834SStanimir Varbanov 
257af2c3834SStanimir Varbanov 		buf->type = bufreq.type;
258af2c3834SStanimir Varbanov 		buf->size = bufreq.size;
259af2c3834SStanimir Varbanov 		buf->attrs = DMA_ATTR_WRITE_COMBINE |
260af2c3834SStanimir Varbanov 			     DMA_ATTR_NO_KERNEL_MAPPING;
261af2c3834SStanimir Varbanov 		buf->va = dma_alloc_attrs(dev, buf->size, &buf->da, GFP_KERNEL,
262af2c3834SStanimir Varbanov 					  buf->attrs);
263af2c3834SStanimir Varbanov 		if (!buf->va) {
264af2c3834SStanimir Varbanov 			ret = -ENOMEM;
265af2c3834SStanimir Varbanov 			goto fail;
266af2c3834SStanimir Varbanov 		}
267af2c3834SStanimir Varbanov 
268af2c3834SStanimir Varbanov 		memset(&bd, 0, sizeof(bd));
269af2c3834SStanimir Varbanov 		bd.buffer_size = buf->size;
270af2c3834SStanimir Varbanov 		bd.buffer_type = buf->type;
271af2c3834SStanimir Varbanov 		bd.num_buffers = 1;
272af2c3834SStanimir Varbanov 		bd.device_addr = buf->da;
273af2c3834SStanimir Varbanov 
274af2c3834SStanimir Varbanov 		ret = hfi_session_set_buffers(inst, &bd);
275af2c3834SStanimir Varbanov 		if (ret) {
276af2c3834SStanimir Varbanov 			dev_err(dev, "set session buffers failed\n");
277af2c3834SStanimir Varbanov 			goto dma_free;
278af2c3834SStanimir Varbanov 		}
279af2c3834SStanimir Varbanov 
280af2c3834SStanimir Varbanov 		list_add_tail(&buf->list, &inst->internalbufs);
281af2c3834SStanimir Varbanov 	}
282af2c3834SStanimir Varbanov 
283af2c3834SStanimir Varbanov 	return 0;
284af2c3834SStanimir Varbanov 
285af2c3834SStanimir Varbanov dma_free:
286af2c3834SStanimir Varbanov 	dma_free_attrs(dev, buf->size, buf->va, buf->da, buf->attrs);
287af2c3834SStanimir Varbanov fail:
288af2c3834SStanimir Varbanov 	kfree(buf);
289af2c3834SStanimir Varbanov 	return ret;
290af2c3834SStanimir Varbanov }
291af2c3834SStanimir Varbanov 
292af2c3834SStanimir Varbanov static int intbufs_unset_buffers(struct venus_inst *inst)
293af2c3834SStanimir Varbanov {
294af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd = {0};
295af2c3834SStanimir Varbanov 	struct intbuf *buf, *n;
296af2c3834SStanimir Varbanov 	int ret = 0;
297af2c3834SStanimir Varbanov 
298af2c3834SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {
299af2c3834SStanimir Varbanov 		bd.buffer_size = buf->size;
300af2c3834SStanimir Varbanov 		bd.buffer_type = buf->type;
301af2c3834SStanimir Varbanov 		bd.num_buffers = 1;
302af2c3834SStanimir Varbanov 		bd.device_addr = buf->da;
303af2c3834SStanimir Varbanov 		bd.response_required = true;
304af2c3834SStanimir Varbanov 
305af2c3834SStanimir Varbanov 		ret = hfi_session_unset_buffers(inst, &bd);
306af2c3834SStanimir Varbanov 
307af2c3834SStanimir Varbanov 		list_del_init(&buf->list);
308af2c3834SStanimir Varbanov 		dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
309af2c3834SStanimir Varbanov 			       buf->attrs);
310af2c3834SStanimir Varbanov 		kfree(buf);
311af2c3834SStanimir Varbanov 	}
312af2c3834SStanimir Varbanov 
313af2c3834SStanimir Varbanov 	return ret;
314af2c3834SStanimir Varbanov }
315af2c3834SStanimir Varbanov 
316f04997bdSStanimir Varbanov static const unsigned int intbuf_types_1xx[] = {
317f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX),
318f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX),
319f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX),
320f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_PERSIST,
321f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_PERSIST_1,
322f04997bdSStanimir Varbanov };
323f04997bdSStanimir Varbanov 
324f04997bdSStanimir Varbanov static const unsigned int intbuf_types_4xx[] = {
325f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX),
326f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX),
327f04997bdSStanimir Varbanov 	HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX),
328af2c3834SStanimir Varbanov 	HFI_BUFFER_INTERNAL_PERSIST,
329af2c3834SStanimir Varbanov 	HFI_BUFFER_INTERNAL_PERSIST_1,
330af2c3834SStanimir Varbanov };
331af2c3834SStanimir Varbanov 
332c934d9d4SDikshita Agarwal static const unsigned int intbuf_types_6xx[] = {
333c934d9d4SDikshita Agarwal 	HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_6XX),
334c934d9d4SDikshita Agarwal 	HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_6XX),
335c934d9d4SDikshita Agarwal 	HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_6XX),
336c934d9d4SDikshita Agarwal 	HFI_BUFFER_INTERNAL_PERSIST,
337c934d9d4SDikshita Agarwal 	HFI_BUFFER_INTERNAL_PERSIST_1,
338c934d9d4SDikshita Agarwal };
339c934d9d4SDikshita Agarwal 
3401e485ee5SStanimir Varbanov int venus_helper_intbufs_alloc(struct venus_inst *inst)
341af2c3834SStanimir Varbanov {
342f04997bdSStanimir Varbanov 	const unsigned int *intbuf;
343f04997bdSStanimir Varbanov 	size_t arr_sz, i;
344af2c3834SStanimir Varbanov 	int ret;
345af2c3834SStanimir Varbanov 
346c934d9d4SDikshita Agarwal 	if (IS_V6(inst->core)) {
347c934d9d4SDikshita Agarwal 		arr_sz = ARRAY_SIZE(intbuf_types_6xx);
348c934d9d4SDikshita Agarwal 		intbuf = intbuf_types_6xx;
349c934d9d4SDikshita Agarwal 	} else if (IS_V4(inst->core)) {
350f04997bdSStanimir Varbanov 		arr_sz = ARRAY_SIZE(intbuf_types_4xx);
351f04997bdSStanimir Varbanov 		intbuf = intbuf_types_4xx;
352f04997bdSStanimir Varbanov 	} else {
353f04997bdSStanimir Varbanov 		arr_sz = ARRAY_SIZE(intbuf_types_1xx);
354f04997bdSStanimir Varbanov 		intbuf = intbuf_types_1xx;
355f04997bdSStanimir Varbanov 	}
356f04997bdSStanimir Varbanov 
357f04997bdSStanimir Varbanov 	for (i = 0; i < arr_sz; i++) {
358f04997bdSStanimir Varbanov 		ret = intbufs_set_buffer(inst, intbuf[i]);
359af2c3834SStanimir Varbanov 		if (ret)
360af2c3834SStanimir Varbanov 			goto error;
361af2c3834SStanimir Varbanov 	}
362af2c3834SStanimir Varbanov 
363af2c3834SStanimir Varbanov 	return 0;
364af2c3834SStanimir Varbanov 
365af2c3834SStanimir Varbanov error:
366af2c3834SStanimir Varbanov 	intbufs_unset_buffers(inst);
367af2c3834SStanimir Varbanov 	return ret;
368af2c3834SStanimir Varbanov }
3691e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc);
370af2c3834SStanimir Varbanov 
3711e485ee5SStanimir Varbanov int venus_helper_intbufs_free(struct venus_inst *inst)
372af2c3834SStanimir Varbanov {
373af2c3834SStanimir Varbanov 	return intbufs_unset_buffers(inst);
374af2c3834SStanimir Varbanov }
3751e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_free);
376af2c3834SStanimir Varbanov 
37714ea00d6SStanimir Varbanov int venus_helper_intbufs_realloc(struct venus_inst *inst)
37814ea00d6SStanimir Varbanov {
37914ea00d6SStanimir Varbanov 	enum hfi_version ver = inst->core->res->hfi_version;
38014ea00d6SStanimir Varbanov 	struct hfi_buffer_desc bd;
38114ea00d6SStanimir Varbanov 	struct intbuf *buf, *n;
38214ea00d6SStanimir Varbanov 	int ret;
38314ea00d6SStanimir Varbanov 
38414ea00d6SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {
38514ea00d6SStanimir Varbanov 		if (buf->type == HFI_BUFFER_INTERNAL_PERSIST ||
38614ea00d6SStanimir Varbanov 		    buf->type == HFI_BUFFER_INTERNAL_PERSIST_1)
38714ea00d6SStanimir Varbanov 			continue;
38814ea00d6SStanimir Varbanov 
38914ea00d6SStanimir Varbanov 		memset(&bd, 0, sizeof(bd));
39014ea00d6SStanimir Varbanov 		bd.buffer_size = buf->size;
39114ea00d6SStanimir Varbanov 		bd.buffer_type = buf->type;
39214ea00d6SStanimir Varbanov 		bd.num_buffers = 1;
39314ea00d6SStanimir Varbanov 		bd.device_addr = buf->da;
39414ea00d6SStanimir Varbanov 		bd.response_required = true;
39514ea00d6SStanimir Varbanov 
39614ea00d6SStanimir Varbanov 		ret = hfi_session_unset_buffers(inst, &bd);
39714ea00d6SStanimir Varbanov 
39814ea00d6SStanimir Varbanov 		dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
39914ea00d6SStanimir Varbanov 			       buf->attrs);
40014ea00d6SStanimir Varbanov 
40114ea00d6SStanimir Varbanov 		list_del_init(&buf->list);
40214ea00d6SStanimir Varbanov 		kfree(buf);
40314ea00d6SStanimir Varbanov 	}
40414ea00d6SStanimir Varbanov 
40514ea00d6SStanimir Varbanov 	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver));
40614ea00d6SStanimir Varbanov 	if (ret)
40714ea00d6SStanimir Varbanov 		goto err;
40814ea00d6SStanimir Varbanov 
40914ea00d6SStanimir Varbanov 	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver));
41014ea00d6SStanimir Varbanov 	if (ret)
41114ea00d6SStanimir Varbanov 		goto err;
41214ea00d6SStanimir Varbanov 
41314ea00d6SStanimir Varbanov 	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver));
41414ea00d6SStanimir Varbanov 	if (ret)
41514ea00d6SStanimir Varbanov 		goto err;
41614ea00d6SStanimir Varbanov 
41714ea00d6SStanimir Varbanov 	return 0;
41814ea00d6SStanimir Varbanov err:
41914ea00d6SStanimir Varbanov 	return ret;
42014ea00d6SStanimir Varbanov }
42114ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);
42214ea00d6SStanimir Varbanov 
423af2c3834SStanimir Varbanov static void fill_buffer_desc(const struct venus_buffer *buf,
424af2c3834SStanimir Varbanov 			     struct hfi_buffer_desc *bd, bool response)
425af2c3834SStanimir Varbanov {
426af2c3834SStanimir Varbanov 	memset(bd, 0, sizeof(*bd));
427af2c3834SStanimir Varbanov 	bd->buffer_type = HFI_BUFFER_OUTPUT;
428af2c3834SStanimir Varbanov 	bd->buffer_size = buf->size;
429af2c3834SStanimir Varbanov 	bd->num_buffers = 1;
430af2c3834SStanimir Varbanov 	bd->device_addr = buf->dma_addr;
431af2c3834SStanimir Varbanov 	bd->response_required = response;
432af2c3834SStanimir Varbanov }
433af2c3834SStanimir Varbanov 
434af2c3834SStanimir Varbanov static void return_buf_error(struct venus_inst *inst,
435af2c3834SStanimir Varbanov 			     struct vb2_v4l2_buffer *vbuf)
436af2c3834SStanimir Varbanov {
437af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
438af2c3834SStanimir Varbanov 
439af2c3834SStanimir Varbanov 	if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
440af2c3834SStanimir Varbanov 		v4l2_m2m_src_buf_remove_by_buf(m2m_ctx, vbuf);
441af2c3834SStanimir Varbanov 	else
4420de0ef6cSGustavo A. R. Silva 		v4l2_m2m_dst_buf_remove_by_buf(m2m_ctx, vbuf);
443af2c3834SStanimir Varbanov 
444af2c3834SStanimir Varbanov 	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
445af2c3834SStanimir Varbanov }
446af2c3834SStanimir Varbanov 
447d42974e4SStanimir Varbanov static void
448d42974e4SStanimir Varbanov put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
449d42974e4SStanimir Varbanov {
450d42974e4SStanimir Varbanov 	struct vb2_buffer *vb = &vbuf->vb2_buf;
451d42974e4SStanimir Varbanov 	unsigned int i;
452d42974e4SStanimir Varbanov 	int slot = -1;
453d42974e4SStanimir Varbanov 	u64 ts_us = vb->timestamp;
454d42974e4SStanimir Varbanov 
455d42974e4SStanimir Varbanov 	for (i = 0; i < ARRAY_SIZE(inst->tss); i++) {
456d42974e4SStanimir Varbanov 		if (!inst->tss[i].used) {
457d42974e4SStanimir Varbanov 			slot = i;
458d42974e4SStanimir Varbanov 			break;
459d42974e4SStanimir Varbanov 		}
460d42974e4SStanimir Varbanov 	}
461d42974e4SStanimir Varbanov 
462d42974e4SStanimir Varbanov 	if (slot == -1) {
4638c91dc08SStanimir Varbanov 		dev_dbg(inst->core->dev, VDBGL "no free slot\n");
464d42974e4SStanimir Varbanov 		return;
465d42974e4SStanimir Varbanov 	}
466d42974e4SStanimir Varbanov 
467d42974e4SStanimir Varbanov 	do_div(ts_us, NSEC_PER_USEC);
468d42974e4SStanimir Varbanov 
469d42974e4SStanimir Varbanov 	inst->tss[slot].used = true;
470d42974e4SStanimir Varbanov 	inst->tss[slot].flags = vbuf->flags;
471d42974e4SStanimir Varbanov 	inst->tss[slot].tc = vbuf->timecode;
472d42974e4SStanimir Varbanov 	inst->tss[slot].ts_us = ts_us;
473d42974e4SStanimir Varbanov 	inst->tss[slot].ts_ns = vb->timestamp;
474d42974e4SStanimir Varbanov }
475d42974e4SStanimir Varbanov 
476d42974e4SStanimir Varbanov void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
477d42974e4SStanimir Varbanov 				  struct vb2_v4l2_buffer *vbuf)
478d42974e4SStanimir Varbanov {
479d42974e4SStanimir Varbanov 	struct vb2_buffer *vb = &vbuf->vb2_buf;
480d42974e4SStanimir Varbanov 	unsigned int i;
481d42974e4SStanimir Varbanov 
482d42974e4SStanimir Varbanov 	for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) {
483d42974e4SStanimir Varbanov 		if (!inst->tss[i].used)
484d42974e4SStanimir Varbanov 			continue;
485d42974e4SStanimir Varbanov 
486d42974e4SStanimir Varbanov 		if (inst->tss[i].ts_us != timestamp_us)
487d42974e4SStanimir Varbanov 			continue;
488d42974e4SStanimir Varbanov 
489d42974e4SStanimir Varbanov 		inst->tss[i].used = false;
490d42974e4SStanimir Varbanov 		vbuf->flags |= inst->tss[i].flags;
491d42974e4SStanimir Varbanov 		vbuf->timecode = inst->tss[i].tc;
492d42974e4SStanimir Varbanov 		vb->timestamp = inst->tss[i].ts_ns;
493d42974e4SStanimir Varbanov 		break;
494d42974e4SStanimir Varbanov 	}
495d42974e4SStanimir Varbanov }
496d42974e4SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata);
497d42974e4SStanimir Varbanov 
498af2c3834SStanimir Varbanov static int
499af2c3834SStanimir Varbanov session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
500af2c3834SStanimir Varbanov {
501af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
502af2c3834SStanimir Varbanov 	struct vb2_buffer *vb = &vbuf->vb2_buf;
503af2c3834SStanimir Varbanov 	unsigned int type = vb->type;
504af2c3834SStanimir Varbanov 	struct hfi_frame_data fdata;
505af2c3834SStanimir Varbanov 
506af2c3834SStanimir Varbanov 	memset(&fdata, 0, sizeof(fdata));
507af2c3834SStanimir Varbanov 	fdata.alloc_len = buf->size;
508af2c3834SStanimir Varbanov 	fdata.device_addr = buf->dma_addr;
509af2c3834SStanimir Varbanov 	fdata.timestamp = vb->timestamp;
510af2c3834SStanimir Varbanov 	do_div(fdata.timestamp, NSEC_PER_USEC);
511af2c3834SStanimir Varbanov 	fdata.flags = 0;
512af2c3834SStanimir Varbanov 	fdata.clnt_data = vbuf->vb2_buf.index;
513af2c3834SStanimir Varbanov 
514af2c3834SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
515af2c3834SStanimir Varbanov 		fdata.buffer_type = HFI_BUFFER_INPUT;
516af2c3834SStanimir Varbanov 		fdata.filled_len = vb2_get_plane_payload(vb, 0);
517af2c3834SStanimir Varbanov 		fdata.offset = vb->planes[0].data_offset;
518af2c3834SStanimir Varbanov 
519af2c3834SStanimir Varbanov 		if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
520af2c3834SStanimir Varbanov 			fdata.flags |= HFI_BUFFERFLAG_EOS;
521d42974e4SStanimir Varbanov 
522d42974e4SStanimir Varbanov 		if (inst->session_type == VIDC_SESSION_TYPE_DEC)
523d42974e4SStanimir Varbanov 			put_ts_metadata(inst, vbuf);
524c0e284ccSAniket Masule 
5257482a983SStanimir Varbanov 		venus_pm_load_scale(inst);
526af2c3834SStanimir Varbanov 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
527f012b23dSStanimir Varbanov 		if (inst->session_type == VIDC_SESSION_TYPE_ENC)
528af2c3834SStanimir Varbanov 			fdata.buffer_type = HFI_BUFFER_OUTPUT;
529f012b23dSStanimir Varbanov 		else
530f012b23dSStanimir Varbanov 			fdata.buffer_type = inst->opb_buftype;
531af2c3834SStanimir Varbanov 		fdata.filled_len = 0;
532af2c3834SStanimir Varbanov 		fdata.offset = 0;
533af2c3834SStanimir Varbanov 	}
534af2c3834SStanimir Varbanov 
53598d43518SQinglang Miao 	return hfi_session_process_buf(inst, &fdata);
536af2c3834SStanimir Varbanov }
537af2c3834SStanimir Varbanov 
538f0383520SStanimir Varbanov static bool is_dynamic_bufmode(struct venus_inst *inst)
539af2c3834SStanimir Varbanov {
540f0383520SStanimir Varbanov 	struct venus_core *core = inst->core;
5418f3b41dcSStanimir Varbanov 	struct hfi_plat_caps *caps;
542f0383520SStanimir Varbanov 
543bc8c479aSStanimir Varbanov 	/*
544bc8c479aSStanimir Varbanov 	 * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports
545bc8c479aSStanimir Varbanov 	 * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2.
546bc8c479aSStanimir Varbanov 	 */
5477ed9e0b3SBryan O'Donoghue 	if (IS_V4(core) || IS_V6(core))
548bc8c479aSStanimir Varbanov 		return true;
549bc8c479aSStanimir Varbanov 
550f0383520SStanimir Varbanov 	caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
551f0383520SStanimir Varbanov 	if (!caps)
5521cafbb86SGustavo A. R. Silva 		return false;
553af2c3834SStanimir Varbanov 
554f0383520SStanimir Varbanov 	return caps->cap_bufs_mode_dynamic;
555af2c3834SStanimir Varbanov }
556af2c3834SStanimir Varbanov 
5571e485ee5SStanimir Varbanov int venus_helper_unregister_bufs(struct venus_inst *inst)
558af2c3834SStanimir Varbanov {
559af2c3834SStanimir Varbanov 	struct venus_buffer *buf, *n;
560af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd;
561af2c3834SStanimir Varbanov 	int ret = 0;
562af2c3834SStanimir Varbanov 
563f0383520SStanimir Varbanov 	if (is_dynamic_bufmode(inst))
564af2c3834SStanimir Varbanov 		return 0;
565af2c3834SStanimir Varbanov 
566af2c3834SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->registeredbufs, reg_list) {
567af2c3834SStanimir Varbanov 		fill_buffer_desc(buf, &bd, true);
568af2c3834SStanimir Varbanov 		ret = hfi_session_unset_buffers(inst, &bd);
569af2c3834SStanimir Varbanov 		list_del_init(&buf->reg_list);
570af2c3834SStanimir Varbanov 	}
571af2c3834SStanimir Varbanov 
572af2c3834SStanimir Varbanov 	return ret;
573af2c3834SStanimir Varbanov }
5741e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs);
575af2c3834SStanimir Varbanov 
576af2c3834SStanimir Varbanov static int session_register_bufs(struct venus_inst *inst)
577af2c3834SStanimir Varbanov {
578af2c3834SStanimir Varbanov 	struct venus_core *core = inst->core;
579af2c3834SStanimir Varbanov 	struct device *dev = core->dev;
580af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd;
581af2c3834SStanimir Varbanov 	struct venus_buffer *buf;
582af2c3834SStanimir Varbanov 	int ret = 0;
583af2c3834SStanimir Varbanov 
584f0383520SStanimir Varbanov 	if (is_dynamic_bufmode(inst))
585af2c3834SStanimir Varbanov 		return 0;
586af2c3834SStanimir Varbanov 
587af2c3834SStanimir Varbanov 	list_for_each_entry(buf, &inst->registeredbufs, reg_list) {
588af2c3834SStanimir Varbanov 		fill_buffer_desc(buf, &bd, false);
589af2c3834SStanimir Varbanov 		ret = hfi_session_set_buffers(inst, &bd);
590af2c3834SStanimir Varbanov 		if (ret) {
591af2c3834SStanimir Varbanov 			dev_err(dev, "%s: set buffer failed\n", __func__);
592af2c3834SStanimir Varbanov 			break;
593af2c3834SStanimir Varbanov 		}
594af2c3834SStanimir Varbanov 	}
595af2c3834SStanimir Varbanov 
596af2c3834SStanimir Varbanov 	return ret;
597af2c3834SStanimir Varbanov }
598af2c3834SStanimir Varbanov 
599ab97a3fbSStanimir Varbanov static u32 to_hfi_raw_fmt(u32 v4l2_fmt)
600ab97a3fbSStanimir Varbanov {
601ab97a3fbSStanimir Varbanov 	switch (v4l2_fmt) {
602ab97a3fbSStanimir Varbanov 	case V4L2_PIX_FMT_NV12:
603ab97a3fbSStanimir Varbanov 		return HFI_COLOR_FORMAT_NV12;
604ab97a3fbSStanimir Varbanov 	case V4L2_PIX_FMT_NV21:
605ab97a3fbSStanimir Varbanov 		return HFI_COLOR_FORMAT_NV21;
6069593126dSStanimir Varbanov 	case V4L2_PIX_FMT_QC08C:
6079593126dSStanimir Varbanov 		return HFI_COLOR_FORMAT_NV12_UBWC;
608cef92b14SStanimir Varbanov 	case V4L2_PIX_FMT_QC10C:
609cef92b14SStanimir Varbanov 		return HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
61030956077SDikshita Agarwal 	case V4L2_PIX_FMT_P010:
61130956077SDikshita Agarwal 		return HFI_COLOR_FORMAT_P010;
612ab97a3fbSStanimir Varbanov 	default:
613ab97a3fbSStanimir Varbanov 		break;
614ab97a3fbSStanimir Varbanov 	}
615ab97a3fbSStanimir Varbanov 
616ab97a3fbSStanimir Varbanov 	return 0;
617ab97a3fbSStanimir Varbanov }
618ab97a3fbSStanimir Varbanov 
6197371093fSStanimir Varbanov static int platform_get_bufreq(struct venus_inst *inst, u32 buftype,
6207371093fSStanimir Varbanov 			       struct hfi_buffer_requirements *req)
6217371093fSStanimir Varbanov {
6227371093fSStanimir Varbanov 	enum hfi_version version = inst->core->res->hfi_version;
6237371093fSStanimir Varbanov 	const struct hfi_platform *hfi_plat;
6247371093fSStanimir Varbanov 	struct hfi_plat_buffers_params params;
6257371093fSStanimir Varbanov 	bool is_dec = inst->session_type == VIDC_SESSION_TYPE_DEC;
6267371093fSStanimir Varbanov 	struct venc_controls *enc_ctr = &inst->controls.enc;
6277371093fSStanimir Varbanov 
6287371093fSStanimir Varbanov 	hfi_plat = hfi_platform_get(version);
6297371093fSStanimir Varbanov 
6307371093fSStanimir Varbanov 	if (!hfi_plat || !hfi_plat->bufreq)
6317371093fSStanimir Varbanov 		return -EINVAL;
6327371093fSStanimir Varbanov 
6337371093fSStanimir Varbanov 	params.version = version;
634920173c7SDikshita Agarwal 	params.num_vpp_pipes = inst->core->res->num_vpp_pipes;
6357371093fSStanimir Varbanov 
6367371093fSStanimir Varbanov 	if (is_dec) {
6377371093fSStanimir Varbanov 		params.width = inst->width;
6387371093fSStanimir Varbanov 		params.height = inst->height;
63958b64dd0SDikshita Agarwal 		params.out_width = inst->out_width;
64058b64dd0SDikshita Agarwal 		params.out_height = inst->out_height;
6417371093fSStanimir Varbanov 		params.codec = inst->fmt_out->pixfmt;
6427371093fSStanimir Varbanov 		params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_cap->pixfmt);
6437371093fSStanimir Varbanov 		params.dec.max_mbs_per_frame = mbs_per_frame_max(inst);
6447371093fSStanimir Varbanov 		params.dec.buffer_size_limit = 0;
6457371093fSStanimir Varbanov 		params.dec.is_secondary_output =
6467371093fSStanimir Varbanov 			inst->opb_buftype == HFI_BUFFER_OUTPUT2;
64758b64dd0SDikshita Agarwal 		if (params.dec.is_secondary_output)
64858b64dd0SDikshita Agarwal 			params.hfi_dpb_color_fmt = inst->dpb_fmt;
6497371093fSStanimir Varbanov 		params.dec.is_interlaced =
6506fc46680SZhen Lei 			inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE;
6517371093fSStanimir Varbanov 	} else {
6527371093fSStanimir Varbanov 		params.width = inst->out_width;
6537371093fSStanimir Varbanov 		params.height = inst->out_height;
6547371093fSStanimir Varbanov 		params.codec = inst->fmt_cap->pixfmt;
6557371093fSStanimir Varbanov 		params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_out->pixfmt);
6567371093fSStanimir Varbanov 		params.enc.work_mode = VIDC_WORK_MODE_2;
6577371093fSStanimir Varbanov 		params.enc.rc_type = HFI_RATE_CONTROL_OFF;
6587371093fSStanimir Varbanov 		if (enc_ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
6597371093fSStanimir Varbanov 			params.enc.rc_type = HFI_RATE_CONTROL_CQ;
6607371093fSStanimir Varbanov 		params.enc.num_b_frames = enc_ctr->num_b_frames;
6617371093fSStanimir Varbanov 		params.enc.is_tenbit = inst->bit_depth == VIDC_BITDEPTH_10;
6627371093fSStanimir Varbanov 	}
6637371093fSStanimir Varbanov 
6647371093fSStanimir Varbanov 	return hfi_plat->bufreq(&params, inst->session_type, buftype, req);
6657371093fSStanimir Varbanov }
6667371093fSStanimir Varbanov 
667af2c3834SStanimir Varbanov int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
668af2c3834SStanimir Varbanov 			    struct hfi_buffer_requirements *req)
669af2c3834SStanimir Varbanov {
670af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS;
671af2c3834SStanimir Varbanov 	union hfi_get_property hprop;
672af2c3834SStanimir Varbanov 	unsigned int i;
673af2c3834SStanimir Varbanov 	int ret;
674af2c3834SStanimir Varbanov 
675af2c3834SStanimir Varbanov 	memset(req, 0, sizeof(*req));
676af2c3834SStanimir Varbanov 
67716545aa3SDikshita Agarwal 	if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2)
67816545aa3SDikshita Agarwal 		req->count_min = inst->fw_min_cnt;
67916545aa3SDikshita Agarwal 
6807371093fSStanimir Varbanov 	ret = platform_get_bufreq(inst, type, req);
68116545aa3SDikshita Agarwal 	if (!ret) {
68216545aa3SDikshita Agarwal 		if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2)
68316545aa3SDikshita Agarwal 			inst->fw_min_cnt = req->count_min;
6847371093fSStanimir Varbanov 		return 0;
68516545aa3SDikshita Agarwal 	}
6867371093fSStanimir Varbanov 
687af2c3834SStanimir Varbanov 	ret = hfi_session_get_property(inst, ptype, &hprop);
688af2c3834SStanimir Varbanov 	if (ret)
689af2c3834SStanimir Varbanov 		return ret;
690af2c3834SStanimir Varbanov 
691af2c3834SStanimir Varbanov 	ret = -EINVAL;
692af2c3834SStanimir Varbanov 
693af2c3834SStanimir Varbanov 	for (i = 0; i < HFI_BUFFER_TYPE_MAX; i++) {
694af2c3834SStanimir Varbanov 		if (hprop.bufreq[i].type != type)
695af2c3834SStanimir Varbanov 			continue;
696af2c3834SStanimir Varbanov 
697af2c3834SStanimir Varbanov 		memcpy(req, &hprop.bufreq[i], sizeof(*req));
698af2c3834SStanimir Varbanov 		ret = 0;
699af2c3834SStanimir Varbanov 		break;
700af2c3834SStanimir Varbanov 	}
701af2c3834SStanimir Varbanov 
702af2c3834SStanimir Varbanov 	return ret;
703af2c3834SStanimir Varbanov }
704af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
705af2c3834SStanimir Varbanov 
7062c2dc2fdSStanimir Varbanov struct id_mapping {
7072c2dc2fdSStanimir Varbanov 	u32 hfi_id;
7082c2dc2fdSStanimir Varbanov 	u32 v4l2_id;
7092c2dc2fdSStanimir Varbanov };
7102c2dc2fdSStanimir Varbanov 
7112c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_profiles[] = {
7122c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE },
7132c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_PROFILE_ADVANCEDSIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE },
7142c2dc2fdSStanimir Varbanov };
7152c2dc2fdSStanimir Varbanov 
7162c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_levels[] = {
7172c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 },
7182c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_0b, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B },
7192c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 },
7202c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 },
7212c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 },
7222c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 },
7232c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 },
7242c2dc2fdSStanimir Varbanov };
7252c2dc2fdSStanimir Varbanov 
7262c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_profiles[] = {
7272c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE },
7282c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_MAIN, V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN },
7292c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SNR, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE },
7302c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SPATIAL, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE },
7312c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_HIGH, V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH },
7322c2dc2fdSStanimir Varbanov };
7332c2dc2fdSStanimir Varbanov 
7342c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_levels[] = {
7352c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_LL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW },
7362c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_ML, V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN },
7372c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_H14, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440 },
7382c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_HL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH },
7392c2dc2fdSStanimir Varbanov };
7402c2dc2fdSStanimir Varbanov 
7412c2dc2fdSStanimir Varbanov static const struct id_mapping h264_profiles[] = {
7422c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE },
7432c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN },
7442c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH },
7452c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH },
7462c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH },
7472c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE },
7482c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH },
7492c2dc2fdSStanimir Varbanov };
7502c2dc2fdSStanimir Varbanov 
7512c2dc2fdSStanimir Varbanov static const struct id_mapping h264_levels[] = {
7522c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 },
7532c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B },
7542c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 },
7552c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 },
7562c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 },
7572c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 },
7582c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 },
7592c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 },
7602c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 },
7612c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 },
7622c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 },
7632c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 },
7642c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 },
7652c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 },
7662c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 },
7672c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
7682c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
7692c2dc2fdSStanimir Varbanov };
7702c2dc2fdSStanimir Varbanov 
7712c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_profiles[] = {
7722c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN },
7732c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE },
7742c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 },
7752c2dc2fdSStanimir Varbanov };
7762c2dc2fdSStanimir Varbanov 
7772c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_levels[] = {
7782c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 },
7792c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 },
7802c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 },
7812c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 },
7822c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 },
7832c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 },
7842c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 },
7852c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 },
7862c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 },
7872c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 },
7882c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 },
7892c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 },
7902c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 },
7912c2dc2fdSStanimir Varbanov };
7922c2dc2fdSStanimir Varbanov 
7932c2dc2fdSStanimir Varbanov static const struct id_mapping vp8_profiles[] = {
7942c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 },
7952c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 },
7962c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 },
7972c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 },
7982c2dc2fdSStanimir Varbanov };
7992c2dc2fdSStanimir Varbanov 
8002c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_profiles[] = {
8012c2dc2fdSStanimir Varbanov 	{ HFI_VP9_PROFILE_P0, V4L2_MPEG_VIDEO_VP9_PROFILE_0 },
8022c2dc2fdSStanimir Varbanov 	{ HFI_VP9_PROFILE_P2_10B, V4L2_MPEG_VIDEO_VP9_PROFILE_2 },
8032c2dc2fdSStanimir Varbanov };
8042c2dc2fdSStanimir Varbanov 
8052c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_levels[] = {
8062c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_1, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 },
8072c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_11, V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 },
8082c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_2, V4L2_MPEG_VIDEO_VP9_LEVEL_2_0},
8092c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_21, V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 },
8102c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_3, V4L2_MPEG_VIDEO_VP9_LEVEL_3_0},
8112c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_31, V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 },
8122c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_4, V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 },
8132c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_41, V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 },
8142c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_5, V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 },
8152c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_51, V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 },
8162c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_6, V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 },
8172c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_61, V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 },
8182c2dc2fdSStanimir Varbanov };
8192c2dc2fdSStanimir Varbanov 
8202c2dc2fdSStanimir Varbanov static u32 find_v4l2_id(u32 hfi_id, const struct id_mapping *array, unsigned int array_sz)
8212c2dc2fdSStanimir Varbanov {
8222c2dc2fdSStanimir Varbanov 	unsigned int i;
8232c2dc2fdSStanimir Varbanov 
8242c2dc2fdSStanimir Varbanov 	if (!array || !array_sz)
8252c2dc2fdSStanimir Varbanov 		return 0;
8262c2dc2fdSStanimir Varbanov 
8272c2dc2fdSStanimir Varbanov 	for (i = 0; i < array_sz; i++)
8282c2dc2fdSStanimir Varbanov 		if (hfi_id == array[i].hfi_id)
8292c2dc2fdSStanimir Varbanov 			return array[i].v4l2_id;
8302c2dc2fdSStanimir Varbanov 
8312c2dc2fdSStanimir Varbanov 	return 0;
8322c2dc2fdSStanimir Varbanov }
8332c2dc2fdSStanimir Varbanov 
8342c2dc2fdSStanimir Varbanov static u32 find_hfi_id(u32 v4l2_id, const struct id_mapping *array, unsigned int array_sz)
8352c2dc2fdSStanimir Varbanov {
8362c2dc2fdSStanimir Varbanov 	unsigned int i;
8372c2dc2fdSStanimir Varbanov 
8382c2dc2fdSStanimir Varbanov 	if (!array || !array_sz)
8392c2dc2fdSStanimir Varbanov 		return 0;
8402c2dc2fdSStanimir Varbanov 
8412c2dc2fdSStanimir Varbanov 	for (i = 0; i < array_sz; i++)
8422c2dc2fdSStanimir Varbanov 		if (v4l2_id == array[i].v4l2_id)
8432c2dc2fdSStanimir Varbanov 			return array[i].hfi_id;
8442c2dc2fdSStanimir Varbanov 
8452c2dc2fdSStanimir Varbanov 	return 0;
8462c2dc2fdSStanimir Varbanov }
8472c2dc2fdSStanimir Varbanov 
8482c2dc2fdSStanimir Varbanov static void
8492c2dc2fdSStanimir Varbanov v4l2_id_profile_level(u32 hfi_codec, struct hfi_profile_level *pl, u32 *profile, u32 *level)
8502c2dc2fdSStanimir Varbanov {
8512c2dc2fdSStanimir Varbanov 	u32 hfi_pf = pl->profile;
8522c2dc2fdSStanimir Varbanov 	u32 hfi_lvl = pl->level;
8532c2dc2fdSStanimir Varbanov 
8542c2dc2fdSStanimir Varbanov 	switch (hfi_codec) {
8552c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_H264:
8562c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
8572c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, h264_levels, ARRAY_SIZE(h264_levels));
8582c2dc2fdSStanimir Varbanov 		break;
8592c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG2:
8602c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
8612c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
8622c2dc2fdSStanimir Varbanov 		break;
8632c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG4:
8642c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
8652c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
8662c2dc2fdSStanimir Varbanov 		break;
8672c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP8:
8682c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
8692c2dc2fdSStanimir Varbanov 		*level = 0;
8702c2dc2fdSStanimir Varbanov 		break;
8712c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP9:
8722c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
8732c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
8742c2dc2fdSStanimir Varbanov 		break;
8752c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_HEVC:
8762c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
8772c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
8782c2dc2fdSStanimir Varbanov 		break;
8792c2dc2fdSStanimir Varbanov 	default:
8802c2dc2fdSStanimir Varbanov 		break;
8812c2dc2fdSStanimir Varbanov 	}
8822c2dc2fdSStanimir Varbanov }
8832c2dc2fdSStanimir Varbanov 
8842c2dc2fdSStanimir Varbanov static void
8852c2dc2fdSStanimir Varbanov hfi_id_profile_level(u32 hfi_codec, u32 v4l2_pf, u32 v4l2_lvl, struct hfi_profile_level *pl)
8862c2dc2fdSStanimir Varbanov {
8872c2dc2fdSStanimir Varbanov 	switch (hfi_codec) {
8882c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_H264:
8892c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
8902c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, h264_levels, ARRAY_SIZE(h264_levels));
8912c2dc2fdSStanimir Varbanov 		break;
8922c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG2:
8932c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
8942c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
8952c2dc2fdSStanimir Varbanov 		break;
8962c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG4:
8972c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
8982c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
8992c2dc2fdSStanimir Varbanov 		break;
9002c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP8:
9012c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
9022c2dc2fdSStanimir Varbanov 		pl->level = 0;
9032c2dc2fdSStanimir Varbanov 		break;
9042c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP9:
9052c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
9062c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
9072c2dc2fdSStanimir Varbanov 		break;
9082c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_HEVC:
9092c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
9102c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
9112c2dc2fdSStanimir Varbanov 		break;
9122c2dc2fdSStanimir Varbanov 	default:
9132c2dc2fdSStanimir Varbanov 		break;
9142c2dc2fdSStanimir Varbanov 	}
9152c2dc2fdSStanimir Varbanov }
9162c2dc2fdSStanimir Varbanov 
9172c2dc2fdSStanimir Varbanov int venus_helper_get_profile_level(struct venus_inst *inst, u32 *profile, u32 *level)
9182c2dc2fdSStanimir Varbanov {
9192c2dc2fdSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
9202c2dc2fdSStanimir Varbanov 	union hfi_get_property hprop;
9212c2dc2fdSStanimir Varbanov 	int ret;
9222c2dc2fdSStanimir Varbanov 
9232c2dc2fdSStanimir Varbanov 	ret = hfi_session_get_property(inst, ptype, &hprop);
9242c2dc2fdSStanimir Varbanov 	if (ret)
9252c2dc2fdSStanimir Varbanov 		return ret;
9262c2dc2fdSStanimir Varbanov 
9272c2dc2fdSStanimir Varbanov 	v4l2_id_profile_level(inst->hfi_codec, &hprop.profile_level, profile, level);
9282c2dc2fdSStanimir Varbanov 
9292c2dc2fdSStanimir Varbanov 	return 0;
9302c2dc2fdSStanimir Varbanov }
9312c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_profile_level);
9322c2dc2fdSStanimir Varbanov 
9332c2dc2fdSStanimir Varbanov int venus_helper_set_profile_level(struct venus_inst *inst, u32 profile, u32 level)
9342c2dc2fdSStanimir Varbanov {
9352c2dc2fdSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
9362c2dc2fdSStanimir Varbanov 	struct hfi_profile_level pl;
9372c2dc2fdSStanimir Varbanov 
9382c2dc2fdSStanimir Varbanov 	hfi_id_profile_level(inst->hfi_codec, profile, level, &pl);
9392c2dc2fdSStanimir Varbanov 
9402c2dc2fdSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &pl);
9412c2dc2fdSStanimir Varbanov }
9422c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_profile_level);
9432c2dc2fdSStanimir Varbanov 
944e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12(u32 width, u32 height)
945e1cb72deSStanimir Varbanov {
946e1cb72deSStanimir Varbanov 	u32 y_stride, uv_stride, y_plane;
947e1cb72deSStanimir Varbanov 	u32 y_sclines, uv_sclines, uv_plane;
948e1cb72deSStanimir Varbanov 	u32 size;
949e1cb72deSStanimir Varbanov 
950e1cb72deSStanimir Varbanov 	y_stride = ALIGN(width, 128);
951e1cb72deSStanimir Varbanov 	uv_stride = ALIGN(width, 128);
952e1cb72deSStanimir Varbanov 	y_sclines = ALIGN(height, 32);
953e1cb72deSStanimir Varbanov 	uv_sclines = ALIGN(((height + 1) >> 1), 16);
954e1cb72deSStanimir Varbanov 
955e1cb72deSStanimir Varbanov 	y_plane = y_stride * y_sclines;
956e1cb72deSStanimir Varbanov 	uv_plane = uv_stride * uv_sclines + SZ_4K;
957e1cb72deSStanimir Varbanov 	size = y_plane + uv_plane + SZ_8K;
958e1cb72deSStanimir Varbanov 
959e1cb72deSStanimir Varbanov 	return ALIGN(size, SZ_4K);
960e1cb72deSStanimir Varbanov }
961e1cb72deSStanimir Varbanov 
962e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height)
963e1cb72deSStanimir Varbanov {
964e1cb72deSStanimir Varbanov 	u32 y_meta_stride, y_meta_plane;
965e1cb72deSStanimir Varbanov 	u32 y_stride, y_plane;
966e1cb72deSStanimir Varbanov 	u32 uv_meta_stride, uv_meta_plane;
967e1cb72deSStanimir Varbanov 	u32 uv_stride, uv_plane;
968e1cb72deSStanimir Varbanov 	u32 extradata = SZ_16K;
969e1cb72deSStanimir Varbanov 
970e1cb72deSStanimir Varbanov 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
971e1cb72deSStanimir Varbanov 	y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16);
972e1cb72deSStanimir Varbanov 	y_meta_plane = ALIGN(y_meta_plane, SZ_4K);
973e1cb72deSStanimir Varbanov 
974e1cb72deSStanimir Varbanov 	y_stride = ALIGN(width, 128);
975e1cb72deSStanimir Varbanov 	y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K);
976e1cb72deSStanimir Varbanov 
977e1cb72deSStanimir Varbanov 	uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64);
978e1cb72deSStanimir Varbanov 	uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16);
979e1cb72deSStanimir Varbanov 	uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K);
980e1cb72deSStanimir Varbanov 
981e1cb72deSStanimir Varbanov 	uv_stride = ALIGN(width, 128);
982e1cb72deSStanimir Varbanov 	uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K);
983e1cb72deSStanimir Varbanov 
984e1cb72deSStanimir Varbanov 	return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
985e1cb72deSStanimir Varbanov 		     max(extradata, y_stride * 48), SZ_4K);
986e1cb72deSStanimir Varbanov }
987e1cb72deSStanimir Varbanov 
988ab1eda44SAniket Masule static u32 get_framesize_raw_p010(u32 width, u32 height)
989ab1eda44SAniket Masule {
990ab1eda44SAniket Masule 	u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines;
991ab1eda44SAniket Masule 
992a47a3ae5SFritz Koenig 	y_stride = ALIGN(width * 2, 128);
993a47a3ae5SFritz Koenig 	uv_stride = ALIGN(width * 2, 128);
994ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 32);
995ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
996ab1eda44SAniket Masule 	y_plane = y_stride * y_sclines;
997ab1eda44SAniket Masule 	uv_plane = uv_stride * uv_sclines;
998ab1eda44SAniket Masule 
999ab1eda44SAniket Masule 	return ALIGN((y_plane + uv_plane), SZ_4K);
1000ab1eda44SAniket Masule }
1001ab1eda44SAniket Masule 
1002ab1eda44SAniket Masule static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height)
1003ab1eda44SAniket Masule {
1004ab1eda44SAniket Masule 	u32 y_stride, uv_stride, y_sclines, uv_sclines;
1005ab1eda44SAniket Masule 	u32 y_ubwc_plane, uv_ubwc_plane;
1006ab1eda44SAniket Masule 	u32 y_meta_stride, y_meta_scanlines;
1007ab1eda44SAniket Masule 	u32 uv_meta_stride, uv_meta_scanlines;
1008ab1eda44SAniket Masule 	u32 y_meta_plane, uv_meta_plane;
1009ab1eda44SAniket Masule 	u32 size;
1010ab1eda44SAniket Masule 
1011ab1eda44SAniket Masule 	y_stride = ALIGN(width * 2, 256);
1012ab1eda44SAniket Masule 	uv_stride = ALIGN(width * 2, 256);
1013ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 16);
1014ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
1015ab1eda44SAniket Masule 
1016ab1eda44SAniket Masule 	y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
1017ab1eda44SAniket Masule 	uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
1018ab1eda44SAniket Masule 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
1019ab1eda44SAniket Masule 	y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
1020ab1eda44SAniket Masule 	y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
1021ab1eda44SAniket Masule 	uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
1022ab1eda44SAniket Masule 	uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
1023ab1eda44SAniket Masule 	uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
1024ab1eda44SAniket Masule 
1025ab1eda44SAniket Masule 	size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
1026ab1eda44SAniket Masule 
1027ab1eda44SAniket Masule 	return ALIGN(size, SZ_4K);
1028ab1eda44SAniket Masule }
1029ab1eda44SAniket Masule 
1030ab1eda44SAniket Masule static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height)
1031ab1eda44SAniket Masule {
1032ab1eda44SAniket Masule 	u32 y_stride, uv_stride, y_sclines, uv_sclines;
1033ab1eda44SAniket Masule 	u32 y_ubwc_plane, uv_ubwc_plane;
1034ab1eda44SAniket Masule 	u32 y_meta_stride, y_meta_scanlines;
1035ab1eda44SAniket Masule 	u32 uv_meta_stride, uv_meta_scanlines;
1036ab1eda44SAniket Masule 	u32 y_meta_plane, uv_meta_plane;
1037ab1eda44SAniket Masule 	u32 extradata = SZ_16K;
1038ab1eda44SAniket Masule 	u32 size;
1039ab1eda44SAniket Masule 
1040927e78acSRikard Falkeborn 	y_stride = ALIGN(width * 4 / 3, 256);
1041927e78acSRikard Falkeborn 	uv_stride = ALIGN(width * 4 / 3, 256);
1042ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 16);
1043ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
1044ab1eda44SAniket Masule 
1045ab1eda44SAniket Masule 	y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
1046ab1eda44SAniket Masule 	uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
1047ab1eda44SAniket Masule 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64);
1048ab1eda44SAniket Masule 	y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
1049ab1eda44SAniket Masule 	y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
1050ab1eda44SAniket Masule 	uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
1051ab1eda44SAniket Masule 	uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
1052ab1eda44SAniket Masule 	uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
1053ab1eda44SAniket Masule 
1054ab1eda44SAniket Masule 	size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
1055ab1eda44SAniket Masule 	size += max(extradata + SZ_8K, y_stride * 48);
1056ab1eda44SAniket Masule 
1057ab1eda44SAniket Masule 	return ALIGN(size, SZ_4K);
1058ab1eda44SAniket Masule }
1059ab1eda44SAniket Masule 
1060e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
1061e1cb72deSStanimir Varbanov {
1062e1cb72deSStanimir Varbanov 	switch (hfi_fmt) {
1063e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV12:
1064e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV21:
1065e1cb72deSStanimir Varbanov 		return get_framesize_raw_nv12(width, height);
1066e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV12_UBWC:
1067e1cb72deSStanimir Varbanov 		return get_framesize_raw_nv12_ubwc(width, height);
1068ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_P010:
1069ab1eda44SAniket Masule 		return get_framesize_raw_p010(width, height);
1070ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_P010_UBWC:
1071ab1eda44SAniket Masule 		return get_framesize_raw_p010_ubwc(width, height);
1072ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_YUV420_TP10_UBWC:
1073ab1eda44SAniket Masule 		return get_framesize_raw_yuv420_tp10_ubwc(width, height);
1074e1cb72deSStanimir Varbanov 	default:
1075e1cb72deSStanimir Varbanov 		return 0;
1076e1cb72deSStanimir Varbanov 	}
1077e1cb72deSStanimir Varbanov }
1078e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw);
1079e1cb72deSStanimir Varbanov 
1080e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height)
1081e1cb72deSStanimir Varbanov {
1082e1cb72deSStanimir Varbanov 	u32 hfi_fmt, sz;
1083e1cb72deSStanimir Varbanov 	bool compressed;
1084e1cb72deSStanimir Varbanov 
1085e1cb72deSStanimir Varbanov 	switch (v4l2_fmt) {
1086e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG:
1087e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264:
1088e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264_NO_SC:
1089e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264_MVC:
1090e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H263:
1091e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG1:
1092e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG2:
1093e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG4:
1094e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_XVID:
1095e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_G:
1096e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_L:
1097e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VP8:
1098e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VP9:
1099e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_HEVC:
1100e1cb72deSStanimir Varbanov 		compressed = true;
1101e1cb72deSStanimir Varbanov 		break;
1102e1cb72deSStanimir Varbanov 	default:
1103e1cb72deSStanimir Varbanov 		compressed = false;
1104e1cb72deSStanimir Varbanov 		break;
1105e1cb72deSStanimir Varbanov 	}
1106e1cb72deSStanimir Varbanov 
1107e1cb72deSStanimir Varbanov 	if (compressed) {
1108e1cb72deSStanimir Varbanov 		sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
1109ddd1fc49SStanimir Varbanov 		if (width < 1280 || height < 720)
1110ddd1fc49SStanimir Varbanov 			sz *= 8;
1111e1cb72deSStanimir Varbanov 		return ALIGN(sz, SZ_4K);
1112e1cb72deSStanimir Varbanov 	}
1113e1cb72deSStanimir Varbanov 
1114e1cb72deSStanimir Varbanov 	hfi_fmt = to_hfi_raw_fmt(v4l2_fmt);
1115e1cb72deSStanimir Varbanov 	if (!hfi_fmt)
1116e1cb72deSStanimir Varbanov 		return 0;
1117e1cb72deSStanimir Varbanov 
1118e1cb72deSStanimir Varbanov 	return venus_helper_get_framesz_raw(hfi_fmt, width, height);
1119e1cb72deSStanimir Varbanov }
1120e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz);
1121e1cb72deSStanimir Varbanov 
1122af2c3834SStanimir Varbanov int venus_helper_set_input_resolution(struct venus_inst *inst,
1123af2c3834SStanimir Varbanov 				      unsigned int width, unsigned int height)
1124af2c3834SStanimir Varbanov {
1125af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
1126af2c3834SStanimir Varbanov 	struct hfi_framesize fs;
1127af2c3834SStanimir Varbanov 
1128af2c3834SStanimir Varbanov 	fs.buffer_type = HFI_BUFFER_INPUT;
1129af2c3834SStanimir Varbanov 	fs.width = width;
1130af2c3834SStanimir Varbanov 	fs.height = height;
1131af2c3834SStanimir Varbanov 
1132af2c3834SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fs);
1133af2c3834SStanimir Varbanov }
1134af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution);
1135af2c3834SStanimir Varbanov 
1136af2c3834SStanimir Varbanov int venus_helper_set_output_resolution(struct venus_inst *inst,
1137404054e1SStanimir Varbanov 				       unsigned int width, unsigned int height,
1138404054e1SStanimir Varbanov 				       u32 buftype)
1139af2c3834SStanimir Varbanov {
1140af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
1141af2c3834SStanimir Varbanov 	struct hfi_framesize fs;
1142af2c3834SStanimir Varbanov 
1143404054e1SStanimir Varbanov 	fs.buffer_type = buftype;
1144af2c3834SStanimir Varbanov 	fs.width = width;
1145af2c3834SStanimir Varbanov 	fs.height = height;
1146af2c3834SStanimir Varbanov 
1147af2c3834SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fs);
1148af2c3834SStanimir Varbanov }
1149af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution);
1150af2c3834SStanimir Varbanov 
11511ad17595SDikshita Agarwal static u32 venus_helper_get_work_mode(struct venus_inst *inst)
11521ad17595SDikshita Agarwal {
11531ad17595SDikshita Agarwal 	u32 mode;
11541ad17595SDikshita Agarwal 	u32 num_mbs;
11551ad17595SDikshita Agarwal 
11561ad17595SDikshita Agarwal 	mode = VIDC_WORK_MODE_2;
11571ad17595SDikshita Agarwal 	if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
11581ad17595SDikshita Agarwal 		num_mbs = (ALIGN(inst->height, 16) * ALIGN(inst->width, 16)) / 256;
11591ad17595SDikshita Agarwal 		if (inst->hfi_codec == HFI_VIDEO_CODEC_MPEG2 ||
11601ad17595SDikshita Agarwal 		    inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE ||
11611ad17595SDikshita Agarwal 		    num_mbs <= NUM_MBS_720P)
11621ad17595SDikshita Agarwal 			mode = VIDC_WORK_MODE_1;
11631ad17595SDikshita Agarwal 	} else {
11641ad17595SDikshita Agarwal 		num_mbs = (ALIGN(inst->out_height, 16) * ALIGN(inst->out_width, 16)) / 256;
11651ad17595SDikshita Agarwal 		if (inst->hfi_codec == HFI_VIDEO_CODEC_VP8 &&
11661ad17595SDikshita Agarwal 		    num_mbs <= NUM_MBS_4K)
11671ad17595SDikshita Agarwal 			mode = VIDC_WORK_MODE_1;
11681ad17595SDikshita Agarwal 	}
11691ad17595SDikshita Agarwal 
11701ad17595SDikshita Agarwal 	return mode;
11711ad17595SDikshita Agarwal }
11721ad17595SDikshita Agarwal 
11731ad17595SDikshita Agarwal int venus_helper_set_work_mode(struct venus_inst *inst)
117401165b84SStanimir Varbanov {
117501165b84SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE;
117601165b84SStanimir Varbanov 	struct hfi_video_work_mode wm;
11771ad17595SDikshita Agarwal 	u32 mode;
117801165b84SStanimir Varbanov 
11797ed9e0b3SBryan O'Donoghue 	if (!IS_V4(inst->core) && !IS_V6(inst->core))
118001165b84SStanimir Varbanov 		return 0;
118101165b84SStanimir Varbanov 
11821ad17595SDikshita Agarwal 	mode = venus_helper_get_work_mode(inst);
118301165b84SStanimir Varbanov 	wm.video_work_mode = mode;
118401165b84SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &wm);
118501165b84SStanimir Varbanov }
118601165b84SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
118701165b84SStanimir Varbanov 
1188bc28936bSDikshita Agarwal int venus_helper_set_format_constraints(struct venus_inst *inst)
1189bc28936bSDikshita Agarwal {
1190bc28936bSDikshita Agarwal 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
1191bc28936bSDikshita Agarwal 	struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
1192bc28936bSDikshita Agarwal 
1193bc28936bSDikshita Agarwal 	if (!IS_V6(inst->core))
1194bc28936bSDikshita Agarwal 		return 0;
1195bc28936bSDikshita Agarwal 
1196cef92b14SStanimir Varbanov 	if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC ||
1197cef92b14SStanimir Varbanov 	    inst->opb_fmt == HFI_COLOR_FORMAT_YUV420_TP10_UBWC)
11981ac61fafSMansur Alisha Shaik 		return 0;
11991ac61fafSMansur Alisha Shaik 
1200bc28936bSDikshita Agarwal 	pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
1201bc28936bSDikshita Agarwal 	pconstraint.num_planes = 2;
1202bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].stride_multiples = 128;
1203bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].max_stride = 8192;
1204bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32;
1205bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].buffer_alignment = 256;
1206bc28936bSDikshita Agarwal 
1207bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].stride_multiples = 128;
1208bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].max_stride = 8192;
1209bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16;
1210bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].buffer_alignment = 256;
1211bc28936bSDikshita Agarwal 
1212bc28936bSDikshita Agarwal 	return hfi_session_set_property(inst, ptype, &pconstraint);
1213bc28936bSDikshita Agarwal }
1214bc28936bSDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_format_constraints);
1215bc28936bSDikshita Agarwal 
1216af2c3834SStanimir Varbanov int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
12171eb04b2eSStanimir Varbanov 			      unsigned int output_bufs,
12181eb04b2eSStanimir Varbanov 			      unsigned int output2_bufs)
1219af2c3834SStanimir Varbanov {
1220af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
1221af2c3834SStanimir Varbanov 	struct hfi_buffer_count_actual buf_count;
1222af2c3834SStanimir Varbanov 	int ret;
1223af2c3834SStanimir Varbanov 
1224af2c3834SStanimir Varbanov 	buf_count.type = HFI_BUFFER_INPUT;
1225af2c3834SStanimir Varbanov 	buf_count.count_actual = input_bufs;
1226af2c3834SStanimir Varbanov 
1227af2c3834SStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &buf_count);
1228af2c3834SStanimir Varbanov 	if (ret)
1229af2c3834SStanimir Varbanov 		return ret;
1230af2c3834SStanimir Varbanov 
1231af2c3834SStanimir Varbanov 	buf_count.type = HFI_BUFFER_OUTPUT;
1232af2c3834SStanimir Varbanov 	buf_count.count_actual = output_bufs;
1233af2c3834SStanimir Varbanov 
12341eb04b2eSStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &buf_count);
12351eb04b2eSStanimir Varbanov 	if (ret)
12361eb04b2eSStanimir Varbanov 		return ret;
12371eb04b2eSStanimir Varbanov 
12381eb04b2eSStanimir Varbanov 	if (output2_bufs) {
12391eb04b2eSStanimir Varbanov 		buf_count.type = HFI_BUFFER_OUTPUT2;
12401eb04b2eSStanimir Varbanov 		buf_count.count_actual = output2_bufs;
12411eb04b2eSStanimir Varbanov 
12421eb04b2eSStanimir Varbanov 		ret = hfi_session_set_property(inst, ptype, &buf_count);
12431eb04b2eSStanimir Varbanov 	}
12441eb04b2eSStanimir Varbanov 
12451eb04b2eSStanimir Varbanov 	return ret;
1246af2c3834SStanimir Varbanov }
1247af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
1248af2c3834SStanimir Varbanov 
1249ab97a3fbSStanimir Varbanov int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
1250ab97a3fbSStanimir Varbanov 				u32 buftype)
1251ab97a3fbSStanimir Varbanov {
1252ab97a3fbSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
1253ab97a3fbSStanimir Varbanov 	struct hfi_uncompressed_format_select fmt;
1254ab97a3fbSStanimir Varbanov 
1255ab97a3fbSStanimir Varbanov 	fmt.buffer_type = buftype;
1256ab97a3fbSStanimir Varbanov 	fmt.format = hfi_format;
1257ab97a3fbSStanimir Varbanov 
1258ab97a3fbSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fmt);
1259ab97a3fbSStanimir Varbanov }
1260ab97a3fbSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_raw_format);
1261ab97a3fbSStanimir Varbanov 
1262af2c3834SStanimir Varbanov int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
1263af2c3834SStanimir Varbanov {
1264ab97a3fbSStanimir Varbanov 	u32 hfi_format, buftype;
1265af2c3834SStanimir Varbanov 
1266af2c3834SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC)
1267ab97a3fbSStanimir Varbanov 		buftype = HFI_BUFFER_OUTPUT;
1268af2c3834SStanimir Varbanov 	else if (inst->session_type == VIDC_SESSION_TYPE_ENC)
1269ab97a3fbSStanimir Varbanov 		buftype = HFI_BUFFER_INPUT;
1270af2c3834SStanimir Varbanov 	else
1271af2c3834SStanimir Varbanov 		return -EINVAL;
1272af2c3834SStanimir Varbanov 
1273ab97a3fbSStanimir Varbanov 	hfi_format = to_hfi_raw_fmt(pixfmt);
1274ab97a3fbSStanimir Varbanov 	if (!hfi_format)
1275af2c3834SStanimir Varbanov 		return -EINVAL;
1276af2c3834SStanimir Varbanov 
1277ab97a3fbSStanimir Varbanov 	return venus_helper_set_raw_format(inst, hfi_format, buftype);
1278af2c3834SStanimir Varbanov }
1279af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
1280af2c3834SStanimir Varbanov 
1281f012b23dSStanimir Varbanov int venus_helper_set_multistream(struct venus_inst *inst, bool out_en,
1282f012b23dSStanimir Varbanov 				 bool out2_en)
1283f012b23dSStanimir Varbanov {
1284f012b23dSStanimir Varbanov 	struct hfi_multi_stream multi = {0};
1285f012b23dSStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
1286f012b23dSStanimir Varbanov 	int ret;
1287f012b23dSStanimir Varbanov 
1288f012b23dSStanimir Varbanov 	multi.buffer_type = HFI_BUFFER_OUTPUT;
1289f012b23dSStanimir Varbanov 	multi.enable = out_en;
1290f012b23dSStanimir Varbanov 
1291f012b23dSStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &multi);
1292f012b23dSStanimir Varbanov 	if (ret)
1293f012b23dSStanimir Varbanov 		return ret;
1294f012b23dSStanimir Varbanov 
1295f012b23dSStanimir Varbanov 	multi.buffer_type = HFI_BUFFER_OUTPUT2;
1296f012b23dSStanimir Varbanov 	multi.enable = out2_en;
1297f012b23dSStanimir Varbanov 
1298f012b23dSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &multi);
1299f012b23dSStanimir Varbanov }
1300f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_multistream);
1301f012b23dSStanimir Varbanov 
13022b0a8517SStanimir Varbanov int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
13032b0a8517SStanimir Varbanov {
13042b0a8517SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
13052b0a8517SStanimir Varbanov 	struct hfi_buffer_alloc_mode mode;
13062b0a8517SStanimir Varbanov 	int ret;
13072b0a8517SStanimir Varbanov 
13082b0a8517SStanimir Varbanov 	if (!is_dynamic_bufmode(inst))
13092b0a8517SStanimir Varbanov 		return 0;
13102b0a8517SStanimir Varbanov 
13112b0a8517SStanimir Varbanov 	mode.type = HFI_BUFFER_OUTPUT;
13122b0a8517SStanimir Varbanov 	mode.mode = HFI_BUFFER_MODE_DYNAMIC;
13132b0a8517SStanimir Varbanov 
13142b0a8517SStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &mode);
13152b0a8517SStanimir Varbanov 	if (ret)
13162b0a8517SStanimir Varbanov 		return ret;
13172b0a8517SStanimir Varbanov 
13182b0a8517SStanimir Varbanov 	mode.type = HFI_BUFFER_OUTPUT2;
13192b0a8517SStanimir Varbanov 
13202b0a8517SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &mode);
13212b0a8517SStanimir Varbanov }
13222b0a8517SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
13232b0a8517SStanimir Varbanov 
1324d4a5b0a6SStanimir Varbanov int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype)
1325d4a5b0a6SStanimir Varbanov {
1326d4a5b0a6SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
1327d4a5b0a6SStanimir Varbanov 	struct hfi_buffer_size_actual bufsz;
1328d4a5b0a6SStanimir Varbanov 
1329d4a5b0a6SStanimir Varbanov 	bufsz.type = buftype;
1330d4a5b0a6SStanimir Varbanov 	bufsz.size = bufsize;
1331d4a5b0a6SStanimir Varbanov 
1332d4a5b0a6SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &bufsz);
1333d4a5b0a6SStanimir Varbanov }
1334d4a5b0a6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
1335d4a5b0a6SStanimir Varbanov 
1336130c0117SStanimir Varbanov unsigned int venus_helper_get_opb_size(struct venus_inst *inst)
1337130c0117SStanimir Varbanov {
1338130c0117SStanimir Varbanov 	/* the encoder has only one output */
1339130c0117SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_ENC)
1340130c0117SStanimir Varbanov 		return inst->output_buf_size;
1341130c0117SStanimir Varbanov 
1342130c0117SStanimir Varbanov 	if (inst->opb_buftype == HFI_BUFFER_OUTPUT)
1343130c0117SStanimir Varbanov 		return inst->output_buf_size;
1344130c0117SStanimir Varbanov 	else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2)
1345130c0117SStanimir Varbanov 		return inst->output2_buf_size;
1346130c0117SStanimir Varbanov 
1347130c0117SStanimir Varbanov 	return 0;
1348130c0117SStanimir Varbanov }
1349130c0117SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_opb_size);
1350130c0117SStanimir Varbanov 
1351af2c3834SStanimir Varbanov static void delayed_process_buf_func(struct work_struct *work)
1352af2c3834SStanimir Varbanov {
1353af2c3834SStanimir Varbanov 	struct venus_buffer *buf, *n;
1354af2c3834SStanimir Varbanov 	struct venus_inst *inst;
1355af2c3834SStanimir Varbanov 	int ret;
1356af2c3834SStanimir Varbanov 
1357af2c3834SStanimir Varbanov 	inst = container_of(work, struct venus_inst, delayed_process_work);
1358af2c3834SStanimir Varbanov 
1359af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1360af2c3834SStanimir Varbanov 
1361af2c3834SStanimir Varbanov 	if (!(inst->streamon_out & inst->streamon_cap))
1362af2c3834SStanimir Varbanov 		goto unlock;
1363af2c3834SStanimir Varbanov 
1364af2c3834SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->delayed_process, ref_list) {
1365af2c3834SStanimir Varbanov 		if (buf->flags & HFI_BUFFERFLAG_READONLY)
1366af2c3834SStanimir Varbanov 			continue;
1367af2c3834SStanimir Varbanov 
1368af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1369af2c3834SStanimir Varbanov 		if (ret)
1370af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1371af2c3834SStanimir Varbanov 
1372af2c3834SStanimir Varbanov 		list_del_init(&buf->ref_list);
1373af2c3834SStanimir Varbanov 	}
1374af2c3834SStanimir Varbanov unlock:
1375af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1376af2c3834SStanimir Varbanov }
1377af2c3834SStanimir Varbanov 
1378af2c3834SStanimir Varbanov void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx)
1379af2c3834SStanimir Varbanov {
1380af2c3834SStanimir Varbanov 	struct venus_buffer *buf;
1381af2c3834SStanimir Varbanov 
1382af2c3834SStanimir Varbanov 	list_for_each_entry(buf, &inst->registeredbufs, reg_list) {
1383af2c3834SStanimir Varbanov 		if (buf->vb.vb2_buf.index == idx) {
1384af2c3834SStanimir Varbanov 			buf->flags &= ~HFI_BUFFERFLAG_READONLY;
1385af2c3834SStanimir Varbanov 			schedule_work(&inst->delayed_process_work);
1386af2c3834SStanimir Varbanov 			break;
1387af2c3834SStanimir Varbanov 		}
1388af2c3834SStanimir Varbanov 	}
1389af2c3834SStanimir Varbanov }
1390af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_release_buf_ref);
1391af2c3834SStanimir Varbanov 
1392af2c3834SStanimir Varbanov void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf)
1393af2c3834SStanimir Varbanov {
1394af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1395af2c3834SStanimir Varbanov 
1396af2c3834SStanimir Varbanov 	buf->flags |= HFI_BUFFERFLAG_READONLY;
1397af2c3834SStanimir Varbanov }
1398af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_acquire_buf_ref);
1399af2c3834SStanimir Varbanov 
1400af2c3834SStanimir Varbanov static int is_buf_refed(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
1401af2c3834SStanimir Varbanov {
1402af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1403af2c3834SStanimir Varbanov 
1404af2c3834SStanimir Varbanov 	if (buf->flags & HFI_BUFFERFLAG_READONLY) {
1405af2c3834SStanimir Varbanov 		list_add_tail(&buf->ref_list, &inst->delayed_process);
1406af2c3834SStanimir Varbanov 		schedule_work(&inst->delayed_process_work);
1407af2c3834SStanimir Varbanov 		return 1;
1408af2c3834SStanimir Varbanov 	}
1409af2c3834SStanimir Varbanov 
1410af2c3834SStanimir Varbanov 	return 0;
1411af2c3834SStanimir Varbanov }
1412af2c3834SStanimir Varbanov 
1413af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *
1414af2c3834SStanimir Varbanov venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx)
1415af2c3834SStanimir Varbanov {
1416af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1417af2c3834SStanimir Varbanov 
1418af2c3834SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1419af2c3834SStanimir Varbanov 		return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx);
1420af2c3834SStanimir Varbanov 	else
1421af2c3834SStanimir Varbanov 		return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx);
1422af2c3834SStanimir Varbanov }
1423af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_find_buf);
1424af2c3834SStanimir Varbanov 
142540d87aafSMansur Alisha Shaik void venus_helper_change_dpb_owner(struct venus_inst *inst,
142640d87aafSMansur Alisha Shaik 				   struct vb2_v4l2_buffer *vbuf, unsigned int type,
142740d87aafSMansur Alisha Shaik 				   unsigned int buf_type, u32 tag)
142840d87aafSMansur Alisha Shaik {
142940d87aafSMansur Alisha Shaik 	struct intbuf *dpb_buf;
143040d87aafSMansur Alisha Shaik 
143140d87aafSMansur Alisha Shaik 	if (!V4L2_TYPE_IS_CAPTURE(type) ||
143240d87aafSMansur Alisha Shaik 	    buf_type != inst->dpb_buftype)
143340d87aafSMansur Alisha Shaik 		return;
143440d87aafSMansur Alisha Shaik 
143540d87aafSMansur Alisha Shaik 	list_for_each_entry(dpb_buf, &inst->dpbbufs, list)
143640d87aafSMansur Alisha Shaik 		if (dpb_buf->dpb_out_tag == tag) {
143740d87aafSMansur Alisha Shaik 			dpb_buf->owned_by = DRIVER;
143840d87aafSMansur Alisha Shaik 			break;
143940d87aafSMansur Alisha Shaik 		}
144040d87aafSMansur Alisha Shaik }
144140d87aafSMansur Alisha Shaik EXPORT_SYMBOL_GPL(venus_helper_change_dpb_owner);
144240d87aafSMansur Alisha Shaik 
1443af2c3834SStanimir Varbanov int venus_helper_vb2_buf_init(struct vb2_buffer *vb)
1444af2c3834SStanimir Varbanov {
1445af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1446af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1447af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1448af2c3834SStanimir Varbanov 
1449af2c3834SStanimir Varbanov 	buf->size = vb2_plane_size(vb, 0);
1450cc82fd69SAlexandre Courbot 	buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1451af2c3834SStanimir Varbanov 
1452af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1453af2c3834SStanimir Varbanov 		list_add_tail(&buf->reg_list, &inst->registeredbufs);
1454af2c3834SStanimir Varbanov 
1455af2c3834SStanimir Varbanov 	return 0;
1456af2c3834SStanimir Varbanov }
1457af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_init);
1458af2c3834SStanimir Varbanov 
1459af2c3834SStanimir Varbanov int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb)
1460af2c3834SStanimir Varbanov {
1461af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1462f012b23dSStanimir Varbanov 	unsigned int out_buf_size = venus_helper_get_opb_size(inst);
146305979046SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
146405979046SStanimir Varbanov 
146505979046SStanimir Varbanov 	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
146605979046SStanimir Varbanov 		if (vbuf->field == V4L2_FIELD_ANY)
146705979046SStanimir Varbanov 			vbuf->field = V4L2_FIELD_NONE;
146805979046SStanimir Varbanov 		if (vbuf->field != V4L2_FIELD_NONE) {
146905979046SStanimir Varbanov 			dev_err(inst->core->dev, "%s field isn't supported\n",
147005979046SStanimir Varbanov 				__func__);
147105979046SStanimir Varbanov 			return -EINVAL;
147205979046SStanimir Varbanov 		}
147305979046SStanimir Varbanov 	}
1474af2c3834SStanimir Varbanov 
1475af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
1476f012b23dSStanimir Varbanov 	    vb2_plane_size(vb, 0) < out_buf_size)
1477af2c3834SStanimir Varbanov 		return -EINVAL;
1478af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
1479af2c3834SStanimir Varbanov 	    vb2_plane_size(vb, 0) < inst->input_buf_size)
1480af2c3834SStanimir Varbanov 		return -EINVAL;
1481af2c3834SStanimir Varbanov 
1482af2c3834SStanimir Varbanov 	return 0;
1483af2c3834SStanimir Varbanov }
1484af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare);
1485af2c3834SStanimir Varbanov 
1486fd1ee315SStanimir Varbanov static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb)
1487fd1ee315SStanimir Varbanov {
1488fd1ee315SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1489fd1ee315SStanimir Varbanov 	unsigned int idx = vbuf->vb2_buf.index;
1490fd1ee315SStanimir Varbanov 
1491fd1ee315SStanimir Varbanov 	if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1492fd1ee315SStanimir Varbanov 		inst->payloads[idx] = vb2_get_plane_payload(vb, 0);
1493fd1ee315SStanimir Varbanov }
1494fd1ee315SStanimir Varbanov 
1495af2c3834SStanimir Varbanov void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
1496af2c3834SStanimir Varbanov {
1497af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1498af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1499af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1500af2c3834SStanimir Varbanov 	int ret;
1501af2c3834SStanimir Varbanov 
1502af2c3834SStanimir Varbanov 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
1503af2c3834SStanimir Varbanov 
1504acf8a57dSStanimir Varbanov 	/* Skip processing queued capture buffers after LAST flag */
1505acf8a57dSStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
1506acf8a57dSStanimir Varbanov 	    V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1507acf8a57dSStanimir Varbanov 	    inst->codec_state == VENUS_DEC_STATE_DRC)
150821560ddfSStanimir Varbanov 		return;
1509acf8a57dSStanimir Varbanov 
1510fd1ee315SStanimir Varbanov 	cache_payload(inst, vb);
1511fd1ee315SStanimir Varbanov 
1512beac8290SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
1513beac8290SStanimir Varbanov 	    !(inst->streamon_out && inst->streamon_cap))
151421560ddfSStanimir Varbanov 		return;
1515af2c3834SStanimir Varbanov 
1516beac8290SStanimir Varbanov 	if (vb2_start_streaming_called(vb->vb2_queue)) {
1517af2c3834SStanimir Varbanov 		ret = is_buf_refed(inst, vbuf);
1518af2c3834SStanimir Varbanov 		if (ret)
151921560ddfSStanimir Varbanov 			return;
1520af2c3834SStanimir Varbanov 
1521af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, vbuf);
1522af2c3834SStanimir Varbanov 		if (ret)
1523af2c3834SStanimir Varbanov 			return_buf_error(inst, vbuf);
1524beac8290SStanimir Varbanov 	}
1525af2c3834SStanimir Varbanov }
1526af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue);
1527af2c3834SStanimir Varbanov 
15280febf923SStanimir Varbanov void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type,
1529af2c3834SStanimir Varbanov 			       enum vb2_buffer_state state)
1530af2c3834SStanimir Varbanov {
1531af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *buf;
1532af2c3834SStanimir Varbanov 
15330febf923SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1534af2c3834SStanimir Varbanov 		while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
1535af2c3834SStanimir Varbanov 			v4l2_m2m_buf_done(buf, state);
15360febf923SStanimir Varbanov 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1537af2c3834SStanimir Varbanov 		while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
1538af2c3834SStanimir Varbanov 			v4l2_m2m_buf_done(buf, state);
1539af2c3834SStanimir Varbanov 	}
15400febf923SStanimir Varbanov }
1541af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_buffers_done);
1542af2c3834SStanimir Varbanov 
1543af2c3834SStanimir Varbanov void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
1544af2c3834SStanimir Varbanov {
1545af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(q);
1546af2c3834SStanimir Varbanov 	struct venus_core *core = inst->core;
1547af2c3834SStanimir Varbanov 	int ret;
1548af2c3834SStanimir Varbanov 
1549af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1550af2c3834SStanimir Varbanov 
1551af2c3834SStanimir Varbanov 	if (inst->streamon_out & inst->streamon_cap) {
1552af2c3834SStanimir Varbanov 		ret = hfi_session_stop(inst);
1553af2c3834SStanimir Varbanov 		ret |= hfi_session_unload_res(inst);
15541e485ee5SStanimir Varbanov 		ret |= venus_helper_unregister_bufs(inst);
15551e485ee5SStanimir Varbanov 		ret |= venus_helper_intbufs_free(inst);
1556af2c3834SStanimir Varbanov 		ret |= hfi_session_deinit(inst);
1557af2c3834SStanimir Varbanov 
1558b46ff4ebSStanimir Varbanov 		if (inst->session_error || test_bit(0, &core->sys_error))
1559af2c3834SStanimir Varbanov 			ret = -EIO;
1560af2c3834SStanimir Varbanov 
1561af2c3834SStanimir Varbanov 		if (ret)
1562af2c3834SStanimir Varbanov 			hfi_session_abort(inst);
1563af2c3834SStanimir Varbanov 
1564f012b23dSStanimir Varbanov 		venus_helper_free_dpb_bufs(inst);
1565f012b23dSStanimir Varbanov 
15667482a983SStanimir Varbanov 		venus_pm_load_scale(inst);
1567bbd770aeSStanimir Varbanov 		INIT_LIST_HEAD(&inst->registeredbufs);
1568af2c3834SStanimir Varbanov 	}
1569af2c3834SStanimir Varbanov 
15700febf923SStanimir Varbanov 	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
15710febf923SStanimir Varbanov 				  VB2_BUF_STATE_ERROR);
15720febf923SStanimir Varbanov 	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
15730febf923SStanimir Varbanov 				  VB2_BUF_STATE_ERROR);
1574af2c3834SStanimir Varbanov 
1575af2c3834SStanimir Varbanov 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1576af2c3834SStanimir Varbanov 		inst->streamon_out = 0;
1577af2c3834SStanimir Varbanov 	else
1578af2c3834SStanimir Varbanov 		inst->streamon_cap = 0;
1579af2c3834SStanimir Varbanov 
15804ebf9693SAniket Masule 	venus_pm_release_core(inst);
15814ebf9693SAniket Masule 
15823227a8f7SStanimir Varbanov 	inst->session_error = 0;
15833227a8f7SStanimir Varbanov 
1584af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1585af2c3834SStanimir Varbanov }
1586af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
1587af2c3834SStanimir Varbanov 
1588aa6dcf17SStanimir Varbanov void venus_helper_vb2_queue_error(struct venus_inst *inst)
1589aa6dcf17SStanimir Varbanov {
1590aa6dcf17SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1591aa6dcf17SStanimir Varbanov 	struct vb2_queue *q;
1592aa6dcf17SStanimir Varbanov 
1593aa6dcf17SStanimir Varbanov 	q = v4l2_m2m_get_src_vq(m2m_ctx);
1594aa6dcf17SStanimir Varbanov 	vb2_queue_error(q);
1595aa6dcf17SStanimir Varbanov 	q = v4l2_m2m_get_dst_vq(m2m_ctx);
1596aa6dcf17SStanimir Varbanov 	vb2_queue_error(q);
1597aa6dcf17SStanimir Varbanov }
1598aa6dcf17SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_queue_error);
1599aa6dcf17SStanimir Varbanov 
160014ea00d6SStanimir Varbanov int venus_helper_process_initial_cap_bufs(struct venus_inst *inst)
160114ea00d6SStanimir Varbanov {
160214ea00d6SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
160314ea00d6SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
160414ea00d6SStanimir Varbanov 	int ret;
160514ea00d6SStanimir Varbanov 
160614ea00d6SStanimir Varbanov 	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
160714ea00d6SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
160814ea00d6SStanimir Varbanov 		if (ret) {
160914ea00d6SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
161014ea00d6SStanimir Varbanov 			return ret;
161114ea00d6SStanimir Varbanov 		}
161214ea00d6SStanimir Varbanov 	}
161314ea00d6SStanimir Varbanov 
161414ea00d6SStanimir Varbanov 	return 0;
161514ea00d6SStanimir Varbanov }
161614ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs);
161714ea00d6SStanimir Varbanov 
161814ea00d6SStanimir Varbanov int venus_helper_process_initial_out_bufs(struct venus_inst *inst)
161914ea00d6SStanimir Varbanov {
162014ea00d6SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
162114ea00d6SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
162214ea00d6SStanimir Varbanov 	int ret;
162314ea00d6SStanimir Varbanov 
162414ea00d6SStanimir Varbanov 	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
162514ea00d6SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
162614ea00d6SStanimir Varbanov 		if (ret) {
162714ea00d6SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
162814ea00d6SStanimir Varbanov 			return ret;
162914ea00d6SStanimir Varbanov 		}
163014ea00d6SStanimir Varbanov 	}
163114ea00d6SStanimir Varbanov 
163214ea00d6SStanimir Varbanov 	return 0;
163314ea00d6SStanimir Varbanov }
163414ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs);
163514ea00d6SStanimir Varbanov 
1636af2c3834SStanimir Varbanov int venus_helper_vb2_start_streaming(struct venus_inst *inst)
1637af2c3834SStanimir Varbanov {
1638af2c3834SStanimir Varbanov 	int ret;
1639af2c3834SStanimir Varbanov 
16401e485ee5SStanimir Varbanov 	ret = venus_helper_intbufs_alloc(inst);
1641af2c3834SStanimir Varbanov 	if (ret)
1642af2c3834SStanimir Varbanov 		return ret;
1643af2c3834SStanimir Varbanov 
1644af2c3834SStanimir Varbanov 	ret = session_register_bufs(inst);
1645af2c3834SStanimir Varbanov 	if (ret)
1646af2c3834SStanimir Varbanov 		goto err_bufs_free;
1647af2c3834SStanimir Varbanov 
16487482a983SStanimir Varbanov 	venus_pm_load_scale(inst);
1649af2c3834SStanimir Varbanov 
1650af2c3834SStanimir Varbanov 	ret = hfi_session_load_res(inst);
1651af2c3834SStanimir Varbanov 	if (ret)
1652af2c3834SStanimir Varbanov 		goto err_unreg_bufs;
1653af2c3834SStanimir Varbanov 
1654af2c3834SStanimir Varbanov 	ret = hfi_session_start(inst);
1655af2c3834SStanimir Varbanov 	if (ret)
1656af2c3834SStanimir Varbanov 		goto err_unload_res;
1657af2c3834SStanimir Varbanov 
1658af2c3834SStanimir Varbanov 	return 0;
1659af2c3834SStanimir Varbanov 
1660af2c3834SStanimir Varbanov err_unload_res:
1661af2c3834SStanimir Varbanov 	hfi_session_unload_res(inst);
1662af2c3834SStanimir Varbanov err_unreg_bufs:
16631e485ee5SStanimir Varbanov 	venus_helper_unregister_bufs(inst);
1664af2c3834SStanimir Varbanov err_bufs_free:
16651e485ee5SStanimir Varbanov 	venus_helper_intbufs_free(inst);
1666af2c3834SStanimir Varbanov 	return ret;
1667af2c3834SStanimir Varbanov }
1668af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming);
1669af2c3834SStanimir Varbanov 
1670af2c3834SStanimir Varbanov void venus_helper_m2m_device_run(void *priv)
1671af2c3834SStanimir Varbanov {
1672af2c3834SStanimir Varbanov 	struct venus_inst *inst = priv;
1673af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1674af2c3834SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
1675af2c3834SStanimir Varbanov 	int ret;
1676af2c3834SStanimir Varbanov 
1677af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1678af2c3834SStanimir Varbanov 
1679af2c3834SStanimir Varbanov 	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
1680af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1681af2c3834SStanimir Varbanov 		if (ret)
1682af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1683af2c3834SStanimir Varbanov 	}
1684af2c3834SStanimir Varbanov 
1685af2c3834SStanimir Varbanov 	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
1686af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1687af2c3834SStanimir Varbanov 		if (ret)
1688af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1689af2c3834SStanimir Varbanov 	}
1690af2c3834SStanimir Varbanov 
1691af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1692af2c3834SStanimir Varbanov }
1693af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_device_run);
1694af2c3834SStanimir Varbanov 
1695af2c3834SStanimir Varbanov void venus_helper_m2m_job_abort(void *priv)
1696af2c3834SStanimir Varbanov {
1697af2c3834SStanimir Varbanov 	struct venus_inst *inst = priv;
1698af2c3834SStanimir Varbanov 
1699af2c3834SStanimir Varbanov 	v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx);
1700af2c3834SStanimir Varbanov }
1701af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort);
1702af2c3834SStanimir Varbanov 
1703aa603389SStanimir Varbanov int venus_helper_session_init(struct venus_inst *inst)
1704aa603389SStanimir Varbanov {
1705aa603389SStanimir Varbanov 	enum hfi_version version = inst->core->res->hfi_version;
1706aa603389SStanimir Varbanov 	u32 session_type = inst->session_type;
1707aa603389SStanimir Varbanov 	u32 codec;
1708aa603389SStanimir Varbanov 	int ret;
1709aa603389SStanimir Varbanov 
1710aa603389SStanimir Varbanov 	codec = inst->session_type == VIDC_SESSION_TYPE_DEC ?
1711aa603389SStanimir Varbanov 			inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
1712aa603389SStanimir Varbanov 
1713aa603389SStanimir Varbanov 	ret = hfi_session_init(inst, codec);
1714aa603389SStanimir Varbanov 	if (ret)
1715aa603389SStanimir Varbanov 		return ret;
1716aa603389SStanimir Varbanov 
1717aa603389SStanimir Varbanov 	inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
1718aa603389SStanimir Varbanov 								  session_type);
1719aa603389SStanimir Varbanov 	inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
1720aa603389SStanimir Varbanov 								  session_type);
17213cfe5815SDikshita Agarwal 	inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec,
17223cfe5815SDikshita Agarwal 								       session_type);
1723aa603389SStanimir Varbanov 
1724aa603389SStanimir Varbanov 	return 0;
1725aa603389SStanimir Varbanov }
1726aa603389SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_session_init);
1727aa603389SStanimir Varbanov 
1728af2c3834SStanimir Varbanov void venus_helper_init_instance(struct venus_inst *inst)
1729af2c3834SStanimir Varbanov {
1730af2c3834SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
1731af2c3834SStanimir Varbanov 		INIT_LIST_HEAD(&inst->delayed_process);
1732af2c3834SStanimir Varbanov 		INIT_WORK(&inst->delayed_process_work,
1733af2c3834SStanimir Varbanov 			  delayed_process_buf_func);
1734af2c3834SStanimir Varbanov 	}
1735af2c3834SStanimir Varbanov }
1736af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_init_instance);
1737aa3a8414SStanimir Varbanov 
17388f3b41dcSStanimir Varbanov static bool find_fmt_from_caps(struct hfi_plat_caps *caps, u32 buftype, u32 fmt)
1739f012b23dSStanimir Varbanov {
1740f012b23dSStanimir Varbanov 	unsigned int i;
1741f012b23dSStanimir Varbanov 
1742f012b23dSStanimir Varbanov 	for (i = 0; i < caps->num_fmts; i++) {
1743f012b23dSStanimir Varbanov 		if (caps->fmts[i].buftype == buftype &&
1744f012b23dSStanimir Varbanov 		    caps->fmts[i].fmt == fmt)
1745f012b23dSStanimir Varbanov 			return true;
1746f012b23dSStanimir Varbanov 	}
1747f012b23dSStanimir Varbanov 
1748f012b23dSStanimir Varbanov 	return false;
1749f012b23dSStanimir Varbanov }
1750f012b23dSStanimir Varbanov 
1751f012b23dSStanimir Varbanov int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt,
1752f012b23dSStanimir Varbanov 			      u32 *out_fmt, u32 *out2_fmt, bool ubwc)
1753f012b23dSStanimir Varbanov {
1754f012b23dSStanimir Varbanov 	struct venus_core *core = inst->core;
17558f3b41dcSStanimir Varbanov 	struct hfi_plat_caps *caps;
1756f012b23dSStanimir Varbanov 	u32 ubwc_fmt, fmt = to_hfi_raw_fmt(v4l2_fmt);
1757f012b23dSStanimir Varbanov 	bool found, found_ubwc;
1758f012b23dSStanimir Varbanov 
1759f012b23dSStanimir Varbanov 	*out_fmt = *out2_fmt = 0;
1760f012b23dSStanimir Varbanov 
1761f012b23dSStanimir Varbanov 	if (!fmt)
1762f012b23dSStanimir Varbanov 		return -EINVAL;
1763f012b23dSStanimir Varbanov 
1764f012b23dSStanimir Varbanov 	caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
1765f012b23dSStanimir Varbanov 	if (!caps)
1766f012b23dSStanimir Varbanov 		return -EINVAL;
1767f012b23dSStanimir Varbanov 
1768996d2155SDikshita Agarwal 	if (inst->bit_depth == VIDC_BITDEPTH_10 && inst->session_type == VIDC_SESSION_TYPE_DEC) {
1769996d2155SDikshita Agarwal 		found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1770996d2155SDikshita Agarwal 						HFI_COLOR_FORMAT_YUV420_TP10_UBWC);
1771996d2155SDikshita Agarwal 		found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
1772996d2155SDikshita Agarwal 		if (found_ubwc && found) {
1773996d2155SDikshita Agarwal 			/*
1774996d2155SDikshita Agarwal 			 * Hard-code DPB buffers to be 10bit UBWC
1775996d2155SDikshita Agarwal 			 * until V4L2 is able to expose compressed/tiled
1776996d2155SDikshita Agarwal 			 * formats to applications.
1777996d2155SDikshita Agarwal 			 */
1778996d2155SDikshita Agarwal 			*out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
1779996d2155SDikshita Agarwal 			*out2_fmt = fmt;
1780996d2155SDikshita Agarwal 			return 0;
1781996d2155SDikshita Agarwal 		}
1782996d2155SDikshita Agarwal 	}
1783996d2155SDikshita Agarwal 
1784f012b23dSStanimir Varbanov 	if (ubwc) {
1785f012b23dSStanimir Varbanov 		ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;
1786f012b23dSStanimir Varbanov 		found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1787f012b23dSStanimir Varbanov 						ubwc_fmt);
1788f012b23dSStanimir Varbanov 		found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
1789f012b23dSStanimir Varbanov 
1790f012b23dSStanimir Varbanov 		if (found_ubwc && found) {
1791f012b23dSStanimir Varbanov 			*out_fmt = ubwc_fmt;
1792f012b23dSStanimir Varbanov 			*out2_fmt = fmt;
1793f012b23dSStanimir Varbanov 			return 0;
1794f012b23dSStanimir Varbanov 		}
1795f012b23dSStanimir Varbanov 	}
1796f012b23dSStanimir Varbanov 
1797f012b23dSStanimir Varbanov 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt);
1798f012b23dSStanimir Varbanov 	if (found) {
1799f012b23dSStanimir Varbanov 		*out_fmt = fmt;
1800f012b23dSStanimir Varbanov 		*out2_fmt = 0;
1801f012b23dSStanimir Varbanov 		return 0;
1802f012b23dSStanimir Varbanov 	}
1803f012b23dSStanimir Varbanov 
1804f012b23dSStanimir Varbanov 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
1805f012b23dSStanimir Varbanov 	if (found) {
1806f012b23dSStanimir Varbanov 		*out_fmt = 0;
1807f012b23dSStanimir Varbanov 		*out2_fmt = fmt;
1808f012b23dSStanimir Varbanov 		return 0;
1809f012b23dSStanimir Varbanov 	}
1810f012b23dSStanimir Varbanov 
1811f012b23dSStanimir Varbanov 	return -EINVAL;
1812f012b23dSStanimir Varbanov }
1813f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts);
181401e869e7SDikshita Agarwal 
1815fc00086eSStanimir Varbanov bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt)
1816fc00086eSStanimir Varbanov {
1817fc00086eSStanimir Varbanov 	struct venus_core *core = inst->core;
1818fc00086eSStanimir Varbanov 	u32 fmt = to_hfi_raw_fmt(v4l2_pixfmt);
1819fc00086eSStanimir Varbanov 	struct hfi_plat_caps *caps;
18207f77fa9fSBryan O'Donoghue 	bool found;
1821fc00086eSStanimir Varbanov 
1822fc00086eSStanimir Varbanov 	if (!fmt)
1823fc00086eSStanimir Varbanov 		return false;
1824fc00086eSStanimir Varbanov 
1825fc00086eSStanimir Varbanov 	caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
1826fc00086eSStanimir Varbanov 	if (!caps)
1827fc00086eSStanimir Varbanov 		return false;
1828fc00086eSStanimir Varbanov 
18297f77fa9fSBryan O'Donoghue 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt);
18307f77fa9fSBryan O'Donoghue 	if (found)
18317f77fa9fSBryan O'Donoghue 		goto done;
1832fc00086eSStanimir Varbanov 
18337f77fa9fSBryan O'Donoghue 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
18347f77fa9fSBryan O'Donoghue done:
18357f77fa9fSBryan O'Donoghue 	return found;
1836fc00086eSStanimir Varbanov }
1837fc00086eSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_check_format);
1838fc00086eSStanimir Varbanov 
183901e869e7SDikshita Agarwal int venus_helper_set_stride(struct venus_inst *inst,
184001e869e7SDikshita Agarwal 			    unsigned int width, unsigned int height)
184101e869e7SDikshita Agarwal {
184201e869e7SDikshita Agarwal 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO;
184301e869e7SDikshita Agarwal 
184401e869e7SDikshita Agarwal 	struct hfi_uncompressed_plane_actual_info plane_actual_info;
184501e869e7SDikshita Agarwal 
184601e869e7SDikshita Agarwal 	plane_actual_info.buffer_type = HFI_BUFFER_INPUT;
184701e869e7SDikshita Agarwal 	plane_actual_info.num_planes = 2;
184801e869e7SDikshita Agarwal 	plane_actual_info.plane_format[0].actual_stride = width;
184901e869e7SDikshita Agarwal 	plane_actual_info.plane_format[0].actual_plane_buffer_height = height;
185001e869e7SDikshita Agarwal 	plane_actual_info.plane_format[1].actual_stride = width;
185101e869e7SDikshita Agarwal 	plane_actual_info.plane_format[1].actual_plane_buffer_height = height / 2;
185201e869e7SDikshita Agarwal 
185301e869e7SDikshita Agarwal 	return hfi_session_set_property(inst, ptype, &plane_actual_info);
185401e869e7SDikshita Agarwal }
185501e869e7SDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_stride);
1856