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(u32 plane)91 static u32 iris_hfi_gen2_get_port(u32 plane)
92 {
93 	switch (plane) {
94 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
95 		return HFI_PORT_BITSTREAM;
96 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
97 		return HFI_PORT_RAW;
98 	default:
99 		return HFI_PORT_NONE;
100 	}
101 }
102 
iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buffer_type)103 static u32 iris_hfi_gen2_get_port_from_buf_type(enum iris_buffer_type buffer_type)
104 {
105 	switch (buffer_type) {
106 	case BUF_INPUT:
107 	case BUF_BIN:
108 	case BUF_COMV:
109 	case BUF_NON_COMV:
110 	case BUF_LINE:
111 		return HFI_PORT_BITSTREAM;
112 	case BUF_OUTPUT:
113 	case BUF_DPB:
114 		return HFI_PORT_RAW;
115 	case BUF_PERSIST:
116 	default:
117 		return HFI_PORT_NONE;
118 	}
119 }
120 
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)121 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
122 					      u32 plane, u32 payload_type, void *payload,
123 					      u32 payload_size)
124 {
125 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
126 
127 	iris_hfi_gen2_packet_session_property(inst,
128 					      packet_type,
129 					      flag,
130 					      plane,
131 					      payload_type,
132 					      payload,
133 					      payload_size);
134 
135 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
136 					inst_hfi_gen2->packet->size);
137 }
138 
iris_hfi_gen2_set_bitstream_resolution(struct iris_inst * inst)139 static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst)
140 {
141 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
142 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
143 	u32 resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
144 		inst->fmt_src->fmt.pix_mp.height;
145 
146 	inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
147 
148 	return iris_hfi_gen2_session_set_property(inst,
149 						  HFI_PROP_BITSTREAM_RESOLUTION,
150 						  HFI_HOST_FLAGS_NONE,
151 						  port,
152 						  HFI_PAYLOAD_U32,
153 						  &resolution,
154 						  sizeof(u32));
155 }
156 
iris_hfi_gen2_set_crop_offsets(struct iris_inst * inst)157 static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst)
158 {
159 	u32 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
160 	u32 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
161 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
162 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
163 	u32 left_offset = inst->crop.left;
164 	u32 top_offset = inst->crop.top;
165 	u32 payload[2];
166 
167 	payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
168 	payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
169 	inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
170 	inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1];
171 
172 	return iris_hfi_gen2_session_set_property(inst,
173 						  HFI_PROP_CROP_OFFSETS,
174 						  HFI_HOST_FLAGS_NONE,
175 						  port,
176 						  HFI_PAYLOAD_64_PACKED,
177 						  &payload,
178 						  sizeof(u64));
179 }
180 
iris_hfi_gen2_set_bit_dpeth(struct iris_inst * inst)181 static int iris_hfi_gen2_set_bit_dpeth(struct iris_inst *inst)
182 {
183 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
184 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
185 	u32 bitdepth = BIT_DEPTH_8;
186 
187 	inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
188 
189 	return iris_hfi_gen2_session_set_property(inst,
190 						  HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
191 						  HFI_HOST_FLAGS_NONE,
192 						  port,
193 						  HFI_PAYLOAD_U32,
194 						  &bitdepth,
195 						  sizeof(u32));
196 }
197 
iris_hfi_gen2_set_coded_frames(struct iris_inst * inst)198 static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst)
199 {
200 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
201 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
202 	u32 coded_frames = 0;
203 
204 	if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
205 		coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
206 	inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames;
207 
208 	return iris_hfi_gen2_session_set_property(inst,
209 						  HFI_PROP_CODED_FRAMES,
210 						  HFI_HOST_FLAGS_NONE,
211 						  port,
212 						  HFI_PAYLOAD_U32,
213 						  &coded_frames,
214 						  sizeof(u32));
215 }
216 
iris_hfi_gen2_set_min_output_count(struct iris_inst * inst)217 static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst)
218 {
219 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
220 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
221 	u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
222 
223 	inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
224 
225 	return iris_hfi_gen2_session_set_property(inst,
226 						  HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
227 						  HFI_HOST_FLAGS_NONE,
228 						  port,
229 						  HFI_PAYLOAD_U32,
230 						  &min_output,
231 						  sizeof(u32));
232 }
233 
iris_hfi_gen2_set_picture_order_count(struct iris_inst * inst)234 static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst)
235 {
236 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
237 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
238 	u32 poc = 0;
239 
240 	inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
241 
242 	return iris_hfi_gen2_session_set_property(inst,
243 						  HFI_PROP_PIC_ORDER_CNT_TYPE,
244 						  HFI_HOST_FLAGS_NONE,
245 						  port,
246 						  HFI_PAYLOAD_U32,
247 						  &poc,
248 						  sizeof(u32));
249 }
250 
iris_hfi_gen2_set_colorspace(struct iris_inst * inst)251 static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst)
252 {
253 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
254 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
255 	struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
256 	u32 video_signal_type_present_flag = 0, color_info;
257 	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
258 	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
259 	u32 full_range = V4L2_QUANTIZATION_DEFAULT;
260 	u32 transfer_char = HFI_TRANSFER_RESERVED;
261 	u32 colour_description_present_flag = 0;
262 	u32 primaries = HFI_PRIMARIES_RESERVED;
263 
264 	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
265 	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
266 	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
267 		colour_description_present_flag = 1;
268 		video_signal_type_present_flag = 1;
269 		primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
270 		matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
271 		transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
272 	}
273 
274 	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
275 		video_signal_type_present_flag = 1;
276 		full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
277 	}
278 
279 	color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
280 						  colour_description_present_flag, full_range,
281 						  video_format, video_signal_type_present_flag);
282 
283 	inst_hfi_gen2->src_subcr_params.color_info = color_info;
284 
285 	return iris_hfi_gen2_session_set_property(inst,
286 						  HFI_PROP_SIGNAL_COLOR_INFO,
287 						  HFI_HOST_FLAGS_NONE,
288 						  port,
289 						  HFI_PAYLOAD_32_PACKED,
290 						  &color_info,
291 						  sizeof(u32));
292 }
293 
iris_hfi_gen2_set_profile(struct iris_inst * inst)294 static int iris_hfi_gen2_set_profile(struct iris_inst *inst)
295 {
296 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
297 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
298 	u32 profile = inst->fw_caps[PROFILE].value;
299 
300 	inst_hfi_gen2->src_subcr_params.profile = profile;
301 
302 	return iris_hfi_gen2_session_set_property(inst,
303 						  HFI_PROP_PROFILE,
304 						  HFI_HOST_FLAGS_NONE,
305 						  port,
306 						  HFI_PAYLOAD_U32_ENUM,
307 						  &profile,
308 						  sizeof(u32));
309 }
310 
iris_hfi_gen2_set_level(struct iris_inst * inst)311 static int iris_hfi_gen2_set_level(struct iris_inst *inst)
312 {
313 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
314 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
315 	u32 level = inst->fw_caps[LEVEL].value;
316 
317 	inst_hfi_gen2->src_subcr_params.level = level;
318 
319 	return iris_hfi_gen2_session_set_property(inst,
320 						  HFI_PROP_LEVEL,
321 						  HFI_HOST_FLAGS_NONE,
322 						  port,
323 						  HFI_PAYLOAD_U32_ENUM,
324 						  &level,
325 						  sizeof(u32));
326 }
327 
iris_hfi_gen2_set_colorformat(struct iris_inst * inst)328 static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst)
329 {
330 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
331 	u32 hfi_colorformat, pixelformat;
332 
333 	pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
334 	hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
335 
336 	return iris_hfi_gen2_session_set_property(inst,
337 						  HFI_PROP_COLOR_FORMAT,
338 						  HFI_HOST_FLAGS_NONE,
339 						  port,
340 						  HFI_PAYLOAD_U32,
341 						  &hfi_colorformat,
342 						  sizeof(u32));
343 }
344 
iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst * inst)345 static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
346 {
347 	u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
348 	u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
349 	u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height;
350 	u32 stride_y = inst->fmt_dst->fmt.pix_mp.width;
351 	u32 scanline_uv = scanline_y / 2;
352 	u32 stride_uv = stride_y;
353 	u32 payload[2];
354 
355 	if (pixelformat != V4L2_PIX_FMT_NV12)
356 		return 0;
357 
358 	payload[0] = stride_y << 16 | scanline_y;
359 	payload[1] = stride_uv << 16 | scanline_uv;
360 
361 	return iris_hfi_gen2_session_set_property(inst,
362 						  HFI_PROP_LINEAR_STRIDE_SCANLINE,
363 						  HFI_HOST_FLAGS_NONE,
364 						  port,
365 						  HFI_PAYLOAD_U64,
366 						  &payload,
367 						  sizeof(u64));
368 }
369 
iris_hfi_gen2_session_set_config_params(struct iris_inst * inst,u32 plane)370 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
371 {
372 	struct iris_core *core = inst->core;
373 	u32 config_params_size, i, j;
374 	const u32 *config_params;
375 	int ret;
376 
377 	static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
378 		{HFI_PROP_BITSTREAM_RESOLUTION,       iris_hfi_gen2_set_bitstream_resolution   },
379 		{HFI_PROP_CROP_OFFSETS,               iris_hfi_gen2_set_crop_offsets           },
380 		{HFI_PROP_CODED_FRAMES,               iris_hfi_gen2_set_coded_frames           },
381 		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,      iris_hfi_gen2_set_bit_dpeth              },
382 		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count       },
383 		{HFI_PROP_PIC_ORDER_CNT_TYPE,         iris_hfi_gen2_set_picture_order_count    },
384 		{HFI_PROP_SIGNAL_COLOR_INFO,          iris_hfi_gen2_set_colorspace             },
385 		{HFI_PROP_PROFILE,                    iris_hfi_gen2_set_profile                },
386 		{HFI_PROP_LEVEL,                      iris_hfi_gen2_set_level                  },
387 		{HFI_PROP_COLOR_FORMAT,               iris_hfi_gen2_set_colorformat            },
388 		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     iris_hfi_gen2_set_linear_stride_scanline },
389 	};
390 
391 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
392 		config_params = core->iris_platform_data->input_config_params;
393 		config_params_size = core->iris_platform_data->input_config_params_size;
394 	} else {
395 		config_params = core->iris_platform_data->output_config_params;
396 		config_params_size = core->iris_platform_data->output_config_params_size;
397 	}
398 
399 	if (!config_params || !config_params_size)
400 		return -EINVAL;
401 
402 	for (i = 0; i < config_params_size; i++) {
403 		for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
404 			if (prop_type_handle_arr[j].type == config_params[i]) {
405 				ret = prop_type_handle_arr[j].handle(inst);
406 				if (ret)
407 					return ret;
408 				break;
409 			}
410 		}
411 	}
412 
413 	return 0;
414 }
415 
iris_hfi_gen2_session_set_codec(struct iris_inst * inst)416 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
417 {
418 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
419 	u32 codec = HFI_CODEC_DECODE_AVC;
420 
421 	iris_hfi_gen2_packet_session_property(inst,
422 					      HFI_PROP_CODEC,
423 					      HFI_HOST_FLAGS_NONE,
424 					      HFI_PORT_NONE,
425 					      HFI_PAYLOAD_U32_ENUM,
426 					      &codec,
427 					      sizeof(u32));
428 
429 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
430 					inst_hfi_gen2->packet->size);
431 }
432 
iris_hfi_gen2_session_set_default_header(struct iris_inst * inst)433 static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
434 {
435 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
436 	u32 default_header = false;
437 
438 	iris_hfi_gen2_packet_session_property(inst,
439 					      HFI_PROP_DEC_DEFAULT_HEADER,
440 					      HFI_HOST_FLAGS_NONE,
441 					      HFI_PORT_BITSTREAM,
442 					      HFI_PAYLOAD_U32,
443 					      &default_header,
444 					      sizeof(u32));
445 
446 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
447 					inst_hfi_gen2->packet->size);
448 }
449 
iris_hfi_gen2_session_open(struct iris_inst * inst)450 static int iris_hfi_gen2_session_open(struct iris_inst *inst)
451 {
452 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
453 	int ret;
454 
455 	if (inst->state != IRIS_INST_DEINIT)
456 		return -EALREADY;
457 
458 	inst_hfi_gen2->ipsc_properties_set = false;
459 	inst_hfi_gen2->opsc_properties_set = false;
460 
461 	inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
462 	if (!inst_hfi_gen2->packet)
463 		return -ENOMEM;
464 
465 	iris_hfi_gen2_packet_session_command(inst,
466 					     HFI_CMD_OPEN,
467 					     HFI_HOST_FLAGS_RESPONSE_REQUIRED |
468 					     HFI_HOST_FLAGS_INTR_REQUIRED,
469 					     HFI_PORT_NONE,
470 					     0,
471 					     HFI_PAYLOAD_U32,
472 					     &inst->session_id,
473 					     sizeof(u32));
474 
475 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
476 				       inst_hfi_gen2->packet->size);
477 	if (ret)
478 		goto fail_free_packet;
479 
480 	ret = iris_hfi_gen2_session_set_codec(inst);
481 	if (ret)
482 		goto fail_free_packet;
483 
484 	ret = iris_hfi_gen2_session_set_default_header(inst);
485 	if (ret)
486 		goto fail_free_packet;
487 
488 	return 0;
489 
490 fail_free_packet:
491 	kfree(inst_hfi_gen2->packet);
492 	inst_hfi_gen2->packet = NULL;
493 
494 	return ret;
495 }
496 
iris_hfi_gen2_session_close(struct iris_inst * inst)497 static int iris_hfi_gen2_session_close(struct iris_inst *inst)
498 {
499 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
500 	int ret;
501 
502 	if (!inst_hfi_gen2->packet)
503 		return -EINVAL;
504 
505 	iris_hfi_gen2_packet_session_command(inst,
506 					     HFI_CMD_CLOSE,
507 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
508 					     HFI_HOST_FLAGS_INTR_REQUIRED |
509 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
510 					     HFI_PORT_NONE,
511 					     inst->session_id,
512 					     HFI_PAYLOAD_NONE,
513 					     NULL,
514 					     0);
515 
516 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
517 				       inst_hfi_gen2->packet->size);
518 
519 	kfree(inst_hfi_gen2->packet);
520 	inst_hfi_gen2->packet = NULL;
521 
522 	return ret;
523 }
524 
iris_hfi_gen2_session_subscribe_mode(struct iris_inst * inst,u32 cmd,u32 plane,u32 payload_type,void * payload,u32 payload_size)525 static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
526 						u32 cmd, u32 plane, u32 payload_type,
527 						void *payload, u32 payload_size)
528 {
529 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
530 
531 	iris_hfi_gen2_packet_session_command(inst,
532 					     cmd,
533 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
534 					     HFI_HOST_FLAGS_INTR_REQUIRED),
535 					     iris_hfi_gen2_get_port(plane),
536 					     inst->session_id,
537 					     payload_type,
538 					     payload,
539 					     payload_size);
540 
541 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
542 					inst_hfi_gen2->packet->size);
543 }
544 
iris_hfi_gen2_subscribe_change_param(struct iris_inst * inst,u32 plane)545 static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
546 {
547 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
548 	struct hfi_subscription_params subsc_params;
549 	u32 prop_type, payload_size, payload_type;
550 	struct iris_core *core = inst->core;
551 	const u32 *change_param;
552 	u32 change_param_size;
553 	u32 payload[32] = {0};
554 	u32 hfi_port = 0, i;
555 	int ret;
556 
557 	if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
558 	    (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
559 		dev_err(core->dev, "invalid plane\n");
560 		return 0;
561 	}
562 
563 	change_param = core->iris_platform_data->input_config_params;
564 	change_param_size = core->iris_platform_data->input_config_params_size;
565 
566 	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
567 
568 	for (i = 0; i < change_param_size; i++)
569 		payload[i + 1] = change_param[i];
570 
571 	ret = iris_hfi_gen2_session_subscribe_mode(inst,
572 						   HFI_CMD_SUBSCRIBE_MODE,
573 						   plane,
574 						   HFI_PAYLOAD_U32_ARRAY,
575 						   &payload[0],
576 						   ((change_param_size + 1) * sizeof(u32)));
577 	if (ret)
578 		return ret;
579 
580 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
581 		inst_hfi_gen2->ipsc_properties_set = true;
582 	} else {
583 		hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
584 		memcpy(&inst_hfi_gen2->dst_subcr_params,
585 		       &inst_hfi_gen2->src_subcr_params,
586 		       sizeof(inst_hfi_gen2->src_subcr_params));
587 		subsc_params = inst_hfi_gen2->dst_subcr_params;
588 		for (i = 0; i < change_param_size; i++) {
589 			payload[0] = 0;
590 			payload[1] = 0;
591 			payload_size = 0;
592 			payload_type = 0;
593 			prop_type = change_param[i];
594 			switch (prop_type) {
595 			case HFI_PROP_BITSTREAM_RESOLUTION:
596 				payload[0] = subsc_params.bitstream_resolution;
597 				payload_size = sizeof(u32);
598 				payload_type = HFI_PAYLOAD_U32;
599 				break;
600 			case HFI_PROP_CROP_OFFSETS:
601 				payload[0] = subsc_params.crop_offsets[0];
602 				payload[1] = subsc_params.crop_offsets[1];
603 				payload_size = sizeof(u64);
604 				payload_type = HFI_PAYLOAD_64_PACKED;
605 				break;
606 			case HFI_PROP_CODED_FRAMES:
607 				payload[0] = subsc_params.coded_frames;
608 				payload_size = sizeof(u32);
609 				payload_type = HFI_PAYLOAD_U32;
610 				break;
611 			case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
612 				payload[0] = subsc_params.fw_min_count;
613 				payload_size = sizeof(u32);
614 				payload_type = HFI_PAYLOAD_U32;
615 				break;
616 			case HFI_PROP_PIC_ORDER_CNT_TYPE:
617 				payload[0] = subsc_params.pic_order_cnt;
618 				payload_size = sizeof(u32);
619 				payload_type = HFI_PAYLOAD_U32;
620 				break;
621 			case HFI_PROP_SIGNAL_COLOR_INFO:
622 				payload[0] = subsc_params.color_info;
623 				payload_size = sizeof(u32);
624 				payload_type = HFI_PAYLOAD_U32;
625 				break;
626 			case HFI_PROP_PROFILE:
627 				payload[0] = subsc_params.profile;
628 				payload_size = sizeof(u32);
629 				payload_type = HFI_PAYLOAD_U32;
630 				break;
631 			case HFI_PROP_LEVEL:
632 				payload[0] = subsc_params.level;
633 				payload_size = sizeof(u32);
634 				payload_type = HFI_PAYLOAD_U32;
635 				break;
636 			default:
637 				prop_type = 0;
638 				ret = -EINVAL;
639 				break;
640 			}
641 			if (prop_type) {
642 				ret = iris_hfi_gen2_session_set_property(inst,
643 									 prop_type,
644 									 HFI_HOST_FLAGS_NONE,
645 									 hfi_port,
646 									 payload_type,
647 									 &payload,
648 									 payload_size);
649 				if (ret)
650 					return ret;
651 			}
652 		}
653 		inst_hfi_gen2->opsc_properties_set = true;
654 	}
655 
656 	return 0;
657 }
658 
iris_hfi_gen2_subscribe_property(struct iris_inst * inst,u32 plane)659 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
660 {
661 	struct iris_core *core = inst->core;
662 	u32 subscribe_prop_size, i;
663 	const u32 *subcribe_prop;
664 	u32 payload[32] = {0};
665 
666 	payload[0] = HFI_MODE_PROPERTY;
667 
668 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
669 		subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
670 		subcribe_prop = core->iris_platform_data->dec_input_prop;
671 	} else {
672 		subscribe_prop_size = core->iris_platform_data->dec_output_prop_size;
673 		subcribe_prop = core->iris_platform_data->dec_output_prop;
674 	}
675 
676 	for (i = 0; i < subscribe_prop_size; i++)
677 		payload[i + 1] = subcribe_prop[i];
678 
679 	return iris_hfi_gen2_session_subscribe_mode(inst,
680 						    HFI_CMD_SUBSCRIBE_MODE,
681 						    plane,
682 						    HFI_PAYLOAD_U32_ARRAY,
683 						    &payload[0],
684 						    (subscribe_prop_size + 1) * sizeof(u32));
685 }
686 
iris_hfi_gen2_session_start(struct iris_inst * inst,u32 plane)687 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
688 {
689 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
690 	int ret = 0;
691 
692 	ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
693 	if (ret)
694 		return ret;
695 
696 	ret = iris_hfi_gen2_subscribe_property(inst, plane);
697 	if (ret)
698 		return ret;
699 
700 	iris_hfi_gen2_packet_session_command(inst,
701 					     HFI_CMD_START,
702 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
703 					     HFI_HOST_FLAGS_INTR_REQUIRED),
704 					     iris_hfi_gen2_get_port(plane),
705 					     inst->session_id,
706 					     HFI_PAYLOAD_NONE,
707 					     NULL,
708 					     0);
709 
710 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
711 					inst_hfi_gen2->packet->size);
712 }
713 
iris_hfi_gen2_session_stop(struct iris_inst * inst,u32 plane)714 static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
715 {
716 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
717 	int ret = 0;
718 
719 	reinit_completion(&inst->completion);
720 
721 	iris_hfi_gen2_packet_session_command(inst,
722 					     HFI_CMD_STOP,
723 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
724 					     HFI_HOST_FLAGS_INTR_REQUIRED |
725 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
726 					     iris_hfi_gen2_get_port(plane),
727 					     inst->session_id,
728 					     HFI_PAYLOAD_NONE,
729 					     NULL,
730 					     0);
731 
732 	ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
733 				       inst_hfi_gen2->packet->size);
734 	if (ret)
735 		return ret;
736 
737 	return iris_wait_for_session_response(inst, false);
738 }
739 
iris_hfi_gen2_session_pause(struct iris_inst * inst,u32 plane)740 static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
741 {
742 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
743 
744 	iris_hfi_gen2_packet_session_command(inst,
745 					     HFI_CMD_PAUSE,
746 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
747 					     HFI_HOST_FLAGS_INTR_REQUIRED),
748 					     iris_hfi_gen2_get_port(plane),
749 					     inst->session_id,
750 					     HFI_PAYLOAD_NONE,
751 					     NULL,
752 					     0);
753 
754 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
755 					inst_hfi_gen2->packet->size);
756 }
757 
iris_hfi_gen2_session_resume_drc(struct iris_inst * inst,u32 plane)758 static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
759 {
760 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
761 	u32 payload = HFI_CMD_SETTINGS_CHANGE;
762 
763 	iris_hfi_gen2_packet_session_command(inst,
764 					     HFI_CMD_RESUME,
765 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
766 					     HFI_HOST_FLAGS_INTR_REQUIRED),
767 					     iris_hfi_gen2_get_port(plane),
768 					     inst->session_id,
769 					     HFI_PAYLOAD_U32,
770 					     &payload,
771 					     sizeof(u32));
772 
773 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
774 					inst_hfi_gen2->packet->size);
775 }
776 
iris_hfi_gen2_session_resume_drain(struct iris_inst * inst,u32 plane)777 static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
778 {
779 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
780 	u32 payload = HFI_CMD_DRAIN;
781 
782 	iris_hfi_gen2_packet_session_command(inst,
783 					     HFI_CMD_RESUME,
784 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
785 					     HFI_HOST_FLAGS_INTR_REQUIRED),
786 					     iris_hfi_gen2_get_port(plane),
787 					     inst->session_id,
788 					     HFI_PAYLOAD_U32,
789 					     &payload,
790 					     sizeof(u32));
791 
792 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
793 					inst_hfi_gen2->packet->size);
794 }
795 
iris_hfi_gen2_session_drain(struct iris_inst * inst,u32 plane)796 static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
797 {
798 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
799 
800 	if (!V4L2_TYPE_IS_OUTPUT(plane))
801 		return 0;
802 
803 	iris_hfi_gen2_packet_session_command(inst,
804 					     HFI_CMD_DRAIN,
805 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
806 					     HFI_HOST_FLAGS_INTR_REQUIRED |
807 					     HFI_HOST_FLAGS_NON_DISCARDABLE),
808 					     iris_hfi_gen2_get_port(plane),
809 					     inst->session_id,
810 					     HFI_PAYLOAD_NONE,
811 					     NULL,
812 					     0);
813 
814 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
815 					inst_hfi_gen2->packet->size);
816 }
817 
iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)818 static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
819 {
820 	switch (buffer_type) {
821 	case BUF_INPUT:
822 		return HFI_BUFFER_BITSTREAM;
823 	case BUF_OUTPUT:
824 		return HFI_BUFFER_RAW;
825 	case BUF_BIN:
826 		return HFI_BUFFER_BIN;
827 	case BUF_COMV:
828 		return HFI_BUFFER_COMV;
829 	case BUF_NON_COMV:
830 		return HFI_BUFFER_NON_COMV;
831 	case BUF_LINE:
832 		return HFI_BUFFER_LINE;
833 	case BUF_DPB:
834 		return HFI_BUFFER_DPB;
835 	case BUF_PERSIST:
836 		return HFI_BUFFER_PERSIST;
837 	default:
838 		return 0;
839 	}
840 }
841 
iris_set_num_comv(struct iris_inst * inst)842 static int iris_set_num_comv(struct iris_inst *inst)
843 {
844 	struct platform_inst_caps *caps;
845 	struct iris_core *core = inst->core;
846 	u32 num_comv;
847 
848 	caps = core->iris_platform_data->inst_caps;
849 	num_comv = caps->num_comv;
850 
851 	return core->hfi_ops->session_set_property(inst,
852 						   HFI_PROP_COMV_BUFFER_COUNT,
853 						   HFI_HOST_FLAGS_NONE,
854 						   HFI_PORT_BITSTREAM,
855 						   HFI_PAYLOAD_U32,
856 						   &num_comv, sizeof(u32));
857 }
858 
iris_hfi_gen2_get_buffer(struct iris_buffer * buffer,struct iris_hfi_buffer * buf)859 static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf)
860 {
861 	memset(buf, 0, sizeof(*buf));
862 	buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type);
863 	buf->index = buffer->index;
864 	buf->base_address = buffer->device_addr;
865 	buf->addr_offset = 0;
866 	buf->buffer_size = buffer->buffer_size;
867 
868 	if (buffer->type == BUF_INPUT)
869 		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
870 	buf->data_offset = buffer->data_offset;
871 	buf->data_size = buffer->data_size;
872 	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
873 		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
874 	buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
875 	buf->timestamp = buffer->timestamp;
876 }
877 
iris_hfi_gen2_session_queue_buffer(struct iris_inst * inst,struct iris_buffer * buffer)878 static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
879 {
880 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
881 	struct iris_hfi_buffer hfi_buffer;
882 	u32 port;
883 	int ret;
884 
885 	iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
886 	if (buffer->type == BUF_COMV) {
887 		ret = iris_set_num_comv(inst);
888 		if (ret)
889 			return ret;
890 	}
891 
892 	port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
893 	iris_hfi_gen2_packet_session_command(inst,
894 					     HFI_CMD_BUFFER,
895 					     HFI_HOST_FLAGS_INTR_REQUIRED,
896 					     port,
897 					     inst->session_id,
898 					     HFI_PAYLOAD_STRUCTURE,
899 					     &hfi_buffer,
900 					     sizeof(hfi_buffer));
901 
902 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
903 					inst_hfi_gen2->packet->size);
904 }
905 
iris_hfi_gen2_session_release_buffer(struct iris_inst * inst,struct iris_buffer * buffer)906 static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
907 {
908 	struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
909 	struct iris_hfi_buffer hfi_buffer;
910 	u32 port;
911 
912 	iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
913 	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
914 	port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
915 
916 	iris_hfi_gen2_packet_session_command(inst,
917 					     HFI_CMD_BUFFER,
918 					     (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
919 					     HFI_HOST_FLAGS_INTR_REQUIRED),
920 					     port,
921 					     inst->session_id,
922 					     HFI_PAYLOAD_STRUCTURE,
923 					     &hfi_buffer,
924 					     sizeof(hfi_buffer));
925 
926 	return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
927 					inst_hfi_gen2->packet->size);
928 }
929 
930 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
931 	.sys_init = iris_hfi_gen2_sys_init,
932 	.sys_image_version = iris_hfi_gen2_sys_image_version,
933 	.sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
934 	.sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
935 	.session_open = iris_hfi_gen2_session_open,
936 	.session_set_config_params = iris_hfi_gen2_session_set_config_params,
937 	.session_set_property = iris_hfi_gen2_session_set_property,
938 	.session_start = iris_hfi_gen2_session_start,
939 	.session_queue_buf = iris_hfi_gen2_session_queue_buffer,
940 	.session_release_buf = iris_hfi_gen2_session_release_buffer,
941 	.session_pause = iris_hfi_gen2_session_pause,
942 	.session_resume_drc = iris_hfi_gen2_session_resume_drc,
943 	.session_stop = iris_hfi_gen2_session_stop,
944 	.session_drain = iris_hfi_gen2_session_drain,
945 	.session_resume_drain = iris_hfi_gen2_session_resume_drain,
946 	.session_close = iris_hfi_gen2_session_close,
947 };
948 
iris_hfi_gen2_command_ops_init(struct iris_core * core)949 void iris_hfi_gen2_command_ops_init(struct iris_core *core)
950 {
951 	core->hfi_ops = &iris_hfi_gen2_command_ops;
952 }
953 
iris_hfi_gen2_get_instance(void)954 struct iris_inst *iris_hfi_gen2_get_instance(void)
955 {
956 	return kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL);
957 }
958