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 #define NUM_COMV_AV1 18
14
15 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \
16 NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32)))
17
18 #define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \
19 sizeof(struct iris_hfi_packet) + sizeof(u32))
20
21 #define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \
22 sizeof(struct iris_hfi_packet))
23
iris_hfi_gen2_sys_init(struct iris_core * core)24 static int iris_hfi_gen2_sys_init(struct iris_core *core)
25 {
26 struct iris_hfi_header *hdr;
27 int ret;
28
29 hdr = kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL);
30 if (!hdr)
31 return -ENOMEM;
32
33 iris_hfi_gen2_packet_sys_init(core, hdr);
34 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
35
36 kfree(hdr);
37
38 return ret;
39 }
40
iris_hfi_gen2_sys_image_version(struct iris_core * core)41 static int iris_hfi_gen2_sys_image_version(struct iris_core *core)
42 {
43 struct iris_hfi_header *hdr;
44 int ret;
45
46 hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
47 if (!hdr)
48 return -ENOMEM;
49
50 iris_hfi_gen2_packet_image_version(core, hdr);
51 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
52
53 kfree(hdr);
54
55 return ret;
56 }
57
iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core * core)58 static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core)
59 {
60 struct iris_hfi_header *hdr;
61 int ret;
62
63 hdr = kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL);
64 if (!hdr)
65 return -ENOMEM;
66
67 iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr);
68 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
69
70 kfree(hdr);
71
72 return ret;
73 }
74
iris_hfi_gen2_sys_pc_prep(struct iris_core * core)75 static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core)
76 {
77 struct iris_hfi_header *hdr;
78 int ret;
79
80 hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL);
81 if (!hdr)
82 return -ENOMEM;
83
84 iris_hfi_gen2_packet_sys_pc_prep(core, hdr);
85 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size);
86
87 kfree(hdr);
88
89 return ret;
90 }
91
iris_hfi_gen2_get_port(struct iris_inst * inst,u32 plane)92 static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane)
93 {
94 if (inst->domain == DECODER) {
95 switch (plane) {
96 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
97 return HFI_PORT_BITSTREAM;
98 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
99 return HFI_PORT_RAW;
100 default:
101 return HFI_PORT_NONE;
102 }
103 } else {
104 switch (plane) {
105 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
106 return HFI_PORT_RAW;
107 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
108 return HFI_PORT_BITSTREAM;
109 default:
110 return HFI_PORT_NONE;
111 }
112 }
113 }
114
iris_hfi_gen2_get_port_from_buf_type(struct iris_inst * inst,enum iris_buffer_type buffer_type)115 static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst,
116 enum iris_buffer_type buffer_type)
117 {
118 if (inst->domain == DECODER) {
119 switch (buffer_type) {
120 case BUF_INPUT:
121 case BUF_BIN:
122 case BUF_COMV:
123 case BUF_NON_COMV:
124 case BUF_LINE:
125 case BUF_PARTIAL:
126 return HFI_PORT_BITSTREAM;
127 case BUF_OUTPUT:
128 case BUF_DPB:
129 return HFI_PORT_RAW;
130 case BUF_PERSIST:
131 default:
132 return HFI_PORT_NONE;
133 }
134 } else {
135 switch (buffer_type) {
136 case BUF_INPUT:
137 case BUF_VPSS:
138 return HFI_PORT_RAW;
139 case BUF_OUTPUT:
140 case BUF_BIN:
141 case BUF_COMV:
142 case BUF_NON_COMV:
143 case BUF_LINE:
144 case BUF_SCRATCH_2:
145 return HFI_PORT_BITSTREAM;
146 case BUF_ARP:
147 default:
148 return HFI_PORT_NONE;
149 }
150 }
151 }
152
iris_hfi_gen2_session_set_property(struct iris_inst * inst,u32 packet_type,u32 flag,u32 plane,u32 payload_type,void * payload,u32 payload_size)153 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag,
154 u32 plane, u32 payload_type, void *payload,
155 u32 payload_size)
156 {
157 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
158
159 iris_hfi_gen2_packet_session_property(inst,
160 packet_type,
161 flag,
162 plane,
163 payload_type,
164 payload,
165 payload_size);
166
167 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
168 inst_hfi_gen2->packet->size);
169 }
170
iris_hfi_gen2_set_raw_resolution(struct iris_inst * inst,u32 plane)171 static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane)
172 {
173 u32 resolution = inst->enc_raw_width << 16 | inst->enc_raw_height;
174 u32 port = iris_hfi_gen2_get_port(inst, plane);
175
176 return iris_hfi_gen2_session_set_property(inst,
177 HFI_PROP_RAW_RESOLUTION,
178 HFI_HOST_FLAGS_NONE,
179 port,
180 HFI_PAYLOAD_32_PACKED,
181 &resolution,
182 sizeof(u32));
183 }
184
iris_hfi_get_aligned_resolution(struct iris_inst * inst,u32 width,u32 height)185 static inline u32 iris_hfi_get_aligned_resolution(struct iris_inst *inst, u32 width, u32 height)
186 {
187 u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
188
189 return (ALIGN(width, codec_align) << 16 | ALIGN(height, codec_align));
190 }
191
iris_hfi_gen2_set_bitstream_resolution(struct iris_inst * inst,u32 plane)192 static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane)
193 {
194 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
195 u32 port = iris_hfi_gen2_get_port(inst, plane);
196 enum hfi_packet_payload_info payload_type;
197 u32 width, height;
198 u32 resolution;
199
200 if (inst->domain == DECODER) {
201 width = inst->fmt_src->fmt.pix_mp.width;
202 height = inst->fmt_src->fmt.pix_mp.height;
203 resolution = iris_hfi_get_aligned_resolution(inst, width, height);
204 inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution;
205 payload_type = HFI_PAYLOAD_U32;
206 } else {
207 if (is_rotation_90_or_270(inst)) {
208 width = inst->enc_scale_height;
209 height = inst->enc_scale_width;
210 } else {
211 width = inst->enc_scale_width;
212 height = inst->enc_scale_height;
213 }
214 resolution = iris_hfi_get_aligned_resolution(inst, width, height);
215 inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution;
216 payload_type = HFI_PAYLOAD_32_PACKED;
217 }
218
219 return iris_hfi_gen2_session_set_property(inst,
220 HFI_PROP_BITSTREAM_RESOLUTION,
221 HFI_HOST_FLAGS_NONE,
222 port,
223 payload_type,
224 &resolution,
225 sizeof(u32));
226 }
227
iris_hfi_gen2_set_crop_offsets(struct iris_inst * inst,u32 plane)228 static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane)
229 {
230 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
231 u32 port = iris_hfi_gen2_get_port(inst, plane);
232 u32 bottom_offset, right_offset;
233 u32 left_offset, top_offset;
234 u32 payload[2], codec_align;
235
236 if (inst->domain == DECODER) {
237 if (V4L2_TYPE_IS_OUTPUT(plane)) {
238 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height);
239 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width);
240 left_offset = inst->crop.left;
241 top_offset = inst->crop.top;
242 } else {
243 bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height);
244 right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width);
245 left_offset = inst->compose.left;
246 top_offset = inst->compose.top;
247 }
248 } else {
249 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16;
250 if (V4L2_TYPE_IS_OUTPUT(plane)) {
251 bottom_offset = (inst->enc_raw_height - inst->crop.height);
252 right_offset = (inst->enc_raw_width - inst->crop.width);
253 left_offset = inst->crop.left;
254 top_offset = inst->crop.top;
255 } else {
256 if (is_rotation_90_or_270(inst)) {
257 bottom_offset = (ALIGN(inst->enc_scale_width, codec_align) -
258 inst->enc_scale_width);
259 right_offset = (ALIGN(inst->enc_scale_height, codec_align) -
260 inst->enc_scale_height);
261 } else {
262 bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) -
263 inst->enc_scale_height);
264 right_offset = (ALIGN(inst->enc_scale_width, codec_align) -
265 inst->enc_scale_width);
266 }
267 left_offset = 0;
268 top_offset = 0;
269 }
270 }
271
272 payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset;
273 payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset;
274 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0];
275 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1];
276
277 return iris_hfi_gen2_session_set_property(inst,
278 HFI_PROP_CROP_OFFSETS,
279 HFI_HOST_FLAGS_NONE,
280 port,
281 HFI_PAYLOAD_64_PACKED,
282 &payload,
283 sizeof(u64));
284 }
285
iris_hfi_gen2_set_bit_depth(struct iris_inst * inst,u32 plane)286 static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane)
287 {
288 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
289 u32 port = iris_hfi_gen2_get_port(inst, plane);
290 u32 bitdepth = BIT_DEPTH_8;
291
292 inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth;
293
294 return iris_hfi_gen2_session_set_property(inst,
295 HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
296 HFI_HOST_FLAGS_NONE,
297 port,
298 HFI_PAYLOAD_U32,
299 &bitdepth,
300 sizeof(u32));
301 }
302
iris_hfi_gen2_set_coded_frames(struct iris_inst * inst,u32 plane)303 static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane)
304 {
305 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
306 u32 port = iris_hfi_gen2_get_port(inst, plane);
307 u32 coded_frames = 0;
308
309 if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
310 coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
311 inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames;
312
313 return iris_hfi_gen2_session_set_property(inst,
314 HFI_PROP_CODED_FRAMES,
315 HFI_HOST_FLAGS_NONE,
316 port,
317 HFI_PAYLOAD_U32,
318 &coded_frames,
319 sizeof(u32));
320 }
321
iris_hfi_gen2_set_min_output_count(struct iris_inst * inst,u32 plane)322 static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane)
323 {
324 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
325 u32 min_output = inst->buffers[BUF_OUTPUT].min_count;
326 u32 port = iris_hfi_gen2_get_port(inst, plane);
327
328 inst_hfi_gen2->src_subcr_params.fw_min_count = min_output;
329
330 return iris_hfi_gen2_session_set_property(inst,
331 HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
332 HFI_HOST_FLAGS_NONE,
333 port,
334 HFI_PAYLOAD_U32,
335 &min_output,
336 sizeof(u32));
337 }
338
iris_hfi_gen2_set_picture_order_count(struct iris_inst * inst,u32 plane)339 static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane)
340 {
341 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
342 u32 port = iris_hfi_gen2_get_port(inst, plane);
343 u32 poc = 0;
344
345 inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc;
346
347 return iris_hfi_gen2_session_set_property(inst,
348 HFI_PROP_PIC_ORDER_CNT_TYPE,
349 HFI_HOST_FLAGS_NONE,
350 port,
351 HFI_PAYLOAD_U32,
352 &poc,
353 sizeof(u32));
354 }
355
iris_hfi_gen2_set_colorspace(struct iris_inst * inst,u32 plane)356 static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane)
357 {
358 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
359 struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp;
360 u32 video_signal_type_present_flag = 0, color_info;
361 u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
362 u32 video_format = UNSPECIFIED_COLOR_FORMAT;
363 u32 full_range = V4L2_QUANTIZATION_DEFAULT;
364 u32 transfer_char = HFI_TRANSFER_RESERVED;
365 u32 port = iris_hfi_gen2_get_port(inst, plane);
366 u32 colour_description_present_flag = 0;
367 u32 primaries = HFI_PRIMARIES_RESERVED;
368
369 if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
370 pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
371 pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
372 colour_description_present_flag = 1;
373 video_signal_type_present_flag = 1;
374 primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace);
375 matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc);
376 transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func);
377 }
378
379 if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
380 video_signal_type_present_flag = 1;
381 full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
382 }
383
384 color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries,
385 colour_description_present_flag, full_range,
386 video_format, video_signal_type_present_flag);
387
388 inst_hfi_gen2->src_subcr_params.color_info = color_info;
389
390 return iris_hfi_gen2_session_set_property(inst,
391 HFI_PROP_SIGNAL_COLOR_INFO,
392 HFI_HOST_FLAGS_NONE,
393 port,
394 HFI_PAYLOAD_32_PACKED,
395 &color_info,
396 sizeof(u32));
397 }
398
iris_hfi_gen2_set_profile(struct iris_inst * inst,u32 plane)399 static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane)
400 {
401 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
402 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
403 u32 profile = 0;
404
405 switch (inst->codec) {
406 case V4L2_PIX_FMT_HEVC:
407 profile = inst->fw_caps[PROFILE_HEVC].value;
408 break;
409 case V4L2_PIX_FMT_VP9:
410 profile = inst->fw_caps[PROFILE_VP9].value;
411 break;
412 case V4L2_PIX_FMT_H264:
413 profile = inst->fw_caps[PROFILE_H264].value;
414 break;
415 case V4L2_PIX_FMT_AV1:
416 profile = inst->fw_caps[PROFILE_AV1].value;
417 break;
418 }
419
420 inst_hfi_gen2->src_subcr_params.profile = profile;
421
422 return iris_hfi_gen2_session_set_property(inst,
423 HFI_PROP_PROFILE,
424 HFI_HOST_FLAGS_NONE,
425 port,
426 HFI_PAYLOAD_U32_ENUM,
427 &profile,
428 sizeof(u32));
429 }
430
iris_hfi_gen2_set_level(struct iris_inst * inst,u32 plane)431 static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane)
432 {
433 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
434 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
435 u32 level = 0;
436
437 switch (inst->codec) {
438 case V4L2_PIX_FMT_HEVC:
439 level = inst->fw_caps[LEVEL_HEVC].value;
440 break;
441 case V4L2_PIX_FMT_VP9:
442 level = inst->fw_caps[LEVEL_VP9].value;
443 break;
444 case V4L2_PIX_FMT_H264:
445 level = inst->fw_caps[LEVEL_H264].value;
446 break;
447 case V4L2_PIX_FMT_AV1:
448 level = inst->fw_caps[LEVEL_AV1].value;
449 break;
450 }
451
452 inst_hfi_gen2->src_subcr_params.level = level;
453
454 return iris_hfi_gen2_session_set_property(inst,
455 HFI_PROP_LEVEL,
456 HFI_HOST_FLAGS_NONE,
457 port,
458 HFI_PAYLOAD_U32_ENUM,
459 &level,
460 sizeof(u32));
461 }
462
iris_hfi_gen2_set_opb_enable(struct iris_inst * inst,u32 plane)463 static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane)
464 {
465 u32 port = iris_hfi_gen2_get_port(inst, plane);
466 u32 opb_enable = iris_split_mode_enabled(inst);
467
468 return iris_hfi_gen2_session_set_property(inst,
469 HFI_PROP_OPB_ENABLE,
470 HFI_HOST_FLAGS_NONE,
471 port,
472 HFI_PAYLOAD_U32,
473 &opb_enable,
474 sizeof(u32));
475 }
476
iris_hfi_gen2_set_colorformat(struct iris_inst * inst,u32 plane)477 static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane)
478 {
479 u32 port = iris_hfi_gen2_get_port(inst, plane);
480 u32 hfi_colorformat, pixelformat;
481
482 if (inst->domain == DECODER) {
483 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
484 hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
485 HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
486 } else {
487 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
488 hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ?
489 HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC;
490 }
491
492 return iris_hfi_gen2_session_set_property(inst,
493 HFI_PROP_COLOR_FORMAT,
494 HFI_HOST_FLAGS_NONE,
495 port,
496 HFI_PAYLOAD_U32_ENUM,
497 &hfi_colorformat,
498 sizeof(u32));
499 }
500
iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst * inst,u32 plane)501 static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane)
502 {
503 u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv;
504 u32 port = iris_hfi_gen2_get_port(inst, plane);
505 u32 payload[2];
506
507 if (inst->domain == DECODER) {
508 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
509 stride_y = inst->fmt_dst->fmt.pix_mp.width;
510 scanline_y = inst->fmt_dst->fmt.pix_mp.height;
511 } else {
512 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
513 stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
514 scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
515 }
516
517 stride_uv = stride_y;
518 scanline_uv = scanline_y / 2;
519
520 if (pixelformat != V4L2_PIX_FMT_NV12)
521 return 0;
522
523 payload[0] = stride_y << 16 | scanline_y;
524 payload[1] = stride_uv << 16 | scanline_uv;
525
526 return iris_hfi_gen2_session_set_property(inst,
527 HFI_PROP_LINEAR_STRIDE_SCANLINE,
528 HFI_HOST_FLAGS_NONE,
529 port,
530 HFI_PAYLOAD_64_PACKED,
531 &payload,
532 sizeof(u64));
533 }
534
iris_hfi_gen2_set_tier(struct iris_inst * inst,u32 plane)535 static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane)
536 {
537 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
538 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
539 u32 tier = inst->fw_caps[TIER].value;
540
541 tier = (inst->codec == V4L2_PIX_FMT_AV1) ? inst->fw_caps[TIER_AV1].value :
542 inst->fw_caps[TIER].value;
543 inst_hfi_gen2->src_subcr_params.tier = tier;
544
545 return iris_hfi_gen2_session_set_property(inst,
546 HFI_PROP_TIER,
547 HFI_HOST_FLAGS_NONE,
548 port,
549 HFI_PAYLOAD_U32_ENUM,
550 &tier,
551 sizeof(u32));
552 }
553
iris_hfi_gen2_set_frame_rate(struct iris_inst * inst,u32 plane)554 static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane)
555 {
556 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
557 u32 frame_rate = inst->frame_rate << 16;
558
559 return iris_hfi_gen2_session_set_property(inst,
560 HFI_PROP_FRAME_RATE,
561 HFI_HOST_FLAGS_NONE,
562 port,
563 HFI_PAYLOAD_Q16,
564 &frame_rate,
565 sizeof(u32));
566 }
567
iris_hfi_gen2_set_film_grain(struct iris_inst * inst,u32 plane)568 static int iris_hfi_gen2_set_film_grain(struct iris_inst *inst, u32 plane)
569 {
570 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
571 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
572 u32 film_grain = inst->fw_caps[FILM_GRAIN].value;
573
574 inst_hfi_gen2->src_subcr_params.film_grain = film_grain;
575
576 return iris_hfi_gen2_session_set_property(inst,
577 HFI_PROP_AV1_FILM_GRAIN_PRESENT,
578 HFI_HOST_FLAGS_NONE,
579 port,
580 HFI_PAYLOAD_U32_ENUM,
581 &film_grain,
582 sizeof(u32));
583 }
584
iris_hfi_gen2_set_super_block(struct iris_inst * inst,u32 plane)585 static int iris_hfi_gen2_set_super_block(struct iris_inst *inst, u32 plane)
586 {
587 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
588 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
589 u32 super_block = inst->fw_caps[SUPER_BLOCK].value;
590
591 inst_hfi_gen2->src_subcr_params.super_block = super_block;
592
593 return iris_hfi_gen2_session_set_property(inst,
594 HFI_PROP_AV1_SUPER_BLOCK_ENABLED,
595 HFI_HOST_FLAGS_NONE,
596 port,
597 HFI_PAYLOAD_U32_ENUM,
598 &super_block,
599 sizeof(u32));
600 }
601
iris_hfi_gen2_session_set_config_params(struct iris_inst * inst,u32 plane)602 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane)
603 {
604 const struct iris_platform_data *pdata = inst->core->iris_platform_data;
605 u32 config_params_size = 0, i, j;
606 const u32 *config_params = NULL;
607 int ret;
608
609 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = {
610 {HFI_PROP_RAW_RESOLUTION, iris_hfi_gen2_set_raw_resolution },
611 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution },
612 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets },
613 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames },
614 {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth },
615 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count },
616 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count },
617 {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace },
618 {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile },
619 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level },
620 {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable },
621 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat },
622 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline },
623 {HFI_PROP_TIER, iris_hfi_gen2_set_tier },
624 {HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate },
625 {HFI_PROP_AV1_FILM_GRAIN_PRESENT, iris_hfi_gen2_set_film_grain },
626 {HFI_PROP_AV1_SUPER_BLOCK_ENABLED, iris_hfi_gen2_set_super_block },
627 {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable },
628 };
629
630 if (inst->domain == DECODER) {
631 if (V4L2_TYPE_IS_OUTPUT(plane)) {
632 if (inst->codec == V4L2_PIX_FMT_H264) {
633 config_params = pdata->dec_input_config_params_default;
634 config_params_size = pdata->dec_input_config_params_default_size;
635 } else if (inst->codec == V4L2_PIX_FMT_HEVC) {
636 config_params = pdata->dec_input_config_params_hevc;
637 config_params_size = pdata->dec_input_config_params_hevc_size;
638 } else if (inst->codec == V4L2_PIX_FMT_VP9) {
639 config_params = pdata->dec_input_config_params_vp9;
640 config_params_size = pdata->dec_input_config_params_vp9_size;
641 } else if (inst->codec == V4L2_PIX_FMT_AV1) {
642 config_params = pdata->dec_input_config_params_av1;
643 config_params_size = pdata->dec_input_config_params_av1_size;
644 } else {
645 return -EINVAL;
646 }
647 } else {
648 config_params = pdata->dec_output_config_params;
649 config_params_size = pdata->dec_output_config_params_size;
650 }
651 } else {
652 if (V4L2_TYPE_IS_OUTPUT(plane)) {
653 config_params = pdata->enc_input_config_params;
654 config_params_size = pdata->enc_input_config_params_size;
655 } else {
656 config_params = pdata->enc_output_config_params;
657 config_params_size = pdata->enc_output_config_params_size;
658 }
659 }
660
661 if (!config_params || !config_params_size)
662 return -EINVAL;
663
664 for (i = 0; i < config_params_size; i++) {
665 for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
666 if (prop_type_handle_arr[j].type == config_params[i]) {
667 ret = prop_type_handle_arr[j].handle(inst, plane);
668 if (ret)
669 return ret;
670 break;
671 }
672 }
673 }
674
675 return 0;
676 }
677
iris_hfi_gen2_session_set_codec(struct iris_inst * inst)678 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst)
679 {
680 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
681 u32 codec = 0;
682
683 switch (inst->codec) {
684 case V4L2_PIX_FMT_H264:
685 if (inst->domain == ENCODER)
686 codec = HFI_CODEC_ENCODE_AVC;
687 else
688 codec = HFI_CODEC_DECODE_AVC;
689 break;
690 case V4L2_PIX_FMT_HEVC:
691 if (inst->domain == ENCODER)
692 codec = HFI_CODEC_ENCODE_HEVC;
693 else
694 codec = HFI_CODEC_DECODE_HEVC;
695 break;
696 case V4L2_PIX_FMT_VP9:
697 codec = HFI_CODEC_DECODE_VP9;
698 break;
699 case V4L2_PIX_FMT_AV1:
700 codec = HFI_CODEC_DECODE_AV1;
701 }
702
703 iris_hfi_gen2_packet_session_property(inst,
704 HFI_PROP_CODEC,
705 HFI_HOST_FLAGS_NONE,
706 HFI_PORT_NONE,
707 HFI_PAYLOAD_U32_ENUM,
708 &codec,
709 sizeof(u32));
710
711 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
712 inst_hfi_gen2->packet->size);
713 }
714
iris_hfi_gen2_session_set_default_header(struct iris_inst * inst)715 static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst)
716 {
717 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
718 u32 default_header = false;
719
720 iris_hfi_gen2_packet_session_property(inst,
721 HFI_PROP_DEC_DEFAULT_HEADER,
722 HFI_HOST_FLAGS_NONE,
723 HFI_PORT_BITSTREAM,
724 HFI_PAYLOAD_U32,
725 &default_header,
726 sizeof(u32));
727
728 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
729 inst_hfi_gen2->packet->size);
730 }
731
iris_hfi_gen2_session_open(struct iris_inst * inst)732 static int iris_hfi_gen2_session_open(struct iris_inst *inst)
733 {
734 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
735 int ret;
736
737 if (inst->state != IRIS_INST_DEINIT)
738 return -EALREADY;
739
740 inst_hfi_gen2->ipsc_properties_set = false;
741 inst_hfi_gen2->opsc_properties_set = false;
742
743 inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL);
744 if (!inst_hfi_gen2->packet)
745 return -ENOMEM;
746
747 iris_hfi_gen2_packet_session_command(inst,
748 HFI_CMD_OPEN,
749 HFI_HOST_FLAGS_RESPONSE_REQUIRED |
750 HFI_HOST_FLAGS_INTR_REQUIRED,
751 HFI_PORT_NONE,
752 0,
753 HFI_PAYLOAD_U32,
754 &inst->session_id,
755 sizeof(u32));
756
757 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
758 inst_hfi_gen2->packet->size);
759 if (ret)
760 goto fail_free_packet;
761
762 ret = iris_hfi_gen2_session_set_codec(inst);
763 if (ret)
764 goto fail_free_packet;
765
766 if (inst->domain == DECODER) {
767 ret = iris_hfi_gen2_session_set_default_header(inst);
768 if (ret)
769 goto fail_free_packet;
770 }
771
772 return 0;
773
774 fail_free_packet:
775 kfree(inst_hfi_gen2->packet);
776 inst_hfi_gen2->packet = NULL;
777
778 return ret;
779 }
780
iris_hfi_gen2_session_close(struct iris_inst * inst)781 static int iris_hfi_gen2_session_close(struct iris_inst *inst)
782 {
783 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
784 int ret;
785
786 if (!inst_hfi_gen2->packet)
787 return -EINVAL;
788
789 iris_hfi_gen2_packet_session_command(inst,
790 HFI_CMD_CLOSE,
791 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
792 HFI_HOST_FLAGS_INTR_REQUIRED |
793 HFI_HOST_FLAGS_NON_DISCARDABLE),
794 HFI_PORT_NONE,
795 inst->session_id,
796 HFI_PAYLOAD_NONE,
797 NULL,
798 0);
799
800 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
801 inst_hfi_gen2->packet->size);
802
803 kfree(inst_hfi_gen2->packet);
804 inst_hfi_gen2->packet = NULL;
805
806 return ret;
807 }
808
iris_hfi_gen2_session_subscribe_mode(struct iris_inst * inst,u32 cmd,u32 plane,u32 payload_type,void * payload,u32 payload_size)809 static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst,
810 u32 cmd, u32 plane, u32 payload_type,
811 void *payload, u32 payload_size)
812 {
813 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
814
815 iris_hfi_gen2_packet_session_command(inst,
816 cmd,
817 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
818 HFI_HOST_FLAGS_INTR_REQUIRED),
819 iris_hfi_gen2_get_port(inst, plane),
820 inst->session_id,
821 payload_type,
822 payload,
823 payload_size);
824
825 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
826 inst_hfi_gen2->packet->size);
827 }
828
iris_hfi_gen2_subscribe_change_param(struct iris_inst * inst,u32 plane)829 static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane)
830 {
831 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
832 struct hfi_subscription_params subsc_params;
833 u32 prop_type, payload_size, payload_type;
834 struct iris_core *core = inst->core;
835 const u32 *change_param = NULL;
836 u32 change_param_size = 0;
837 u32 payload[32] = {0};
838 u32 hfi_port = 0, i;
839 int ret;
840
841 if (inst->domain == ENCODER)
842 return 0;
843
844 if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) ||
845 (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) {
846 dev_dbg(core->dev, "%cPSC already set\n", V4L2_TYPE_IS_OUTPUT(plane) ? 'I' : 'O');
847 return 0;
848 }
849
850 switch (inst->codec) {
851 case V4L2_PIX_FMT_H264:
852 change_param = core->iris_platform_data->dec_input_config_params_default;
853 change_param_size =
854 core->iris_platform_data->dec_input_config_params_default_size;
855 break;
856 case V4L2_PIX_FMT_HEVC:
857 change_param = core->iris_platform_data->dec_input_config_params_hevc;
858 change_param_size =
859 core->iris_platform_data->dec_input_config_params_hevc_size;
860 break;
861 case V4L2_PIX_FMT_VP9:
862 change_param = core->iris_platform_data->dec_input_config_params_vp9;
863 change_param_size =
864 core->iris_platform_data->dec_input_config_params_vp9_size;
865 break;
866 case V4L2_PIX_FMT_AV1:
867 change_param = core->iris_platform_data->dec_input_config_params_av1;
868 change_param_size =
869 core->iris_platform_data->dec_input_config_params_av1_size;
870 break;
871 }
872
873 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
874
875 for (i = 0; i < change_param_size; i++)
876 payload[i + 1] = change_param[i];
877
878 ret = iris_hfi_gen2_session_subscribe_mode(inst,
879 HFI_CMD_SUBSCRIBE_MODE,
880 plane,
881 HFI_PAYLOAD_U32_ARRAY,
882 &payload[0],
883 ((change_param_size + 1) * sizeof(u32)));
884 if (ret)
885 return ret;
886
887 if (V4L2_TYPE_IS_OUTPUT(plane)) {
888 inst_hfi_gen2->ipsc_properties_set = true;
889 } else {
890 hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
891 memcpy(&inst_hfi_gen2->dst_subcr_params,
892 &inst_hfi_gen2->src_subcr_params,
893 sizeof(inst_hfi_gen2->src_subcr_params));
894 subsc_params = inst_hfi_gen2->dst_subcr_params;
895 for (i = 0; i < change_param_size; i++) {
896 payload[0] = 0;
897 payload[1] = 0;
898 payload_size = 0;
899 payload_type = 0;
900 prop_type = change_param[i];
901 switch (prop_type) {
902 case HFI_PROP_BITSTREAM_RESOLUTION:
903 payload[0] = subsc_params.bitstream_resolution;
904 payload_size = sizeof(u32);
905 payload_type = HFI_PAYLOAD_U32;
906 break;
907 case HFI_PROP_CROP_OFFSETS:
908 payload[0] = subsc_params.crop_offsets[0];
909 payload[1] = subsc_params.crop_offsets[1];
910 payload_size = sizeof(u64);
911 payload_type = HFI_PAYLOAD_64_PACKED;
912 break;
913 case HFI_PROP_CODED_FRAMES:
914 payload[0] = subsc_params.coded_frames;
915 payload_size = sizeof(u32);
916 payload_type = HFI_PAYLOAD_U32;
917 break;
918 case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
919 payload[0] = subsc_params.bit_depth;
920 payload_size = sizeof(u32);
921 payload_type = HFI_PAYLOAD_U32;
922 break;
923 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
924 payload[0] = subsc_params.fw_min_count;
925 payload_size = sizeof(u32);
926 payload_type = HFI_PAYLOAD_U32;
927 break;
928 case HFI_PROP_PIC_ORDER_CNT_TYPE:
929 payload[0] = subsc_params.pic_order_cnt;
930 payload_size = sizeof(u32);
931 payload_type = HFI_PAYLOAD_U32;
932 break;
933 case HFI_PROP_SIGNAL_COLOR_INFO:
934 payload[0] = subsc_params.color_info;
935 payload_size = sizeof(u32);
936 payload_type = HFI_PAYLOAD_U32;
937 break;
938 case HFI_PROP_PROFILE:
939 payload[0] = subsc_params.profile;
940 payload_size = sizeof(u32);
941 payload_type = HFI_PAYLOAD_U32;
942 break;
943 case HFI_PROP_LEVEL:
944 payload[0] = subsc_params.level;
945 payload_size = sizeof(u32);
946 payload_type = HFI_PAYLOAD_U32;
947 break;
948 case HFI_PROP_TIER:
949 payload[0] = subsc_params.tier;
950 payload_size = sizeof(u32);
951 payload_type = HFI_PAYLOAD_U32;
952 break;
953 case HFI_PROP_AV1_FILM_GRAIN_PRESENT:
954 payload[0] = subsc_params.film_grain;
955 payload_size = sizeof(u32);
956 payload_type = HFI_PAYLOAD_U32;
957 break;
958 case HFI_PROP_AV1_SUPER_BLOCK_ENABLED:
959 payload[0] = subsc_params.super_block;
960 payload_size = sizeof(u32);
961 payload_type = HFI_PAYLOAD_U32;
962 break;
963 default:
964 prop_type = 0;
965 ret = -EINVAL;
966 break;
967 }
968 if (prop_type) {
969 ret = iris_hfi_gen2_session_set_property(inst,
970 prop_type,
971 HFI_HOST_FLAGS_NONE,
972 hfi_port,
973 payload_type,
974 &payload,
975 payload_size);
976 if (ret)
977 return ret;
978 }
979 }
980 inst_hfi_gen2->opsc_properties_set = true;
981 }
982
983 return 0;
984 }
985
iris_hfi_gen2_subscribe_property(struct iris_inst * inst,u32 plane)986 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane)
987 {
988 struct iris_core *core = inst->core;
989 u32 subscribe_prop_size = 0, i;
990 const u32 *subcribe_prop = NULL;
991 u32 payload[32] = {0};
992
993 payload[0] = HFI_MODE_PROPERTY;
994
995 if (inst->domain == ENCODER)
996 return 0;
997
998 if (V4L2_TYPE_IS_OUTPUT(plane)) {
999 subscribe_prop_size = core->iris_platform_data->dec_input_prop_size;
1000 subcribe_prop = core->iris_platform_data->dec_input_prop;
1001 } else {
1002 switch (inst->codec) {
1003 case V4L2_PIX_FMT_H264:
1004 subcribe_prop = core->iris_platform_data->dec_output_prop_avc;
1005 subscribe_prop_size =
1006 core->iris_platform_data->dec_output_prop_avc_size;
1007 break;
1008 case V4L2_PIX_FMT_HEVC:
1009 subcribe_prop = core->iris_platform_data->dec_output_prop_hevc;
1010 subscribe_prop_size =
1011 core->iris_platform_data->dec_output_prop_hevc_size;
1012 break;
1013 case V4L2_PIX_FMT_VP9:
1014 subcribe_prop = core->iris_platform_data->dec_output_prop_vp9;
1015 subscribe_prop_size =
1016 core->iris_platform_data->dec_output_prop_vp9_size;
1017 break;
1018 case V4L2_PIX_FMT_AV1:
1019 subcribe_prop = core->iris_platform_data->dec_output_prop_av1;
1020 subscribe_prop_size =
1021 core->iris_platform_data->dec_output_prop_av1_size;
1022 break;
1023 }
1024 }
1025
1026 for (i = 0; i < subscribe_prop_size; i++)
1027 payload[i + 1] = subcribe_prop[i];
1028
1029 return iris_hfi_gen2_session_subscribe_mode(inst,
1030 HFI_CMD_SUBSCRIBE_MODE,
1031 plane,
1032 HFI_PAYLOAD_U32_ARRAY,
1033 &payload[0],
1034 (subscribe_prop_size + 1) * sizeof(u32));
1035 }
1036
iris_hfi_gen2_session_start(struct iris_inst * inst,u32 plane)1037 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane)
1038 {
1039 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1040 int ret = 0;
1041
1042 ret = iris_hfi_gen2_subscribe_change_param(inst, plane);
1043 if (ret)
1044 return ret;
1045
1046 ret = iris_hfi_gen2_subscribe_property(inst, plane);
1047 if (ret)
1048 return ret;
1049
1050 iris_hfi_gen2_packet_session_command(inst,
1051 HFI_CMD_START,
1052 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1053 HFI_HOST_FLAGS_INTR_REQUIRED),
1054 iris_hfi_gen2_get_port(inst, plane),
1055 inst->session_id,
1056 HFI_PAYLOAD_NONE,
1057 NULL,
1058 0);
1059
1060 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1061 inst_hfi_gen2->packet->size);
1062 }
1063
iris_hfi_gen2_session_stop(struct iris_inst * inst,u32 plane)1064 static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane)
1065 {
1066 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1067 int ret = 0;
1068
1069 if (!inst_hfi_gen2->packet)
1070 return -EINVAL;
1071
1072 reinit_completion(&inst->completion);
1073
1074 iris_hfi_gen2_packet_session_command(inst,
1075 HFI_CMD_STOP,
1076 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1077 HFI_HOST_FLAGS_INTR_REQUIRED |
1078 HFI_HOST_FLAGS_NON_DISCARDABLE),
1079 iris_hfi_gen2_get_port(inst, plane),
1080 inst->session_id,
1081 HFI_PAYLOAD_NONE,
1082 NULL,
1083 0);
1084
1085 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1086 inst_hfi_gen2->packet->size);
1087 if (ret)
1088 return ret;
1089
1090 return iris_wait_for_session_response(inst, false);
1091 }
1092
iris_hfi_gen2_session_pause(struct iris_inst * inst,u32 plane)1093 static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane)
1094 {
1095 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1096
1097 iris_hfi_gen2_packet_session_command(inst,
1098 HFI_CMD_PAUSE,
1099 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1100 HFI_HOST_FLAGS_INTR_REQUIRED),
1101 iris_hfi_gen2_get_port(inst, plane),
1102 inst->session_id,
1103 HFI_PAYLOAD_NONE,
1104 NULL,
1105 0);
1106
1107 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1108 inst_hfi_gen2->packet->size);
1109 }
1110
iris_hfi_gen2_session_resume_drc(struct iris_inst * inst,u32 plane)1111 static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane)
1112 {
1113 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1114 u32 payload = HFI_CMD_SETTINGS_CHANGE;
1115
1116 iris_hfi_gen2_packet_session_command(inst,
1117 HFI_CMD_RESUME,
1118 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1119 HFI_HOST_FLAGS_INTR_REQUIRED),
1120 iris_hfi_gen2_get_port(inst, plane),
1121 inst->session_id,
1122 HFI_PAYLOAD_U32,
1123 &payload,
1124 sizeof(u32));
1125
1126 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1127 inst_hfi_gen2->packet->size);
1128 }
1129
iris_hfi_gen2_session_resume_drain(struct iris_inst * inst,u32 plane)1130 static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane)
1131 {
1132 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1133 u32 payload = HFI_CMD_DRAIN;
1134
1135 iris_hfi_gen2_packet_session_command(inst,
1136 HFI_CMD_RESUME,
1137 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1138 HFI_HOST_FLAGS_INTR_REQUIRED),
1139 iris_hfi_gen2_get_port(inst, plane),
1140 inst->session_id,
1141 HFI_PAYLOAD_U32,
1142 &payload,
1143 sizeof(u32));
1144
1145 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1146 inst_hfi_gen2->packet->size);
1147 }
1148
iris_hfi_gen2_session_drain(struct iris_inst * inst,u32 plane)1149 static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane)
1150 {
1151 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1152
1153 if (!V4L2_TYPE_IS_OUTPUT(plane))
1154 return 0;
1155
1156 iris_hfi_gen2_packet_session_command(inst,
1157 HFI_CMD_DRAIN,
1158 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1159 HFI_HOST_FLAGS_INTR_REQUIRED |
1160 HFI_HOST_FLAGS_NON_DISCARDABLE),
1161 iris_hfi_gen2_get_port(inst, plane),
1162 inst->session_id,
1163 HFI_PAYLOAD_NONE,
1164 NULL,
1165 0);
1166
1167 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1168 inst_hfi_gen2->packet->size);
1169 }
1170
iris_hfi_gen2_buf_type_from_driver(u32 domain,enum iris_buffer_type buffer_type)1171 static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type)
1172 {
1173 switch (buffer_type) {
1174 case BUF_INPUT:
1175 if (domain == DECODER)
1176 return HFI_BUFFER_BITSTREAM;
1177 else
1178 return HFI_BUFFER_RAW;
1179 case BUF_OUTPUT:
1180 if (domain == DECODER)
1181 return HFI_BUFFER_RAW;
1182 else
1183 return HFI_BUFFER_BITSTREAM;
1184 case BUF_BIN:
1185 return HFI_BUFFER_BIN;
1186 case BUF_COMV:
1187 return HFI_BUFFER_COMV;
1188 case BUF_NON_COMV:
1189 return HFI_BUFFER_NON_COMV;
1190 case BUF_LINE:
1191 return HFI_BUFFER_LINE;
1192 case BUF_DPB:
1193 case BUF_SCRATCH_2:
1194 return HFI_BUFFER_DPB;
1195 case BUF_PERSIST:
1196 return HFI_BUFFER_PERSIST;
1197 case BUF_ARP:
1198 return HFI_BUFFER_ARP;
1199 case BUF_VPSS:
1200 return HFI_BUFFER_VPSS;
1201 case BUF_PARTIAL:
1202 return HFI_BUFFER_PARTIAL_DATA;
1203 default:
1204 return 0;
1205 }
1206 }
1207
iris_set_num_comv(struct iris_inst * inst)1208 static int iris_set_num_comv(struct iris_inst *inst)
1209 {
1210 struct platform_inst_caps *caps;
1211 struct iris_core *core = inst->core;
1212 u32 num_comv;
1213
1214 caps = core->iris_platform_data->inst_caps;
1215
1216 /*
1217 * AV1 needs more comv buffers than other codecs.
1218 * Update accordingly.
1219 */
1220 num_comv = (inst->codec == V4L2_PIX_FMT_AV1) ?
1221 NUM_COMV_AV1 : caps->num_comv;
1222
1223 return core->hfi_ops->session_set_property(inst,
1224 HFI_PROP_COMV_BUFFER_COUNT,
1225 HFI_HOST_FLAGS_NONE,
1226 HFI_PORT_BITSTREAM,
1227 HFI_PAYLOAD_U32,
1228 &num_comv, sizeof(u32));
1229 }
1230
iris_hfi_gen2_get_buffer(u32 domain,struct iris_buffer * buffer,struct iris_hfi_buffer * buf)1231 static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer,
1232 struct iris_hfi_buffer *buf)
1233 {
1234 memset(buf, 0, sizeof(*buf));
1235 buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type);
1236 buf->index = buffer->index;
1237 buf->base_address = buffer->device_addr;
1238 buf->addr_offset = 0;
1239 buf->buffer_size = buffer->buffer_size;
1240
1241 if (domain == DECODER && buffer->type == BUF_INPUT)
1242 buf->buffer_size = ALIGN(buffer->buffer_size, 256);
1243 buf->data_offset = buffer->data_offset;
1244 buf->data_size = buffer->data_size;
1245 if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
1246 buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
1247 buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
1248 buf->timestamp = buffer->timestamp;
1249 }
1250
iris_hfi_gen2_session_queue_buffer(struct iris_inst * inst,struct iris_buffer * buffer)1251 static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1252 {
1253 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1254 struct iris_hfi_buffer hfi_buffer;
1255 u32 port;
1256 int ret;
1257
1258 iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1259 if (buffer->type == BUF_COMV) {
1260 ret = iris_set_num_comv(inst);
1261 if (ret)
1262 return ret;
1263 }
1264
1265 port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1266 iris_hfi_gen2_packet_session_command(inst,
1267 HFI_CMD_BUFFER,
1268 HFI_HOST_FLAGS_INTR_REQUIRED,
1269 port,
1270 inst->session_id,
1271 HFI_PAYLOAD_STRUCTURE,
1272 &hfi_buffer,
1273 sizeof(hfi_buffer));
1274
1275 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1276 inst_hfi_gen2->packet->size);
1277 }
1278
iris_hfi_gen2_session_release_buffer(struct iris_inst * inst,struct iris_buffer * buffer)1279 static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer)
1280 {
1281 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst);
1282 struct iris_hfi_buffer hfi_buffer;
1283 u32 port;
1284
1285 iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer);
1286 hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
1287 port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type);
1288
1289 iris_hfi_gen2_packet_session_command(inst,
1290 HFI_CMD_BUFFER,
1291 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
1292 HFI_HOST_FLAGS_INTR_REQUIRED),
1293 port,
1294 inst->session_id,
1295 HFI_PAYLOAD_STRUCTURE,
1296 &hfi_buffer,
1297 sizeof(hfi_buffer));
1298
1299 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet,
1300 inst_hfi_gen2->packet->size);
1301 }
1302
1303 static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = {
1304 .sys_init = iris_hfi_gen2_sys_init,
1305 .sys_image_version = iris_hfi_gen2_sys_image_version,
1306 .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse,
1307 .sys_pc_prep = iris_hfi_gen2_sys_pc_prep,
1308 .session_open = iris_hfi_gen2_session_open,
1309 .session_set_config_params = iris_hfi_gen2_session_set_config_params,
1310 .session_set_property = iris_hfi_gen2_session_set_property,
1311 .session_start = iris_hfi_gen2_session_start,
1312 .session_queue_buf = iris_hfi_gen2_session_queue_buffer,
1313 .session_release_buf = iris_hfi_gen2_session_release_buffer,
1314 .session_pause = iris_hfi_gen2_session_pause,
1315 .session_resume_drc = iris_hfi_gen2_session_resume_drc,
1316 .session_stop = iris_hfi_gen2_session_stop,
1317 .session_drain = iris_hfi_gen2_session_drain,
1318 .session_resume_drain = iris_hfi_gen2_session_resume_drain,
1319 .session_close = iris_hfi_gen2_session_close,
1320 };
1321
iris_hfi_gen2_command_ops_init(struct iris_core * core)1322 void iris_hfi_gen2_command_ops_init(struct iris_core *core)
1323 {
1324 core->hfi_ops = &iris_hfi_gen2_command_ops;
1325 }
1326
iris_hfi_gen2_get_instance(void)1327 struct iris_inst *iris_hfi_gen2_get_instance(void)
1328 {
1329 struct iris_inst_hfi_gen2 *out;
1330
1331 /* The allocation is intentionally larger than struct iris_inst. */
1332 out = kzalloc_obj(*out);
1333
1334 return &out->inst;
1335 }
1336