xref: /linux/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c (revision 3ea0343c09be74ae9eda9dff9c153750a6d9b961)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <linux/bitfield.h>
7 
8 #include "iris_hfi_gen2.h"
9 #include "iris_hfi_gen2_packet.h"
10 
11 #define UNSPECIFIED_COLOR_FORMAT 5
12 #define NUM_SYS_INIT_PACKETS 8
13 
14 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \
15 	NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32)))
16 
17 #define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \
18 	sizeof(struct iris_hfi_packet) + sizeof(u32))
19 
20 #define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \
21 	sizeof(struct iris_hfi_packet))
22 
23 static int iris_hfi_gen2_sys_init(struct iris_core *core)
24 {
25 	struct iris_hfi_header *hdr;
26 	int ret;
27 
28 	hdr = kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL);
29 	if (!hdr)
30 		return -ENOMEM;
31 
32 	iris_hfi_gen2_packet_sys_init(core, hdr);
33 	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
34 
35 	kfree(hdr);
36 
37 	return ret;
38 }
39 
40 static int iris_hfi_gen2_sys_image_version(struct iris_core *core)
41 {
42 	struct iris_hfi_header *hdr;
43 	int ret;
44 
45 	hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
46 	if (!hdr)
47 		return -ENOMEM;
48 
49 	iris_hfi_gen2_packet_image_version(core, hdr);
50 	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
51 
52 	kfree(hdr);
53 
54 	return ret;
55 }
56 
57 static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core)
58 {
59 	struct iris_hfi_header *hdr;
60 	int ret;
61 
62 	hdr = kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL);
63 	if (!hdr)
64 		return -ENOMEM;
65 
66 	iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr);
67 	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
68 
69 	kfree(hdr);
70 
71 	return ret;
72 }
73 
74 static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
75 {
76 	struct iris_hfi_header *hdr;
77 	int ret;
78 
79 	hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
80 	if (!hdr)
81 		return -ENOMEM;
82 
83 	iris_hfi_gen2_packet_sys_pc_prep(core, hdr);
84 	ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
85 
86 	kfree(hdr);
87 
88 	return ret;
89 }
90 
91 static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane)
92 {
93 	if (inst->domain == DECODER) {
94 		switch (plane) {
95 		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
96 			return HFI_PORT_BITSTREAM;
97 		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
98 			return HFI_PORT_RAW;
99 		default:
100 			return HFI_PORT_NONE;
101 		}
102 	} else {
103 		switch (plane) {
104 		case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
105 			return HFI_PORT_RAW;
106 		case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
107 			return HFI_PORT_BITSTREAM;
108 		default:
109 			return HFI_PORT_NONE;
110 		}
111 	}
112 }
113 
114 static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst,
115 						enum iris_buffer_type buffer_type)
116 {
117 	if (inst->domain == DECODER) {
118 		switch (buffer_type) {
119 		case BUF_INPUT:
120 		case BUF_BIN:
121 		case BUF_COMV:
122 		case BUF_NON_COMV:
123 		case BUF_LINE:
124 		case BUF_PARTIAL:
125 			return HFI_PORT_BITSTREAM;
126 		case BUF_OUTPUT:
127 		case BUF_DPB:
128 			return HFI_PORT_RAW;
129 		case BUF_PERSIST:
130 		default:
131 			return HFI_PORT_NONE;
132 		}
133 	} else {
134 		switch (buffer_type) {
135 		case BUF_INPUT:
136 		case BUF_VPSS:
137 			return HFI_PORT_RAW;
138 		case BUF_OUTPUT:
139 		case BUF_BIN:
140 		case BUF_COMV:
141 		case BUF_NON_COMV:
142 		case BUF_LINE:
143 		case BUF_SCRATCH_2:
144 			return HFI_PORT_BITSTREAM;
145 		case BUF_ARP:
146 		default:
147 			return HFI_PORT_NONE;
148 		}
149 	}
150 }
151 
152 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
153 					      u32 plane, u32 payload_type, void *payload,
154 					      u32 payload_size)
155 {
156 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
157 
158 	iris_hfi_gen2_packet_session_property(inst,
159 					      packet_type,
160 					      flag,
161 					      plane,
162 					      payload_type,
163 					      payload,
164 					      payload_size);
165 
166 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
167 					inst_hfi_gen2->packet->size);
168 }
169 
170 static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
171 {
172 	u32 resolution = inst->enc_raw_width << 16 | inst->enc_raw_height;
173 	u32 port = iris_hfi_gen2_get_port(inst, plane);
174 
175 	return iris_hfi_gen2_session_set_property(inst,
176 						  HFI_PROP_RAW_RESOLUTION,
177 						  HFI_HOST_FLAGS_NONE,
178 						  port,
179 						  HFI_PAYLOAD_32_PACKED,
180 						  &resolution,
181 						  sizeof(u32));
182 }
183 
184 static inline u32 iris_hfi_get_aligned_resolution(struct iris_inst *inst, u32 width, u32 height)
185 {
186 	u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
187 
188 	return (ALIGN(width, codec_align) << 16 | ALIGN(height, codec_align));
189 }
190 
191 static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
192 {
193 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
194 	u32 port = iris_hfi_gen2_get_port(inst, plane);
195 	enum hfi_packet_payload_info payload_type;
196 	u32 width, height;
197 	u32 resolution;
198 
199 	if (inst->domain == DECODER) {
200 		width = inst->fmt_src->fmt.pix_mp.width;
201 		height = inst->fmt_src->fmt.pix_mp.height;
202 		resolution = iris_hfi_get_aligned_resolution(inst, width, height);
203 		inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
204 		payload_type = HFI_PAYLOAD_U32;
205 	} else {
206 		if (is_rotation_90_or_270(inst)) {
207 			width = inst->enc_scale_height;
208 			height = inst->enc_scale_width;
209 		} else {
210 			width = inst->enc_scale_width;
211 			height = inst->enc_scale_height;
212 		}
213 		resolution = iris_hfi_get_aligned_resolution(inst, width, height);
214 		inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
215 		payload_type = HFI_PAYLOAD_32_PACKED;
216 	}
217 
218 	return iris_hfi_gen2_session_set_property(inst,
219 						  HFI_PROP_BITSTREAM_RESOLUTION,
220 						  HFI_HOST_FLAGS_NONE,
221 						  port,
222 						  payload_type,
223 						  &resolution,
224 						  sizeof(u32));
225 }
226 
227 static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
228 {
229 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
230 	u32 port = iris_hfi_gen2_get_port(inst, plane);
231 	u32 bottom_offset, right_offset;
232 	u32 left_offset, top_offset;
233 	u32 payload[2], codec_align;
234 
235 	if (inst->domain == DECODER) {
236 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
237 			bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
238 			right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
239 			left_offset = inst->crop.left;
240 			top_offset = inst->crop.top;
241 		} else {
242 			bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
243 			right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
244 			left_offset = inst->compose.left;
245 			top_offset = inst->compose.top;
246 		}
247 	} else {
248 		codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
249 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
250 			bottom_offset = (inst->enc_raw_height - inst->crop.height);
251 			right_offset = (inst->enc_raw_width - inst->crop.width);
252 			left_offset = inst->crop.left;
253 			top_offset = inst->crop.top;
254 		} else {
255 			if (is_rotation_90_or_270(inst)) {
256 				bottom_offset = (ALIGN(inst->enc_scale_width, codec_align) -
257 						inst->enc_scale_width);
258 				right_offset = (ALIGN(inst->enc_scale_height, codec_align) -
259 					       inst->enc_scale_height);
260 			} else {
261 				bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) -
262 						inst->enc_scale_height);
263 				right_offset = (ALIGN(inst->enc_scale_width, codec_align) -
264 					       inst->enc_scale_width);
265 			}
266 			left_offset = 0;
267 			top_offset = 0;
268 		}
269 	}
270 
271 	payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
272 	payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
273 	inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
274 	inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1];
275 
276 	return iris_hfi_gen2_session_set_property(inst,
277 						  HFI_PROP_CROP_OFFSETS,
278 						  HFI_HOST_FLAGS_NONE,
279 						  port,
280 						  HFI_PAYLOAD_64_PACKED,
281 						  &payload,
282 						  sizeof(u64));
283 }
284 
285 static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
286 {
287 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
288 	u32 port = iris_hfi_gen2_get_port(inst, plane);
289 	u32 bitdepth = BIT_DEPTH_8;
290 
291 	inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
292 
293 	return iris_hfi_gen2_session_set_property(inst,
294 						  HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
295 						  HFI_HOST_FLAGS_NONE,
296 						  port,
297 						  HFI_PAYLOAD_U32,
298 						  &bitdepth,
299 						  sizeof(u32));
300 }
301 
302 static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
303 {
304 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
305 	u32 port = iris_hfi_gen2_get_port(inst, plane);
306 	u32 coded_frames = 0;
307 
308 	if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
309 		coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
310 	inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames;
311 
312 	return iris_hfi_gen2_session_set_property(inst,
313 						  HFI_PROP_CODED_FRAMES,
314 						  HFI_HOST_FLAGS_NONE,
315 						  port,
316 						  HFI_PAYLOAD_U32,
317 						  &coded_frames,
318 						  sizeof(u32));
319 }
320 
321 static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
322 {
323 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
324 	u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
325 	u32 port = iris_hfi_gen2_get_port(inst, plane);
326 
327 	inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
328 
329 	return iris_hfi_gen2_session_set_property(inst,
330 						  HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
331 						  HFI_HOST_FLAGS_NONE,
332 						  port,
333 						  HFI_PAYLOAD_U32,
334 						  &min_output,
335 						  sizeof(u32));
336 }
337 
338 static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
339 {
340 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
341 	u32 port = iris_hfi_gen2_get_port(inst, plane);
342 	u32 poc = 0;
343 
344 	inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
345 
346 	return iris_hfi_gen2_session_set_property(inst,
347 						  HFI_PROP_PIC_ORDER_CNT_TYPE,
348 						  HFI_HOST_FLAGS_NONE,
349 						  port,
350 						  HFI_PAYLOAD_U32,
351 						  &poc,
352 						  sizeof(u32));
353 }
354 
355 static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
356 {
357 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
358 	struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
359 	u32 video_signal_type_present_flag = 0, color_info;
360 	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
361 	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
362 	u32 full_range = V4L2_QUANTIZATION_DEFAULT;
363 	u32 transfer_char = HFI_TRANSFER_RESERVED;
364 	u32 port = iris_hfi_gen2_get_port(inst, plane);
365 	u32 colour_description_present_flag = 0;
366 	u32 primaries = HFI_PRIMARIES_RESERVED;
367 
368 	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
369 	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
370 	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
371 		colour_description_present_flag = 1;
372 		video_signal_type_present_flag = 1;
373 		primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
374 		matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
375 		transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
376 	}
377 
378 	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
379 		video_signal_type_present_flag = 1;
380 		full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
381 	}
382 
383 	color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
384 						  colour_description_present_flag, full_range,
385 						  video_format, video_signal_type_present_flag);
386 
387 	inst_hfi_gen2->src_subcr_params.color_info = color_info;
388 
389 	return iris_hfi_gen2_session_set_property(inst,
390 						  HFI_PROP_SIGNAL_COLOR_INFO,
391 						  HFI_HOST_FLAGS_NONE,
392 						  port,
393 						  HFI_PAYLOAD_32_PACKED,
394 						  &color_info,
395 						  sizeof(u32));
396 }
397 
398 static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
399 {
400 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
401 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
402 	u32 profile = 0;
403 
404 	switch (inst->codec) {
405 	case V4L2_PIX_FMT_HEVC:
406 		profile = inst->fw_caps[PROFILE_HEVC].value;
407 		break;
408 	case V4L2_PIX_FMT_VP9:
409 		profile = inst->fw_caps[PROFILE_VP9].value;
410 		break;
411 	case V4L2_PIX_FMT_H264:
412 		profile = inst->fw_caps[PROFILE_H264].value;
413 		break;
414 	case V4L2_PIX_FMT_AV1:
415 		profile = inst->fw_caps[PROFILE_AV1].value;
416 		break;
417 	}
418 
419 	inst_hfi_gen2->src_subcr_params.profile = profile;
420 
421 	return iris_hfi_gen2_session_set_property(inst,
422 						  HFI_PROP_PROFILE,
423 						  HFI_HOST_FLAGS_NONE,
424 						  port,
425 						  HFI_PAYLOAD_U32_ENUM,
426 						  &profile,
427 						  sizeof(u32));
428 }
429 
430 static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
431 {
432 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
433 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
434 	u32 level = 0;
435 
436 	switch (inst->codec) {
437 	case V4L2_PIX_FMT_HEVC:
438 		level = inst->fw_caps[LEVEL_HEVC].value;
439 		break;
440 	case V4L2_PIX_FMT_VP9:
441 		level = inst->fw_caps[LEVEL_VP9].value;
442 		break;
443 	case V4L2_PIX_FMT_H264:
444 		level = inst->fw_caps[LEVEL_H264].value;
445 		break;
446 	case V4L2_PIX_FMT_AV1:
447 		level = inst->fw_caps[LEVEL_AV1].value;
448 		break;
449 	}
450 
451 	inst_hfi_gen2->src_subcr_params.level = level;
452 
453 	return iris_hfi_gen2_session_set_property(inst,
454 						  HFI_PROP_LEVEL,
455 						  HFI_HOST_FLAGS_NONE,
456 						  port,
457 						  HFI_PAYLOAD_U32_ENUM,
458 						  &level,
459 						  sizeof(u32));
460 }
461 
462 static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane)
463 {
464 	u32 port = iris_hfi_gen2_get_port(inst, plane);
465 	u32 opb_enable = iris_split_mode_enabled(inst);
466 
467 	return iris_hfi_gen2_session_set_property(inst,
468 						  HFI_PROP_OPB_ENABLE,
469 						  HFI_HOST_FLAGS_NONE,
470 						  port,
471 						  HFI_PAYLOAD_U32,
472 						  &opb_enable,
473 						  sizeof(u32));
474 }
475 
476 static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
477 {
478 	u32 port = iris_hfi_gen2_get_port(inst, plane);
479 	u32 hfi_colorformat, pixelformat;
480 
481 	if (inst->domain == DECODER) {
482 		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
483 		switch (pixelformat) {
484 		case V4L2_PIX_FMT_NV12:
485 			hfi_colorformat = HFI_COLOR_FMT_NV12;
486 			break;
487 		case V4L2_PIX_FMT_QC08C:
488 			hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC;
489 			break;
490 		case V4L2_PIX_FMT_P010:
491 			hfi_colorformat = HFI_COLOR_FMT_P010;
492 			break;
493 		case V4L2_PIX_FMT_QC10C:
494 			hfi_colorformat = HFI_COLOR_FMT_TP10_UBWC;
495 			break;
496 		}
497 	} else {
498 		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
499 		hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
500 			HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
501 	}
502 
503 	return iris_hfi_gen2_session_set_property(inst,
504 						  HFI_PROP_COLOR_FORMAT,
505 						  HFI_HOST_FLAGS_NONE,
506 						  port,
507 						  HFI_PAYLOAD_U32_ENUM,
508 						  &hfi_colorformat,
509 						  sizeof(u32));
510 }
511 
512 static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
513 {
514 	u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
515 	u32 port = iris_hfi_gen2_get_port(inst, plane);
516 	u32 payload[2];
517 
518 	if (inst->domain == DECODER) {
519 		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
520 		stride_y = inst->fmt_dst->fmt.pix_mp.width;
521 		scanline_y = inst->fmt_dst->fmt.pix_mp.height;
522 	} else {
523 		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
524 		stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
525 		scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
526 	}
527 
528 	stride_uv = stride_y;
529 	scanline_uv = scanline_y / 2;
530 
531 	if (pixelformat != V4L2_PIX_FMT_NV12 &&
532 	    pixelformat != V4L2_PIX_FMT_P010)
533 		return 0;
534 
535 	payload[0] = stride_y << 16 | scanline_y;
536 	payload[1] = stride_uv << 16 | scanline_uv;
537 
538 	return iris_hfi_gen2_session_set_property(inst,
539 						  HFI_PROP_LINEAR_STRIDE_SCANLINE,
540 						  HFI_HOST_FLAGS_NONE,
541 						  port,
542 						  HFI_PAYLOAD_64_PACKED,
543 						  &payload,
544 						  sizeof(u64));
545 }
546 
547 static int iris_hfi_gen2_set_ubwc_stride_scanline(struct iris_inst *inst, u32 plane)
548 {
549 	u32 meta_stride_y, meta_scanline_y, meta_stride_uv, meta_scanline_uv;
550 	u32 stride_y, scanline_y, stride_uv, scanline_uv;
551 	u32 port = iris_hfi_gen2_get_port(inst, plane);
552 	u32 pixelformat, width, height;
553 	u32 payload[4];
554 
555 	if (inst->domain != DECODER ||
556 	    inst->fmt_src->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_AV1)
557 		return 0;
558 
559 	pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
560 	width = inst->fmt_dst->fmt.pix_mp.width;
561 	height = inst->fmt_dst->fmt.pix_mp.height;
562 
563 	switch (pixelformat) {
564 	case V4L2_PIX_FMT_QC08C:
565 		stride_y = ALIGN(width, 128);
566 		scanline_y = ALIGN(height, 32);
567 		stride_uv = ALIGN(width, 128);
568 		scanline_uv = ALIGN((height + 1) >> 1, 32);
569 		meta_stride_y = ALIGN(DIV_ROUND_UP(width, 32), 64);
570 		meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 8), 16);
571 		meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
572 		meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 8), 16);
573 		break;
574 	case V4L2_PIX_FMT_QC10C:
575 		stride_y = ALIGN(width * 4 / 3, 256);
576 		scanline_y = ALIGN(height, 16);
577 		stride_uv = ALIGN(width * 4 / 3, 256);
578 		scanline_uv = ALIGN((height + 1) >> 1, 16);
579 		meta_stride_y = ALIGN(DIV_ROUND_UP(width, 48), 64);
580 		meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 4), 16);
581 		meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
582 		meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
583 		break;
584 	default:
585 		return 0;
586 	}
587 
588 	payload[0] = stride_y << 16 | scanline_y;
589 	payload[1] = stride_uv << 16 | scanline_uv;
590 	payload[2] = meta_stride_y << 16 | meta_scanline_y;
591 	payload[3] = meta_stride_uv << 16 | meta_scanline_uv;
592 
593 	return iris_hfi_gen2_session_set_property(inst,
594 						  HFI_PROP_UBWC_STRIDE_SCANLINE,
595 						  HFI_HOST_FLAGS_NONE,
596 						  port,
597 						  HFI_PAYLOAD_U32_ARRAY,
598 						  &payload[0],
599 						  sizeof(u32) * 4);
600 }
601 
602 static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
603 {
604 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
605 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
606 	u32 tier = inst->fw_caps[TIER].value;
607 
608 	tier = (inst->codec == V4L2_PIX_FMT_AV1) ? inst->fw_caps[TIER_AV1].value :
609 							inst->fw_caps[TIER].value;
610 	inst_hfi_gen2->src_subcr_params.tier = tier;
611 
612 	return iris_hfi_gen2_session_set_property(inst,
613 						  HFI_PROP_TIER,
614 						  HFI_HOST_FLAGS_NONE,
615 						  port,
616 						  HFI_PAYLOAD_U32_ENUM,
617 						  &tier,
618 						  sizeof(u32));
619 }
620 
621 static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
622 {
623 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
624 	u32 frame_rate = inst->frame_rate << 16;
625 
626 	return iris_hfi_gen2_session_set_property(inst,
627 						  HFI_PROP_FRAME_RATE,
628 						  HFI_HOST_FLAGS_NONE,
629 						  port,
630 						  HFI_PAYLOAD_Q16,
631 						  &frame_rate,
632 						  sizeof(u32));
633 }
634 
635 static int iris_hfi_gen2_set_film_grain(struct iris_inst *inst, u32 plane)
636 {
637 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
638 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
639 	u32 film_grain = inst->fw_caps[FILM_GRAIN].value;
640 
641 	inst_hfi_gen2->src_subcr_params.film_grain = film_grain;
642 
643 	return iris_hfi_gen2_session_set_property(inst,
644 						  HFI_PROP_AV1_FILM_GRAIN_PRESENT,
645 						  HFI_HOST_FLAGS_NONE,
646 						  port,
647 						  HFI_PAYLOAD_U32_ENUM,
648 						  &film_grain,
649 						  sizeof(u32));
650 }
651 
652 static int iris_hfi_gen2_set_super_block(struct iris_inst *inst, u32 plane)
653 {
654 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
655 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
656 	u32 super_block = inst->fw_caps[SUPER_BLOCK].value;
657 
658 	inst_hfi_gen2->src_subcr_params.super_block = super_block;
659 
660 	return iris_hfi_gen2_session_set_property(inst,
661 						  HFI_PROP_AV1_SUPER_BLOCK_ENABLED,
662 						  HFI_HOST_FLAGS_NONE,
663 						  port,
664 						  HFI_PAYLOAD_U32_ENUM,
665 						  &super_block,
666 						  sizeof(u32));
667 }
668 
669 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
670 {
671 	const struct iris_firmware_data *fdata = inst->core->iris_firmware_data;
672 	u32 config_params_size = 0, i, j;
673 	const u32 *config_params = NULL;
674 	int ret;
675 
676 	static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
677 		{HFI_PROP_RAW_RESOLUTION,             iris_hfi_gen2_set_raw_resolution         },
678 		{HFI_PROP_BITSTREAM_RESOLUTION,       iris_hfi_gen2_set_bitstream_resolution   },
679 		{HFI_PROP_CROP_OFFSETS,               iris_hfi_gen2_set_crop_offsets           },
680 		{HFI_PROP_CODED_FRAMES,               iris_hfi_gen2_set_coded_frames           },
681 		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,      iris_hfi_gen2_set_bit_depth              },
682 		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count       },
683 		{HFI_PROP_PIC_ORDER_CNT_TYPE,         iris_hfi_gen2_set_picture_order_count    },
684 		{HFI_PROP_SIGNAL_COLOR_INFO,          iris_hfi_gen2_set_colorspace             },
685 		{HFI_PROP_PROFILE,                    iris_hfi_gen2_set_profile                },
686 		{HFI_PROP_LEVEL,                      iris_hfi_gen2_set_level                  },
687 		{HFI_PROP_OPB_ENABLE,                 iris_hfi_gen2_set_opb_enable             },
688 		{HFI_PROP_COLOR_FORMAT,               iris_hfi_gen2_set_colorformat            },
689 		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     iris_hfi_gen2_set_linear_stride_scanline },
690 		{HFI_PROP_UBWC_STRIDE_SCANLINE,       iris_hfi_gen2_set_ubwc_stride_scanline   },
691 		{HFI_PROP_TIER,                       iris_hfi_gen2_set_tier                   },
692 		{HFI_PROP_FRAME_RATE,                 iris_hfi_gen2_set_frame_rate             },
693 		{HFI_PROP_AV1_FILM_GRAIN_PRESENT,     iris_hfi_gen2_set_film_grain             },
694 		{HFI_PROP_AV1_SUPER_BLOCK_ENABLED,    iris_hfi_gen2_set_super_block            },
695 		{HFI_PROP_OPB_ENABLE,                 iris_hfi_gen2_set_opb_enable             },
696 	};
697 
698 	if (inst->domain == DECODER) {
699 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
700 			if (inst->codec == V4L2_PIX_FMT_H264) {
701 				config_params = fdata->dec_input_config_params_default;
702 				config_params_size = fdata->dec_input_config_params_default_size;
703 			} else if (inst->codec == V4L2_PIX_FMT_HEVC) {
704 				config_params = fdata->dec_input_config_params_hevc;
705 				config_params_size = fdata->dec_input_config_params_hevc_size;
706 			} else if (inst->codec == V4L2_PIX_FMT_VP9) {
707 				config_params = fdata->dec_input_config_params_vp9;
708 				config_params_size = fdata->dec_input_config_params_vp9_size;
709 			} else if (inst->codec == V4L2_PIX_FMT_AV1) {
710 				config_params = fdata->dec_input_config_params_av1;
711 				config_params_size = fdata->dec_input_config_params_av1_size;
712 			} else {
713 				return -EINVAL;
714 			}
715 		} else {
716 			config_params = fdata->dec_output_config_params;
717 			config_params_size = fdata->dec_output_config_params_size;
718 		}
719 	} else {
720 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
721 			config_params = fdata->enc_input_config_params;
722 			config_params_size = fdata->enc_input_config_params_size;
723 		} else {
724 			config_params = fdata->enc_output_config_params;
725 			config_params_size = fdata->enc_output_config_params_size;
726 		}
727 	}
728 
729 	if (!config_params || !config_params_size)
730 		return -EINVAL;
731 
732 	for (i = 0; i < config_params_size; i++) {
733 		for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
734 			if (prop_type_handle_arr[j].type == config_params[i]) {
735 				ret = prop_type_handle_arr[j].handle(inst, plane);
736 				if (ret)
737 					return ret;
738 				break;
739 			}
740 		}
741 	}
742 
743 	return 0;
744 }
745 
746 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
747 {
748 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
749 	u32 codec = 0;
750 
751 	switch (inst->codec) {
752 	case V4L2_PIX_FMT_H264:
753 		if (inst->domain == ENCODER)
754 			codec = HFI_CODEC_ENCODE_AVC;
755 		else
756 			codec = HFI_CODEC_DECODE_AVC;
757 		break;
758 	case V4L2_PIX_FMT_HEVC:
759 		if (inst->domain == ENCODER)
760 			codec = HFI_CODEC_ENCODE_HEVC;
761 		else
762 			codec = HFI_CODEC_DECODE_HEVC;
763 		break;
764 	case V4L2_PIX_FMT_VP9:
765 		codec = HFI_CODEC_DECODE_VP9;
766 		break;
767 	case V4L2_PIX_FMT_AV1:
768 		codec = HFI_CODEC_DECODE_AV1;
769 	}
770 
771 	iris_hfi_gen2_packet_session_property(inst,
772 					      HFI_PROP_CODEC,
773 					      HFI_HOST_FLAGS_NONE,
774 					      HFI_PORT_NONE,
775 					      HFI_PAYLOAD_U32_ENUM,
776 					      &codec,
777 					      sizeof(u32));
778 
779 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
780 					inst_hfi_gen2->packet->size);
781 }
782 
783 static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
784 {
785 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
786 	u32 default_header = false;
787 
788 	iris_hfi_gen2_packet_session_property(inst,
789 					      HFI_PROP_DEC_DEFAULT_HEADER,
790 					      HFI_HOST_FLAGS_NONE,
791 					      HFI_PORT_BITSTREAM,
792 					      HFI_PAYLOAD_U32,
793 					      &default_header,
794 					      sizeof(u32));
795 
796 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
797 					inst_hfi_gen2->packet->size);
798 }
799 
800 static int iris_hfi_gen2_session_open(struct iris_inst *inst)
801 {
802 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
803 	int ret;
804 
805 	if (inst->state != IRIS_INST_DEINIT)
806 		return -EALREADY;
807 
808 	inst_hfi_gen2->ipsc_properties_set = false;
809 	inst_hfi_gen2->opsc_properties_set = false;
810 
811 	inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
812 	if (!inst_hfi_gen2->packet)
813 		return -ENOMEM;
814 
815 	iris_hfi_gen2_packet_session_command(inst,
816 					     HFI_CMD_OPEN,
817 					     HFI_HOST_FLAGS_RESPONSE_REQUIRED |
818 					     HFI_HOST_FLAGS_INTR_REQUIRED,
819 					     HFI_PORT_NONE,
820 					     0,
821 					     HFI_PAYLOAD_U32,
822 					     &inst->session_id,
823 					     sizeof(u32));
824 
825 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
826 				       inst_hfi_gen2->packet->size);
827 	if (ret)
828 		goto fail_free_packet;
829 
830 	ret = iris_hfi_gen2_session_set_codec(inst);
831 	if (ret)
832 		goto fail_free_packet;
833 
834 	if (inst->domain == DECODER) {
835 		ret = iris_hfi_gen2_session_set_default_header(inst);
836 		if (ret)
837 			goto fail_free_packet;
838 	}
839 
840 	return 0;
841 
842 fail_free_packet:
843 	kfree(inst_hfi_gen2->packet);
844 	inst_hfi_gen2->packet = NULL;
845 
846 	return ret;
847 }
848 
849 static int iris_hfi_gen2_session_close(struct iris_inst *inst)
850 {
851 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
852 	int ret;
853 
854 	if (!inst_hfi_gen2->packet)
855 		return -EINVAL;
856 
857 	iris_hfi_gen2_packet_session_command(inst,
858 					     HFI_CMD_CLOSE,
859 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
860 					     HFI_HOST_FLAGS_INTR_REQUIRED |
861 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
862 					     HFI_PORT_NONE,
863 					     inst->session_id,
864 					     HFI_PAYLOAD_NONE,
865 					     NULL,
866 					     0);
867 
868 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
869 				       inst_hfi_gen2->packet->size);
870 
871 	kfree(inst_hfi_gen2->packet);
872 	inst_hfi_gen2->packet = NULL;
873 
874 	return ret;
875 }
876 
877 static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
878 						u32 cmd, u32 plane, u32 payload_type,
879 						void *payload, u32 payload_size)
880 {
881 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
882 
883 	iris_hfi_gen2_packet_session_command(inst,
884 					     cmd,
885 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
886 					     HFI_HOST_FLAGS_INTR_REQUIRED),
887 					     iris_hfi_gen2_get_port(inst, plane),
888 					     inst->session_id,
889 					     payload_type,
890 					     payload,
891 					     payload_size);
892 
893 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
894 					inst_hfi_gen2->packet->size);
895 }
896 
897 static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
898 {
899 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
900 	struct hfi_subscription_params subsc_params;
901 	u32 prop_type, payload_size, payload_type;
902 	struct iris_core *core = inst->core;
903 	const u32 *change_param = NULL;
904 	u32 change_param_size = 0;
905 	u32 payload[32] = {0};
906 	u32 hfi_port = 0, i;
907 	int ret;
908 
909 	if (inst->domain == ENCODER)
910 		return 0;
911 
912 	if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
913 	    (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
914 		dev_dbg(core->dev, "%cPSC already set\n", V4L2_TYPE_IS_OUTPUT(plane) ? 'I' : 'O');
915 		return 0;
916 	}
917 
918 	switch (inst->codec) {
919 	case V4L2_PIX_FMT_H264:
920 		change_param = core->iris_firmware_data->dec_input_config_params_default;
921 		change_param_size =
922 			core->iris_firmware_data->dec_input_config_params_default_size;
923 		break;
924 	case V4L2_PIX_FMT_HEVC:
925 		change_param = core->iris_firmware_data->dec_input_config_params_hevc;
926 		change_param_size =
927 			core->iris_firmware_data->dec_input_config_params_hevc_size;
928 		break;
929 	case V4L2_PIX_FMT_VP9:
930 		change_param = core->iris_firmware_data->dec_input_config_params_vp9;
931 		change_param_size =
932 			core->iris_firmware_data->dec_input_config_params_vp9_size;
933 		break;
934 	case V4L2_PIX_FMT_AV1:
935 		change_param = core->iris_firmware_data->dec_input_config_params_av1;
936 		change_param_size =
937 			core->iris_firmware_data->dec_input_config_params_av1_size;
938 		break;
939 	}
940 
941 	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
942 
943 	for (i = 0; i < change_param_size; i++)
944 		payload[i + 1] = change_param[i];
945 
946 	ret = iris_hfi_gen2_session_subscribe_mode(inst,
947 						   HFI_CMD_SUBSCRIBE_MODE,
948 						   plane,
949 						   HFI_PAYLOAD_U32_ARRAY,
950 						   &payload[0],
951 						   ((change_param_size + 1) * sizeof(u32)));
952 	if (ret)
953 		return ret;
954 
955 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
956 		inst_hfi_gen2->ipsc_properties_set = true;
957 	} else {
958 		hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
959 		memcpy(&inst_hfi_gen2->dst_subcr_params,
960 		       &inst_hfi_gen2->src_subcr_params,
961 		       sizeof(inst_hfi_gen2->src_subcr_params));
962 		subsc_params = inst_hfi_gen2->dst_subcr_params;
963 		for (i = 0; i < change_param_size; i++) {
964 			payload[0] = 0;
965 			payload[1] = 0;
966 			payload_size = 0;
967 			payload_type = 0;
968 			prop_type = change_param[i];
969 			switch (prop_type) {
970 			case HFI_PROP_BITSTREAM_RESOLUTION:
971 				payload[0] = subsc_params.bitstream_resolution;
972 				payload_size = sizeof(u32);
973 				payload_type = HFI_PAYLOAD_U32;
974 				break;
975 			case HFI_PROP_CROP_OFFSETS:
976 				payload[0] = subsc_params.crop_offsets[0];
977 				payload[1] = subsc_params.crop_offsets[1];
978 				payload_size = sizeof(u64);
979 				payload_type = HFI_PAYLOAD_64_PACKED;
980 				break;
981 			case HFI_PROP_CODED_FRAMES:
982 				payload[0] = subsc_params.coded_frames;
983 				payload_size = sizeof(u32);
984 				payload_type = HFI_PAYLOAD_U32;
985 				break;
986 			case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
987 				payload[0] = subsc_params.bit_depth;
988 				payload_size = sizeof(u32);
989 				payload_type = HFI_PAYLOAD_U32;
990 				break;
991 			case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
992 				payload[0] = subsc_params.fw_min_count;
993 				payload_size = sizeof(u32);
994 				payload_type = HFI_PAYLOAD_U32;
995 				break;
996 			case HFI_PROP_PIC_ORDER_CNT_TYPE:
997 				payload[0] = subsc_params.pic_order_cnt;
998 				payload_size = sizeof(u32);
999 				payload_type = HFI_PAYLOAD_U32;
1000 				break;
1001 			case HFI_PROP_SIGNAL_COLOR_INFO:
1002 				payload[0] = subsc_params.color_info;
1003 				payload_size = sizeof(u32);
1004 				payload_type = HFI_PAYLOAD_U32;
1005 				break;
1006 			case HFI_PROP_PROFILE:
1007 				payload[0] = subsc_params.profile;
1008 				payload_size = sizeof(u32);
1009 				payload_type = HFI_PAYLOAD_U32;
1010 				break;
1011 			case HFI_PROP_LEVEL:
1012 				payload[0] = subsc_params.level;
1013 				payload_size = sizeof(u32);
1014 				payload_type = HFI_PAYLOAD_U32;
1015 				break;
1016 			case HFI_PROP_TIER:
1017 				payload[0] = subsc_params.tier;
1018 				payload_size = sizeof(u32);
1019 				payload_type = HFI_PAYLOAD_U32;
1020 				break;
1021 			case HFI_PROP_AV1_FILM_GRAIN_PRESENT:
1022 				payload[0] = subsc_params.film_grain;
1023 				payload_size = sizeof(u32);
1024 				payload_type = HFI_PAYLOAD_U32;
1025 				break;
1026 			case HFI_PROP_AV1_SUPER_BLOCK_ENABLED:
1027 				payload[0] = subsc_params.super_block;
1028 				payload_size = sizeof(u32);
1029 				payload_type = HFI_PAYLOAD_U32;
1030 				break;
1031 			default:
1032 				prop_type = 0;
1033 				ret = -EINVAL;
1034 				break;
1035 			}
1036 			if (prop_type) {
1037 				ret = iris_hfi_gen2_session_set_property(inst,
1038 									 prop_type,
1039 									 HFI_HOST_FLAGS_NONE,
1040 									 hfi_port,
1041 									 payload_type,
1042 									 &payload,
1043 									 payload_size);
1044 				if (ret)
1045 					return ret;
1046 			}
1047 		}
1048 		inst_hfi_gen2->opsc_properties_set = true;
1049 	}
1050 
1051 	return 0;
1052 }
1053 
1054 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
1055 {
1056 	struct iris_core *core = inst->core;
1057 	u32 subscribe_prop_size = 0, i;
1058 	const u32 *subcribe_prop = NULL;
1059 	u32 payload[32] = {0};
1060 
1061 	payload[0] = HFI_MODE_PROPERTY;
1062 
1063 	if (inst->domain == ENCODER)
1064 		return 0;
1065 
1066 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
1067 		subscribe_prop_size = core->iris_firmware_data->dec_input_prop_size;
1068 		subcribe_prop = core->iris_firmware_data->dec_input_prop;
1069 	} else {
1070 		switch (inst->codec) {
1071 		case V4L2_PIX_FMT_H264:
1072 			subcribe_prop = core->iris_firmware_data->dec_output_prop_avc;
1073 			subscribe_prop_size =
1074 				core->iris_firmware_data->dec_output_prop_avc_size;
1075 			break;
1076 		case V4L2_PIX_FMT_HEVC:
1077 			subcribe_prop = core->iris_firmware_data->dec_output_prop_hevc;
1078 			subscribe_prop_size =
1079 				core->iris_firmware_data->dec_output_prop_hevc_size;
1080 			break;
1081 		case V4L2_PIX_FMT_VP9:
1082 			subcribe_prop = core->iris_firmware_data->dec_output_prop_vp9;
1083 			subscribe_prop_size =
1084 				core->iris_firmware_data->dec_output_prop_vp9_size;
1085 			break;
1086 		case V4L2_PIX_FMT_AV1:
1087 			subcribe_prop = core->iris_firmware_data->dec_output_prop_av1;
1088 			subscribe_prop_size =
1089 				core->iris_firmware_data->dec_output_prop_av1_size;
1090 			break;
1091 		}
1092 	}
1093 
1094 	for (i = 0; i < subscribe_prop_size; i++)
1095 		payload[i + 1] = subcribe_prop[i];
1096 
1097 	return iris_hfi_gen2_session_subscribe_mode(inst,
1098 						    HFI_CMD_SUBSCRIBE_MODE,
1099 						    plane,
1100 						    HFI_PAYLOAD_U32_ARRAY,
1101 						    &payload[0],
1102 						    (subscribe_prop_size + 1) * sizeof(u32));
1103 }
1104 
1105 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
1106 {
1107 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1108 	int ret = 0;
1109 
1110 	ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
1111 	if (ret)
1112 		return ret;
1113 
1114 	ret = iris_hfi_gen2_subscribe_property(inst, plane);
1115 	if (ret)
1116 		return ret;
1117 
1118 	iris_hfi_gen2_packet_session_command(inst,
1119 					     HFI_CMD_START,
1120 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1121 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1122 					     iris_hfi_gen2_get_port(inst, plane),
1123 					     inst->session_id,
1124 					     HFI_PAYLOAD_NONE,
1125 					     NULL,
1126 					     0);
1127 
1128 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1129 					inst_hfi_gen2->packet->size);
1130 }
1131 
1132 static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
1133 {
1134 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1135 	int ret = 0;
1136 
1137 	if (!inst_hfi_gen2->packet)
1138 		return -EINVAL;
1139 
1140 	reinit_completion(&inst->completion);
1141 
1142 	iris_hfi_gen2_packet_session_command(inst,
1143 					     HFI_CMD_STOP,
1144 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1145 					     HFI_HOST_FLAGS_INTR_REQUIRED |
1146 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
1147 					     iris_hfi_gen2_get_port(inst, plane),
1148 					     inst->session_id,
1149 					     HFI_PAYLOAD_NONE,
1150 					     NULL,
1151 					     0);
1152 
1153 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1154 				       inst_hfi_gen2->packet->size);
1155 	if (ret)
1156 		return ret;
1157 
1158 	return iris_wait_for_session_response(inst, false);
1159 }
1160 
1161 static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
1162 {
1163 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1164 
1165 	iris_hfi_gen2_packet_session_command(inst,
1166 					     HFI_CMD_PAUSE,
1167 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1168 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1169 					     iris_hfi_gen2_get_port(inst, plane),
1170 					     inst->session_id,
1171 					     HFI_PAYLOAD_NONE,
1172 					     NULL,
1173 					     0);
1174 
1175 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1176 					inst_hfi_gen2->packet->size);
1177 }
1178 
1179 static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
1180 {
1181 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1182 	u32 payload = HFI_CMD_SETTINGS_CHANGE;
1183 
1184 	iris_hfi_gen2_packet_session_command(inst,
1185 					     HFI_CMD_RESUME,
1186 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1187 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1188 					     iris_hfi_gen2_get_port(inst, plane),
1189 					     inst->session_id,
1190 					     HFI_PAYLOAD_U32,
1191 					     &payload,
1192 					     sizeof(u32));
1193 
1194 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1195 					inst_hfi_gen2->packet->size);
1196 }
1197 
1198 static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
1199 {
1200 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1201 	u32 payload = HFI_CMD_DRAIN;
1202 
1203 	iris_hfi_gen2_packet_session_command(inst,
1204 					     HFI_CMD_RESUME,
1205 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1206 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1207 					     iris_hfi_gen2_get_port(inst, plane),
1208 					     inst->session_id,
1209 					     HFI_PAYLOAD_U32,
1210 					     &payload,
1211 					     sizeof(u32));
1212 
1213 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1214 					inst_hfi_gen2->packet->size);
1215 }
1216 
1217 static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
1218 {
1219 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1220 
1221 	if (!V4L2_TYPE_IS_OUTPUT(plane))
1222 		return 0;
1223 
1224 	iris_hfi_gen2_packet_session_command(inst,
1225 					     HFI_CMD_DRAIN,
1226 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1227 					     HFI_HOST_FLAGS_INTR_REQUIRED |
1228 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
1229 					     iris_hfi_gen2_get_port(inst, plane),
1230 					     inst->session_id,
1231 					     HFI_PAYLOAD_NONE,
1232 					     NULL,
1233 					     0);
1234 
1235 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1236 					inst_hfi_gen2->packet->size);
1237 }
1238 
1239 static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
1240 {
1241 	switch (buffer_type) {
1242 	case BUF_INPUT:
1243 		if (domain == DECODER)
1244 			return HFI_BUFFER_BITSTREAM;
1245 		else
1246 			return HFI_BUFFER_RAW;
1247 	case BUF_OUTPUT:
1248 		if (domain == DECODER)
1249 			return HFI_BUFFER_RAW;
1250 		else
1251 			return HFI_BUFFER_BITSTREAM;
1252 	case BUF_BIN:
1253 		return HFI_BUFFER_BIN;
1254 	case BUF_COMV:
1255 		return HFI_BUFFER_COMV;
1256 	case BUF_NON_COMV:
1257 		return HFI_BUFFER_NON_COMV;
1258 	case BUF_LINE:
1259 		return HFI_BUFFER_LINE;
1260 	case BUF_DPB:
1261 	case BUF_SCRATCH_2:
1262 		return HFI_BUFFER_DPB;
1263 	case BUF_PERSIST:
1264 		return HFI_BUFFER_PERSIST;
1265 	case BUF_ARP:
1266 		return HFI_BUFFER_ARP;
1267 	case BUF_VPSS:
1268 		return HFI_BUFFER_VPSS;
1269 	case BUF_PARTIAL:
1270 		return HFI_BUFFER_PARTIAL_DATA;
1271 	default:
1272 		return 0;
1273 	}
1274 }
1275 
1276 static int iris_hfi_gen2_set_num_comv(struct iris_inst *inst)
1277 {
1278 	u32 num_comv = inst->buffers[BUF_OUTPUT].min_count;
1279 
1280 	if (inst->fw_min_count)
1281 		num_comv = inst->fw_min_count;
1282 
1283 	return iris_hfi_gen2_session_set_property(inst,
1284 						  HFI_PROP_COMV_BUFFER_COUNT,
1285 						  HFI_HOST_FLAGS_NONE,
1286 						  HFI_PORT_BITSTREAM,
1287 						  HFI_PAYLOAD_U32,
1288 						  &num_comv, sizeof(u32));
1289 }
1290 
1291 static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
1292 				     struct iris_hfi_buffer *buf)
1293 {
1294 	memset(buf, 0, sizeof(*buf));
1295 	buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
1296 	buf->index = buffer->index;
1297 	buf->base_address = buffer->device_addr;
1298 	buf->addr_offset = 0;
1299 	buf->buffer_size = buffer->buffer_size;
1300 
1301 	if (domain == DECODER && buffer->type == BUF_INPUT)
1302 		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
1303 	buf->data_offset = buffer->data_offset;
1304 	buf->data_size = buffer->data_size;
1305 	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
1306 		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
1307 	buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
1308 	buf->timestamp = buffer->timestamp;
1309 }
1310 
1311 static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1312 {
1313 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1314 	struct iris_hfi_buffer hfi_buffer;
1315 	u32 port;
1316 	int ret;
1317 
1318 	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1319 	if (buffer->type == BUF_COMV) {
1320 		ret = iris_hfi_gen2_set_num_comv(inst);
1321 		if (ret)
1322 			return ret;
1323 	}
1324 
1325 	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1326 	iris_hfi_gen2_packet_session_command(inst,
1327 					     HFI_CMD_BUFFER,
1328 					     HFI_HOST_FLAGS_INTR_REQUIRED,
1329 					     port,
1330 					     inst->session_id,
1331 					     HFI_PAYLOAD_STRUCTURE,
1332 					     &hfi_buffer,
1333 					     sizeof(hfi_buffer));
1334 
1335 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1336 					inst_hfi_gen2->packet->size);
1337 }
1338 
1339 static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1340 {
1341 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1342 	struct iris_hfi_buffer hfi_buffer;
1343 	u32 port;
1344 
1345 	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1346 	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
1347 	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1348 
1349 	iris_hfi_gen2_packet_session_command(inst,
1350 					     HFI_CMD_BUFFER,
1351 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1352 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1353 					     port,
1354 					     inst->session_id,
1355 					     HFI_PAYLOAD_STRUCTURE,
1356 					     &hfi_buffer,
1357 					     sizeof(hfi_buffer));
1358 
1359 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1360 					inst_hfi_gen2->packet->size);
1361 }
1362 
1363 static const struct iris_hfi_session_ops iris_hfi_gen2_session_ops = {
1364 	.session_open = iris_hfi_gen2_session_open,
1365 	.session_set_config_params = iris_hfi_gen2_session_set_config_params,
1366 	.session_set_property = iris_hfi_gen2_session_set_property,
1367 	.session_start = iris_hfi_gen2_session_start,
1368 	.session_queue_buf = iris_hfi_gen2_session_queue_buffer,
1369 	.session_release_buf = iris_hfi_gen2_session_release_buffer,
1370 	.session_pause = iris_hfi_gen2_session_pause,
1371 	.session_resume_drc = iris_hfi_gen2_session_resume_drc,
1372 	.session_stop = iris_hfi_gen2_session_stop,
1373 	.session_drain = iris_hfi_gen2_session_drain,
1374 	.session_resume_drain = iris_hfi_gen2_session_resume_drain,
1375 	.session_close = iris_hfi_gen2_session_close,
1376 };
1377 
1378 static struct iris_inst *iris_hfi_gen2_get_instance(void)
1379 {
1380 	struct iris_inst_hfi_gen2 *out;
1381 
1382 	/* The allocation is intentionally larger than struct iris_inst. */
1383 	out = kzalloc_obj(*out);
1384 	if (!out)
1385 		return NULL;
1386 
1387 	out->inst.hfi_session_ops = &iris_hfi_gen2_session_ops;
1388 
1389 	return &out->inst;
1390 }
1391 
1392 static const struct iris_hfi_sys_ops iris_hfi_gen2_sys_ops = {
1393 	.sys_init = iris_hfi_gen2_sys_init,
1394 	.sys_image_version = iris_hfi_gen2_sys_image_version,
1395 	.sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
1396 	.sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
1397 
1398 	.sys_hfi_response_handler = iris_hfi_gen2_response_handler,
1399 
1400 	.sys_get_instance = iris_hfi_gen2_get_instance,
1401 };
1402 
1403 void iris_hfi_gen2_sys_ops_init(struct iris_core *core)
1404 {
1405 	core->hfi_sys_ops = &iris_hfi_gen2_sys_ops;
1406 }
1407