xref: /linux/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c (revision ed1b409137bb9f49090362d34360ab80f88b9a5e)
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 
iris_hfi_gen2_sys_init(struct iris_core * core)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 
iris_hfi_gen2_sys_image_version(struct iris_core * core)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 
iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core * core)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 
iris_hfi_gen2_sys_pc_prep(struct iris_core * core)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 
iris_hfi_gen2_get_port(struct iris_inst * inst,u32 plane)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 
iris_hfi_gen2_get_port_from_buf_type(struct iris_inst * inst,enum iris_buffer_type buffer_type)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 			return HFI_PORT_BITSTREAM;
125 		case BUF_OUTPUT:
126 		case BUF_DPB:
127 			return HFI_PORT_RAW;
128 		case BUF_PERSIST:
129 		default:
130 			return HFI_PORT_NONE;
131 		}
132 	} else {
133 		switch (buffer_type) {
134 		case BUF_INPUT:
135 		case BUF_VPSS:
136 			return HFI_PORT_RAW;
137 		case BUF_OUTPUT:
138 		case BUF_BIN:
139 		case BUF_COMV:
140 		case BUF_NON_COMV:
141 		case BUF_LINE:
142 		case BUF_SCRATCH_2:
143 			return HFI_PORT_BITSTREAM;
144 		case BUF_ARP:
145 		default:
146 			return HFI_PORT_NONE;
147 		}
148 	}
149 }
150 
iris_hfi_gen2_session_set_property(struct iris_inst * inst,u32 packet_type,u32 flag,u32 plane,u32 payload_type,void * payload,u32 payload_size)151 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
152 					      u32 plane, u32 payload_type, void *payload,
153 					      u32 payload_size)
154 {
155 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
156 
157 	iris_hfi_gen2_packet_session_property(inst,
158 					      packet_type,
159 					      flag,
160 					      plane,
161 					      payload_type,
162 					      payload,
163 					      payload_size);
164 
165 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
166 					inst_hfi_gen2->packet->size);
167 }
168 
iris_hfi_gen2_set_raw_resolution(struct iris_inst * inst,u32 plane)169 static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
170 {
171 	u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
172 		inst->fmt_src->fmt.pix_mp.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 
iris_hfi_gen2_set_bitstream_resolution(struct iris_inst * inst,u32 plane)184 static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
185 {
186 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
187 	u32 port = iris_hfi_gen2_get_port(inst, plane);
188 	enum hfi_packet_payload_info payload_type;
189 	u32 resolution, codec_align;
190 
191 	if (inst->domain == DECODER) {
192 		resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
193 			inst->fmt_src->fmt.pix_mp.height;
194 		inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
195 		payload_type = HFI_PAYLOAD_U32;
196 	} else {
197 		codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
198 		resolution = ALIGN(inst->fmt_dst->fmt.pix_mp.width, codec_align) << 16 |
199 			ALIGN(inst->fmt_dst->fmt.pix_mp.height, codec_align);
200 		inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
201 		payload_type = HFI_PAYLOAD_32_PACKED;
202 	}
203 
204 	return iris_hfi_gen2_session_set_property(inst,
205 						  HFI_PROP_BITSTREAM_RESOLUTION,
206 						  HFI_HOST_FLAGS_NONE,
207 						  port,
208 						  payload_type,
209 						  &resolution,
210 						  sizeof(u32));
211 }
212 
iris_hfi_gen2_set_crop_offsets(struct iris_inst * inst,u32 plane)213 static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
214 {
215 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
216 	u32 port = iris_hfi_gen2_get_port(inst, plane);
217 	u32 bottom_offset, right_offset;
218 	u32 left_offset, top_offset;
219 	u32 payload[2];
220 
221 	if (inst->domain == DECODER) {
222 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
223 			bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
224 			right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
225 			left_offset = inst->crop.left;
226 			top_offset = inst->crop.top;
227 		} else {
228 			bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
229 			right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
230 			left_offset = inst->compose.left;
231 			top_offset = inst->compose.top;
232 		}
233 	} else {
234 		bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
235 		right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
236 		left_offset = inst->crop.left;
237 		top_offset = inst->crop.top;
238 	}
239 
240 	payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
241 	payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
242 	inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
243 	inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1];
244 
245 	return iris_hfi_gen2_session_set_property(inst,
246 						  HFI_PROP_CROP_OFFSETS,
247 						  HFI_HOST_FLAGS_NONE,
248 						  port,
249 						  HFI_PAYLOAD_64_PACKED,
250 						  &payload,
251 						  sizeof(u64));
252 }
253 
iris_hfi_gen2_set_bit_depth(struct iris_inst * inst,u32 plane)254 static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
255 {
256 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
257 	u32 port = iris_hfi_gen2_get_port(inst, plane);
258 	u32 bitdepth = BIT_DEPTH_8;
259 
260 	inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
261 
262 	return iris_hfi_gen2_session_set_property(inst,
263 						  HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
264 						  HFI_HOST_FLAGS_NONE,
265 						  port,
266 						  HFI_PAYLOAD_U32,
267 						  &bitdepth,
268 						  sizeof(u32));
269 }
270 
iris_hfi_gen2_set_coded_frames(struct iris_inst * inst,u32 plane)271 static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
272 {
273 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
274 	u32 port = iris_hfi_gen2_get_port(inst, plane);
275 	u32 coded_frames = 0;
276 
277 	if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
278 		coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
279 	inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames;
280 
281 	return iris_hfi_gen2_session_set_property(inst,
282 						  HFI_PROP_CODED_FRAMES,
283 						  HFI_HOST_FLAGS_NONE,
284 						  port,
285 						  HFI_PAYLOAD_U32,
286 						  &coded_frames,
287 						  sizeof(u32));
288 }
289 
iris_hfi_gen2_set_min_output_count(struct iris_inst * inst,u32 plane)290 static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
291 {
292 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
293 	u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
294 	u32 port = iris_hfi_gen2_get_port(inst, plane);
295 
296 	inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
297 
298 	return iris_hfi_gen2_session_set_property(inst,
299 						  HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
300 						  HFI_HOST_FLAGS_NONE,
301 						  port,
302 						  HFI_PAYLOAD_U32,
303 						  &min_output,
304 						  sizeof(u32));
305 }
306 
iris_hfi_gen2_set_picture_order_count(struct iris_inst * inst,u32 plane)307 static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
308 {
309 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
310 	u32 port = iris_hfi_gen2_get_port(inst, plane);
311 	u32 poc = 0;
312 
313 	inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
314 
315 	return iris_hfi_gen2_session_set_property(inst,
316 						  HFI_PROP_PIC_ORDER_CNT_TYPE,
317 						  HFI_HOST_FLAGS_NONE,
318 						  port,
319 						  HFI_PAYLOAD_U32,
320 						  &poc,
321 						  sizeof(u32));
322 }
323 
iris_hfi_gen2_set_colorspace(struct iris_inst * inst,u32 plane)324 static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
325 {
326 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
327 	struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
328 	u32 video_signal_type_present_flag = 0, color_info;
329 	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
330 	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
331 	u32 full_range = V4L2_QUANTIZATION_DEFAULT;
332 	u32 transfer_char = HFI_TRANSFER_RESERVED;
333 	u32 port = iris_hfi_gen2_get_port(inst, plane);
334 	u32 colour_description_present_flag = 0;
335 	u32 primaries = HFI_PRIMARIES_RESERVED;
336 
337 	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
338 	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
339 	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
340 		colour_description_present_flag = 1;
341 		video_signal_type_present_flag = 1;
342 		primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
343 		matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
344 		transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
345 	}
346 
347 	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
348 		video_signal_type_present_flag = 1;
349 		full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
350 	}
351 
352 	color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
353 						  colour_description_present_flag, full_range,
354 						  video_format, video_signal_type_present_flag);
355 
356 	inst_hfi_gen2->src_subcr_params.color_info = color_info;
357 
358 	return iris_hfi_gen2_session_set_property(inst,
359 						  HFI_PROP_SIGNAL_COLOR_INFO,
360 						  HFI_HOST_FLAGS_NONE,
361 						  port,
362 						  HFI_PAYLOAD_32_PACKED,
363 						  &color_info,
364 						  sizeof(u32));
365 }
366 
iris_hfi_gen2_set_profile(struct iris_inst * inst,u32 plane)367 static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
368 {
369 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
370 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
371 	u32 profile = 0;
372 
373 	switch (inst->codec) {
374 	case V4L2_PIX_FMT_HEVC:
375 		profile = inst->fw_caps[PROFILE_HEVC].value;
376 		break;
377 	case V4L2_PIX_FMT_VP9:
378 		profile = inst->fw_caps[PROFILE_VP9].value;
379 		break;
380 	case V4L2_PIX_FMT_H264:
381 		profile = inst->fw_caps[PROFILE_H264].value;
382 		break;
383 	}
384 
385 	inst_hfi_gen2->src_subcr_params.profile = profile;
386 
387 	return iris_hfi_gen2_session_set_property(inst,
388 						  HFI_PROP_PROFILE,
389 						  HFI_HOST_FLAGS_NONE,
390 						  port,
391 						  HFI_PAYLOAD_U32_ENUM,
392 						  &profile,
393 						  sizeof(u32));
394 }
395 
iris_hfi_gen2_set_level(struct iris_inst * inst,u32 plane)396 static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
397 {
398 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
399 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
400 	u32 level = 0;
401 
402 	switch (inst->codec) {
403 	case V4L2_PIX_FMT_HEVC:
404 		level = inst->fw_caps[LEVEL_HEVC].value;
405 		break;
406 	case V4L2_PIX_FMT_VP9:
407 		level = inst->fw_caps[LEVEL_VP9].value;
408 		break;
409 	case V4L2_PIX_FMT_H264:
410 		level = inst->fw_caps[LEVEL_H264].value;
411 		break;
412 	}
413 
414 	inst_hfi_gen2->src_subcr_params.level = level;
415 
416 	return iris_hfi_gen2_session_set_property(inst,
417 						  HFI_PROP_LEVEL,
418 						  HFI_HOST_FLAGS_NONE,
419 						  port,
420 						  HFI_PAYLOAD_U32_ENUM,
421 						  &level,
422 						  sizeof(u32));
423 }
424 
iris_hfi_gen2_set_opb_enable(struct iris_inst * inst,u32 plane)425 static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane)
426 {
427 	u32 port = iris_hfi_gen2_get_port(inst, plane);
428 	u32 opb_enable = iris_split_mode_enabled(inst);
429 
430 	return iris_hfi_gen2_session_set_property(inst,
431 						  HFI_PROP_OPB_ENABLE,
432 						  HFI_HOST_FLAGS_NONE,
433 						  port,
434 						  HFI_PAYLOAD_U32,
435 						  &opb_enable,
436 						  sizeof(u32));
437 }
438 
iris_hfi_gen2_set_colorformat(struct iris_inst * inst,u32 plane)439 static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
440 {
441 	u32 port = iris_hfi_gen2_get_port(inst, plane);
442 	u32 hfi_colorformat, pixelformat;
443 
444 	if (inst->domain == DECODER) {
445 		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
446 		hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
447 			HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
448 	} else {
449 		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
450 		hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
451 			HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
452 	}
453 
454 	return iris_hfi_gen2_session_set_property(inst,
455 						  HFI_PROP_COLOR_FORMAT,
456 						  HFI_HOST_FLAGS_NONE,
457 						  port,
458 						  HFI_PAYLOAD_U32_ENUM,
459 						  &hfi_colorformat,
460 						  sizeof(u32));
461 }
462 
iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst * inst,u32 plane)463 static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
464 {
465 	u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
466 	u32 port = iris_hfi_gen2_get_port(inst, plane);
467 	u32 payload[2];
468 
469 	if (inst->domain == DECODER) {
470 		pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
471 		stride_y = inst->fmt_dst->fmt.pix_mp.width;
472 		scanline_y = inst->fmt_dst->fmt.pix_mp.height;
473 	} else {
474 		pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
475 		stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
476 		scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
477 	}
478 
479 	stride_uv = stride_y;
480 	scanline_uv = scanline_y / 2;
481 
482 	if (pixelformat != V4L2_PIX_FMT_NV12)
483 		return 0;
484 
485 	payload[0] = stride_y << 16 | scanline_y;
486 	payload[1] = stride_uv << 16 | scanline_uv;
487 
488 	return iris_hfi_gen2_session_set_property(inst,
489 						  HFI_PROP_LINEAR_STRIDE_SCANLINE,
490 						  HFI_HOST_FLAGS_NONE,
491 						  port,
492 						  HFI_PAYLOAD_64_PACKED,
493 						  &payload,
494 						  sizeof(u64));
495 }
496 
iris_hfi_gen2_set_tier(struct iris_inst * inst,u32 plane)497 static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
498 {
499 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
500 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
501 	u32 tier = inst->fw_caps[TIER].value;
502 
503 	inst_hfi_gen2->src_subcr_params.tier = tier;
504 
505 	return iris_hfi_gen2_session_set_property(inst,
506 						  HFI_PROP_TIER,
507 						  HFI_HOST_FLAGS_NONE,
508 						  port,
509 						  HFI_PAYLOAD_U32_ENUM,
510 						  &tier,
511 						  sizeof(u32));
512 }
513 
iris_hfi_gen2_set_frame_rate(struct iris_inst * inst,u32 plane)514 static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
515 {
516 	u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
517 	u32 frame_rate = inst->frame_rate << 16;
518 
519 	return iris_hfi_gen2_session_set_property(inst,
520 						  HFI_PROP_FRAME_RATE,
521 						  HFI_HOST_FLAGS_NONE,
522 						  port,
523 						  HFI_PAYLOAD_Q16,
524 						  &frame_rate,
525 						  sizeof(u32));
526 }
527 
iris_hfi_gen2_session_set_config_params(struct iris_inst * inst,u32 plane)528 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
529 {
530 	const struct iris_platform_data *pdata = inst->core->iris_platform_data;
531 	u32 config_params_size = 0, i, j;
532 	const u32 *config_params = NULL;
533 	int ret;
534 
535 	static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
536 		{HFI_PROP_RAW_RESOLUTION,             iris_hfi_gen2_set_raw_resolution         },
537 		{HFI_PROP_BITSTREAM_RESOLUTION,       iris_hfi_gen2_set_bitstream_resolution   },
538 		{HFI_PROP_CROP_OFFSETS,               iris_hfi_gen2_set_crop_offsets           },
539 		{HFI_PROP_CODED_FRAMES,               iris_hfi_gen2_set_coded_frames           },
540 		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,      iris_hfi_gen2_set_bit_depth              },
541 		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count       },
542 		{HFI_PROP_PIC_ORDER_CNT_TYPE,         iris_hfi_gen2_set_picture_order_count    },
543 		{HFI_PROP_SIGNAL_COLOR_INFO,          iris_hfi_gen2_set_colorspace             },
544 		{HFI_PROP_PROFILE,                    iris_hfi_gen2_set_profile                },
545 		{HFI_PROP_LEVEL,                      iris_hfi_gen2_set_level                  },
546 		{HFI_PROP_OPB_ENABLE,                 iris_hfi_gen2_set_opb_enable             },
547 		{HFI_PROP_COLOR_FORMAT,               iris_hfi_gen2_set_colorformat            },
548 		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     iris_hfi_gen2_set_linear_stride_scanline },
549 		{HFI_PROP_TIER,                       iris_hfi_gen2_set_tier                   },
550 		{HFI_PROP_FRAME_RATE,                 iris_hfi_gen2_set_frame_rate             },
551 	};
552 
553 	if (inst->domain == DECODER) {
554 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
555 			if (inst->codec == V4L2_PIX_FMT_H264) {
556 				config_params = pdata->dec_input_config_params_default;
557 				config_params_size = pdata->dec_input_config_params_default_size;
558 			} else if (inst->codec == V4L2_PIX_FMT_HEVC) {
559 				config_params = pdata->dec_input_config_params_hevc;
560 				config_params_size = pdata->dec_input_config_params_hevc_size;
561 			} else if (inst->codec == V4L2_PIX_FMT_VP9) {
562 				config_params = pdata->dec_input_config_params_vp9;
563 				config_params_size = pdata->dec_input_config_params_vp9_size;
564 			} else {
565 				return -EINVAL;
566 			}
567 		} else {
568 			config_params = pdata->dec_output_config_params;
569 			config_params_size = pdata->dec_output_config_params_size;
570 		}
571 	} else {
572 		if (V4L2_TYPE_IS_OUTPUT(plane)) {
573 			config_params = pdata->enc_input_config_params;
574 			config_params_size = pdata->enc_input_config_params_size;
575 		} else {
576 			config_params = pdata->enc_output_config_params;
577 			config_params_size = pdata->enc_output_config_params_size;
578 		}
579 	}
580 
581 	if (!config_params || !config_params_size)
582 		return -EINVAL;
583 
584 	for (i = 0; i < config_params_size; i++) {
585 		for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
586 			if (prop_type_handle_arr[j].type == config_params[i]) {
587 				ret = prop_type_handle_arr[j].handle(inst, plane);
588 				if (ret)
589 					return ret;
590 				break;
591 			}
592 		}
593 	}
594 
595 	return 0;
596 }
597 
iris_hfi_gen2_session_set_codec(struct iris_inst * inst)598 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
599 {
600 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
601 	u32 codec = 0;
602 
603 	switch (inst->codec) {
604 	case V4L2_PIX_FMT_H264:
605 		if (inst->domain == ENCODER)
606 			codec = HFI_CODEC_ENCODE_AVC;
607 		else
608 			codec = HFI_CODEC_DECODE_AVC;
609 		break;
610 	case V4L2_PIX_FMT_HEVC:
611 		if (inst->domain == ENCODER)
612 			codec = HFI_CODEC_ENCODE_HEVC;
613 		else
614 			codec = HFI_CODEC_DECODE_HEVC;
615 		break;
616 	case V4L2_PIX_FMT_VP9:
617 		codec = HFI_CODEC_DECODE_VP9;
618 	}
619 
620 	iris_hfi_gen2_packet_session_property(inst,
621 					      HFI_PROP_CODEC,
622 					      HFI_HOST_FLAGS_NONE,
623 					      HFI_PORT_NONE,
624 					      HFI_PAYLOAD_U32_ENUM,
625 					      &codec,
626 					      sizeof(u32));
627 
628 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
629 					inst_hfi_gen2->packet->size);
630 }
631 
iris_hfi_gen2_session_set_default_header(struct iris_inst * inst)632 static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
633 {
634 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
635 	u32 default_header = false;
636 
637 	iris_hfi_gen2_packet_session_property(inst,
638 					      HFI_PROP_DEC_DEFAULT_HEADER,
639 					      HFI_HOST_FLAGS_NONE,
640 					      HFI_PORT_BITSTREAM,
641 					      HFI_PAYLOAD_U32,
642 					      &default_header,
643 					      sizeof(u32));
644 
645 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
646 					inst_hfi_gen2->packet->size);
647 }
648 
iris_hfi_gen2_session_open(struct iris_inst * inst)649 static int iris_hfi_gen2_session_open(struct iris_inst *inst)
650 {
651 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
652 	int ret;
653 
654 	if (inst->state != IRIS_INST_DEINIT)
655 		return -EALREADY;
656 
657 	inst_hfi_gen2->ipsc_properties_set = false;
658 	inst_hfi_gen2->opsc_properties_set = false;
659 
660 	inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
661 	if (!inst_hfi_gen2->packet)
662 		return -ENOMEM;
663 
664 	iris_hfi_gen2_packet_session_command(inst,
665 					     HFI_CMD_OPEN,
666 					     HFI_HOST_FLAGS_RESPONSE_REQUIRED |
667 					     HFI_HOST_FLAGS_INTR_REQUIRED,
668 					     HFI_PORT_NONE,
669 					     0,
670 					     HFI_PAYLOAD_U32,
671 					     &inst->session_id,
672 					     sizeof(u32));
673 
674 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
675 				       inst_hfi_gen2->packet->size);
676 	if (ret)
677 		goto fail_free_packet;
678 
679 	ret = iris_hfi_gen2_session_set_codec(inst);
680 	if (ret)
681 		goto fail_free_packet;
682 
683 	if (inst->domain == DECODER) {
684 		ret = iris_hfi_gen2_session_set_default_header(inst);
685 		if (ret)
686 			goto fail_free_packet;
687 	}
688 
689 	return 0;
690 
691 fail_free_packet:
692 	kfree(inst_hfi_gen2->packet);
693 	inst_hfi_gen2->packet = NULL;
694 
695 	return ret;
696 }
697 
iris_hfi_gen2_session_close(struct iris_inst * inst)698 static int iris_hfi_gen2_session_close(struct iris_inst *inst)
699 {
700 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
701 	int ret;
702 
703 	if (!inst_hfi_gen2->packet)
704 		return -EINVAL;
705 
706 	iris_hfi_gen2_packet_session_command(inst,
707 					     HFI_CMD_CLOSE,
708 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
709 					     HFI_HOST_FLAGS_INTR_REQUIRED |
710 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
711 					     HFI_PORT_NONE,
712 					     inst->session_id,
713 					     HFI_PAYLOAD_NONE,
714 					     NULL,
715 					     0);
716 
717 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
718 				       inst_hfi_gen2->packet->size);
719 
720 	kfree(inst_hfi_gen2->packet);
721 	inst_hfi_gen2->packet = NULL;
722 
723 	return ret;
724 }
725 
iris_hfi_gen2_session_subscribe_mode(struct iris_inst * inst,u32 cmd,u32 plane,u32 payload_type,void * payload,u32 payload_size)726 static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
727 						u32 cmd, u32 plane, u32 payload_type,
728 						void *payload, u32 payload_size)
729 {
730 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
731 
732 	iris_hfi_gen2_packet_session_command(inst,
733 					     cmd,
734 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
735 					     HFI_HOST_FLAGS_INTR_REQUIRED),
736 					     iris_hfi_gen2_get_port(inst, plane),
737 					     inst->session_id,
738 					     payload_type,
739 					     payload,
740 					     payload_size);
741 
742 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
743 					inst_hfi_gen2->packet->size);
744 }
745 
iris_hfi_gen2_subscribe_change_param(struct iris_inst * inst,u32 plane)746 static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
747 {
748 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
749 	struct hfi_subscription_params subsc_params;
750 	u32 prop_type, payload_size, payload_type;
751 	struct iris_core *core = inst->core;
752 	const u32 *change_param = NULL;
753 	u32 change_param_size = 0;
754 	u32 payload[32] = {0};
755 	u32 hfi_port = 0, i;
756 	int ret;
757 
758 	if (inst->domain == ENCODER)
759 		return 0;
760 
761 	if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
762 	    (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
763 		dev_err(core->dev, "invalid plane\n");
764 		return 0;
765 	}
766 
767 	switch (inst->codec) {
768 	case V4L2_PIX_FMT_H264:
769 		change_param = core->iris_platform_data->dec_input_config_params_default;
770 		change_param_size =
771 			core->iris_platform_data->dec_input_config_params_default_size;
772 		break;
773 	case V4L2_PIX_FMT_HEVC:
774 		change_param = core->iris_platform_data->dec_input_config_params_hevc;
775 		change_param_size =
776 			core->iris_platform_data->dec_input_config_params_hevc_size;
777 		break;
778 	case V4L2_PIX_FMT_VP9:
779 		change_param = core->iris_platform_data->dec_input_config_params_vp9;
780 		change_param_size =
781 			core->iris_platform_data->dec_input_config_params_vp9_size;
782 		break;
783 	}
784 
785 	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
786 
787 	for (i = 0; i < change_param_size; i++)
788 		payload[i + 1] = change_param[i];
789 
790 	ret = iris_hfi_gen2_session_subscribe_mode(inst,
791 						   HFI_CMD_SUBSCRIBE_MODE,
792 						   plane,
793 						   HFI_PAYLOAD_U32_ARRAY,
794 						   &payload[0],
795 						   ((change_param_size + 1) * sizeof(u32)));
796 	if (ret)
797 		return ret;
798 
799 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
800 		inst_hfi_gen2->ipsc_properties_set = true;
801 	} else {
802 		hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
803 		memcpy(&inst_hfi_gen2->dst_subcr_params,
804 		       &inst_hfi_gen2->src_subcr_params,
805 		       sizeof(inst_hfi_gen2->src_subcr_params));
806 		subsc_params = inst_hfi_gen2->dst_subcr_params;
807 		for (i = 0; i < change_param_size; i++) {
808 			payload[0] = 0;
809 			payload[1] = 0;
810 			payload_size = 0;
811 			payload_type = 0;
812 			prop_type = change_param[i];
813 			switch (prop_type) {
814 			case HFI_PROP_BITSTREAM_RESOLUTION:
815 				payload[0] = subsc_params.bitstream_resolution;
816 				payload_size = sizeof(u32);
817 				payload_type = HFI_PAYLOAD_U32;
818 				break;
819 			case HFI_PROP_CROP_OFFSETS:
820 				payload[0] = subsc_params.crop_offsets[0];
821 				payload[1] = subsc_params.crop_offsets[1];
822 				payload_size = sizeof(u64);
823 				payload_type = HFI_PAYLOAD_64_PACKED;
824 				break;
825 			case HFI_PROP_CODED_FRAMES:
826 				payload[0] = subsc_params.coded_frames;
827 				payload_size = sizeof(u32);
828 				payload_type = HFI_PAYLOAD_U32;
829 				break;
830 			case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
831 				payload[0] = subsc_params.bit_depth;
832 				payload_size = sizeof(u32);
833 				payload_type = HFI_PAYLOAD_U32;
834 				break;
835 			case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
836 				payload[0] = subsc_params.fw_min_count;
837 				payload_size = sizeof(u32);
838 				payload_type = HFI_PAYLOAD_U32;
839 				break;
840 			case HFI_PROP_PIC_ORDER_CNT_TYPE:
841 				payload[0] = subsc_params.pic_order_cnt;
842 				payload_size = sizeof(u32);
843 				payload_type = HFI_PAYLOAD_U32;
844 				break;
845 			case HFI_PROP_SIGNAL_COLOR_INFO:
846 				payload[0] = subsc_params.color_info;
847 				payload_size = sizeof(u32);
848 				payload_type = HFI_PAYLOAD_U32;
849 				break;
850 			case HFI_PROP_PROFILE:
851 				payload[0] = subsc_params.profile;
852 				payload_size = sizeof(u32);
853 				payload_type = HFI_PAYLOAD_U32;
854 				break;
855 			case HFI_PROP_LEVEL:
856 				payload[0] = subsc_params.level;
857 				payload_size = sizeof(u32);
858 				payload_type = HFI_PAYLOAD_U32;
859 				break;
860 			case HFI_PROP_TIER:
861 				payload[0] = subsc_params.tier;
862 				payload_size = sizeof(u32);
863 				payload_type = HFI_PAYLOAD_U32;
864 				break;
865 			default:
866 				prop_type = 0;
867 				ret = -EINVAL;
868 				break;
869 			}
870 			if (prop_type) {
871 				ret = iris_hfi_gen2_session_set_property(inst,
872 									 prop_type,
873 									 HFI_HOST_FLAGS_NONE,
874 									 hfi_port,
875 									 payload_type,
876 									 &payload,
877 									 payload_size);
878 				if (ret)
879 					return ret;
880 			}
881 		}
882 		inst_hfi_gen2->opsc_properties_set = true;
883 	}
884 
885 	return 0;
886 }
887 
iris_hfi_gen2_subscribe_property(struct iris_inst * inst,u32 plane)888 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
889 {
890 	struct iris_core *core = inst->core;
891 	u32 subscribe_prop_size = 0, i;
892 	const u32 *subcribe_prop = NULL;
893 	u32 payload[32] = {0};
894 
895 	payload[0] = HFI_MODE_PROPERTY;
896 
897 	if (inst->domain == ENCODER)
898 		return 0;
899 
900 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
901 		subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
902 		subcribe_prop = core->iris_platform_data->dec_input_prop;
903 	} else {
904 		switch (inst->codec) {
905 		case V4L2_PIX_FMT_H264:
906 			subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
907 			subscribe_prop_size =
908 				core->iris_platform_data->dec_output_prop_avc_size;
909 			break;
910 		case V4L2_PIX_FMT_HEVC:
911 			subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
912 			subscribe_prop_size =
913 				core->iris_platform_data->dec_output_prop_hevc_size;
914 			break;
915 		case V4L2_PIX_FMT_VP9:
916 			subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
917 			subscribe_prop_size =
918 				core->iris_platform_data->dec_output_prop_vp9_size;
919 			break;
920 		}
921 	}
922 
923 	for (i = 0; i < subscribe_prop_size; i++)
924 		payload[i + 1] = subcribe_prop[i];
925 
926 	return iris_hfi_gen2_session_subscribe_mode(inst,
927 						    HFI_CMD_SUBSCRIBE_MODE,
928 						    plane,
929 						    HFI_PAYLOAD_U32_ARRAY,
930 						    &payload[0],
931 						    (subscribe_prop_size + 1) * sizeof(u32));
932 }
933 
iris_hfi_gen2_session_start(struct iris_inst * inst,u32 plane)934 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
935 {
936 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
937 	int ret = 0;
938 
939 	ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
940 	if (ret)
941 		return ret;
942 
943 	ret = iris_hfi_gen2_subscribe_property(inst, plane);
944 	if (ret)
945 		return ret;
946 
947 	iris_hfi_gen2_packet_session_command(inst,
948 					     HFI_CMD_START,
949 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
950 					     HFI_HOST_FLAGS_INTR_REQUIRED),
951 					     iris_hfi_gen2_get_port(inst, plane),
952 					     inst->session_id,
953 					     HFI_PAYLOAD_NONE,
954 					     NULL,
955 					     0);
956 
957 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
958 					inst_hfi_gen2->packet->size);
959 }
960 
iris_hfi_gen2_session_stop(struct iris_inst * inst,u32 plane)961 static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
962 {
963 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
964 	int ret = 0;
965 
966 	reinit_completion(&inst->completion);
967 
968 	iris_hfi_gen2_packet_session_command(inst,
969 					     HFI_CMD_STOP,
970 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
971 					     HFI_HOST_FLAGS_INTR_REQUIRED |
972 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
973 					     iris_hfi_gen2_get_port(inst, plane),
974 					     inst->session_id,
975 					     HFI_PAYLOAD_NONE,
976 					     NULL,
977 					     0);
978 
979 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
980 				       inst_hfi_gen2->packet->size);
981 	if (ret)
982 		return ret;
983 
984 	return iris_wait_for_session_response(inst, false);
985 }
986 
iris_hfi_gen2_session_pause(struct iris_inst * inst,u32 plane)987 static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
988 {
989 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
990 
991 	iris_hfi_gen2_packet_session_command(inst,
992 					     HFI_CMD_PAUSE,
993 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
994 					     HFI_HOST_FLAGS_INTR_REQUIRED),
995 					     iris_hfi_gen2_get_port(inst, plane),
996 					     inst->session_id,
997 					     HFI_PAYLOAD_NONE,
998 					     NULL,
999 					     0);
1000 
1001 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1002 					inst_hfi_gen2->packet->size);
1003 }
1004 
iris_hfi_gen2_session_resume_drc(struct iris_inst * inst,u32 plane)1005 static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
1006 {
1007 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1008 	u32 payload = HFI_CMD_SETTINGS_CHANGE;
1009 
1010 	iris_hfi_gen2_packet_session_command(inst,
1011 					     HFI_CMD_RESUME,
1012 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1013 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1014 					     iris_hfi_gen2_get_port(inst, plane),
1015 					     inst->session_id,
1016 					     HFI_PAYLOAD_U32,
1017 					     &payload,
1018 					     sizeof(u32));
1019 
1020 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1021 					inst_hfi_gen2->packet->size);
1022 }
1023 
iris_hfi_gen2_session_resume_drain(struct iris_inst * inst,u32 plane)1024 static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
1025 {
1026 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1027 	u32 payload = HFI_CMD_DRAIN;
1028 
1029 	iris_hfi_gen2_packet_session_command(inst,
1030 					     HFI_CMD_RESUME,
1031 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1032 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1033 					     iris_hfi_gen2_get_port(inst, plane),
1034 					     inst->session_id,
1035 					     HFI_PAYLOAD_U32,
1036 					     &payload,
1037 					     sizeof(u32));
1038 
1039 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1040 					inst_hfi_gen2->packet->size);
1041 }
1042 
iris_hfi_gen2_session_drain(struct iris_inst * inst,u32 plane)1043 static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
1044 {
1045 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1046 
1047 	if (!V4L2_TYPE_IS_OUTPUT(plane))
1048 		return 0;
1049 
1050 	iris_hfi_gen2_packet_session_command(inst,
1051 					     HFI_CMD_DRAIN,
1052 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1053 					     HFI_HOST_FLAGS_INTR_REQUIRED |
1054 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
1055 					     iris_hfi_gen2_get_port(inst, plane),
1056 					     inst->session_id,
1057 					     HFI_PAYLOAD_NONE,
1058 					     NULL,
1059 					     0);
1060 
1061 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1062 					inst_hfi_gen2->packet->size);
1063 }
1064 
iris_hfi_gen2_buf_type_from_driver(u32 domain,enum iris_buffer_type buffer_type)1065 static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
1066 {
1067 	switch (buffer_type) {
1068 	case BUF_INPUT:
1069 		if (domain == DECODER)
1070 			return HFI_BUFFER_BITSTREAM;
1071 		else
1072 			return HFI_BUFFER_RAW;
1073 	case BUF_OUTPUT:
1074 		if (domain == DECODER)
1075 			return HFI_BUFFER_RAW;
1076 		else
1077 			return HFI_BUFFER_BITSTREAM;
1078 	case BUF_BIN:
1079 		return HFI_BUFFER_BIN;
1080 	case BUF_COMV:
1081 		return HFI_BUFFER_COMV;
1082 	case BUF_NON_COMV:
1083 		return HFI_BUFFER_NON_COMV;
1084 	case BUF_LINE:
1085 		return HFI_BUFFER_LINE;
1086 	case BUF_DPB:
1087 	case BUF_SCRATCH_2:
1088 		return HFI_BUFFER_DPB;
1089 	case BUF_PERSIST:
1090 		return HFI_BUFFER_PERSIST;
1091 	case BUF_ARP:
1092 		return HFI_BUFFER_ARP;
1093 	case BUF_VPSS:
1094 		return HFI_BUFFER_VPSS;
1095 	default:
1096 		return 0;
1097 	}
1098 }
1099 
iris_set_num_comv(struct iris_inst * inst)1100 static int iris_set_num_comv(struct iris_inst *inst)
1101 {
1102 	struct platform_inst_caps *caps;
1103 	struct iris_core *core = inst->core;
1104 	u32 num_comv;
1105 
1106 	caps = core->iris_platform_data->inst_caps;
1107 	num_comv = caps->num_comv;
1108 
1109 	return core->hfi_ops->session_set_property(inst,
1110 						   HFI_PROP_COMV_BUFFER_COUNT,
1111 						   HFI_HOST_FLAGS_NONE,
1112 						   HFI_PORT_BITSTREAM,
1113 						   HFI_PAYLOAD_U32,
1114 						   &num_comv, sizeof(u32));
1115 }
1116 
iris_hfi_gen2_get_buffer(u32 domain,struct iris_buffer * buffer,struct iris_hfi_buffer * buf)1117 static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
1118 				     struct iris_hfi_buffer *buf)
1119 {
1120 	memset(buf, 0, sizeof(*buf));
1121 	buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
1122 	buf->index = buffer->index;
1123 	buf->base_address = buffer->device_addr;
1124 	buf->addr_offset = 0;
1125 	buf->buffer_size = buffer->buffer_size;
1126 
1127 	if (domain == DECODER && buffer->type == BUF_INPUT)
1128 		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
1129 	buf->data_offset = buffer->data_offset;
1130 	buf->data_size = buffer->data_size;
1131 	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
1132 		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
1133 	buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
1134 	buf->timestamp = buffer->timestamp;
1135 }
1136 
iris_hfi_gen2_session_queue_buffer(struct iris_inst * inst,struct iris_buffer * buffer)1137 static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1138 {
1139 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1140 	struct iris_hfi_buffer hfi_buffer;
1141 	u32 port;
1142 	int ret;
1143 
1144 	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1145 	if (buffer->type == BUF_COMV) {
1146 		ret = iris_set_num_comv(inst);
1147 		if (ret)
1148 			return ret;
1149 	}
1150 
1151 	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1152 	iris_hfi_gen2_packet_session_command(inst,
1153 					     HFI_CMD_BUFFER,
1154 					     HFI_HOST_FLAGS_INTR_REQUIRED,
1155 					     port,
1156 					     inst->session_id,
1157 					     HFI_PAYLOAD_STRUCTURE,
1158 					     &hfi_buffer,
1159 					     sizeof(hfi_buffer));
1160 
1161 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1162 					inst_hfi_gen2->packet->size);
1163 }
1164 
iris_hfi_gen2_session_release_buffer(struct iris_inst * inst,struct iris_buffer * buffer)1165 static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1166 {
1167 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1168 	struct iris_hfi_buffer hfi_buffer;
1169 	u32 port;
1170 
1171 	iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1172 	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
1173 	port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1174 
1175 	iris_hfi_gen2_packet_session_command(inst,
1176 					     HFI_CMD_BUFFER,
1177 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1178 					     HFI_HOST_FLAGS_INTR_REQUIRED),
1179 					     port,
1180 					     inst->session_id,
1181 					     HFI_PAYLOAD_STRUCTURE,
1182 					     &hfi_buffer,
1183 					     sizeof(hfi_buffer));
1184 
1185 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1186 					inst_hfi_gen2->packet->size);
1187 }
1188 
1189 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
1190 	.sys_init = iris_hfi_gen2_sys_init,
1191 	.sys_image_version = iris_hfi_gen2_sys_image_version,
1192 	.sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
1193 	.sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
1194 	.session_open = iris_hfi_gen2_session_open,
1195 	.session_set_config_params = iris_hfi_gen2_session_set_config_params,
1196 	.session_set_property = iris_hfi_gen2_session_set_property,
1197 	.session_start = iris_hfi_gen2_session_start,
1198 	.session_queue_buf = iris_hfi_gen2_session_queue_buffer,
1199 	.session_release_buf = iris_hfi_gen2_session_release_buffer,
1200 	.session_pause = iris_hfi_gen2_session_pause,
1201 	.session_resume_drc = iris_hfi_gen2_session_resume_drc,
1202 	.session_stop = iris_hfi_gen2_session_stop,
1203 	.session_drain = iris_hfi_gen2_session_drain,
1204 	.session_resume_drain = iris_hfi_gen2_session_resume_drain,
1205 	.session_close = iris_hfi_gen2_session_close,
1206 };
1207 
iris_hfi_gen2_command_ops_init(struct iris_core * core)1208 void iris_hfi_gen2_command_ops_init(struct iris_core *core)
1209 {
1210 	core->hfi_ops = &iris_hfi_gen2_command_ops;
1211 }
1212 
iris_hfi_gen2_get_instance(void)1213 struct iris_inst *iris_hfi_gen2_get_instance(void)
1214 {
1215 	return (struct iris_inst *)kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL);
1216 }
1217