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