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