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 "iris_hfi_gen1.h"
7 #include "iris_hfi_gen1_defines.h"
8 #include "iris_instance.h"
9 #include "iris_vpu_buffer.h"
10 
iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type)11 static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type)
12 {
13 	switch (buffer_type) {
14 	case BUF_INPUT:
15 		return HFI_BUFFER_INPUT;
16 	case BUF_OUTPUT:
17 		return HFI_BUFFER_OUTPUT;
18 	case BUF_PERSIST:
19 		return HFI_BUFFER_INTERNAL_PERSIST_1;
20 	case BUF_BIN:
21 		return HFI_BUFFER_INTERNAL_SCRATCH;
22 	case BUF_SCRATCH_1:
23 		return HFI_BUFFER_INTERNAL_SCRATCH_1;
24 	default:
25 		return -EINVAL;
26 	}
27 }
28 
iris_hfi_gen1_sys_init(struct iris_core * core)29 static int iris_hfi_gen1_sys_init(struct iris_core *core)
30 {
31 	struct hfi_sys_init_pkt sys_init_pkt;
32 
33 	sys_init_pkt.hdr.size = sizeof(sys_init_pkt);
34 	sys_init_pkt.hdr.pkt_type = HFI_CMD_SYS_INIT;
35 	sys_init_pkt.arch_type = HFI_VIDEO_ARCH_OX;
36 
37 	return iris_hfi_queue_cmd_write_locked(core, &sys_init_pkt, sys_init_pkt.hdr.size);
38 }
39 
iris_hfi_gen1_sys_image_version(struct iris_core * core)40 static int iris_hfi_gen1_sys_image_version(struct iris_core *core)
41 {
42 	struct hfi_sys_get_property_pkt packet;
43 
44 	packet.hdr.size = sizeof(packet);
45 	packet.hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY;
46 	packet.num_properties = 1;
47 	packet.data = HFI_PROPERTY_SYS_IMAGE_VERSION;
48 
49 	return iris_hfi_queue_cmd_write_locked(core, &packet, packet.hdr.size);
50 }
51 
iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core * core)52 static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *core)
53 {
54 	struct hfi_sys_set_property_pkt *pkt;
55 	struct hfi_enable *hfi;
56 	u32 packet_size;
57 	int ret;
58 
59 	packet_size = struct_size(pkt, data, 1) + sizeof(*hfi);
60 	pkt = kzalloc(packet_size, GFP_KERNEL);
61 	if (!pkt)
62 		return -ENOMEM;
63 
64 	hfi = (struct hfi_enable *)&pkt->data[1];
65 
66 	pkt->hdr.size = packet_size;
67 	pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
68 	pkt->num_properties = 1;
69 	pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL;
70 	hfi->enable = true;
71 
72 	ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt->hdr.size);
73 	kfree(pkt);
74 
75 	return ret;
76 }
77 
iris_hfi_gen1_sys_pc_prep(struct iris_core * core)78 static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core)
79 {
80 	struct hfi_sys_pc_prep_pkt pkt;
81 
82 	pkt.hdr.size = sizeof(struct hfi_sys_pc_prep_pkt);
83 	pkt.hdr.pkt_type = HFI_CMD_SYS_PC_PREP;
84 
85 	return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size);
86 }
87 
iris_hfi_gen1_session_open(struct iris_inst * inst)88 static int iris_hfi_gen1_session_open(struct iris_inst *inst)
89 {
90 	struct hfi_session_open_pkt packet;
91 	int ret;
92 
93 	if (inst->state != IRIS_INST_DEINIT)
94 		return -EALREADY;
95 
96 	packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt);
97 	packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT;
98 	packet.shdr.session_id = inst->session_id;
99 	packet.session_domain = HFI_SESSION_TYPE_DEC;
100 	packet.session_codec = HFI_VIDEO_CODEC_H264;
101 
102 	reinit_completion(&inst->completion);
103 
104 	ret = iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size);
105 	if (ret)
106 		return ret;
107 
108 	return iris_wait_for_session_response(inst, false);
109 }
110 
iris_hfi_gen1_packet_session_cmd(struct iris_inst * inst,struct hfi_session_pkt * packet,u32 ptype)111 static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst,
112 					     struct hfi_session_pkt *packet,
113 					     u32 ptype)
114 {
115 	packet->shdr.hdr.size = sizeof(*packet);
116 	packet->shdr.hdr.pkt_type = ptype;
117 	packet->shdr.session_id = inst->session_id;
118 }
119 
iris_hfi_gen1_session_close(struct iris_inst * inst)120 static int iris_hfi_gen1_session_close(struct iris_inst *inst)
121 {
122 	struct hfi_session_pkt packet;
123 
124 	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SYS_SESSION_END);
125 
126 	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size);
127 }
128 
iris_hfi_gen1_session_start(struct iris_inst * inst,u32 plane)129 static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane)
130 {
131 	struct iris_core *core = inst->core;
132 	struct hfi_session_pkt packet;
133 	int ret;
134 
135 	if (!V4L2_TYPE_IS_OUTPUT(plane))
136 		return 0;
137 
138 	if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES)
139 		return 0;
140 
141 	reinit_completion(&inst->completion);
142 	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESOURCES);
143 
144 	ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size);
145 	if (ret)
146 		return ret;
147 
148 	ret = iris_wait_for_session_response(inst, false);
149 	if (ret)
150 		return ret;
151 
152 	reinit_completion(&inst->completion);
153 	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_START);
154 
155 	ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size);
156 	if (ret)
157 		return ret;
158 
159 	ret = iris_wait_for_session_response(inst, false);
160 	if (ret)
161 		return ret;
162 
163 	return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_LOAD_RESOURCES);
164 }
165 
iris_hfi_gen1_session_stop(struct iris_inst * inst,u32 plane)166 static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane)
167 {
168 	struct hfi_session_flush_pkt flush_pkt;
169 	struct iris_core *core = inst->core;
170 	struct hfi_session_pkt pkt;
171 	u32 flush_type = 0;
172 	int ret = 0;
173 
174 	if ((V4L2_TYPE_IS_OUTPUT(plane) &&
175 	     inst->state == IRIS_INST_INPUT_STREAMING) ||
176 	    (V4L2_TYPE_IS_CAPTURE(plane) &&
177 	     inst->state == IRIS_INST_OUTPUT_STREAMING) ||
178 	    inst->state == IRIS_INST_ERROR) {
179 		reinit_completion(&inst->completion);
180 		iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP);
181 		ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
182 		if (!ret)
183 			ret = iris_wait_for_session_response(inst, false);
184 
185 		reinit_completion(&inst->completion);
186 		iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES);
187 		ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size);
188 		if (!ret)
189 			ret = iris_wait_for_session_response(inst, false);
190 
191 		iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0);
192 
193 		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
194 					 VB2_BUF_STATE_ERROR);
195 		iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
196 					 VB2_BUF_STATE_ERROR);
197 	} else if (inst->state == IRIS_INST_STREAMING) {
198 		if (V4L2_TYPE_IS_OUTPUT(plane))
199 			flush_type = HFI_FLUSH_ALL;
200 		else if (V4L2_TYPE_IS_CAPTURE(plane))
201 			flush_type = HFI_FLUSH_OUTPUT;
202 
203 		reinit_completion(&inst->flush_completion);
204 
205 		flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt);
206 		flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH;
207 		flush_pkt.shdr.session_id = inst->session_id;
208 		flush_pkt.flush_type = flush_type;
209 
210 		ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size);
211 		if (!ret)
212 			ret = iris_wait_for_session_response(inst, true);
213 	}
214 
215 	return ret;
216 }
217 
iris_hfi_gen1_session_continue(struct iris_inst * inst,u32 plane)218 static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane)
219 {
220 	struct hfi_session_pkt packet;
221 
222 	iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE);
223 
224 	return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size);
225 }
226 
iris_hfi_gen1_queue_input_buffer(struct iris_inst * inst,struct iris_buffer * buf)227 static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf)
228 {
229 	struct hfi_session_empty_buffer_compressed_pkt ip_pkt;
230 
231 	ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
232 	ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
233 	ip_pkt.shdr.session_id = inst->session_id;
234 	ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp);
235 	ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp);
236 	ip_pkt.flags = buf->flags;
237 	ip_pkt.mark_target = 0;
238 	ip_pkt.mark_data = 0;
239 	ip_pkt.offset = buf->data_offset;
240 	ip_pkt.alloc_len = buf->buffer_size;
241 	ip_pkt.filled_len = buf->data_size;
242 	ip_pkt.input_tag = buf->index;
243 	ip_pkt.packet_buffer = buf->device_addr;
244 
245 	return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
246 }
247 
iris_hfi_gen1_queue_output_buffer(struct iris_inst * inst,struct iris_buffer * buf)248 static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf)
249 {
250 	struct hfi_session_fill_buffer_pkt op_pkt;
251 
252 	op_pkt.shdr.hdr.size = sizeof(struct hfi_session_fill_buffer_pkt);
253 	op_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FILL_BUFFER;
254 	op_pkt.shdr.session_id = inst->session_id;
255 	op_pkt.output_tag = buf->index;
256 	op_pkt.packet_buffer = buf->device_addr;
257 	op_pkt.extradata_buffer = 0;
258 	op_pkt.alloc_len = buf->buffer_size;
259 	op_pkt.filled_len = buf->data_size;
260 	op_pkt.offset = buf->data_offset;
261 	op_pkt.data = 0;
262 
263 	if (buf->type == BUF_OUTPUT && iris_split_mode_enabled(inst))
264 		op_pkt.stream_id = 1;
265 	else
266 		op_pkt.stream_id = 0;
267 
268 	return iris_hfi_queue_cmd_write(inst->core, &op_pkt, op_pkt.shdr.hdr.size);
269 }
270 
iris_hfi_gen1_queue_internal_buffer(struct iris_inst * inst,struct iris_buffer * buf)271 static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf)
272 {
273 	struct hfi_session_set_buffers_pkt *int_pkt;
274 	u32 buffer_type, i;
275 	u32 packet_size;
276 	int ret;
277 
278 	packet_size = struct_size(int_pkt, buffer_info, 1);
279 	int_pkt = kzalloc(packet_size, GFP_KERNEL);
280 	if (!int_pkt)
281 		return -ENOMEM;
282 
283 	int_pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS;
284 	int_pkt->shdr.session_id = inst->session_id;
285 	int_pkt->buffer_size = buf->buffer_size;
286 	int_pkt->min_buffer_size = buf->buffer_size;
287 	int_pkt->num_buffers = 1;
288 	int_pkt->extradata_size = 0;
289 	int_pkt->shdr.hdr.size = packet_size;
290 	for (i = 0; i < int_pkt->num_buffers; i++)
291 		int_pkt->buffer_info[i] = buf->device_addr;
292 	buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type);
293 	if (buffer_type == -EINVAL) {
294 		ret = -EINVAL;
295 		goto exit;
296 	}
297 
298 	int_pkt->buffer_type = buffer_type;
299 	ret = iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.size);
300 
301 exit:
302 	kfree(int_pkt);
303 
304 	return ret;
305 }
306 
iris_hfi_gen1_session_queue_buffer(struct iris_inst * inst,struct iris_buffer * buf)307 static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
308 {
309 	switch (buf->type) {
310 	case BUF_INPUT:
311 		return iris_hfi_gen1_queue_input_buffer(inst, buf);
312 	case BUF_OUTPUT:
313 	case BUF_DPB:
314 		return iris_hfi_gen1_queue_output_buffer(inst, buf);
315 	case BUF_PERSIST:
316 	case BUF_BIN:
317 	case BUF_SCRATCH_1:
318 		return iris_hfi_gen1_queue_internal_buffer(inst, buf);
319 	default:
320 		return -EINVAL;
321 	}
322 }
323 
iris_hfi_gen1_session_unset_buffers(struct iris_inst * inst,struct iris_buffer * buf)324 static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct iris_buffer *buf)
325 {
326 	struct hfi_session_release_buffer_pkt *pkt;
327 	u32 packet_size, buffer_type, i;
328 	int ret;
329 
330 	buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type);
331 	if (buffer_type == -EINVAL)
332 		return -EINVAL;
333 
334 	if (buffer_type == HFI_BUFFER_INPUT)
335 		return 0;
336 
337 	packet_size = sizeof(*pkt) + sizeof(struct hfi_buffer_info);
338 	pkt = kzalloc(packet_size, GFP_KERNEL);
339 	if (!pkt)
340 		return -ENOMEM;
341 
342 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS;
343 	pkt->shdr.session_id = inst->session_id;
344 	pkt->buffer_size = buf->buffer_size;
345 	pkt->num_buffers = 1;
346 
347 	if (buffer_type == HFI_BUFFER_OUTPUT ||
348 	    buffer_type == HFI_BUFFER_OUTPUT2) {
349 		struct hfi_buffer_info *bi;
350 
351 		bi = (struct hfi_buffer_info *)pkt->buffer_info;
352 		for (i = 0; i < pkt->num_buffers; i++) {
353 			bi->buffer_addr = buf->device_addr;
354 			bi->extradata_addr = 0;
355 		}
356 		pkt->shdr.hdr.size = packet_size;
357 	} else {
358 		for (i = 0; i < pkt->num_buffers; i++)
359 			pkt->buffer_info[i] = buf->device_addr;
360 		pkt->extradata_size = 0;
361 		pkt->shdr.hdr.size =
362 				sizeof(struct hfi_session_set_buffers_pkt) +
363 				((pkt->num_buffers) * sizeof(u32));
364 	}
365 
366 	pkt->response_req = true;
367 	pkt->buffer_type = buffer_type;
368 
369 	ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size);
370 	if (ret)
371 		goto exit;
372 
373 	ret = iris_wait_for_session_response(inst, false);
374 
375 exit:
376 	kfree(pkt);
377 
378 	return ret;
379 }
380 
iris_hfi_gen1_session_drain(struct iris_inst * inst,u32 plane)381 static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane)
382 {
383 	struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0};
384 
385 	ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt);
386 	ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER;
387 	ip_pkt.shdr.session_id = inst->session_id;
388 	ip_pkt.flags = HFI_BUFFERFLAG_EOS;
389 
390 	return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size);
391 }
392 
393 static int
iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt * packet,struct iris_inst * inst,u32 ptype,void * pdata)394 iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet,
395 					  struct iris_inst *inst, u32 ptype, void *pdata)
396 {
397 	void *prop_data = &packet->data[1];
398 
399 	packet->shdr.hdr.size = sizeof(*packet);
400 	packet->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
401 	packet->shdr.session_id = inst->session_id;
402 	packet->num_properties = 1;
403 	packet->data[0] = ptype;
404 
405 	switch (ptype) {
406 	case HFI_PROPERTY_PARAM_FRAME_SIZE: {
407 		struct hfi_framesize *in = pdata, *fsize = prop_data;
408 
409 		fsize->buffer_type = in->buffer_type;
410 		fsize->height = in->height;
411 		fsize->width = in->width;
412 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*fsize);
413 		break;
414 	}
415 	case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: {
416 		struct hfi_videocores_usage_type *in = pdata, *cu = prop_data;
417 
418 		cu->video_core_enable_mask = in->video_core_enable_mask;
419 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*cu);
420 		break;
421 	}
422 	case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: {
423 		struct hfi_uncompressed_format_select *in = pdata;
424 		struct hfi_uncompressed_format_select *hfi = prop_data;
425 
426 		hfi->buffer_type = in->buffer_type;
427 		hfi->format = in->format;
428 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
429 		break;
430 	}
431 	case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: {
432 		struct hfi_uncompressed_plane_actual_constraints_info *info = prop_data;
433 
434 		info->buffer_type = HFI_BUFFER_OUTPUT2;
435 		info->num_planes = 2;
436 		info->plane_format[0].stride_multiples = 128;
437 		info->plane_format[0].max_stride = 8192;
438 		info->plane_format[0].min_plane_buffer_height_multiple = 32;
439 		info->plane_format[0].buffer_alignment = 256;
440 		if (info->num_planes > 1) {
441 			info->plane_format[1].stride_multiples = 128;
442 			info->plane_format[1].max_stride = 8192;
443 			info->plane_format[1].min_plane_buffer_height_multiple = 16;
444 			info->plane_format[1].buffer_alignment = 256;
445 		}
446 
447 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*info);
448 		break;
449 	}
450 	case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
451 		struct hfi_buffer_count_actual *in = pdata;
452 		struct hfi_buffer_count_actual *count = prop_data;
453 
454 		count->type = in->type;
455 		count->count_actual = in->count_actual;
456 		count->count_min_host = in->count_min_host;
457 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*count);
458 		break;
459 	}
460 	case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
461 		struct hfi_multi_stream *in = pdata;
462 		struct hfi_multi_stream *multi = prop_data;
463 
464 		multi->buffer_type = in->buffer_type;
465 		multi->enable = in->enable;
466 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
467 		break;
468 	}
469 	case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
470 		struct hfi_buffer_size_actual *in = pdata, *sz = prop_data;
471 
472 		sz->size = in->size;
473 		sz->type = in->type;
474 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*sz);
475 		break;
476 	}
477 	case HFI_PROPERTY_PARAM_WORK_ROUTE: {
478 		struct hfi_video_work_route *wr = prop_data;
479 		u32 *in = pdata;
480 
481 		wr->video_work_route = *in;
482 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*wr);
483 		break;
484 	}
485 	case HFI_PROPERTY_PARAM_WORK_MODE: {
486 		struct hfi_video_work_mode *wm = prop_data;
487 		u32 *in = pdata;
488 
489 		wm->video_work_mode = *in;
490 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
491 		break;
492 	}
493 	case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: {
494 		struct hfi_enable *en = prop_data;
495 		u32 *in = pdata;
496 
497 		en->enable = *in;
498 		packet->shdr.hdr.size += sizeof(u32) + sizeof(*en);
499 		break;
500 	}
501 	default:
502 		return -EINVAL;
503 	}
504 
505 	return 0;
506 }
507 
hfi_gen1_set_property(struct iris_inst * inst,u32 packet_type,void * payload,u32 payload_size)508 static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type,
509 				 void *payload, u32 payload_size)
510 {
511 	struct hfi_session_set_property_pkt *pkt;
512 	u32 packet_size;
513 	int ret;
514 
515 	packet_size = sizeof(*pkt) + sizeof(u32) + payload_size;
516 	pkt = kzalloc(packet_size, GFP_KERNEL);
517 	if (!pkt)
518 		return -ENOMEM;
519 
520 	ret = iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type, payload);
521 	if (ret == -EOPNOTSUPP) {
522 		ret = 0;
523 		goto exit;
524 	}
525 	if (ret)
526 		goto exit;
527 
528 	ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size);
529 
530 exit:
531 	kfree(pkt);
532 
533 	return ret;
534 }
535 
iris_hfi_gen1_session_set_property(struct iris_inst * inst,u32 packet_type,u32 flag,u32 plane,u32 payload_type,void * payload,u32 payload_size)536 static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet_type,
537 					      u32 flag, u32 plane, u32 payload_type,
538 					      void *payload, u32 payload_size)
539 {
540 	return hfi_gen1_set_property(inst, packet_type, payload, payload_size);
541 }
542 
iris_hfi_gen1_set_resolution(struct iris_inst * inst)543 static int iris_hfi_gen1_set_resolution(struct iris_inst *inst)
544 {
545 	u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
546 	struct hfi_framesize fs;
547 	int ret;
548 
549 	fs.buffer_type = HFI_BUFFER_INPUT;
550 	fs.width = inst->fmt_src->fmt.pix_mp.width;
551 	fs.height = inst->fmt_src->fmt.pix_mp.height;
552 
553 	ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
554 	if (ret)
555 		return ret;
556 
557 	fs.buffer_type = HFI_BUFFER_OUTPUT2;
558 	fs.width = inst->fmt_dst->fmt.pix_mp.width;
559 	fs.height = inst->fmt_dst->fmt.pix_mp.height;
560 
561 	return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs));
562 }
563 
iris_hfi_gen1_decide_core(struct iris_inst * inst)564 static int iris_hfi_gen1_decide_core(struct iris_inst *inst)
565 {
566 	const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
567 	struct hfi_videocores_usage_type cu;
568 
569 	cu.video_core_enable_mask = HFI_CORE_ID_1;
570 
571 	return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu));
572 }
573 
iris_hfi_gen1_set_raw_format(struct iris_inst * inst)574 static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst)
575 {
576 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
577 	u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
578 	struct hfi_uncompressed_format_select fmt;
579 	int ret;
580 
581 	if (iris_split_mode_enabled(inst)) {
582 		fmt.buffer_type = HFI_BUFFER_OUTPUT;
583 		fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0;
584 
585 		ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
586 		if (ret)
587 			return ret;
588 
589 		fmt.buffer_type = HFI_BUFFER_OUTPUT2;
590 		fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
591 
592 		ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
593 	} else {
594 		fmt.buffer_type = HFI_BUFFER_OUTPUT;
595 		fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0;
596 
597 		ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt));
598 	}
599 
600 	return ret;
601 }
602 
iris_hfi_gen1_set_format_constraints(struct iris_inst * inst)603 static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst)
604 {
605 	const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO;
606 	struct hfi_uncompressed_plane_actual_constraints_info pconstraint;
607 
608 	pconstraint.buffer_type = HFI_BUFFER_OUTPUT2;
609 	pconstraint.num_planes = 2;
610 	pconstraint.plane_format[0].stride_multiples = 128;
611 	pconstraint.plane_format[0].max_stride = 8192;
612 	pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32;
613 	pconstraint.plane_format[0].buffer_alignment = 256;
614 
615 	pconstraint.plane_format[1].stride_multiples = 128;
616 	pconstraint.plane_format[1].max_stride = 8192;
617 	pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16;
618 	pconstraint.plane_format[1].buffer_alignment = 256;
619 
620 	return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint));
621 }
622 
iris_hfi_gen1_set_num_bufs(struct iris_inst * inst)623 static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst)
624 {
625 	u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
626 	struct hfi_buffer_count_actual buf_count;
627 	int ret;
628 
629 	buf_count.type = HFI_BUFFER_INPUT;
630 	buf_count.count_actual = VIDEO_MAX_FRAME;
631 	buf_count.count_min_host = VIDEO_MAX_FRAME;
632 
633 	ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
634 	if (ret)
635 		return ret;
636 
637 	if (iris_split_mode_enabled(inst)) {
638 		buf_count.type = HFI_BUFFER_OUTPUT;
639 		buf_count.count_actual = VIDEO_MAX_FRAME;
640 		buf_count.count_min_host = VIDEO_MAX_FRAME;
641 
642 		ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
643 		if (ret)
644 			return ret;
645 
646 		buf_count.type = HFI_BUFFER_OUTPUT2;
647 		buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB);
648 		buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB);
649 
650 		ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
651 	} else {
652 		buf_count.type = HFI_BUFFER_OUTPUT;
653 		buf_count.count_actual = VIDEO_MAX_FRAME;
654 		buf_count.count_min_host = VIDEO_MAX_FRAME;
655 
656 		ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count));
657 	}
658 
659 	return ret;
660 }
661 
iris_hfi_gen1_set_multistream(struct iris_inst * inst)662 static int iris_hfi_gen1_set_multistream(struct iris_inst *inst)
663 {
664 	u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
665 	struct hfi_multi_stream multi = {0};
666 	int ret;
667 
668 	if (iris_split_mode_enabled(inst)) {
669 		multi.buffer_type = HFI_BUFFER_OUTPUT;
670 		multi.enable = 0;
671 
672 		ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
673 		if (ret)
674 			return ret;
675 
676 		multi.buffer_type = HFI_BUFFER_OUTPUT2;
677 		multi.enable = 1;
678 
679 		ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
680 	} else {
681 		multi.buffer_type = HFI_BUFFER_OUTPUT;
682 		multi.enable = 1;
683 
684 		ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
685 		if (ret)
686 			return ret;
687 
688 		multi.buffer_type = HFI_BUFFER_OUTPUT2;
689 		multi.enable = 0;
690 
691 		ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi));
692 	}
693 
694 	return ret;
695 }
696 
iris_hfi_gen1_set_bufsize(struct iris_inst * inst)697 static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst)
698 {
699 	const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
700 	struct hfi_buffer_size_actual bufsz;
701 	int ret;
702 
703 	if (iris_split_mode_enabled(inst)) {
704 		bufsz.type = HFI_BUFFER_OUTPUT;
705 		bufsz.size = iris_vpu_buf_size(inst, BUF_DPB);
706 
707 		ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
708 		if (ret)
709 			return ret;
710 
711 		bufsz.type = HFI_BUFFER_OUTPUT2;
712 		bufsz.size = inst->buffers[BUF_OUTPUT].size;
713 
714 		ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
715 	} else {
716 		bufsz.type = HFI_BUFFER_OUTPUT;
717 		bufsz.size = inst->buffers[BUF_OUTPUT].size;
718 
719 		ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
720 		if (ret)
721 			return ret;
722 
723 		bufsz.type = HFI_BUFFER_OUTPUT2;
724 		bufsz.size = 0;
725 
726 		ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz));
727 	}
728 
729 	return ret;
730 }
731 
iris_hfi_gen1_session_set_config_params(struct iris_inst * inst,u32 plane)732 static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane)
733 {
734 	struct iris_core *core = inst->core;
735 	u32 config_params_size, i, j;
736 	const u32 *config_params;
737 	int ret;
738 
739 	static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = {
740 		{HFI_PROPERTY_PARAM_FRAME_SIZE,
741 			iris_hfi_gen1_set_resolution},
742 		{HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE,
743 			iris_hfi_gen1_decide_core},
744 		{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
745 			iris_hfi_gen1_set_raw_format},
746 		{HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
747 			iris_hfi_gen1_set_format_constraints},
748 		{HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
749 			iris_hfi_gen1_set_num_bufs},
750 		{HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM,
751 			iris_hfi_gen1_set_multistream},
752 		{HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL,
753 			iris_hfi_gen1_set_bufsize},
754 	};
755 
756 	static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = {
757 		{HFI_PROPERTY_PARAM_FRAME_SIZE,
758 			iris_hfi_gen1_set_resolution},
759 		{HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT,
760 			iris_hfi_gen1_set_raw_format},
761 		{HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO,
762 			iris_hfi_gen1_set_format_constraints},
763 		{HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL,
764 			iris_hfi_gen1_set_num_bufs},
765 		{HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM,
766 			iris_hfi_gen1_set_multistream},
767 		{HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL,
768 			iris_hfi_gen1_set_bufsize},
769 	};
770 
771 	config_params = core->iris_platform_data->input_config_params;
772 	config_params_size = core->iris_platform_data->input_config_params_size;
773 
774 	if (V4L2_TYPE_IS_OUTPUT(plane)) {
775 		for (i = 0; i < config_params_size; i++) {
776 			for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) {
777 				if (prop_type_handle_inp_arr[j].type == config_params[i]) {
778 					ret = prop_type_handle_inp_arr[j].handle(inst);
779 					if (ret)
780 						return ret;
781 					break;
782 				}
783 			}
784 		}
785 	} else if (V4L2_TYPE_IS_CAPTURE(plane)) {
786 		for (i = 0; i < config_params_size; i++) {
787 			for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) {
788 				if (prop_type_handle_out_arr[j].type == config_params[i]) {
789 					ret = prop_type_handle_out_arr[j].handle(inst);
790 					if (ret)
791 						return ret;
792 					break;
793 				}
794 			}
795 		}
796 	}
797 
798 	return 0;
799 }
800 
801 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = {
802 	.sys_init = iris_hfi_gen1_sys_init,
803 	.sys_image_version = iris_hfi_gen1_sys_image_version,
804 	.sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse,
805 	.sys_pc_prep = iris_hfi_gen1_sys_pc_prep,
806 	.session_open = iris_hfi_gen1_session_open,
807 	.session_set_config_params = iris_hfi_gen1_session_set_config_params,
808 	.session_set_property = iris_hfi_gen1_session_set_property,
809 	.session_start = iris_hfi_gen1_session_start,
810 	.session_queue_buf = iris_hfi_gen1_session_queue_buffer,
811 	.session_release_buf = iris_hfi_gen1_session_unset_buffers,
812 	.session_resume_drc = iris_hfi_gen1_session_continue,
813 	.session_stop = iris_hfi_gen1_session_stop,
814 	.session_drain = iris_hfi_gen1_session_drain,
815 	.session_close = iris_hfi_gen1_session_close,
816 };
817 
iris_hfi_gen1_command_ops_init(struct iris_core * core)818 void iris_hfi_gen1_command_ops_init(struct iris_core *core)
819 {
820 	core->hfi_ops = &iris_hfi_gen1_command_ops;
821 }
822 
iris_hfi_gen1_get_instance(void)823 struct iris_inst *iris_hfi_gen1_get_instance(void)
824 {
825 	return kzalloc(sizeof(struct iris_inst), GFP_KERNEL);
826 }
827