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