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