Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
23static 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
40static 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
57static 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
74static 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
91static 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
103static 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
121static 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
139static 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
157static 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
181static int iris_hfi_gen2_set_bit_depth(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
198static 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
217static 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
234static 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
251static 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
294static 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 = 0;
299
300 switch (inst->codec) {
301 case V4L2_PIX_FMT_HEVC:
302 profile = inst->fw_caps[PROFILE_HEVC].value;
303 break;
304 case V4L2_PIX_FMT_VP9:
305 profile = inst->fw_caps[PROFILE_VP9].value;
306 break;
307 case V4L2_PIX_FMT_H264:
308 profile = inst->fw_caps[PROFILE_H264].value;
309 break;
310 }
311
312 inst_hfi_gen2->src_subcr_params.profile = profile;
313
314 return iris_hfi_gen2_session_set_property(inst,
315 HFI_PROP_PROFILE,
316 HFI_HOST_FLAGS_NONE,
317 port,
318 HFI_PAYLOAD_U32_ENUM,
319 &profile,
320 sizeof(u32));
321}
322
323static int iris_hfi_gen2_set_level(struct iris_inst *inst)
324{
325 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
326 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
327 u32 level = 0;
328
329 switch (inst->codec) {
330 case V4L2_PIX_FMT_HEVC:
331 level = inst->fw_caps[LEVEL_HEVC].value;
332 break;
333 case V4L2_PIX_FMT_VP9:
334 level = inst->fw_caps[LEVEL_VP9].value;
335 break;
336 case V4L2_PIX_FMT_H264:
337 level = inst->fw_caps[LEVEL_H264].value;
338 break;
339 }
340
341 inst_hfi_gen2->src_subcr_params.level = level;
342
343 return iris_hfi_gen2_session_set_property(inst,
344 HFI_PROP_LEVEL,
345 HFI_HOST_FLAGS_NONE,
346 port,
347 HFI_PAYLOAD_U32_ENUM,
348 &level,
349 sizeof(u32));
350}
351
352static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst)
353{
354 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
355 u32 hfi_colorformat, pixelformat;
356
357 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
358 hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0;
359
360 return iris_hfi_gen2_session_set_property(inst,
361 HFI_PROP_COLOR_FORMAT,
362 HFI_HOST_FLAGS_NONE,
363 port,
364 HFI_PAYLOAD_U32,
365 &hfi_colorformat,
366 sizeof(u32));
367}
368
369static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst)
370{
371 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
372 u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
373 u32 scanline_y = inst->fmt_dst->fmt.pix_mp.height;
374 u32 stride_y = inst->fmt_dst->fmt.pix_mp.width;
375 u32 scanline_uv = scanline_y / 2;
376 u32 stride_uv = stride_y;
377 u32 payload[2];
378
379 if (pixelformat != V4L2_PIX_FMT_NV12)
380 return 0;
381
382 payload[0] = stride_y << 16 | scanline_y;
383 payload[1] = stride_uv << 16 | scanline_uv;
384
385 return iris_hfi_gen2_session_set_property(inst,
386 HFI_PROP_LINEAR_STRIDE_SCANLINE,
387 HFI_HOST_FLAGS_NONE,
388 port,
389 HFI_PAYLOAD_U64,
390 &payload,
391 sizeof(u64));
392}
393
394static int iris_hfi_gen2_set_tier(struct iris_inst *inst)
395{
396 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
397 u32 port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
398 u32 tier = inst->fw_caps[TIER].value;
399
400 inst_hfi_gen2->src_subcr_params.tier = tier;
401
402 return iris_hfi_gen2_session_set_property(inst,
403 HFI_PROP_TIER,
404 HFI_HOST_FLAGS_NONE,
405 port,
406 HFI_PAYLOAD_U32_ENUM,
407 &tier,
408 sizeof(u32));
409}
410
411static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
412{
413 struct iris_core *core = inst->core;
414 u32 config_params_size = 0, i, j;
415 const u32 *config_params = NULL;
416 int ret;
417
418 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
419 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
420 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
421 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },
422 {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth },
423 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count },
424 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count },
425 {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace },
426 {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile },
427 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level },
428 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
429 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
430 {HFI_PROP_TIER, iris_hfi_gen2_set_tier },
431 };
432
433 if (V4L2_TYPE_IS_OUTPUT(plane)) {
434 switch (inst->codec) {
435 case V4L2_PIX_FMT_H264:
436 config_params = core->iris_platform_data->input_config_params_default;
437 config_params_size =
438 core->iris_platform_data->input_config_params_default_size;
439 break;
440 case V4L2_PIX_FMT_HEVC:
441 config_params = core->iris_platform_data->input_config_params_hevc;
442 config_params_size =
443 core->iris_platform_data->input_config_params_hevc_size;
444 break;
445 case V4L2_PIX_FMT_VP9:
446 config_params = core->iris_platform_data->input_config_params_vp9;
447 config_params_size =
448 core->iris_platform_data->input_config_params_vp9_size;
449 break;
450 }
451 } else {
452 config_params = core->iris_platform_data->output_config_params;
453 config_params_size = core->iris_platform_data->output_config_params_size;
454 }
455
456 if (!config_params || !config_params_size)
457 return -EINVAL;
458
459 for (i = 0; i < config_params_size; i++) {
460 for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
461 if (prop_type_handle_arr[j].type == config_params[i]) {
462 ret = prop_type_handle_arr[j].handle(inst);
463 if (ret)
464 return ret;
465 break;
466 }
467 }
468 }
469
470 return 0;
471}
472
473static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
474{
475 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
476 u32 codec = 0;
477
478 switch (inst->codec) {
479 case V4L2_PIX_FMT_H264:
480 codec = HFI_CODEC_DECODE_AVC;
481 break;
482 case V4L2_PIX_FMT_HEVC:
483 codec = HFI_CODEC_DECODE_HEVC;
484 break;
485 case V4L2_PIX_FMT_VP9:
486 codec = HFI_CODEC_DECODE_VP9;
487 break;
488 }
489
490 iris_hfi_gen2_packet_session_property(inst,
491 HFI_PROP_CODEC,
492 HFI_HOST_FLAGS_NONE,
493 HFI_PORT_NONE,
494 HFI_PAYLOAD_U32_ENUM,
495 &codec,
496 sizeof(u32));
497
498 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
499 inst_hfi_gen2->packet->size);
500}
501
502static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
503{
504 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
505 u32 default_header = false;
506
507 iris_hfi_gen2_packet_session_property(inst,
508 HFI_PROP_DEC_DEFAULT_HEADER,
509 HFI_HOST_FLAGS_NONE,
510 HFI_PORT_BITSTREAM,
511 HFI_PAYLOAD_U32,
512 &default_header,
513 sizeof(u32));
514
515 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
516 inst_hfi_gen2->packet->size);
517}
518
519static int iris_hfi_gen2_session_open(struct iris_inst *inst)
520{
521 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
522 int ret;
523
524 if (inst->state != IRIS_INST_DEINIT)
525 return -EALREADY;
526
527 inst_hfi_gen2->ipsc_properties_set = false;
528 inst_hfi_gen2->opsc_properties_set = false;
529
530 inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
531 if (!inst_hfi_gen2->packet)
532 return -ENOMEM;
533
534 iris_hfi_gen2_packet_session_command(inst,
535 HFI_CMD_OPEN,
536 HFI_HOST_FLAGS_RESPONSE_REQUIRED |
537 HFI_HOST_FLAGS_INTR_REQUIRED,
538 HFI_PORT_NONE,
539 0,
540 HFI_PAYLOAD_U32,
541 &inst->session_id,
542 sizeof(u32));
543
544 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
545 inst_hfi_gen2->packet->size);
546 if (ret)
547 goto fail_free_packet;
548
549 ret = iris_hfi_gen2_session_set_codec(inst);
550 if (ret)
551 goto fail_free_packet;
552
553 ret = iris_hfi_gen2_session_set_default_header(inst);
554 if (ret)
555 goto fail_free_packet;
556
557 return 0;
558
559fail_free_packet:
560 kfree(inst_hfi_gen2->packet);
561 inst_hfi_gen2->packet = NULL;
562
563 return ret;
564}
565
566static int iris_hfi_gen2_session_close(struct iris_inst *inst)
567{
568 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
569 int ret;
570
571 if (!inst_hfi_gen2->packet)
572 return -EINVAL;
573
574 iris_hfi_gen2_packet_session_command(inst,
575 HFI_CMD_CLOSE,
576 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
577 HFI_HOST_FLAGS_INTR_REQUIRED |
578 HFI_HOST_FLAGS_NON_DISCARDABLE),
579 HFI_PORT_NONE,
580 inst->session_id,
581 HFI_PAYLOAD_NONE,
582 NULL,
583 0);
584
585 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
586 inst_hfi_gen2->packet->size);
587
588 kfree(inst_hfi_gen2->packet);
589 inst_hfi_gen2->packet = NULL;
590
591 return ret;
592}
593
594static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
595 u32 cmd, u32 plane, u32 payload_type,
596 void *payload, u32 payload_size)
597{
598 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
599
600 iris_hfi_gen2_packet_session_command(inst,
601 cmd,
602 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
603 HFI_HOST_FLAGS_INTR_REQUIRED),
604 iris_hfi_gen2_get_port(plane),
605 inst->session_id,
606 payload_type,
607 payload,
608 payload_size);
609
610 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
611 inst_hfi_gen2->packet->size);
612}
613
614static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
615{
616 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
617 struct hfi_subscription_params subsc_params;
618 u32 prop_type, payload_size, payload_type;
619 struct iris_core *core = inst->core;
620 const u32 *change_param = NULL;
621 u32 change_param_size = 0;
622 u32 payload[32] = {0};
623 u32 hfi_port = 0, i;
624 int ret;
625
626 if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
627 (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
628 dev_err(core->dev, "invalid plane\n");
629 return 0;
630 }
631
632 switch (inst->codec) {
633 case V4L2_PIX_FMT_H264:
634 change_param = core->iris_platform_data->input_config_params_default;
635 change_param_size =
636 core->iris_platform_data->input_config_params_default_size;
637 break;
638 case V4L2_PIX_FMT_HEVC:
639 change_param = core->iris_platform_data->input_config_params_hevc;
640 change_param_size =
641 core->iris_platform_data->input_config_params_hevc_size;
642 break;
643 case V4L2_PIX_FMT_VP9:
644 change_param = core->iris_platform_data->input_config_params_vp9;
645 change_param_size =
646 core->iris_platform_data->input_config_params_vp9_size;
647 break;
648 }
649
650 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
651
652 for (i = 0; i < change_param_size; i++)
653 payload[i + 1] = change_param[i];
654
655 ret = iris_hfi_gen2_session_subscribe_mode(inst,
656 HFI_CMD_SUBSCRIBE_MODE,
657 plane,
658 HFI_PAYLOAD_U32_ARRAY,
659 &payload[0],
660 ((change_param_size + 1) * sizeof(u32)));
661 if (ret)
662 return ret;
663
664 if (V4L2_TYPE_IS_OUTPUT(plane)) {
665 inst_hfi_gen2->ipsc_properties_set = true;
666 } else {
667 hfi_port = iris_hfi_gen2_get_port(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
668 memcpy(&inst_hfi_gen2->dst_subcr_params,
669 &inst_hfi_gen2->src_subcr_params,
670 sizeof(inst_hfi_gen2->src_subcr_params));
671 subsc_params = inst_hfi_gen2->dst_subcr_params;
672 for (i = 0; i < change_param_size; i++) {
673 payload[0] = 0;
674 payload[1] = 0;
675 payload_size = 0;
676 payload_type = 0;
677 prop_type = change_param[i];
678 switch (prop_type) {
679 case HFI_PROP_BITSTREAM_RESOLUTION:
680 payload[0] = subsc_params.bitstream_resolution;
681 payload_size = sizeof(u32);
682 payload_type = HFI_PAYLOAD_U32;
683 break;
684 case HFI_PROP_CROP_OFFSETS:
685 payload[0] = subsc_params.crop_offsets[0];
686 payload[1] = subsc_params.crop_offsets[1];
687 payload_size = sizeof(u64);
688 payload_type = HFI_PAYLOAD_64_PACKED;
689 break;
690 case HFI_PROP_CODED_FRAMES:
691 payload[0] = subsc_params.coded_frames;
692 payload_size = sizeof(u32);
693 payload_type = HFI_PAYLOAD_U32;
694 break;
695 case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
696 payload[0] = subsc_params.bit_depth;
697 payload_size = sizeof(u32);
698 payload_type = HFI_PAYLOAD_U32;
699 break;
700 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
701 payload[0] = subsc_params.fw_min_count;
702 payload_size = sizeof(u32);
703 payload_type = HFI_PAYLOAD_U32;
704 break;
705 case HFI_PROP_PIC_ORDER_CNT_TYPE:
706 payload[0] = subsc_params.pic_order_cnt;
707 payload_size = sizeof(u32);
708 payload_type = HFI_PAYLOAD_U32;
709 break;
710 case HFI_PROP_SIGNAL_COLOR_INFO:
711 payload[0] = subsc_params.color_info;
712 payload_size = sizeof(u32);
713 payload_type = HFI_PAYLOAD_U32;
714 break;
715 case HFI_PROP_PROFILE:
716 payload[0] = subsc_params.profile;
717 payload_size = sizeof(u32);
718 payload_type = HFI_PAYLOAD_U32;
719 break;
720 case HFI_PROP_LEVEL:
721 payload[0] = subsc_params.level;
722 payload_size = sizeof(u32);
723 payload_type = HFI_PAYLOAD_U32;
724 break;
725 case HFI_PROP_TIER:
726 payload[0] = subsc_params.tier;
727 payload_size = sizeof(u32);
728 payload_type = HFI_PAYLOAD_U32;
729 break;
730 default:
731 prop_type = 0;
732 ret = -EINVAL;
733 break;
734 }
735 if (prop_type) {
736 ret = iris_hfi_gen2_session_set_property(inst,
737 prop_type,
738 HFI_HOST_FLAGS_NONE,
739 hfi_port,
740 payload_type,
741 &payload,
742 payload_size);
743 if (ret)
744 return ret;
745 }
746 }
747 inst_hfi_gen2->opsc_properties_set = true;
748 }
749
750 return 0;
751}
752
753static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
754{
755 struct iris_core *core = inst->core;
756 u32 subscribe_prop_size = 0, i;
757 const u32 *subcribe_prop = NULL;
758 u32 payload[32] = {0};
759
760 payload[0] = HFI_MODE_PROPERTY;
761
762 if (V4L2_TYPE_IS_OUTPUT(plane)) {
763 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
764 subcribe_prop = core->iris_platform_data->dec_input_prop;
765 } else {
766 switch (inst->codec) {
767 case V4L2_PIX_FMT_H264:
768 subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
769 subscribe_prop_size =
770 core->iris_platform_data->dec_output_prop_avc_size;
771 break;
772 case V4L2_PIX_FMT_HEVC:
773 subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
774 subscribe_prop_size =
775 core->iris_platform_data->dec_output_prop_hevc_size;
776 break;
777 case V4L2_PIX_FMT_VP9:
778 subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
779 subscribe_prop_size =
780 core->iris_platform_data->dec_output_prop_vp9_size;
781 break;
782 }
783 }
784
785 for (i = 0; i < subscribe_prop_size; i++)
786 payload[i + 1] = subcribe_prop[i];
787
788 return iris_hfi_gen2_session_subscribe_mode(inst,
789 HFI_CMD_SUBSCRIBE_MODE,
790 plane,
791 HFI_PAYLOAD_U32_ARRAY,
792 &payload[0],
793 (subscribe_prop_size + 1) * sizeof(u32));
794}
795
796static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
797{
798 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
799 int ret = 0;
800
801 ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
802 if (ret)
803 return ret;
804
805 ret = iris_hfi_gen2_subscribe_property(inst, plane);
806 if (ret)
807 return ret;
808
809 iris_hfi_gen2_packet_session_command(inst,
810 HFI_CMD_START,
811 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
812 HFI_HOST_FLAGS_INTR_REQUIRED),
813 iris_hfi_gen2_get_port(plane),
814 inst->session_id,
815 HFI_PAYLOAD_NONE,
816 NULL,
817 0);
818
819 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
820 inst_hfi_gen2->packet->size);
821}
822
823static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
824{
825 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
826 int ret = 0;
827
828 reinit_completion(&inst->completion);
829
830 iris_hfi_gen2_packet_session_command(inst,
831 HFI_CMD_STOP,
832 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
833 HFI_HOST_FLAGS_INTR_REQUIRED |
834 HFI_HOST_FLAGS_NON_DISCARDABLE),
835 iris_hfi_gen2_get_port(plane),
836 inst->session_id,
837 HFI_PAYLOAD_NONE,
838 NULL,
839 0);
840
841 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
842 inst_hfi_gen2->packet->size);
843 if (ret)
844 return ret;
845
846 return iris_wait_for_session_response(inst, false);
847}
848
849static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
850{
851 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
852
853 iris_hfi_gen2_packet_session_command(inst,
854 HFI_CMD_PAUSE,
855 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
856 HFI_HOST_FLAGS_INTR_REQUIRED),
857 iris_hfi_gen2_get_port(plane),
858 inst->session_id,
859 HFI_PAYLOAD_NONE,
860 NULL,
861 0);
862
863 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
864 inst_hfi_gen2->packet->size);
865}
866
867static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
868{
869 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
870 u32 payload = HFI_CMD_SETTINGS_CHANGE;
871
872 iris_hfi_gen2_packet_session_command(inst,
873 HFI_CMD_RESUME,
874 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
875 HFI_HOST_FLAGS_INTR_REQUIRED),
876 iris_hfi_gen2_get_port(plane),
877 inst->session_id,
878 HFI_PAYLOAD_U32,
879 &payload,
880 sizeof(u32));
881
882 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
883 inst_hfi_gen2->packet->size);
884}
885
886static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
887{
888 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
889 u32 payload = HFI_CMD_DRAIN;
890
891 iris_hfi_gen2_packet_session_command(inst,
892 HFI_CMD_RESUME,
893 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
894 HFI_HOST_FLAGS_INTR_REQUIRED),
895 iris_hfi_gen2_get_port(plane),
896 inst->session_id,
897 HFI_PAYLOAD_U32,
898 &payload,
899 sizeof(u32));
900
901 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
902 inst_hfi_gen2->packet->size);
903}
904
905static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
906{
907 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
908
909 if (!V4L2_TYPE_IS_OUTPUT(plane))
910 return 0;
911
912 iris_hfi_gen2_packet_session_command(inst,
913 HFI_CMD_DRAIN,
914 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
915 HFI_HOST_FLAGS_INTR_REQUIRED |
916 HFI_HOST_FLAGS_NON_DISCARDABLE),
917 iris_hfi_gen2_get_port(plane),
918 inst->session_id,
919 HFI_PAYLOAD_NONE,
920 NULL,
921 0);
922
923 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
924 inst_hfi_gen2->packet->size);
925}
926
927static u32 iris_hfi_gen2_buf_type_from_driver(enum iris_buffer_type buffer_type)
928{
929 switch (buffer_type) {
930 case BUF_INPUT:
931 return HFI_BUFFER_BITSTREAM;
932 case BUF_OUTPUT:
933 return HFI_BUFFER_RAW;
934 case BUF_BIN:
935 return HFI_BUFFER_BIN;
936 case BUF_COMV:
937 return HFI_BUFFER_COMV;
938 case BUF_NON_COMV:
939 return HFI_BUFFER_NON_COMV;
940 case BUF_LINE:
941 return HFI_BUFFER_LINE;
942 case BUF_DPB:
943 return HFI_BUFFER_DPB;
944 case BUF_PERSIST:
945 return HFI_BUFFER_PERSIST;
946 default:
947 return 0;
948 }
949}
950
951static int iris_set_num_comv(struct iris_inst *inst)
952{
953 struct platform_inst_caps *caps;
954 struct iris_core *core = inst->core;
955 u32 num_comv;
956
957 caps = core->iris_platform_data->inst_caps;
958 num_comv = caps->num_comv;
959
960 return core->hfi_ops->session_set_property(inst,
961 HFI_PROP_COMV_BUFFER_COUNT,
962 HFI_HOST_FLAGS_NONE,
963 HFI_PORT_BITSTREAM,
964 HFI_PAYLOAD_U32,
965 &num_comv, sizeof(u32));
966}
967
968static void iris_hfi_gen2_get_buffer(struct iris_buffer *buffer, struct iris_hfi_buffer *buf)
969{
970 memset(buf, 0, sizeof(*buf));
971 buf->type = iris_hfi_gen2_buf_type_from_driver(buffer->type);
972 buf->index = buffer->index;
973 buf->base_address = buffer->device_addr;
974 buf->addr_offset = 0;
975 buf->buffer_size = buffer->buffer_size;
976
977 if (buffer->type == BUF_INPUT)
978 buf->buffer_size = ALIGN(buffer->buffer_size, 256);
979 buf->data_offset = buffer->data_offset;
980 buf->data_size = buffer->data_size;
981 if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
982 buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
983 buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
984 buf->timestamp = buffer->timestamp;
985}
986
987static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
988{
989 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
990 struct iris_hfi_buffer hfi_buffer;
991 u32 port;
992 int ret;
993
994 iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
995 if (buffer->type == BUF_COMV) {
996 ret = iris_set_num_comv(inst);
997 if (ret)
998 return ret;
999 }
1000
1001 port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
1002 iris_hfi_gen2_packet_session_command(inst,
1003 HFI_CMD_BUFFER,
1004 HFI_HOST_FLAGS_INTR_REQUIRED,
1005 port,
1006 inst->session_id,
1007 HFI_PAYLOAD_STRUCTURE,
1008 &hfi_buffer,
1009 sizeof(hfi_buffer));
1010
1011 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1012 inst_hfi_gen2->packet->size);
1013}
1014
1015static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1016{
1017 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1018 struct iris_hfi_buffer hfi_buffer;
1019 u32 port;
1020
1021 iris_hfi_gen2_get_buffer(buffer, &hfi_buffer);
1022 hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
1023 port = iris_hfi_gen2_get_port_from_buf_type(buffer->type);
1024
1025 iris_hfi_gen2_packet_session_command(inst,
1026 HFI_CMD_BUFFER,
1027 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1028 HFI_HOST_FLAGS_INTR_REQUIRED),
1029 port,
1030 inst->session_id,
1031 HFI_PAYLOAD_STRUCTURE,
1032 &hfi_buffer,
1033 sizeof(hfi_buffer));
1034
1035 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1036 inst_hfi_gen2->packet->size);
1037}
1038
1039static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
1040 .sys_init = iris_hfi_gen2_sys_init,
1041 .sys_image_version = iris_hfi_gen2_sys_image_version,
1042 .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
1043 .sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
1044 .session_open = iris_hfi_gen2_session_open,
1045 .session_set_config_params = iris_hfi_gen2_session_set_config_params,
1046 .session_set_property = iris_hfi_gen2_session_set_property,
1047 .session_start = iris_hfi_gen2_session_start,
1048 .session_queue_buf = iris_hfi_gen2_session_queue_buffer,
1049 .session_release_buf = iris_hfi_gen2_session_release_buffer,
1050 .session_pause = iris_hfi_gen2_session_pause,
1051 .session_resume_drc = iris_hfi_gen2_session_resume_drc,
1052 .session_stop = iris_hfi_gen2_session_stop,
1053 .session_drain = iris_hfi_gen2_session_drain,
1054 .session_resume_drain = iris_hfi_gen2_session_resume_drain,
1055 .session_close = iris_hfi_gen2_session_close,
1056};
1057
1058void iris_hfi_gen2_command_ops_init(struct iris_core *core)
1059{
1060 core->hfi_ops = &iris_hfi_gen2_command_ops;
1061}
1062
1063struct iris_inst *iris_hfi_gen2_get_instance(void)
1064{
1065 return kzalloc(sizeof(struct iris_inst_hfi_gen2), GFP_KERNEL);
1066}