xref: /linux/drivers/media/platform/qcom/venus/helpers.c (revision 73664f107c0fafb59cd91e576b81c986adb74610)
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 
93*73664f10SVikash Garodia static void free_dpb_buf(struct venus_inst *inst, struct intbuf *buf)
94*73664f10SVikash Garodia {
95*73664f10SVikash Garodia 	ida_free(&inst->dpb_ids, buf->dpb_out_tag);
96*73664f10SVikash Garodia 
97*73664f10SVikash Garodia 	list_del_init(&buf->list);
98*73664f10SVikash Garodia 	dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
99*73664f10SVikash Garodia 		       buf->attrs);
100*73664f10SVikash Garodia 	kfree(buf);
101*73664f10SVikash Garodia }
102*73664f10SVikash Garodia 
1031e485ee5SStanimir Varbanov int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
104f012b23dSStanimir Varbanov {
105*73664f10SVikash Garodia 	struct intbuf *buf, *next;
106*73664f10SVikash Garodia 	unsigned int dpb_size = 0;
107f012b23dSStanimir Varbanov 	int ret = 0;
108f012b23dSStanimir Varbanov 
109*73664f10SVikash Garodia 	if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
110*73664f10SVikash Garodia 		dpb_size = inst->output_buf_size;
111*73664f10SVikash Garodia 	else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
112*73664f10SVikash Garodia 		dpb_size = inst->output2_buf_size;
113*73664f10SVikash Garodia 
114*73664f10SVikash 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 
125*73664f10SVikash Garodia 		/* free buffer from previous sequence which was released later */
126*73664f10SVikash Garodia 		if (dpb_size > buf->size) {
127*73664f10SVikash Garodia 			free_dpb_buf(inst, buf);
128*73664f10SVikash Garodia 			continue;
129*73664f10SVikash Garodia 		}
130*73664f10SVikash 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;
152*73664f10SVikash 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 
192f012b23dSStanimir Varbanov 	count = HFI_BUFREQ_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 	int ret;
506af2c3834SStanimir Varbanov 
507af2c3834SStanimir Varbanov 	memset(&fdata, 0, sizeof(fdata));
508af2c3834SStanimir Varbanov 	fdata.alloc_len = buf->size;
509af2c3834SStanimir Varbanov 	fdata.device_addr = buf->dma_addr;
510af2c3834SStanimir Varbanov 	fdata.timestamp = vb->timestamp;
511af2c3834SStanimir Varbanov 	do_div(fdata.timestamp, NSEC_PER_USEC);
512af2c3834SStanimir Varbanov 	fdata.flags = 0;
513af2c3834SStanimir Varbanov 	fdata.clnt_data = vbuf->vb2_buf.index;
514af2c3834SStanimir Varbanov 
515af2c3834SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
516af2c3834SStanimir Varbanov 		fdata.buffer_type = HFI_BUFFER_INPUT;
517af2c3834SStanimir Varbanov 		fdata.filled_len = vb2_get_plane_payload(vb, 0);
518af2c3834SStanimir Varbanov 		fdata.offset = vb->planes[0].data_offset;
519af2c3834SStanimir Varbanov 
520af2c3834SStanimir Varbanov 		if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
521af2c3834SStanimir Varbanov 			fdata.flags |= HFI_BUFFERFLAG_EOS;
522d42974e4SStanimir Varbanov 
523d42974e4SStanimir Varbanov 		if (inst->session_type == VIDC_SESSION_TYPE_DEC)
524d42974e4SStanimir Varbanov 			put_ts_metadata(inst, vbuf);
525c0e284ccSAniket Masule 
5267482a983SStanimir Varbanov 		venus_pm_load_scale(inst);
527af2c3834SStanimir Varbanov 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
528f012b23dSStanimir Varbanov 		if (inst->session_type == VIDC_SESSION_TYPE_ENC)
529af2c3834SStanimir Varbanov 			fdata.buffer_type = HFI_BUFFER_OUTPUT;
530f012b23dSStanimir Varbanov 		else
531f012b23dSStanimir Varbanov 			fdata.buffer_type = inst->opb_buftype;
532af2c3834SStanimir Varbanov 		fdata.filled_len = 0;
533af2c3834SStanimir Varbanov 		fdata.offset = 0;
534af2c3834SStanimir Varbanov 	}
535af2c3834SStanimir Varbanov 
536af2c3834SStanimir Varbanov 	ret = hfi_session_process_buf(inst, &fdata);
537af2c3834SStanimir Varbanov 	if (ret)
538af2c3834SStanimir Varbanov 		return ret;
539af2c3834SStanimir Varbanov 
540af2c3834SStanimir Varbanov 	return 0;
541af2c3834SStanimir Varbanov }
542af2c3834SStanimir Varbanov 
543f0383520SStanimir Varbanov static bool is_dynamic_bufmode(struct venus_inst *inst)
544af2c3834SStanimir Varbanov {
545f0383520SStanimir Varbanov 	struct venus_core *core = inst->core;
5468f3b41dcSStanimir Varbanov 	struct hfi_plat_caps *caps;
547f0383520SStanimir Varbanov 
548bc8c479aSStanimir Varbanov 	/*
549bc8c479aSStanimir Varbanov 	 * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports
550bc8c479aSStanimir Varbanov 	 * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2.
551bc8c479aSStanimir Varbanov 	 */
5527ed9e0b3SBryan O'Donoghue 	if (IS_V4(core) || IS_V6(core))
553bc8c479aSStanimir Varbanov 		return true;
554bc8c479aSStanimir Varbanov 
555f0383520SStanimir Varbanov 	caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
556f0383520SStanimir Varbanov 	if (!caps)
5571cafbb86SGustavo A. R. Silva 		return false;
558af2c3834SStanimir Varbanov 
559f0383520SStanimir Varbanov 	return caps->cap_bufs_mode_dynamic;
560af2c3834SStanimir Varbanov }
561af2c3834SStanimir Varbanov 
5621e485ee5SStanimir Varbanov int venus_helper_unregister_bufs(struct venus_inst *inst)
563af2c3834SStanimir Varbanov {
564af2c3834SStanimir Varbanov 	struct venus_buffer *buf, *n;
565af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd;
566af2c3834SStanimir Varbanov 	int ret = 0;
567af2c3834SStanimir Varbanov 
568f0383520SStanimir Varbanov 	if (is_dynamic_bufmode(inst))
569af2c3834SStanimir Varbanov 		return 0;
570af2c3834SStanimir Varbanov 
571af2c3834SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->registeredbufs, reg_list) {
572af2c3834SStanimir Varbanov 		fill_buffer_desc(buf, &bd, true);
573af2c3834SStanimir Varbanov 		ret = hfi_session_unset_buffers(inst, &bd);
574af2c3834SStanimir Varbanov 		list_del_init(&buf->reg_list);
575af2c3834SStanimir Varbanov 	}
576af2c3834SStanimir Varbanov 
577af2c3834SStanimir Varbanov 	return ret;
578af2c3834SStanimir Varbanov }
5791e485ee5SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs);
580af2c3834SStanimir Varbanov 
581af2c3834SStanimir Varbanov static int session_register_bufs(struct venus_inst *inst)
582af2c3834SStanimir Varbanov {
583af2c3834SStanimir Varbanov 	struct venus_core *core = inst->core;
584af2c3834SStanimir Varbanov 	struct device *dev = core->dev;
585af2c3834SStanimir Varbanov 	struct hfi_buffer_desc bd;
586af2c3834SStanimir Varbanov 	struct venus_buffer *buf;
587af2c3834SStanimir Varbanov 	int ret = 0;
588af2c3834SStanimir Varbanov 
589f0383520SStanimir Varbanov 	if (is_dynamic_bufmode(inst))
590af2c3834SStanimir Varbanov 		return 0;
591af2c3834SStanimir Varbanov 
592af2c3834SStanimir Varbanov 	list_for_each_entry(buf, &inst->registeredbufs, reg_list) {
593af2c3834SStanimir Varbanov 		fill_buffer_desc(buf, &bd, false);
594af2c3834SStanimir Varbanov 		ret = hfi_session_set_buffers(inst, &bd);
595af2c3834SStanimir Varbanov 		if (ret) {
596af2c3834SStanimir Varbanov 			dev_err(dev, "%s: set buffer failed\n", __func__);
597af2c3834SStanimir Varbanov 			break;
598af2c3834SStanimir Varbanov 		}
599af2c3834SStanimir Varbanov 	}
600af2c3834SStanimir Varbanov 
601af2c3834SStanimir Varbanov 	return ret;
602af2c3834SStanimir Varbanov }
603af2c3834SStanimir Varbanov 
604ab97a3fbSStanimir Varbanov static u32 to_hfi_raw_fmt(u32 v4l2_fmt)
605ab97a3fbSStanimir Varbanov {
606ab97a3fbSStanimir Varbanov 	switch (v4l2_fmt) {
607ab97a3fbSStanimir Varbanov 	case V4L2_PIX_FMT_NV12:
608ab97a3fbSStanimir Varbanov 		return HFI_COLOR_FORMAT_NV12;
609ab97a3fbSStanimir Varbanov 	case V4L2_PIX_FMT_NV21:
610ab97a3fbSStanimir Varbanov 		return HFI_COLOR_FORMAT_NV21;
611ab97a3fbSStanimir Varbanov 	default:
612ab97a3fbSStanimir Varbanov 		break;
613ab97a3fbSStanimir Varbanov 	}
614ab97a3fbSStanimir Varbanov 
615ab97a3fbSStanimir Varbanov 	return 0;
616ab97a3fbSStanimir Varbanov }
617ab97a3fbSStanimir Varbanov 
6187371093fSStanimir Varbanov static int platform_get_bufreq(struct venus_inst *inst, u32 buftype,
6197371093fSStanimir Varbanov 			       struct hfi_buffer_requirements *req)
6207371093fSStanimir Varbanov {
6217371093fSStanimir Varbanov 	enum hfi_version version = inst->core->res->hfi_version;
6227371093fSStanimir Varbanov 	const struct hfi_platform *hfi_plat;
6237371093fSStanimir Varbanov 	struct hfi_plat_buffers_params params;
6247371093fSStanimir Varbanov 	bool is_dec = inst->session_type == VIDC_SESSION_TYPE_DEC;
6257371093fSStanimir Varbanov 	struct venc_controls *enc_ctr = &inst->controls.enc;
6267371093fSStanimir Varbanov 
6277371093fSStanimir Varbanov 	hfi_plat = hfi_platform_get(version);
6287371093fSStanimir Varbanov 
6297371093fSStanimir Varbanov 	if (!hfi_plat || !hfi_plat->bufreq)
6307371093fSStanimir Varbanov 		return -EINVAL;
6317371093fSStanimir Varbanov 
6327371093fSStanimir Varbanov 	params.version = version;
633920173c7SDikshita Agarwal 	params.num_vpp_pipes = inst->core->res->num_vpp_pipes;
6347371093fSStanimir Varbanov 
6357371093fSStanimir Varbanov 	if (is_dec) {
6367371093fSStanimir Varbanov 		params.width = inst->width;
6377371093fSStanimir Varbanov 		params.height = inst->height;
6387371093fSStanimir Varbanov 		params.codec = inst->fmt_out->pixfmt;
6397371093fSStanimir Varbanov 		params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_cap->pixfmt);
6407371093fSStanimir Varbanov 		params.dec.max_mbs_per_frame = mbs_per_frame_max(inst);
6417371093fSStanimir Varbanov 		params.dec.buffer_size_limit = 0;
6427371093fSStanimir Varbanov 		params.dec.is_secondary_output =
6437371093fSStanimir Varbanov 			inst->opb_buftype == HFI_BUFFER_OUTPUT2;
6447371093fSStanimir Varbanov 		params.dec.is_interlaced =
6456fc46680SZhen Lei 			inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE;
6467371093fSStanimir Varbanov 	} else {
6477371093fSStanimir Varbanov 		params.width = inst->out_width;
6487371093fSStanimir Varbanov 		params.height = inst->out_height;
6497371093fSStanimir Varbanov 		params.codec = inst->fmt_cap->pixfmt;
6507371093fSStanimir Varbanov 		params.hfi_color_fmt = to_hfi_raw_fmt(inst->fmt_out->pixfmt);
6517371093fSStanimir Varbanov 		params.enc.work_mode = VIDC_WORK_MODE_2;
6527371093fSStanimir Varbanov 		params.enc.rc_type = HFI_RATE_CONTROL_OFF;
6537371093fSStanimir Varbanov 		if (enc_ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
6547371093fSStanimir Varbanov 			params.enc.rc_type = HFI_RATE_CONTROL_CQ;
6557371093fSStanimir Varbanov 		params.enc.num_b_frames = enc_ctr->num_b_frames;
6567371093fSStanimir Varbanov 		params.enc.is_tenbit = inst->bit_depth == VIDC_BITDEPTH_10;
6577371093fSStanimir Varbanov 	}
6587371093fSStanimir Varbanov 
6597371093fSStanimir Varbanov 	return hfi_plat->bufreq(&params, inst->session_type, buftype, req);
6607371093fSStanimir Varbanov }
6617371093fSStanimir Varbanov 
662af2c3834SStanimir Varbanov int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
663af2c3834SStanimir Varbanov 			    struct hfi_buffer_requirements *req)
664af2c3834SStanimir Varbanov {
665af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS;
666af2c3834SStanimir Varbanov 	union hfi_get_property hprop;
667af2c3834SStanimir Varbanov 	unsigned int i;
668af2c3834SStanimir Varbanov 	int ret;
669af2c3834SStanimir Varbanov 
670af2c3834SStanimir Varbanov 	if (req)
671af2c3834SStanimir Varbanov 		memset(req, 0, sizeof(*req));
672af2c3834SStanimir Varbanov 
67316545aa3SDikshita Agarwal 	if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2)
67416545aa3SDikshita Agarwal 		req->count_min = inst->fw_min_cnt;
67516545aa3SDikshita Agarwal 
6767371093fSStanimir Varbanov 	ret = platform_get_bufreq(inst, type, req);
67716545aa3SDikshita Agarwal 	if (!ret) {
67816545aa3SDikshita Agarwal 		if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2)
67916545aa3SDikshita Agarwal 			inst->fw_min_cnt = req->count_min;
6807371093fSStanimir Varbanov 		return 0;
68116545aa3SDikshita Agarwal 	}
6827371093fSStanimir Varbanov 
683af2c3834SStanimir Varbanov 	ret = hfi_session_get_property(inst, ptype, &hprop);
684af2c3834SStanimir Varbanov 	if (ret)
685af2c3834SStanimir Varbanov 		return ret;
686af2c3834SStanimir Varbanov 
687af2c3834SStanimir Varbanov 	ret = -EINVAL;
688af2c3834SStanimir Varbanov 
689af2c3834SStanimir Varbanov 	for (i = 0; i < HFI_BUFFER_TYPE_MAX; i++) {
690af2c3834SStanimir Varbanov 		if (hprop.bufreq[i].type != type)
691af2c3834SStanimir Varbanov 			continue;
692af2c3834SStanimir Varbanov 
693af2c3834SStanimir Varbanov 		if (req)
694af2c3834SStanimir Varbanov 			memcpy(req, &hprop.bufreq[i], sizeof(*req));
695af2c3834SStanimir Varbanov 		ret = 0;
696af2c3834SStanimir Varbanov 		break;
697af2c3834SStanimir Varbanov 	}
698af2c3834SStanimir Varbanov 
699af2c3834SStanimir Varbanov 	return ret;
700af2c3834SStanimir Varbanov }
701af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
702af2c3834SStanimir Varbanov 
7032c2dc2fdSStanimir Varbanov struct id_mapping {
7042c2dc2fdSStanimir Varbanov 	u32 hfi_id;
7052c2dc2fdSStanimir Varbanov 	u32 v4l2_id;
7062c2dc2fdSStanimir Varbanov };
7072c2dc2fdSStanimir Varbanov 
7082c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_profiles[] = {
7092c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE },
7102c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_PROFILE_ADVANCEDSIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE },
7112c2dc2fdSStanimir Varbanov };
7122c2dc2fdSStanimir Varbanov 
7132c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg4_levels[] = {
7142c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 },
7152c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_0b, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B },
7162c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 },
7172c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 },
7182c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 },
7192c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 },
7202c2dc2fdSStanimir Varbanov 	{ HFI_MPEG4_LEVEL_5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 },
7212c2dc2fdSStanimir Varbanov };
7222c2dc2fdSStanimir Varbanov 
7232c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_profiles[] = {
7242c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE },
7252c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_MAIN, V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN },
7262c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SNR, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE },
7272c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_SPATIAL, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE },
7282c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_PROFILE_HIGH, V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH },
7292c2dc2fdSStanimir Varbanov };
7302c2dc2fdSStanimir Varbanov 
7312c2dc2fdSStanimir Varbanov static const struct id_mapping mpeg2_levels[] = {
7322c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_LL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW },
7332c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_ML, V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN },
7342c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_H14, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440 },
7352c2dc2fdSStanimir Varbanov 	{ HFI_MPEG2_LEVEL_HL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH },
7362c2dc2fdSStanimir Varbanov };
7372c2dc2fdSStanimir Varbanov 
7382c2dc2fdSStanimir Varbanov static const struct id_mapping h264_profiles[] = {
7392c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE },
7402c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN },
7412c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH },
7422c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH },
7432c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH },
7442c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE },
7452c2dc2fdSStanimir Varbanov 	{ HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH },
7462c2dc2fdSStanimir Varbanov };
7472c2dc2fdSStanimir Varbanov 
7482c2dc2fdSStanimir Varbanov static const struct id_mapping h264_levels[] = {
7492c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 },
7502c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B },
7512c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 },
7522c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 },
7532c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 },
7542c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 },
7552c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 },
7562c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 },
7572c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 },
7582c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 },
7592c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 },
7602c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 },
7612c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 },
7622c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 },
7632c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 },
7642c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
7652c2dc2fdSStanimir Varbanov 	{ HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
7662c2dc2fdSStanimir Varbanov };
7672c2dc2fdSStanimir Varbanov 
7682c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_profiles[] = {
7692c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN },
7702c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE },
7712c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 },
7722c2dc2fdSStanimir Varbanov };
7732c2dc2fdSStanimir Varbanov 
7742c2dc2fdSStanimir Varbanov static const struct id_mapping hevc_levels[] = {
7752c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 },
7762c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 },
7772c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 },
7782c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 },
7792c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 },
7802c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 },
7812c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 },
7822c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 },
7832c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 },
7842c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 },
7852c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 },
7862c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 },
7872c2dc2fdSStanimir Varbanov 	{ HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 },
7882c2dc2fdSStanimir Varbanov };
7892c2dc2fdSStanimir Varbanov 
7902c2dc2fdSStanimir Varbanov static const struct id_mapping vp8_profiles[] = {
7912c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 },
7922c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 },
7932c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 },
7942c2dc2fdSStanimir Varbanov 	{ HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 },
7952c2dc2fdSStanimir Varbanov };
7962c2dc2fdSStanimir Varbanov 
7972c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_profiles[] = {
7982c2dc2fdSStanimir Varbanov 	{ HFI_VP9_PROFILE_P0, V4L2_MPEG_VIDEO_VP9_PROFILE_0 },
7992c2dc2fdSStanimir Varbanov 	{ HFI_VP9_PROFILE_P2_10B, V4L2_MPEG_VIDEO_VP9_PROFILE_2 },
8002c2dc2fdSStanimir Varbanov };
8012c2dc2fdSStanimir Varbanov 
8022c2dc2fdSStanimir Varbanov static const struct id_mapping vp9_levels[] = {
8032c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_1, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 },
8042c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_11, V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 },
8052c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_2, V4L2_MPEG_VIDEO_VP9_LEVEL_2_0},
8062c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_21, V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 },
8072c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_3, V4L2_MPEG_VIDEO_VP9_LEVEL_3_0},
8082c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_31, V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 },
8092c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_4, V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 },
8102c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_41, V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 },
8112c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_5, V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 },
8122c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_51, V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 },
8132c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_6, V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 },
8142c2dc2fdSStanimir Varbanov 	{ HFI_VP9_LEVEL_61, V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 },
8152c2dc2fdSStanimir Varbanov };
8162c2dc2fdSStanimir Varbanov 
8172c2dc2fdSStanimir Varbanov static u32 find_v4l2_id(u32 hfi_id, const struct id_mapping *array, unsigned int array_sz)
8182c2dc2fdSStanimir Varbanov {
8192c2dc2fdSStanimir Varbanov 	unsigned int i;
8202c2dc2fdSStanimir Varbanov 
8212c2dc2fdSStanimir Varbanov 	if (!array || !array_sz)
8222c2dc2fdSStanimir Varbanov 		return 0;
8232c2dc2fdSStanimir Varbanov 
8242c2dc2fdSStanimir Varbanov 	for (i = 0; i < array_sz; i++)
8252c2dc2fdSStanimir Varbanov 		if (hfi_id == array[i].hfi_id)
8262c2dc2fdSStanimir Varbanov 			return array[i].v4l2_id;
8272c2dc2fdSStanimir Varbanov 
8282c2dc2fdSStanimir Varbanov 	return 0;
8292c2dc2fdSStanimir Varbanov }
8302c2dc2fdSStanimir Varbanov 
8312c2dc2fdSStanimir Varbanov static u32 find_hfi_id(u32 v4l2_id, const struct id_mapping *array, unsigned int array_sz)
8322c2dc2fdSStanimir Varbanov {
8332c2dc2fdSStanimir Varbanov 	unsigned int i;
8342c2dc2fdSStanimir Varbanov 
8352c2dc2fdSStanimir Varbanov 	if (!array || !array_sz)
8362c2dc2fdSStanimir Varbanov 		return 0;
8372c2dc2fdSStanimir Varbanov 
8382c2dc2fdSStanimir Varbanov 	for (i = 0; i < array_sz; i++)
8392c2dc2fdSStanimir Varbanov 		if (v4l2_id == array[i].v4l2_id)
8402c2dc2fdSStanimir Varbanov 			return array[i].hfi_id;
8412c2dc2fdSStanimir Varbanov 
8422c2dc2fdSStanimir Varbanov 	return 0;
8432c2dc2fdSStanimir Varbanov }
8442c2dc2fdSStanimir Varbanov 
8452c2dc2fdSStanimir Varbanov static void
8462c2dc2fdSStanimir Varbanov v4l2_id_profile_level(u32 hfi_codec, struct hfi_profile_level *pl, u32 *profile, u32 *level)
8472c2dc2fdSStanimir Varbanov {
8482c2dc2fdSStanimir Varbanov 	u32 hfi_pf = pl->profile;
8492c2dc2fdSStanimir Varbanov 	u32 hfi_lvl = pl->level;
8502c2dc2fdSStanimir Varbanov 
8512c2dc2fdSStanimir Varbanov 	switch (hfi_codec) {
8522c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_H264:
8532c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
8542c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, h264_levels, ARRAY_SIZE(h264_levels));
8552c2dc2fdSStanimir Varbanov 		break;
8562c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG2:
8572c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
8582c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
8592c2dc2fdSStanimir Varbanov 		break;
8602c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG4:
8612c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
8622c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
8632c2dc2fdSStanimir Varbanov 		break;
8642c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP8:
8652c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
8662c2dc2fdSStanimir Varbanov 		*level = 0;
8672c2dc2fdSStanimir Varbanov 		break;
8682c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP9:
8692c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
8702c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
8712c2dc2fdSStanimir Varbanov 		break;
8722c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_HEVC:
8732c2dc2fdSStanimir Varbanov 		*profile = find_v4l2_id(hfi_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
8742c2dc2fdSStanimir Varbanov 		*level = find_v4l2_id(hfi_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
8752c2dc2fdSStanimir Varbanov 		break;
8762c2dc2fdSStanimir Varbanov 	default:
8772c2dc2fdSStanimir Varbanov 		break;
8782c2dc2fdSStanimir Varbanov 	}
8792c2dc2fdSStanimir Varbanov }
8802c2dc2fdSStanimir Varbanov 
8812c2dc2fdSStanimir Varbanov static void
8822c2dc2fdSStanimir Varbanov hfi_id_profile_level(u32 hfi_codec, u32 v4l2_pf, u32 v4l2_lvl, struct hfi_profile_level *pl)
8832c2dc2fdSStanimir Varbanov {
8842c2dc2fdSStanimir Varbanov 	switch (hfi_codec) {
8852c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_H264:
8862c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
8872c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, h264_levels, ARRAY_SIZE(h264_levels));
8882c2dc2fdSStanimir Varbanov 		break;
8892c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG2:
8902c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
8912c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
8922c2dc2fdSStanimir Varbanov 		break;
8932c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_MPEG4:
8942c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
8952c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
8962c2dc2fdSStanimir Varbanov 		break;
8972c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP8:
8982c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
8992c2dc2fdSStanimir Varbanov 		pl->level = 0;
9002c2dc2fdSStanimir Varbanov 		break;
9012c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_VP9:
9022c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
9032c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
9042c2dc2fdSStanimir Varbanov 		break;
9052c2dc2fdSStanimir Varbanov 	case HFI_VIDEO_CODEC_HEVC:
9062c2dc2fdSStanimir Varbanov 		pl->profile = find_hfi_id(v4l2_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
9072c2dc2fdSStanimir Varbanov 		pl->level = find_hfi_id(v4l2_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
9082c2dc2fdSStanimir Varbanov 		break;
9092c2dc2fdSStanimir Varbanov 	default:
9102c2dc2fdSStanimir Varbanov 		break;
9112c2dc2fdSStanimir Varbanov 	}
9122c2dc2fdSStanimir Varbanov }
9132c2dc2fdSStanimir Varbanov 
9142c2dc2fdSStanimir Varbanov int venus_helper_get_profile_level(struct venus_inst *inst, u32 *profile, u32 *level)
9152c2dc2fdSStanimir Varbanov {
9162c2dc2fdSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
9172c2dc2fdSStanimir Varbanov 	union hfi_get_property hprop;
9182c2dc2fdSStanimir Varbanov 	int ret;
9192c2dc2fdSStanimir Varbanov 
9202c2dc2fdSStanimir Varbanov 	ret = hfi_session_get_property(inst, ptype, &hprop);
9212c2dc2fdSStanimir Varbanov 	if (ret)
9222c2dc2fdSStanimir Varbanov 		return ret;
9232c2dc2fdSStanimir Varbanov 
9242c2dc2fdSStanimir Varbanov 	v4l2_id_profile_level(inst->hfi_codec, &hprop.profile_level, profile, level);
9252c2dc2fdSStanimir Varbanov 
9262c2dc2fdSStanimir Varbanov 	return 0;
9272c2dc2fdSStanimir Varbanov }
9282c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_profile_level);
9292c2dc2fdSStanimir Varbanov 
9302c2dc2fdSStanimir Varbanov int venus_helper_set_profile_level(struct venus_inst *inst, u32 profile, u32 level)
9312c2dc2fdSStanimir Varbanov {
9322c2dc2fdSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
9332c2dc2fdSStanimir Varbanov 	struct hfi_profile_level pl;
9342c2dc2fdSStanimir Varbanov 
9352c2dc2fdSStanimir Varbanov 	hfi_id_profile_level(inst->hfi_codec, profile, level, &pl);
9362c2dc2fdSStanimir Varbanov 
9372c2dc2fdSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &pl);
9382c2dc2fdSStanimir Varbanov }
9392c2dc2fdSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_profile_level);
9402c2dc2fdSStanimir Varbanov 
941e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12(u32 width, u32 height)
942e1cb72deSStanimir Varbanov {
943e1cb72deSStanimir Varbanov 	u32 y_stride, uv_stride, y_plane;
944e1cb72deSStanimir Varbanov 	u32 y_sclines, uv_sclines, uv_plane;
945e1cb72deSStanimir Varbanov 	u32 size;
946e1cb72deSStanimir Varbanov 
947e1cb72deSStanimir Varbanov 	y_stride = ALIGN(width, 128);
948e1cb72deSStanimir Varbanov 	uv_stride = ALIGN(width, 128);
949e1cb72deSStanimir Varbanov 	y_sclines = ALIGN(height, 32);
950e1cb72deSStanimir Varbanov 	uv_sclines = ALIGN(((height + 1) >> 1), 16);
951e1cb72deSStanimir Varbanov 
952e1cb72deSStanimir Varbanov 	y_plane = y_stride * y_sclines;
953e1cb72deSStanimir Varbanov 	uv_plane = uv_stride * uv_sclines + SZ_4K;
954e1cb72deSStanimir Varbanov 	size = y_plane + uv_plane + SZ_8K;
955e1cb72deSStanimir Varbanov 
956e1cb72deSStanimir Varbanov 	return ALIGN(size, SZ_4K);
957e1cb72deSStanimir Varbanov }
958e1cb72deSStanimir Varbanov 
959e1cb72deSStanimir Varbanov static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height)
960e1cb72deSStanimir Varbanov {
961e1cb72deSStanimir Varbanov 	u32 y_meta_stride, y_meta_plane;
962e1cb72deSStanimir Varbanov 	u32 y_stride, y_plane;
963e1cb72deSStanimir Varbanov 	u32 uv_meta_stride, uv_meta_plane;
964e1cb72deSStanimir Varbanov 	u32 uv_stride, uv_plane;
965e1cb72deSStanimir Varbanov 	u32 extradata = SZ_16K;
966e1cb72deSStanimir Varbanov 
967e1cb72deSStanimir Varbanov 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
968e1cb72deSStanimir Varbanov 	y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16);
969e1cb72deSStanimir Varbanov 	y_meta_plane = ALIGN(y_meta_plane, SZ_4K);
970e1cb72deSStanimir Varbanov 
971e1cb72deSStanimir Varbanov 	y_stride = ALIGN(width, 128);
972e1cb72deSStanimir Varbanov 	y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K);
973e1cb72deSStanimir Varbanov 
974e1cb72deSStanimir Varbanov 	uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64);
975e1cb72deSStanimir Varbanov 	uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16);
976e1cb72deSStanimir Varbanov 	uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K);
977e1cb72deSStanimir Varbanov 
978e1cb72deSStanimir Varbanov 	uv_stride = ALIGN(width, 128);
979e1cb72deSStanimir Varbanov 	uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K);
980e1cb72deSStanimir Varbanov 
981e1cb72deSStanimir Varbanov 	return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
982e1cb72deSStanimir Varbanov 		     max(extradata, y_stride * 48), SZ_4K);
983e1cb72deSStanimir Varbanov }
984e1cb72deSStanimir Varbanov 
985ab1eda44SAniket Masule static u32 get_framesize_raw_p010(u32 width, u32 height)
986ab1eda44SAniket Masule {
987ab1eda44SAniket Masule 	u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines;
988ab1eda44SAniket Masule 
989ab1eda44SAniket Masule 	y_stride = ALIGN(width * 2, 256);
990ab1eda44SAniket Masule 	uv_stride = ALIGN(width * 2, 256);
991ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 32);
992ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
993ab1eda44SAniket Masule 	y_plane = y_stride * y_sclines;
994ab1eda44SAniket Masule 	uv_plane = uv_stride * uv_sclines;
995ab1eda44SAniket Masule 
996ab1eda44SAniket Masule 	return ALIGN((y_plane + uv_plane), SZ_4K);
997ab1eda44SAniket Masule }
998ab1eda44SAniket Masule 
999ab1eda44SAniket Masule static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height)
1000ab1eda44SAniket Masule {
1001ab1eda44SAniket Masule 	u32 y_stride, uv_stride, y_sclines, uv_sclines;
1002ab1eda44SAniket Masule 	u32 y_ubwc_plane, uv_ubwc_plane;
1003ab1eda44SAniket Masule 	u32 y_meta_stride, y_meta_scanlines;
1004ab1eda44SAniket Masule 	u32 uv_meta_stride, uv_meta_scanlines;
1005ab1eda44SAniket Masule 	u32 y_meta_plane, uv_meta_plane;
1006ab1eda44SAniket Masule 	u32 size;
1007ab1eda44SAniket Masule 
1008ab1eda44SAniket Masule 	y_stride = ALIGN(width * 2, 256);
1009ab1eda44SAniket Masule 	uv_stride = ALIGN(width * 2, 256);
1010ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 16);
1011ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
1012ab1eda44SAniket Masule 
1013ab1eda44SAniket Masule 	y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
1014ab1eda44SAniket Masule 	uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
1015ab1eda44SAniket Masule 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
1016ab1eda44SAniket Masule 	y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
1017ab1eda44SAniket Masule 	y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
1018ab1eda44SAniket Masule 	uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
1019ab1eda44SAniket Masule 	uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
1020ab1eda44SAniket Masule 	uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
1021ab1eda44SAniket Masule 
1022ab1eda44SAniket Masule 	size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
1023ab1eda44SAniket Masule 
1024ab1eda44SAniket Masule 	return ALIGN(size, SZ_4K);
1025ab1eda44SAniket Masule }
1026ab1eda44SAniket Masule 
1027ab1eda44SAniket Masule static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height)
1028ab1eda44SAniket Masule {
1029ab1eda44SAniket Masule 	u32 y_stride, uv_stride, y_sclines, uv_sclines;
1030ab1eda44SAniket Masule 	u32 y_ubwc_plane, uv_ubwc_plane;
1031ab1eda44SAniket Masule 	u32 y_meta_stride, y_meta_scanlines;
1032ab1eda44SAniket Masule 	u32 uv_meta_stride, uv_meta_scanlines;
1033ab1eda44SAniket Masule 	u32 y_meta_plane, uv_meta_plane;
1034ab1eda44SAniket Masule 	u32 extradata = SZ_16K;
1035ab1eda44SAniket Masule 	u32 size;
1036ab1eda44SAniket Masule 
1037ab1eda44SAniket Masule 	y_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
1038ab1eda44SAniket Masule 	uv_stride = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
1039ab1eda44SAniket Masule 	y_sclines = ALIGN(height, 16);
1040ab1eda44SAniket Masule 	uv_sclines = ALIGN((height + 1) >> 1, 16);
1041ab1eda44SAniket Masule 
1042ab1eda44SAniket Masule 	y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
1043ab1eda44SAniket Masule 	uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
1044ab1eda44SAniket Masule 	y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64);
1045ab1eda44SAniket Masule 	y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
1046ab1eda44SAniket Masule 	y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
1047ab1eda44SAniket Masule 	uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
1048ab1eda44SAniket Masule 	uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
1049ab1eda44SAniket Masule 	uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
1050ab1eda44SAniket Masule 
1051ab1eda44SAniket Masule 	size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
1052ab1eda44SAniket Masule 	size += max(extradata + SZ_8K, y_stride * 48);
1053ab1eda44SAniket Masule 
1054ab1eda44SAniket Masule 	return ALIGN(size, SZ_4K);
1055ab1eda44SAniket Masule }
1056ab1eda44SAniket Masule 
1057e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
1058e1cb72deSStanimir Varbanov {
1059e1cb72deSStanimir Varbanov 	switch (hfi_fmt) {
1060e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV12:
1061e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV21:
1062e1cb72deSStanimir Varbanov 		return get_framesize_raw_nv12(width, height);
1063e1cb72deSStanimir Varbanov 	case HFI_COLOR_FORMAT_NV12_UBWC:
1064e1cb72deSStanimir Varbanov 		return get_framesize_raw_nv12_ubwc(width, height);
1065ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_P010:
1066ab1eda44SAniket Masule 		return get_framesize_raw_p010(width, height);
1067ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_P010_UBWC:
1068ab1eda44SAniket Masule 		return get_framesize_raw_p010_ubwc(width, height);
1069ab1eda44SAniket Masule 	case HFI_COLOR_FORMAT_YUV420_TP10_UBWC:
1070ab1eda44SAniket Masule 		return get_framesize_raw_yuv420_tp10_ubwc(width, height);
1071e1cb72deSStanimir Varbanov 	default:
1072e1cb72deSStanimir Varbanov 		return 0;
1073e1cb72deSStanimir Varbanov 	}
1074e1cb72deSStanimir Varbanov }
1075e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw);
1076e1cb72deSStanimir Varbanov 
1077e1cb72deSStanimir Varbanov u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height)
1078e1cb72deSStanimir Varbanov {
1079e1cb72deSStanimir Varbanov 	u32 hfi_fmt, sz;
1080e1cb72deSStanimir Varbanov 	bool compressed;
1081e1cb72deSStanimir Varbanov 
1082e1cb72deSStanimir Varbanov 	switch (v4l2_fmt) {
1083e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG:
1084e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264:
1085e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264_NO_SC:
1086e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H264_MVC:
1087e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_H263:
1088e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG1:
1089e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG2:
1090e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_MPEG4:
1091e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_XVID:
1092e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_G:
1093e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VC1_ANNEX_L:
1094e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VP8:
1095e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_VP9:
1096e1cb72deSStanimir Varbanov 	case V4L2_PIX_FMT_HEVC:
1097e1cb72deSStanimir Varbanov 		compressed = true;
1098e1cb72deSStanimir Varbanov 		break;
1099e1cb72deSStanimir Varbanov 	default:
1100e1cb72deSStanimir Varbanov 		compressed = false;
1101e1cb72deSStanimir Varbanov 		break;
1102e1cb72deSStanimir Varbanov 	}
1103e1cb72deSStanimir Varbanov 
1104e1cb72deSStanimir Varbanov 	if (compressed) {
1105e1cb72deSStanimir Varbanov 		sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
1106ddd1fc49SStanimir Varbanov 		if (width < 1280 || height < 720)
1107ddd1fc49SStanimir Varbanov 			sz *= 8;
1108e1cb72deSStanimir Varbanov 		return ALIGN(sz, SZ_4K);
1109e1cb72deSStanimir Varbanov 	}
1110e1cb72deSStanimir Varbanov 
1111e1cb72deSStanimir Varbanov 	hfi_fmt = to_hfi_raw_fmt(v4l2_fmt);
1112e1cb72deSStanimir Varbanov 	if (!hfi_fmt)
1113e1cb72deSStanimir Varbanov 		return 0;
1114e1cb72deSStanimir Varbanov 
1115e1cb72deSStanimir Varbanov 	return venus_helper_get_framesz_raw(hfi_fmt, width, height);
1116e1cb72deSStanimir Varbanov }
1117e1cb72deSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_framesz);
1118e1cb72deSStanimir Varbanov 
1119af2c3834SStanimir Varbanov int venus_helper_set_input_resolution(struct venus_inst *inst,
1120af2c3834SStanimir Varbanov 				      unsigned int width, unsigned int height)
1121af2c3834SStanimir Varbanov {
1122af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
1123af2c3834SStanimir Varbanov 	struct hfi_framesize fs;
1124af2c3834SStanimir Varbanov 
1125af2c3834SStanimir Varbanov 	fs.buffer_type = HFI_BUFFER_INPUT;
1126af2c3834SStanimir Varbanov 	fs.width = width;
1127af2c3834SStanimir Varbanov 	fs.height = height;
1128af2c3834SStanimir Varbanov 
1129af2c3834SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fs);
1130af2c3834SStanimir Varbanov }
1131af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution);
1132af2c3834SStanimir Varbanov 
1133af2c3834SStanimir Varbanov int venus_helper_set_output_resolution(struct venus_inst *inst,
1134404054e1SStanimir Varbanov 				       unsigned int width, unsigned int height,
1135404054e1SStanimir Varbanov 				       u32 buftype)
1136af2c3834SStanimir Varbanov {
1137af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
1138af2c3834SStanimir Varbanov 	struct hfi_framesize fs;
1139af2c3834SStanimir Varbanov 
1140404054e1SStanimir Varbanov 	fs.buffer_type = buftype;
1141af2c3834SStanimir Varbanov 	fs.width = width;
1142af2c3834SStanimir Varbanov 	fs.height = height;
1143af2c3834SStanimir Varbanov 
1144af2c3834SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fs);
1145af2c3834SStanimir Varbanov }
1146af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution);
1147af2c3834SStanimir Varbanov 
11481ad17595SDikshita Agarwal static u32 venus_helper_get_work_mode(struct venus_inst *inst)
11491ad17595SDikshita Agarwal {
11501ad17595SDikshita Agarwal 	u32 mode;
11511ad17595SDikshita Agarwal 	u32 num_mbs;
11521ad17595SDikshita Agarwal 
11531ad17595SDikshita Agarwal 	mode = VIDC_WORK_MODE_2;
11541ad17595SDikshita Agarwal 	if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
11551ad17595SDikshita Agarwal 		num_mbs = (ALIGN(inst->height, 16) * ALIGN(inst->width, 16)) / 256;
11561ad17595SDikshita Agarwal 		if (inst->hfi_codec == HFI_VIDEO_CODEC_MPEG2 ||
11571ad17595SDikshita Agarwal 		    inst->pic_struct != HFI_INTERLACE_FRAME_PROGRESSIVE ||
11581ad17595SDikshita Agarwal 		    num_mbs <= NUM_MBS_720P)
11591ad17595SDikshita Agarwal 			mode = VIDC_WORK_MODE_1;
11601ad17595SDikshita Agarwal 	} else {
11611ad17595SDikshita Agarwal 		num_mbs = (ALIGN(inst->out_height, 16) * ALIGN(inst->out_width, 16)) / 256;
11621ad17595SDikshita Agarwal 		if (inst->hfi_codec == HFI_VIDEO_CODEC_VP8 &&
11631ad17595SDikshita Agarwal 		    num_mbs <= NUM_MBS_4K)
11641ad17595SDikshita Agarwal 			mode = VIDC_WORK_MODE_1;
11651ad17595SDikshita Agarwal 	}
11661ad17595SDikshita Agarwal 
11671ad17595SDikshita Agarwal 	return mode;
11681ad17595SDikshita Agarwal }
11691ad17595SDikshita Agarwal 
11701ad17595SDikshita Agarwal int venus_helper_set_work_mode(struct venus_inst *inst)
117101165b84SStanimir Varbanov {
117201165b84SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE;
117301165b84SStanimir Varbanov 	struct hfi_video_work_mode wm;
11741ad17595SDikshita Agarwal 	u32 mode;
117501165b84SStanimir Varbanov 
11767ed9e0b3SBryan O'Donoghue 	if (!IS_V4(inst->core) && !IS_V6(inst->core))
117701165b84SStanimir Varbanov 		return 0;
117801165b84SStanimir Varbanov 
11791ad17595SDikshita Agarwal 	mode = venus_helper_get_work_mode(inst);
118001165b84SStanimir Varbanov 	wm.video_work_mode = mode;
118101165b84SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &wm);
118201165b84SStanimir Varbanov }
118301165b84SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
118401165b84SStanimir Varbanov 
1185bc28936bSDikshita Agarwal int venus_helper_set_format_constraints(struct venus_inst *inst)
1186bc28936bSDikshita Agarwal {
1187bc28936bSDikshita Agarwal 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
1188bc28936bSDikshita Agarwal 	struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
1189bc28936bSDikshita Agarwal 
1190bc28936bSDikshita Agarwal 	if (!IS_V6(inst->core))
1191bc28936bSDikshita Agarwal 		return 0;
1192bc28936bSDikshita Agarwal 
11931ac61fafSMansur Alisha Shaik 	if (inst->opb_fmt == HFI_COLOR_FORMAT_NV12_UBWC)
11941ac61fafSMansur Alisha Shaik 		return 0;
11951ac61fafSMansur Alisha Shaik 
1196bc28936bSDikshita Agarwal 	pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
1197bc28936bSDikshita Agarwal 	pconstraint.num_planes = 2;
1198bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].stride_multiples = 128;
1199bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].max_stride = 8192;
1200bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32;
1201bc28936bSDikshita Agarwal 	pconstraint.plane_format[0].buffer_alignment = 256;
1202bc28936bSDikshita Agarwal 
1203bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].stride_multiples = 128;
1204bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].max_stride = 8192;
1205bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16;
1206bc28936bSDikshita Agarwal 	pconstraint.plane_format[1].buffer_alignment = 256;
1207bc28936bSDikshita Agarwal 
1208bc28936bSDikshita Agarwal 	return hfi_session_set_property(inst, ptype, &pconstraint);
1209bc28936bSDikshita Agarwal }
1210bc28936bSDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_format_constraints);
1211bc28936bSDikshita Agarwal 
1212af2c3834SStanimir Varbanov int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
12131eb04b2eSStanimir Varbanov 			      unsigned int output_bufs,
12141eb04b2eSStanimir Varbanov 			      unsigned int output2_bufs)
1215af2c3834SStanimir Varbanov {
1216af2c3834SStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
1217af2c3834SStanimir Varbanov 	struct hfi_buffer_count_actual buf_count;
1218af2c3834SStanimir Varbanov 	int ret;
1219af2c3834SStanimir Varbanov 
1220af2c3834SStanimir Varbanov 	buf_count.type = HFI_BUFFER_INPUT;
1221af2c3834SStanimir Varbanov 	buf_count.count_actual = input_bufs;
1222af2c3834SStanimir Varbanov 
1223af2c3834SStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &buf_count);
1224af2c3834SStanimir Varbanov 	if (ret)
1225af2c3834SStanimir Varbanov 		return ret;
1226af2c3834SStanimir Varbanov 
1227af2c3834SStanimir Varbanov 	buf_count.type = HFI_BUFFER_OUTPUT;
1228af2c3834SStanimir Varbanov 	buf_count.count_actual = output_bufs;
1229af2c3834SStanimir Varbanov 
12301eb04b2eSStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &buf_count);
12311eb04b2eSStanimir Varbanov 	if (ret)
12321eb04b2eSStanimir Varbanov 		return ret;
12331eb04b2eSStanimir Varbanov 
12341eb04b2eSStanimir Varbanov 	if (output2_bufs) {
12351eb04b2eSStanimir Varbanov 		buf_count.type = HFI_BUFFER_OUTPUT2;
12361eb04b2eSStanimir Varbanov 		buf_count.count_actual = output2_bufs;
12371eb04b2eSStanimir Varbanov 
12381eb04b2eSStanimir Varbanov 		ret = hfi_session_set_property(inst, ptype, &buf_count);
12391eb04b2eSStanimir Varbanov 	}
12401eb04b2eSStanimir Varbanov 
12411eb04b2eSStanimir Varbanov 	return ret;
1242af2c3834SStanimir Varbanov }
1243af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
1244af2c3834SStanimir Varbanov 
1245ab97a3fbSStanimir Varbanov int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
1246ab97a3fbSStanimir Varbanov 				u32 buftype)
1247ab97a3fbSStanimir Varbanov {
1248ab97a3fbSStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
1249ab97a3fbSStanimir Varbanov 	struct hfi_uncompressed_format_select fmt;
1250ab97a3fbSStanimir Varbanov 
1251ab97a3fbSStanimir Varbanov 	fmt.buffer_type = buftype;
1252ab97a3fbSStanimir Varbanov 	fmt.format = hfi_format;
1253ab97a3fbSStanimir Varbanov 
1254ab97a3fbSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &fmt);
1255ab97a3fbSStanimir Varbanov }
1256ab97a3fbSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_raw_format);
1257ab97a3fbSStanimir Varbanov 
1258af2c3834SStanimir Varbanov int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
1259af2c3834SStanimir Varbanov {
1260ab97a3fbSStanimir Varbanov 	u32 hfi_format, buftype;
1261af2c3834SStanimir Varbanov 
1262af2c3834SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC)
1263ab97a3fbSStanimir Varbanov 		buftype = HFI_BUFFER_OUTPUT;
1264af2c3834SStanimir Varbanov 	else if (inst->session_type == VIDC_SESSION_TYPE_ENC)
1265ab97a3fbSStanimir Varbanov 		buftype = HFI_BUFFER_INPUT;
1266af2c3834SStanimir Varbanov 	else
1267af2c3834SStanimir Varbanov 		return -EINVAL;
1268af2c3834SStanimir Varbanov 
1269ab97a3fbSStanimir Varbanov 	hfi_format = to_hfi_raw_fmt(pixfmt);
1270ab97a3fbSStanimir Varbanov 	if (!hfi_format)
1271af2c3834SStanimir Varbanov 		return -EINVAL;
1272af2c3834SStanimir Varbanov 
1273ab97a3fbSStanimir Varbanov 	return venus_helper_set_raw_format(inst, hfi_format, buftype);
1274af2c3834SStanimir Varbanov }
1275af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
1276af2c3834SStanimir Varbanov 
1277f012b23dSStanimir Varbanov int venus_helper_set_multistream(struct venus_inst *inst, bool out_en,
1278f012b23dSStanimir Varbanov 				 bool out2_en)
1279f012b23dSStanimir Varbanov {
1280f012b23dSStanimir Varbanov 	struct hfi_multi_stream multi = {0};
1281f012b23dSStanimir Varbanov 	u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
1282f012b23dSStanimir Varbanov 	int ret;
1283f012b23dSStanimir Varbanov 
1284f012b23dSStanimir Varbanov 	multi.buffer_type = HFI_BUFFER_OUTPUT;
1285f012b23dSStanimir Varbanov 	multi.enable = out_en;
1286f012b23dSStanimir Varbanov 
1287f012b23dSStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &multi);
1288f012b23dSStanimir Varbanov 	if (ret)
1289f012b23dSStanimir Varbanov 		return ret;
1290f012b23dSStanimir Varbanov 
1291f012b23dSStanimir Varbanov 	multi.buffer_type = HFI_BUFFER_OUTPUT2;
1292f012b23dSStanimir Varbanov 	multi.enable = out2_en;
1293f012b23dSStanimir Varbanov 
1294f012b23dSStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &multi);
1295f012b23dSStanimir Varbanov }
1296f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_multistream);
1297f012b23dSStanimir Varbanov 
12982b0a8517SStanimir Varbanov int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
12992b0a8517SStanimir Varbanov {
13002b0a8517SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
13012b0a8517SStanimir Varbanov 	struct hfi_buffer_alloc_mode mode;
13022b0a8517SStanimir Varbanov 	int ret;
13032b0a8517SStanimir Varbanov 
13042b0a8517SStanimir Varbanov 	if (!is_dynamic_bufmode(inst))
13052b0a8517SStanimir Varbanov 		return 0;
13062b0a8517SStanimir Varbanov 
13072b0a8517SStanimir Varbanov 	mode.type = HFI_BUFFER_OUTPUT;
13082b0a8517SStanimir Varbanov 	mode.mode = HFI_BUFFER_MODE_DYNAMIC;
13092b0a8517SStanimir Varbanov 
13102b0a8517SStanimir Varbanov 	ret = hfi_session_set_property(inst, ptype, &mode);
13112b0a8517SStanimir Varbanov 	if (ret)
13122b0a8517SStanimir Varbanov 		return ret;
13132b0a8517SStanimir Varbanov 
13142b0a8517SStanimir Varbanov 	mode.type = HFI_BUFFER_OUTPUT2;
13152b0a8517SStanimir Varbanov 
13162b0a8517SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &mode);
13172b0a8517SStanimir Varbanov }
13182b0a8517SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
13192b0a8517SStanimir Varbanov 
1320d4a5b0a6SStanimir Varbanov int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype)
1321d4a5b0a6SStanimir Varbanov {
1322d4a5b0a6SStanimir Varbanov 	const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
1323d4a5b0a6SStanimir Varbanov 	struct hfi_buffer_size_actual bufsz;
1324d4a5b0a6SStanimir Varbanov 
1325d4a5b0a6SStanimir Varbanov 	bufsz.type = buftype;
1326d4a5b0a6SStanimir Varbanov 	bufsz.size = bufsize;
1327d4a5b0a6SStanimir Varbanov 
1328d4a5b0a6SStanimir Varbanov 	return hfi_session_set_property(inst, ptype, &bufsz);
1329d4a5b0a6SStanimir Varbanov }
1330d4a5b0a6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
1331d4a5b0a6SStanimir Varbanov 
1332130c0117SStanimir Varbanov unsigned int venus_helper_get_opb_size(struct venus_inst *inst)
1333130c0117SStanimir Varbanov {
1334130c0117SStanimir Varbanov 	/* the encoder has only one output */
1335130c0117SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_ENC)
1336130c0117SStanimir Varbanov 		return inst->output_buf_size;
1337130c0117SStanimir Varbanov 
1338130c0117SStanimir Varbanov 	if (inst->opb_buftype == HFI_BUFFER_OUTPUT)
1339130c0117SStanimir Varbanov 		return inst->output_buf_size;
1340130c0117SStanimir Varbanov 	else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2)
1341130c0117SStanimir Varbanov 		return inst->output2_buf_size;
1342130c0117SStanimir Varbanov 
1343130c0117SStanimir Varbanov 	return 0;
1344130c0117SStanimir Varbanov }
1345130c0117SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_opb_size);
1346130c0117SStanimir Varbanov 
1347af2c3834SStanimir Varbanov static void delayed_process_buf_func(struct work_struct *work)
1348af2c3834SStanimir Varbanov {
1349af2c3834SStanimir Varbanov 	struct venus_buffer *buf, *n;
1350af2c3834SStanimir Varbanov 	struct venus_inst *inst;
1351af2c3834SStanimir Varbanov 	int ret;
1352af2c3834SStanimir Varbanov 
1353af2c3834SStanimir Varbanov 	inst = container_of(work, struct venus_inst, delayed_process_work);
1354af2c3834SStanimir Varbanov 
1355af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1356af2c3834SStanimir Varbanov 
1357af2c3834SStanimir Varbanov 	if (!(inst->streamon_out & inst->streamon_cap))
1358af2c3834SStanimir Varbanov 		goto unlock;
1359af2c3834SStanimir Varbanov 
1360af2c3834SStanimir Varbanov 	list_for_each_entry_safe(buf, n, &inst->delayed_process, ref_list) {
1361af2c3834SStanimir Varbanov 		if (buf->flags & HFI_BUFFERFLAG_READONLY)
1362af2c3834SStanimir Varbanov 			continue;
1363af2c3834SStanimir Varbanov 
1364af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1365af2c3834SStanimir Varbanov 		if (ret)
1366af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1367af2c3834SStanimir Varbanov 
1368af2c3834SStanimir Varbanov 		list_del_init(&buf->ref_list);
1369af2c3834SStanimir Varbanov 	}
1370af2c3834SStanimir Varbanov unlock:
1371af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1372af2c3834SStanimir Varbanov }
1373af2c3834SStanimir Varbanov 
1374af2c3834SStanimir Varbanov void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx)
1375af2c3834SStanimir Varbanov {
1376af2c3834SStanimir Varbanov 	struct venus_buffer *buf;
1377af2c3834SStanimir Varbanov 
1378af2c3834SStanimir Varbanov 	list_for_each_entry(buf, &inst->registeredbufs, reg_list) {
1379af2c3834SStanimir Varbanov 		if (buf->vb.vb2_buf.index == idx) {
1380af2c3834SStanimir Varbanov 			buf->flags &= ~HFI_BUFFERFLAG_READONLY;
1381af2c3834SStanimir Varbanov 			schedule_work(&inst->delayed_process_work);
1382af2c3834SStanimir Varbanov 			break;
1383af2c3834SStanimir Varbanov 		}
1384af2c3834SStanimir Varbanov 	}
1385af2c3834SStanimir Varbanov }
1386af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_release_buf_ref);
1387af2c3834SStanimir Varbanov 
1388af2c3834SStanimir Varbanov void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf)
1389af2c3834SStanimir Varbanov {
1390af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1391af2c3834SStanimir Varbanov 
1392af2c3834SStanimir Varbanov 	buf->flags |= HFI_BUFFERFLAG_READONLY;
1393af2c3834SStanimir Varbanov }
1394af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_acquire_buf_ref);
1395af2c3834SStanimir Varbanov 
1396af2c3834SStanimir Varbanov static int is_buf_refed(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
1397af2c3834SStanimir Varbanov {
1398af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1399af2c3834SStanimir Varbanov 
1400af2c3834SStanimir Varbanov 	if (buf->flags & HFI_BUFFERFLAG_READONLY) {
1401af2c3834SStanimir Varbanov 		list_add_tail(&buf->ref_list, &inst->delayed_process);
1402af2c3834SStanimir Varbanov 		schedule_work(&inst->delayed_process_work);
1403af2c3834SStanimir Varbanov 		return 1;
1404af2c3834SStanimir Varbanov 	}
1405af2c3834SStanimir Varbanov 
1406af2c3834SStanimir Varbanov 	return 0;
1407af2c3834SStanimir Varbanov }
1408af2c3834SStanimir Varbanov 
1409af2c3834SStanimir Varbanov struct vb2_v4l2_buffer *
1410af2c3834SStanimir Varbanov venus_helper_find_buf(struct venus_inst *inst, unsigned int type, u32 idx)
1411af2c3834SStanimir Varbanov {
1412af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1413af2c3834SStanimir Varbanov 
1414af2c3834SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1415af2c3834SStanimir Varbanov 		return v4l2_m2m_src_buf_remove_by_idx(m2m_ctx, idx);
1416af2c3834SStanimir Varbanov 	else
1417af2c3834SStanimir Varbanov 		return v4l2_m2m_dst_buf_remove_by_idx(m2m_ctx, idx);
1418af2c3834SStanimir Varbanov }
1419af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_find_buf);
1420af2c3834SStanimir Varbanov 
142140d87aafSMansur Alisha Shaik void venus_helper_change_dpb_owner(struct venus_inst *inst,
142240d87aafSMansur Alisha Shaik 				   struct vb2_v4l2_buffer *vbuf, unsigned int type,
142340d87aafSMansur Alisha Shaik 				   unsigned int buf_type, u32 tag)
142440d87aafSMansur Alisha Shaik {
142540d87aafSMansur Alisha Shaik 	struct intbuf *dpb_buf;
142640d87aafSMansur Alisha Shaik 
142740d87aafSMansur Alisha Shaik 	if (!V4L2_TYPE_IS_CAPTURE(type) ||
142840d87aafSMansur Alisha Shaik 	    buf_type != inst->dpb_buftype)
142940d87aafSMansur Alisha Shaik 		return;
143040d87aafSMansur Alisha Shaik 
143140d87aafSMansur Alisha Shaik 	list_for_each_entry(dpb_buf, &inst->dpbbufs, list)
143240d87aafSMansur Alisha Shaik 		if (dpb_buf->dpb_out_tag == tag) {
143340d87aafSMansur Alisha Shaik 			dpb_buf->owned_by = DRIVER;
143440d87aafSMansur Alisha Shaik 			break;
143540d87aafSMansur Alisha Shaik 		}
143640d87aafSMansur Alisha Shaik }
143740d87aafSMansur Alisha Shaik EXPORT_SYMBOL_GPL(venus_helper_change_dpb_owner);
143840d87aafSMansur Alisha Shaik 
1439af2c3834SStanimir Varbanov int venus_helper_vb2_buf_init(struct vb2_buffer *vb)
1440af2c3834SStanimir Varbanov {
1441af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1442af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1443af2c3834SStanimir Varbanov 	struct venus_buffer *buf = to_venus_buffer(vbuf);
1444af2c3834SStanimir Varbanov 
1445af2c3834SStanimir Varbanov 	buf->size = vb2_plane_size(vb, 0);
1446cc82fd69SAlexandre Courbot 	buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1447af2c3834SStanimir Varbanov 
1448af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1449af2c3834SStanimir Varbanov 		list_add_tail(&buf->reg_list, &inst->registeredbufs);
1450af2c3834SStanimir Varbanov 
1451af2c3834SStanimir Varbanov 	return 0;
1452af2c3834SStanimir Varbanov }
1453af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_init);
1454af2c3834SStanimir Varbanov 
1455af2c3834SStanimir Varbanov int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb)
1456af2c3834SStanimir Varbanov {
1457af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1458f012b23dSStanimir Varbanov 	unsigned int out_buf_size = venus_helper_get_opb_size(inst);
145905979046SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
146005979046SStanimir Varbanov 
146105979046SStanimir Varbanov 	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
146205979046SStanimir Varbanov 		if (vbuf->field == V4L2_FIELD_ANY)
146305979046SStanimir Varbanov 			vbuf->field = V4L2_FIELD_NONE;
146405979046SStanimir Varbanov 		if (vbuf->field != V4L2_FIELD_NONE) {
146505979046SStanimir Varbanov 			dev_err(inst->core->dev, "%s field isn't supported\n",
146605979046SStanimir Varbanov 				__func__);
146705979046SStanimir Varbanov 			return -EINVAL;
146805979046SStanimir Varbanov 		}
146905979046SStanimir Varbanov 	}
1470af2c3834SStanimir Varbanov 
1471af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
1472f012b23dSStanimir Varbanov 	    vb2_plane_size(vb, 0) < out_buf_size)
1473af2c3834SStanimir Varbanov 		return -EINVAL;
1474af2c3834SStanimir Varbanov 	if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
1475af2c3834SStanimir Varbanov 	    vb2_plane_size(vb, 0) < inst->input_buf_size)
1476af2c3834SStanimir Varbanov 		return -EINVAL;
1477af2c3834SStanimir Varbanov 
1478af2c3834SStanimir Varbanov 	return 0;
1479af2c3834SStanimir Varbanov }
1480af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare);
1481af2c3834SStanimir Varbanov 
1482fd1ee315SStanimir Varbanov static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb)
1483fd1ee315SStanimir Varbanov {
1484fd1ee315SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1485fd1ee315SStanimir Varbanov 	unsigned int idx = vbuf->vb2_buf.index;
1486fd1ee315SStanimir Varbanov 
1487fd1ee315SStanimir Varbanov 	if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1488fd1ee315SStanimir Varbanov 		inst->payloads[idx] = vb2_get_plane_payload(vb, 0);
1489fd1ee315SStanimir Varbanov }
1490fd1ee315SStanimir Varbanov 
1491af2c3834SStanimir Varbanov void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
1492af2c3834SStanimir Varbanov {
1493af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1494af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1495af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1496af2c3834SStanimir Varbanov 	int ret;
1497af2c3834SStanimir Varbanov 
1498af2c3834SStanimir Varbanov 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
1499af2c3834SStanimir Varbanov 
1500acf8a57dSStanimir Varbanov 	/* Skip processing queued capture buffers after LAST flag */
1501acf8a57dSStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
1502acf8a57dSStanimir Varbanov 	    V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1503acf8a57dSStanimir Varbanov 	    inst->codec_state == VENUS_DEC_STATE_DRC)
150421560ddfSStanimir Varbanov 		return;
1505acf8a57dSStanimir Varbanov 
1506fd1ee315SStanimir Varbanov 	cache_payload(inst, vb);
1507fd1ee315SStanimir Varbanov 
1508beac8290SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
1509beac8290SStanimir Varbanov 	    !(inst->streamon_out && inst->streamon_cap))
151021560ddfSStanimir Varbanov 		return;
1511af2c3834SStanimir Varbanov 
1512beac8290SStanimir Varbanov 	if (vb2_start_streaming_called(vb->vb2_queue)) {
1513af2c3834SStanimir Varbanov 		ret = is_buf_refed(inst, vbuf);
1514af2c3834SStanimir Varbanov 		if (ret)
151521560ddfSStanimir Varbanov 			return;
1516af2c3834SStanimir Varbanov 
1517af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, vbuf);
1518af2c3834SStanimir Varbanov 		if (ret)
1519af2c3834SStanimir Varbanov 			return_buf_error(inst, vbuf);
1520beac8290SStanimir Varbanov 	}
1521af2c3834SStanimir Varbanov }
1522af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue);
1523af2c3834SStanimir Varbanov 
15240febf923SStanimir Varbanov void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type,
1525af2c3834SStanimir Varbanov 			       enum vb2_buffer_state state)
1526af2c3834SStanimir Varbanov {
1527af2c3834SStanimir Varbanov 	struct vb2_v4l2_buffer *buf;
1528af2c3834SStanimir Varbanov 
15290febf923SStanimir Varbanov 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1530af2c3834SStanimir Varbanov 		while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
1531af2c3834SStanimir Varbanov 			v4l2_m2m_buf_done(buf, state);
15320febf923SStanimir Varbanov 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1533af2c3834SStanimir Varbanov 		while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
1534af2c3834SStanimir Varbanov 			v4l2_m2m_buf_done(buf, state);
1535af2c3834SStanimir Varbanov 	}
15360febf923SStanimir Varbanov }
1537af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_buffers_done);
1538af2c3834SStanimir Varbanov 
1539af2c3834SStanimir Varbanov void venus_helper_vb2_stop_streaming(struct vb2_queue *q)
1540af2c3834SStanimir Varbanov {
1541af2c3834SStanimir Varbanov 	struct venus_inst *inst = vb2_get_drv_priv(q);
1542af2c3834SStanimir Varbanov 	struct venus_core *core = inst->core;
1543af2c3834SStanimir Varbanov 	int ret;
1544af2c3834SStanimir Varbanov 
1545af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1546af2c3834SStanimir Varbanov 
1547af2c3834SStanimir Varbanov 	if (inst->streamon_out & inst->streamon_cap) {
1548af2c3834SStanimir Varbanov 		ret = hfi_session_stop(inst);
1549af2c3834SStanimir Varbanov 		ret |= hfi_session_unload_res(inst);
15501e485ee5SStanimir Varbanov 		ret |= venus_helper_unregister_bufs(inst);
15511e485ee5SStanimir Varbanov 		ret |= venus_helper_intbufs_free(inst);
1552af2c3834SStanimir Varbanov 		ret |= hfi_session_deinit(inst);
1553af2c3834SStanimir Varbanov 
1554b46ff4ebSStanimir Varbanov 		if (inst->session_error || test_bit(0, &core->sys_error))
1555af2c3834SStanimir Varbanov 			ret = -EIO;
1556af2c3834SStanimir Varbanov 
1557af2c3834SStanimir Varbanov 		if (ret)
1558af2c3834SStanimir Varbanov 			hfi_session_abort(inst);
1559af2c3834SStanimir Varbanov 
1560f012b23dSStanimir Varbanov 		venus_helper_free_dpb_bufs(inst);
1561f012b23dSStanimir Varbanov 
15627482a983SStanimir Varbanov 		venus_pm_load_scale(inst);
1563bbd770aeSStanimir Varbanov 		INIT_LIST_HEAD(&inst->registeredbufs);
1564af2c3834SStanimir Varbanov 	}
1565af2c3834SStanimir Varbanov 
15660febf923SStanimir Varbanov 	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
15670febf923SStanimir Varbanov 				  VB2_BUF_STATE_ERROR);
15680febf923SStanimir Varbanov 	venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
15690febf923SStanimir Varbanov 				  VB2_BUF_STATE_ERROR);
1570af2c3834SStanimir Varbanov 
1571af2c3834SStanimir Varbanov 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1572af2c3834SStanimir Varbanov 		inst->streamon_out = 0;
1573af2c3834SStanimir Varbanov 	else
1574af2c3834SStanimir Varbanov 		inst->streamon_cap = 0;
1575af2c3834SStanimir Varbanov 
15764ebf9693SAniket Masule 	venus_pm_release_core(inst);
15774ebf9693SAniket Masule 
15783227a8f7SStanimir Varbanov 	inst->session_error = 0;
15793227a8f7SStanimir Varbanov 
1580af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1581af2c3834SStanimir Varbanov }
1582af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
1583af2c3834SStanimir Varbanov 
1584aa6dcf17SStanimir Varbanov void venus_helper_vb2_queue_error(struct venus_inst *inst)
1585aa6dcf17SStanimir Varbanov {
1586aa6dcf17SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1587aa6dcf17SStanimir Varbanov 	struct vb2_queue *q;
1588aa6dcf17SStanimir Varbanov 
1589aa6dcf17SStanimir Varbanov 	q = v4l2_m2m_get_src_vq(m2m_ctx);
1590aa6dcf17SStanimir Varbanov 	vb2_queue_error(q);
1591aa6dcf17SStanimir Varbanov 	q = v4l2_m2m_get_dst_vq(m2m_ctx);
1592aa6dcf17SStanimir Varbanov 	vb2_queue_error(q);
1593aa6dcf17SStanimir Varbanov }
1594aa6dcf17SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_queue_error);
1595aa6dcf17SStanimir Varbanov 
159614ea00d6SStanimir Varbanov int venus_helper_process_initial_cap_bufs(struct venus_inst *inst)
159714ea00d6SStanimir Varbanov {
159814ea00d6SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
159914ea00d6SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
160014ea00d6SStanimir Varbanov 	int ret;
160114ea00d6SStanimir Varbanov 
160214ea00d6SStanimir Varbanov 	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
160314ea00d6SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
160414ea00d6SStanimir Varbanov 		if (ret) {
160514ea00d6SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
160614ea00d6SStanimir Varbanov 			return ret;
160714ea00d6SStanimir Varbanov 		}
160814ea00d6SStanimir Varbanov 	}
160914ea00d6SStanimir Varbanov 
161014ea00d6SStanimir Varbanov 	return 0;
161114ea00d6SStanimir Varbanov }
161214ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs);
161314ea00d6SStanimir Varbanov 
161414ea00d6SStanimir Varbanov int venus_helper_process_initial_out_bufs(struct venus_inst *inst)
161514ea00d6SStanimir Varbanov {
161614ea00d6SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
161714ea00d6SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
161814ea00d6SStanimir Varbanov 	int ret;
161914ea00d6SStanimir Varbanov 
162014ea00d6SStanimir Varbanov 	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
162114ea00d6SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
162214ea00d6SStanimir Varbanov 		if (ret) {
162314ea00d6SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
162414ea00d6SStanimir Varbanov 			return ret;
162514ea00d6SStanimir Varbanov 		}
162614ea00d6SStanimir Varbanov 	}
162714ea00d6SStanimir Varbanov 
162814ea00d6SStanimir Varbanov 	return 0;
162914ea00d6SStanimir Varbanov }
163014ea00d6SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs);
163114ea00d6SStanimir Varbanov 
1632af2c3834SStanimir Varbanov int venus_helper_vb2_start_streaming(struct venus_inst *inst)
1633af2c3834SStanimir Varbanov {
1634af2c3834SStanimir Varbanov 	int ret;
1635af2c3834SStanimir Varbanov 
16361e485ee5SStanimir Varbanov 	ret = venus_helper_intbufs_alloc(inst);
1637af2c3834SStanimir Varbanov 	if (ret)
1638af2c3834SStanimir Varbanov 		return ret;
1639af2c3834SStanimir Varbanov 
1640af2c3834SStanimir Varbanov 	ret = session_register_bufs(inst);
1641af2c3834SStanimir Varbanov 	if (ret)
1642af2c3834SStanimir Varbanov 		goto err_bufs_free;
1643af2c3834SStanimir Varbanov 
16447482a983SStanimir Varbanov 	venus_pm_load_scale(inst);
1645af2c3834SStanimir Varbanov 
1646af2c3834SStanimir Varbanov 	ret = hfi_session_load_res(inst);
1647af2c3834SStanimir Varbanov 	if (ret)
1648af2c3834SStanimir Varbanov 		goto err_unreg_bufs;
1649af2c3834SStanimir Varbanov 
1650af2c3834SStanimir Varbanov 	ret = hfi_session_start(inst);
1651af2c3834SStanimir Varbanov 	if (ret)
1652af2c3834SStanimir Varbanov 		goto err_unload_res;
1653af2c3834SStanimir Varbanov 
1654af2c3834SStanimir Varbanov 	return 0;
1655af2c3834SStanimir Varbanov 
1656af2c3834SStanimir Varbanov err_unload_res:
1657af2c3834SStanimir Varbanov 	hfi_session_unload_res(inst);
1658af2c3834SStanimir Varbanov err_unreg_bufs:
16591e485ee5SStanimir Varbanov 	venus_helper_unregister_bufs(inst);
1660af2c3834SStanimir Varbanov err_bufs_free:
16611e485ee5SStanimir Varbanov 	venus_helper_intbufs_free(inst);
1662af2c3834SStanimir Varbanov 	return ret;
1663af2c3834SStanimir Varbanov }
1664af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming);
1665af2c3834SStanimir Varbanov 
1666af2c3834SStanimir Varbanov void venus_helper_m2m_device_run(void *priv)
1667af2c3834SStanimir Varbanov {
1668af2c3834SStanimir Varbanov 	struct venus_inst *inst = priv;
1669af2c3834SStanimir Varbanov 	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1670af2c3834SStanimir Varbanov 	struct v4l2_m2m_buffer *buf, *n;
1671af2c3834SStanimir Varbanov 	int ret;
1672af2c3834SStanimir Varbanov 
1673af2c3834SStanimir Varbanov 	mutex_lock(&inst->lock);
1674af2c3834SStanimir Varbanov 
1675af2c3834SStanimir Varbanov 	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
1676af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1677af2c3834SStanimir Varbanov 		if (ret)
1678af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1679af2c3834SStanimir Varbanov 	}
1680af2c3834SStanimir Varbanov 
1681af2c3834SStanimir Varbanov 	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
1682af2c3834SStanimir Varbanov 		ret = session_process_buf(inst, &buf->vb);
1683af2c3834SStanimir Varbanov 		if (ret)
1684af2c3834SStanimir Varbanov 			return_buf_error(inst, &buf->vb);
1685af2c3834SStanimir Varbanov 	}
1686af2c3834SStanimir Varbanov 
1687af2c3834SStanimir Varbanov 	mutex_unlock(&inst->lock);
1688af2c3834SStanimir Varbanov }
1689af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_device_run);
1690af2c3834SStanimir Varbanov 
1691af2c3834SStanimir Varbanov void venus_helper_m2m_job_abort(void *priv)
1692af2c3834SStanimir Varbanov {
1693af2c3834SStanimir Varbanov 	struct venus_inst *inst = priv;
1694af2c3834SStanimir Varbanov 
1695af2c3834SStanimir Varbanov 	v4l2_m2m_job_finish(inst->m2m_dev, inst->m2m_ctx);
1696af2c3834SStanimir Varbanov }
1697af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_m2m_job_abort);
1698af2c3834SStanimir Varbanov 
1699aa603389SStanimir Varbanov int venus_helper_session_init(struct venus_inst *inst)
1700aa603389SStanimir Varbanov {
1701aa603389SStanimir Varbanov 	enum hfi_version version = inst->core->res->hfi_version;
1702aa603389SStanimir Varbanov 	u32 session_type = inst->session_type;
1703aa603389SStanimir Varbanov 	u32 codec;
1704aa603389SStanimir Varbanov 	int ret;
1705aa603389SStanimir Varbanov 
1706aa603389SStanimir Varbanov 	codec = inst->session_type == VIDC_SESSION_TYPE_DEC ?
1707aa603389SStanimir Varbanov 			inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
1708aa603389SStanimir Varbanov 
1709aa603389SStanimir Varbanov 	ret = hfi_session_init(inst, codec);
1710aa603389SStanimir Varbanov 	if (ret)
1711aa603389SStanimir Varbanov 		return ret;
1712aa603389SStanimir Varbanov 
1713aa603389SStanimir Varbanov 	inst->clk_data.vpp_freq = hfi_platform_get_codec_vpp_freq(version, codec,
1714aa603389SStanimir Varbanov 								  session_type);
1715aa603389SStanimir Varbanov 	inst->clk_data.vsp_freq = hfi_platform_get_codec_vsp_freq(version, codec,
1716aa603389SStanimir Varbanov 								  session_type);
17173cfe5815SDikshita Agarwal 	inst->clk_data.low_power_freq = hfi_platform_get_codec_lp_freq(version, codec,
17183cfe5815SDikshita Agarwal 								       session_type);
1719aa603389SStanimir Varbanov 
1720aa603389SStanimir Varbanov 	return 0;
1721aa603389SStanimir Varbanov }
1722aa603389SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_session_init);
1723aa603389SStanimir Varbanov 
1724af2c3834SStanimir Varbanov void venus_helper_init_instance(struct venus_inst *inst)
1725af2c3834SStanimir Varbanov {
1726af2c3834SStanimir Varbanov 	if (inst->session_type == VIDC_SESSION_TYPE_DEC) {
1727af2c3834SStanimir Varbanov 		INIT_LIST_HEAD(&inst->delayed_process);
1728af2c3834SStanimir Varbanov 		INIT_WORK(&inst->delayed_process_work,
1729af2c3834SStanimir Varbanov 			  delayed_process_buf_func);
1730af2c3834SStanimir Varbanov 	}
1731af2c3834SStanimir Varbanov }
1732af2c3834SStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_init_instance);
1733aa3a8414SStanimir Varbanov 
17348f3b41dcSStanimir Varbanov static bool find_fmt_from_caps(struct hfi_plat_caps *caps, u32 buftype, u32 fmt)
1735f012b23dSStanimir Varbanov {
1736f012b23dSStanimir Varbanov 	unsigned int i;
1737f012b23dSStanimir Varbanov 
1738f012b23dSStanimir Varbanov 	for (i = 0; i < caps->num_fmts; i++) {
1739f012b23dSStanimir Varbanov 		if (caps->fmts[i].buftype == buftype &&
1740f012b23dSStanimir Varbanov 		    caps->fmts[i].fmt == fmt)
1741f012b23dSStanimir Varbanov 			return true;
1742f012b23dSStanimir Varbanov 	}
1743f012b23dSStanimir Varbanov 
1744f012b23dSStanimir Varbanov 	return false;
1745f012b23dSStanimir Varbanov }
1746f012b23dSStanimir Varbanov 
1747f012b23dSStanimir Varbanov int venus_helper_get_out_fmts(struct venus_inst *inst, u32 v4l2_fmt,
1748f012b23dSStanimir Varbanov 			      u32 *out_fmt, u32 *out2_fmt, bool ubwc)
1749f012b23dSStanimir Varbanov {
1750f012b23dSStanimir Varbanov 	struct venus_core *core = inst->core;
17518f3b41dcSStanimir Varbanov 	struct hfi_plat_caps *caps;
1752f012b23dSStanimir Varbanov 	u32 ubwc_fmt, fmt = to_hfi_raw_fmt(v4l2_fmt);
1753f012b23dSStanimir Varbanov 	bool found, found_ubwc;
1754f012b23dSStanimir Varbanov 
1755f012b23dSStanimir Varbanov 	*out_fmt = *out2_fmt = 0;
1756f012b23dSStanimir Varbanov 
1757f012b23dSStanimir Varbanov 	if (!fmt)
1758f012b23dSStanimir Varbanov 		return -EINVAL;
1759f012b23dSStanimir Varbanov 
1760f012b23dSStanimir Varbanov 	caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
1761f012b23dSStanimir Varbanov 	if (!caps)
1762f012b23dSStanimir Varbanov 		return -EINVAL;
1763f012b23dSStanimir Varbanov 
1764ab1eda44SAniket Masule 	if (inst->bit_depth == VIDC_BITDEPTH_10 &&
1765ab1eda44SAniket Masule 	    inst->session_type == VIDC_SESSION_TYPE_DEC) {
1766ab1eda44SAniket Masule 		found_ubwc =
1767ab1eda44SAniket Masule 			find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1768ab1eda44SAniket Masule 					   HFI_COLOR_FORMAT_YUV420_TP10_UBWC);
1769ab1eda44SAniket Masule 		found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2,
1770ab1eda44SAniket Masule 					   HFI_COLOR_FORMAT_NV12);
1771ab1eda44SAniket Masule 		if (found_ubwc && found) {
1772ab1eda44SAniket Masule 			/*
1773ab1eda44SAniket Masule 			 * Hard-code DPB buffers to be 10bit UBWC and decoder
1774ab1eda44SAniket Masule 			 * output buffers in 8bit NV12 until V4L2 is able to
1775ab1eda44SAniket Masule 			 * expose compressed/tiled formats to applications.
1776ab1eda44SAniket Masule 			 */
1777ab1eda44SAniket Masule 			*out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
1778ab1eda44SAniket Masule 			*out2_fmt = HFI_COLOR_FORMAT_NV12;
1779ab1eda44SAniket Masule 			return 0;
1780ab1eda44SAniket Masule 		}
1781ab1eda44SAniket Masule 
1782ab1eda44SAniket Masule 		return -EINVAL;
1783ab1eda44SAniket Masule 	}
1784ab1eda44SAniket Masule 
1785f012b23dSStanimir Varbanov 	if (ubwc) {
1786f012b23dSStanimir Varbanov 		ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;
1787f012b23dSStanimir Varbanov 		found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1788f012b23dSStanimir Varbanov 						ubwc_fmt);
1789f012b23dSStanimir Varbanov 		found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
1790f012b23dSStanimir Varbanov 
1791f012b23dSStanimir Varbanov 		if (found_ubwc && found) {
1792f012b23dSStanimir Varbanov 			*out_fmt = ubwc_fmt;
1793f012b23dSStanimir Varbanov 			*out2_fmt = fmt;
1794f012b23dSStanimir Varbanov 			return 0;
1795f012b23dSStanimir Varbanov 		}
1796f012b23dSStanimir Varbanov 	}
1797f012b23dSStanimir Varbanov 
1798f012b23dSStanimir Varbanov 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt);
1799f012b23dSStanimir Varbanov 	if (found) {
1800f012b23dSStanimir Varbanov 		*out_fmt = fmt;
1801f012b23dSStanimir Varbanov 		*out2_fmt = 0;
1802f012b23dSStanimir Varbanov 		return 0;
1803f012b23dSStanimir Varbanov 	}
1804f012b23dSStanimir Varbanov 
1805f012b23dSStanimir Varbanov 	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
1806f012b23dSStanimir Varbanov 	if (found) {
1807f012b23dSStanimir Varbanov 		*out_fmt = 0;
1808f012b23dSStanimir Varbanov 		*out2_fmt = fmt;
1809f012b23dSStanimir Varbanov 		return 0;
1810f012b23dSStanimir Varbanov 	}
1811f012b23dSStanimir Varbanov 
1812f012b23dSStanimir Varbanov 	return -EINVAL;
1813f012b23dSStanimir Varbanov }
1814f012b23dSStanimir Varbanov EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts);
181501e869e7SDikshita Agarwal 
181601e869e7SDikshita Agarwal int venus_helper_set_stride(struct venus_inst *inst,
181701e869e7SDikshita Agarwal 			    unsigned int width, unsigned int height)
181801e869e7SDikshita Agarwal {
181901e869e7SDikshita Agarwal 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO;
182001e869e7SDikshita Agarwal 
182101e869e7SDikshita Agarwal 	struct hfi_uncompressed_plane_actual_info plane_actual_info;
182201e869e7SDikshita Agarwal 
182301e869e7SDikshita Agarwal 	plane_actual_info.buffer_type = HFI_BUFFER_INPUT;
182401e869e7SDikshita Agarwal 	plane_actual_info.num_planes = 2;
182501e869e7SDikshita Agarwal 	plane_actual_info.plane_format[0].actual_stride = width;
182601e869e7SDikshita Agarwal 	plane_actual_info.plane_format[0].actual_plane_buffer_height = height;
182701e869e7SDikshita Agarwal 	plane_actual_info.plane_format[1].actual_stride = width;
182801e869e7SDikshita Agarwal 	plane_actual_info.plane_format[1].actual_plane_buffer_height = height / 2;
182901e869e7SDikshita Agarwal 
183001e869e7SDikshita Agarwal 	return hfi_session_set_property(inst, ptype, &plane_actual_info);
183101e869e7SDikshita Agarwal }
183201e869e7SDikshita Agarwal EXPORT_SYMBOL_GPL(venus_helper_set_stride);
1833