Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.17 1066 lines 31 kB view raw
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}