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 "iris_hfi_gen1.h" 7 #include "iris_hfi_gen1_defines.h" 8 #include "iris_instance.h" 9 #include "iris_vpu_buffer.h" 10 11 static u32 iris_hfi_gen1_buf_type_from_driver(enum iris_buffer_type buffer_type) 12 { 13 switch (buffer_type) { 14 case BUF_INPUT: 15 return HFI_BUFFER_INPUT; 16 case BUF_OUTPUT: 17 return HFI_BUFFER_OUTPUT; 18 case BUF_PERSIST: 19 return HFI_BUFFER_INTERNAL_PERSIST_1; 20 case BUF_BIN: 21 return HFI_BUFFER_INTERNAL_SCRATCH; 22 case BUF_SCRATCH_1: 23 return HFI_BUFFER_INTERNAL_SCRATCH_1; 24 default: 25 return -EINVAL; 26 } 27 } 28 29 static int iris_hfi_gen1_sys_init(struct iris_core *core) 30 { 31 struct hfi_sys_init_pkt sys_init_pkt; 32 33 sys_init_pkt.hdr.size = sizeof(sys_init_pkt); 34 sys_init_pkt.hdr.pkt_type = HFI_CMD_SYS_INIT; 35 sys_init_pkt.arch_type = HFI_VIDEO_ARCH_OX; 36 37 return iris_hfi_queue_cmd_write_locked(core, &sys_init_pkt, sys_init_pkt.hdr.size); 38 } 39 40 static int iris_hfi_gen1_sys_image_version(struct iris_core *core) 41 { 42 struct hfi_sys_get_property_pkt packet; 43 44 packet.hdr.size = sizeof(packet); 45 packet.hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY; 46 packet.num_properties = 1; 47 packet.data = HFI_PROPERTY_SYS_IMAGE_VERSION; 48 49 return iris_hfi_queue_cmd_write_locked(core, &packet, packet.hdr.size); 50 } 51 52 static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *core) 53 { 54 struct hfi_sys_set_property_pkt *pkt; 55 struct hfi_enable *hfi; 56 u32 packet_size; 57 int ret; 58 59 packet_size = struct_size(pkt, data, 1) + sizeof(*hfi); 60 pkt = kzalloc(packet_size, GFP_KERNEL); 61 if (!pkt) 62 return -ENOMEM; 63 64 hfi = (struct hfi_enable *)&pkt->data[1]; 65 66 pkt->hdr.size = packet_size; 67 pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; 68 pkt->num_properties = 1; 69 pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; 70 hfi->enable = true; 71 72 ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt->hdr.size); 73 kfree(pkt); 74 75 return ret; 76 } 77 78 static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) 79 { 80 struct hfi_sys_pc_prep_pkt pkt; 81 82 pkt.hdr.size = sizeof(struct hfi_sys_pc_prep_pkt); 83 pkt.hdr.pkt_type = HFI_CMD_SYS_PC_PREP; 84 85 return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size); 86 } 87 88 static int iris_hfi_gen1_session_open(struct iris_inst *inst) 89 { 90 struct hfi_session_open_pkt packet; 91 int ret; 92 93 if (inst->state != IRIS_INST_DEINIT) 94 return -EALREADY; 95 96 packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt); 97 packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT; 98 packet.shdr.session_id = inst->session_id; 99 packet.session_domain = HFI_SESSION_TYPE_DEC; 100 packet.session_codec = HFI_VIDEO_CODEC_H264; 101 102 reinit_completion(&inst->completion); 103 104 ret = iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 105 if (ret) 106 return ret; 107 108 return iris_wait_for_session_response(inst, false); 109 } 110 111 static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst, 112 struct hfi_session_pkt *packet, 113 u32 ptype) 114 { 115 packet->shdr.hdr.size = sizeof(*packet); 116 packet->shdr.hdr.pkt_type = ptype; 117 packet->shdr.session_id = inst->session_id; 118 } 119 120 static int iris_hfi_gen1_session_close(struct iris_inst *inst) 121 { 122 struct hfi_session_pkt packet; 123 124 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SYS_SESSION_END); 125 126 return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 127 } 128 129 static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane) 130 { 131 struct iris_core *core = inst->core; 132 struct hfi_session_pkt packet; 133 int ret; 134 135 if (!V4L2_TYPE_IS_OUTPUT(plane)) 136 return 0; 137 138 if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) 139 return 0; 140 141 reinit_completion(&inst->completion); 142 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESOURCES); 143 144 ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); 145 if (ret) 146 return ret; 147 148 ret = iris_wait_for_session_response(inst, false); 149 if (ret) 150 return ret; 151 152 reinit_completion(&inst->completion); 153 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_START); 154 155 ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); 156 if (ret) 157 return ret; 158 159 ret = iris_wait_for_session_response(inst, false); 160 if (ret) 161 return ret; 162 163 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_LOAD_RESOURCES); 164 } 165 166 static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) 167 { 168 struct hfi_session_flush_pkt flush_pkt; 169 struct iris_core *core = inst->core; 170 struct hfi_session_pkt pkt; 171 u32 flush_type = 0; 172 int ret = 0; 173 174 if ((V4L2_TYPE_IS_OUTPUT(plane) && 175 inst->state == IRIS_INST_INPUT_STREAMING) || 176 (V4L2_TYPE_IS_CAPTURE(plane) && 177 inst->state == IRIS_INST_OUTPUT_STREAMING) || 178 inst->state == IRIS_INST_ERROR) { 179 reinit_completion(&inst->completion); 180 iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 181 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 182 if (!ret) 183 ret = iris_wait_for_session_response(inst, false); 184 185 reinit_completion(&inst->completion); 186 iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_RELEASE_RESOURCES); 187 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 188 if (!ret) 189 ret = iris_wait_for_session_response(inst, false); 190 191 iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 192 193 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 194 VB2_BUF_STATE_ERROR); 195 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 196 VB2_BUF_STATE_ERROR); 197 } else if (inst->state == IRIS_INST_STREAMING) { 198 if (V4L2_TYPE_IS_OUTPUT(plane)) 199 flush_type = HFI_FLUSH_ALL; 200 else if (V4L2_TYPE_IS_CAPTURE(plane)) 201 flush_type = HFI_FLUSH_OUTPUT; 202 203 reinit_completion(&inst->flush_completion); 204 205 flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); 206 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; 207 flush_pkt.shdr.session_id = inst->session_id; 208 flush_pkt.flush_type = flush_type; 209 210 ret = iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size); 211 if (!ret) 212 ret = iris_wait_for_session_response(inst, true); 213 } 214 215 return ret; 216 } 217 218 static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane) 219 { 220 struct hfi_session_pkt packet; 221 222 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE); 223 224 return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 225 } 226 227 static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf) 228 { 229 struct hfi_session_empty_buffer_compressed_pkt ip_pkt; 230 231 ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); 232 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 233 ip_pkt.shdr.session_id = inst->session_id; 234 ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp); 235 ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp); 236 ip_pkt.flags = buf->flags; 237 ip_pkt.mark_target = 0; 238 ip_pkt.mark_data = 0; 239 ip_pkt.offset = buf->data_offset; 240 ip_pkt.alloc_len = buf->buffer_size; 241 ip_pkt.filled_len = buf->data_size; 242 ip_pkt.input_tag = buf->index; 243 ip_pkt.packet_buffer = buf->device_addr; 244 245 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); 246 } 247 248 static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf) 249 { 250 struct hfi_session_fill_buffer_pkt op_pkt; 251 252 op_pkt.shdr.hdr.size = sizeof(struct hfi_session_fill_buffer_pkt); 253 op_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FILL_BUFFER; 254 op_pkt.shdr.session_id = inst->session_id; 255 op_pkt.output_tag = buf->index; 256 op_pkt.packet_buffer = buf->device_addr; 257 op_pkt.extradata_buffer = 0; 258 op_pkt.alloc_len = buf->buffer_size; 259 op_pkt.filled_len = buf->data_size; 260 op_pkt.offset = buf->data_offset; 261 op_pkt.data = 0; 262 263 if (buf->type == BUF_OUTPUT && iris_split_mode_enabled(inst)) 264 op_pkt.stream_id = 1; 265 else 266 op_pkt.stream_id = 0; 267 268 return iris_hfi_queue_cmd_write(inst->core, &op_pkt, op_pkt.shdr.hdr.size); 269 } 270 271 static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf) 272 { 273 struct hfi_session_set_buffers_pkt *int_pkt; 274 u32 buffer_type, i; 275 u32 packet_size; 276 int ret; 277 278 packet_size = struct_size(int_pkt, buffer_info, 1); 279 int_pkt = kzalloc(packet_size, GFP_KERNEL); 280 if (!int_pkt) 281 return -ENOMEM; 282 283 int_pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS; 284 int_pkt->shdr.session_id = inst->session_id; 285 int_pkt->buffer_size = buf->buffer_size; 286 int_pkt->min_buffer_size = buf->buffer_size; 287 int_pkt->num_buffers = 1; 288 int_pkt->extradata_size = 0; 289 int_pkt->shdr.hdr.size = packet_size; 290 for (i = 0; i < int_pkt->num_buffers; i++) 291 int_pkt->buffer_info[i] = buf->device_addr; 292 buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); 293 if (buffer_type == -EINVAL) { 294 ret = -EINVAL; 295 goto exit; 296 } 297 298 int_pkt->buffer_type = buffer_type; 299 ret = iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.size); 300 301 exit: 302 kfree(int_pkt); 303 304 return ret; 305 } 306 307 static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) 308 { 309 switch (buf->type) { 310 case BUF_INPUT: 311 return iris_hfi_gen1_queue_input_buffer(inst, buf); 312 case BUF_OUTPUT: 313 case BUF_DPB: 314 return iris_hfi_gen1_queue_output_buffer(inst, buf); 315 case BUF_PERSIST: 316 case BUF_BIN: 317 case BUF_SCRATCH_1: 318 return iris_hfi_gen1_queue_internal_buffer(inst, buf); 319 default: 320 return -EINVAL; 321 } 322 } 323 324 static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct iris_buffer *buf) 325 { 326 struct hfi_session_release_buffer_pkt *pkt; 327 u32 packet_size, buffer_type, i; 328 int ret; 329 330 buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); 331 if (buffer_type == -EINVAL) 332 return -EINVAL; 333 334 if (buffer_type == HFI_BUFFER_INPUT) 335 return 0; 336 337 packet_size = sizeof(*pkt) + sizeof(struct hfi_buffer_info); 338 pkt = kzalloc(packet_size, GFP_KERNEL); 339 if (!pkt) 340 return -ENOMEM; 341 342 pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS; 343 pkt->shdr.session_id = inst->session_id; 344 pkt->buffer_size = buf->buffer_size; 345 pkt->num_buffers = 1; 346 347 if (buffer_type == HFI_BUFFER_OUTPUT || 348 buffer_type == HFI_BUFFER_OUTPUT2) { 349 struct hfi_buffer_info *bi; 350 351 bi = (struct hfi_buffer_info *)pkt->buffer_info; 352 for (i = 0; i < pkt->num_buffers; i++) { 353 bi->buffer_addr = buf->device_addr; 354 bi->extradata_addr = 0; 355 } 356 pkt->shdr.hdr.size = packet_size; 357 } else { 358 for (i = 0; i < pkt->num_buffers; i++) 359 pkt->buffer_info[i] = buf->device_addr; 360 pkt->extradata_size = 0; 361 pkt->shdr.hdr.size = 362 sizeof(struct hfi_session_set_buffers_pkt) + 363 ((pkt->num_buffers) * sizeof(u32)); 364 } 365 366 pkt->response_req = true; 367 pkt->buffer_type = buffer_type; 368 369 ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); 370 if (ret) 371 goto exit; 372 373 ret = iris_wait_for_session_response(inst, false); 374 375 exit: 376 kfree(pkt); 377 378 return ret; 379 } 380 381 static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) 382 { 383 struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0}; 384 385 ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); 386 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 387 ip_pkt.shdr.session_id = inst->session_id; 388 ip_pkt.flags = HFI_BUFFERFLAG_EOS; 389 390 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); 391 } 392 393 static int 394 iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, 395 struct iris_inst *inst, u32 ptype, void *pdata) 396 { 397 void *prop_data = &packet->data[1]; 398 399 packet->shdr.hdr.size = sizeof(*packet); 400 packet->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY; 401 packet->shdr.session_id = inst->session_id; 402 packet->num_properties = 1; 403 packet->data[0] = ptype; 404 405 switch (ptype) { 406 case HFI_PROPERTY_PARAM_FRAME_SIZE: { 407 struct hfi_framesize *in = pdata, *fsize = prop_data; 408 409 fsize->buffer_type = in->buffer_type; 410 fsize->height = in->height; 411 fsize->width = in->width; 412 packet->shdr.hdr.size += sizeof(u32) + sizeof(*fsize); 413 break; 414 } 415 case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: { 416 struct hfi_videocores_usage_type *in = pdata, *cu = prop_data; 417 418 cu->video_core_enable_mask = in->video_core_enable_mask; 419 packet->shdr.hdr.size += sizeof(u32) + sizeof(*cu); 420 break; 421 } 422 case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: { 423 struct hfi_uncompressed_format_select *in = pdata; 424 struct hfi_uncompressed_format_select *hfi = prop_data; 425 426 hfi->buffer_type = in->buffer_type; 427 hfi->format = in->format; 428 packet->shdr.hdr.size += sizeof(u32) + sizeof(*hfi); 429 break; 430 } 431 case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: { 432 struct hfi_uncompressed_plane_actual_constraints_info *info = prop_data; 433 434 info->buffer_type = HFI_BUFFER_OUTPUT2; 435 info->num_planes = 2; 436 info->plane_format[0].stride_multiples = 128; 437 info->plane_format[0].max_stride = 8192; 438 info->plane_format[0].min_plane_buffer_height_multiple = 32; 439 info->plane_format[0].buffer_alignment = 256; 440 if (info->num_planes > 1) { 441 info->plane_format[1].stride_multiples = 128; 442 info->plane_format[1].max_stride = 8192; 443 info->plane_format[1].min_plane_buffer_height_multiple = 16; 444 info->plane_format[1].buffer_alignment = 256; 445 } 446 447 packet->shdr.hdr.size += sizeof(u32) + sizeof(*info); 448 break; 449 } 450 case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: { 451 struct hfi_buffer_count_actual *in = pdata; 452 struct hfi_buffer_count_actual *count = prop_data; 453 454 count->type = in->type; 455 count->count_actual = in->count_actual; 456 count->count_min_host = in->count_min_host; 457 packet->shdr.hdr.size += sizeof(u32) + sizeof(*count); 458 break; 459 } 460 case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: { 461 struct hfi_multi_stream *in = pdata; 462 struct hfi_multi_stream *multi = prop_data; 463 464 multi->buffer_type = in->buffer_type; 465 multi->enable = in->enable; 466 packet->shdr.hdr.size += sizeof(u32) + sizeof(*multi); 467 break; 468 } 469 case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: { 470 struct hfi_buffer_size_actual *in = pdata, *sz = prop_data; 471 472 sz->size = in->size; 473 sz->type = in->type; 474 packet->shdr.hdr.size += sizeof(u32) + sizeof(*sz); 475 break; 476 } 477 case HFI_PROPERTY_PARAM_WORK_ROUTE: { 478 struct hfi_video_work_route *wr = prop_data; 479 u32 *in = pdata; 480 481 wr->video_work_route = *in; 482 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wr); 483 break; 484 } 485 case HFI_PROPERTY_PARAM_WORK_MODE: { 486 struct hfi_video_work_mode *wm = prop_data; 487 u32 *in = pdata; 488 489 wm->video_work_mode = *in; 490 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm); 491 break; 492 } 493 case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER: { 494 struct hfi_enable *en = prop_data; 495 u32 *in = pdata; 496 497 en->enable = *in; 498 packet->shdr.hdr.size += sizeof(u32) + sizeof(*en); 499 break; 500 } 501 default: 502 return -EINVAL; 503 } 504 505 return 0; 506 } 507 508 static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type, 509 void *payload, u32 payload_size) 510 { 511 struct hfi_session_set_property_pkt *pkt; 512 u32 packet_size; 513 int ret; 514 515 packet_size = sizeof(*pkt) + sizeof(u32) + payload_size; 516 pkt = kzalloc(packet_size, GFP_KERNEL); 517 if (!pkt) 518 return -ENOMEM; 519 520 ret = iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type, payload); 521 if (ret == -EOPNOTSUPP) { 522 ret = 0; 523 goto exit; 524 } 525 if (ret) 526 goto exit; 527 528 ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); 529 530 exit: 531 kfree(pkt); 532 533 return ret; 534 } 535 536 static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet_type, 537 u32 flag, u32 plane, u32 payload_type, 538 void *payload, u32 payload_size) 539 { 540 return hfi_gen1_set_property(inst, packet_type, payload, payload_size); 541 } 542 543 static int iris_hfi_gen1_set_resolution(struct iris_inst *inst) 544 { 545 u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 546 struct hfi_framesize fs; 547 int ret; 548 549 fs.buffer_type = HFI_BUFFER_INPUT; 550 fs.width = inst->fmt_src->fmt.pix_mp.width; 551 fs.height = inst->fmt_src->fmt.pix_mp.height; 552 553 ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 554 if (ret) 555 return ret; 556 557 fs.buffer_type = HFI_BUFFER_OUTPUT2; 558 fs.width = inst->fmt_dst->fmt.pix_mp.width; 559 fs.height = inst->fmt_dst->fmt.pix_mp.height; 560 561 return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 562 } 563 564 static int iris_hfi_gen1_decide_core(struct iris_inst *inst) 565 { 566 const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; 567 struct hfi_videocores_usage_type cu; 568 569 cu.video_core_enable_mask = HFI_CORE_ID_1; 570 571 return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu)); 572 } 573 574 static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst) 575 { 576 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 577 u32 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 578 struct hfi_uncompressed_format_select fmt; 579 int ret; 580 581 if (iris_split_mode_enabled(inst)) { 582 fmt.buffer_type = HFI_BUFFER_OUTPUT; 583 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12_UBWC : 0; 584 585 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 586 if (ret) 587 return ret; 588 589 fmt.buffer_type = HFI_BUFFER_OUTPUT2; 590 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 591 592 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 593 } else { 594 fmt.buffer_type = HFI_BUFFER_OUTPUT; 595 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; 596 597 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 598 } 599 600 return ret; 601 } 602 603 static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst) 604 { 605 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 606 struct hfi_uncompressed_plane_actual_constraints_info pconstraint; 607 608 pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; 609 pconstraint.num_planes = 2; 610 pconstraint.plane_format[0].stride_multiples = 128; 611 pconstraint.plane_format[0].max_stride = 8192; 612 pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32; 613 pconstraint.plane_format[0].buffer_alignment = 256; 614 615 pconstraint.plane_format[1].stride_multiples = 128; 616 pconstraint.plane_format[1].max_stride = 8192; 617 pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16; 618 pconstraint.plane_format[1].buffer_alignment = 256; 619 620 return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint)); 621 } 622 623 static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst) 624 { 625 u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 626 struct hfi_buffer_count_actual buf_count; 627 int ret; 628 629 buf_count.type = HFI_BUFFER_INPUT; 630 buf_count.count_actual = VIDEO_MAX_FRAME; 631 buf_count.count_min_host = VIDEO_MAX_FRAME; 632 633 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 634 if (ret) 635 return ret; 636 637 if (iris_split_mode_enabled(inst)) { 638 buf_count.type = HFI_BUFFER_OUTPUT; 639 buf_count.count_actual = VIDEO_MAX_FRAME; 640 buf_count.count_min_host = VIDEO_MAX_FRAME; 641 642 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 643 if (ret) 644 return ret; 645 646 buf_count.type = HFI_BUFFER_OUTPUT2; 647 buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); 648 buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); 649 650 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 651 } else { 652 buf_count.type = HFI_BUFFER_OUTPUT; 653 buf_count.count_actual = VIDEO_MAX_FRAME; 654 buf_count.count_min_host = VIDEO_MAX_FRAME; 655 656 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 657 } 658 659 return ret; 660 } 661 662 static int iris_hfi_gen1_set_multistream(struct iris_inst *inst) 663 { 664 u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 665 struct hfi_multi_stream multi = {0}; 666 int ret; 667 668 if (iris_split_mode_enabled(inst)) { 669 multi.buffer_type = HFI_BUFFER_OUTPUT; 670 multi.enable = 0; 671 672 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 673 if (ret) 674 return ret; 675 676 multi.buffer_type = HFI_BUFFER_OUTPUT2; 677 multi.enable = 1; 678 679 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 680 } else { 681 multi.buffer_type = HFI_BUFFER_OUTPUT; 682 multi.enable = 1; 683 684 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 685 if (ret) 686 return ret; 687 688 multi.buffer_type = HFI_BUFFER_OUTPUT2; 689 multi.enable = 0; 690 691 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 692 } 693 694 return ret; 695 } 696 697 static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst) 698 { 699 const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 700 struct hfi_buffer_size_actual bufsz; 701 int ret; 702 703 if (iris_split_mode_enabled(inst)) { 704 bufsz.type = HFI_BUFFER_OUTPUT; 705 bufsz.size = iris_vpu_buf_size(inst, BUF_DPB); 706 707 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 708 if (ret) 709 return ret; 710 711 bufsz.type = HFI_BUFFER_OUTPUT2; 712 bufsz.size = inst->buffers[BUF_OUTPUT].size; 713 714 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 715 } else { 716 bufsz.type = HFI_BUFFER_OUTPUT; 717 bufsz.size = inst->buffers[BUF_OUTPUT].size; 718 719 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 720 if (ret) 721 return ret; 722 723 bufsz.type = HFI_BUFFER_OUTPUT2; 724 bufsz.size = 0; 725 726 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 727 } 728 729 return ret; 730 } 731 732 static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane) 733 { 734 struct iris_core *core = inst->core; 735 u32 config_params_size, i, j; 736 const u32 *config_params; 737 int ret; 738 739 static const struct iris_hfi_prop_type_handle prop_type_handle_inp_arr[] = { 740 {HFI_PROPERTY_PARAM_FRAME_SIZE, 741 iris_hfi_gen1_set_resolution}, 742 {HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, 743 iris_hfi_gen1_decide_core}, 744 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 745 iris_hfi_gen1_set_raw_format}, 746 {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 747 iris_hfi_gen1_set_format_constraints}, 748 {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 749 iris_hfi_gen1_set_num_bufs}, 750 {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 751 iris_hfi_gen1_set_multistream}, 752 {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 753 iris_hfi_gen1_set_bufsize}, 754 }; 755 756 static const struct iris_hfi_prop_type_handle prop_type_handle_out_arr[] = { 757 {HFI_PROPERTY_PARAM_FRAME_SIZE, 758 iris_hfi_gen1_set_resolution}, 759 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 760 iris_hfi_gen1_set_raw_format}, 761 {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 762 iris_hfi_gen1_set_format_constraints}, 763 {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 764 iris_hfi_gen1_set_num_bufs}, 765 {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 766 iris_hfi_gen1_set_multistream}, 767 {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 768 iris_hfi_gen1_set_bufsize}, 769 }; 770 771 config_params = core->iris_platform_data->input_config_params; 772 config_params_size = core->iris_platform_data->input_config_params_size; 773 774 if (V4L2_TYPE_IS_OUTPUT(plane)) { 775 for (i = 0; i < config_params_size; i++) { 776 for (j = 0; j < ARRAY_SIZE(prop_type_handle_inp_arr); j++) { 777 if (prop_type_handle_inp_arr[j].type == config_params[i]) { 778 ret = prop_type_handle_inp_arr[j].handle(inst); 779 if (ret) 780 return ret; 781 break; 782 } 783 } 784 } 785 } else if (V4L2_TYPE_IS_CAPTURE(plane)) { 786 for (i = 0; i < config_params_size; i++) { 787 for (j = 0; j < ARRAY_SIZE(prop_type_handle_out_arr); j++) { 788 if (prop_type_handle_out_arr[j].type == config_params[i]) { 789 ret = prop_type_handle_out_arr[j].handle(inst); 790 if (ret) 791 return ret; 792 break; 793 } 794 } 795 } 796 } 797 798 return 0; 799 } 800 801 static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { 802 .sys_init = iris_hfi_gen1_sys_init, 803 .sys_image_version = iris_hfi_gen1_sys_image_version, 804 .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, 805 .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, 806 .session_open = iris_hfi_gen1_session_open, 807 .session_set_config_params = iris_hfi_gen1_session_set_config_params, 808 .session_set_property = iris_hfi_gen1_session_set_property, 809 .session_start = iris_hfi_gen1_session_start, 810 .session_queue_buf = iris_hfi_gen1_session_queue_buffer, 811 .session_release_buf = iris_hfi_gen1_session_unset_buffers, 812 .session_resume_drc = iris_hfi_gen1_session_continue, 813 .session_stop = iris_hfi_gen1_session_stop, 814 .session_drain = iris_hfi_gen1_session_drain, 815 .session_close = iris_hfi_gen1_session_close, 816 }; 817 818 void iris_hfi_gen1_command_ops_init(struct iris_core *core) 819 { 820 core->hfi_ops = &iris_hfi_gen1_command_ops; 821 } 822 823 struct iris_inst *iris_hfi_gen1_get_instance(void) 824 { 825 return kzalloc(sizeof(struct iris_inst), GFP_KERNEL); 826 } 827