FILE
iris_hfi_gen2_response.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
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 <media/v4l2-mem2mem.h> 7 8#include "iris_hfi_gen2.h" 9#include "iris_hfi_gen2_defines.h" 10#include "iris_hfi_gen2_packet.h" 11#include "iris_vdec.h" 12#include "iris_vpu_buffer.h" 13#include "iris_vpu_common.h" 14 15struct iris_hfi_gen2_core_hfi_range { 16 u32 begin; 17 u32 end; 18 int (*handle)(struct iris_core *core, struct iris_hfi_packet *pkt); 19}; 20 21struct iris_hfi_gen2_inst_hfi_range { 22 u32 begin; 23 u32 end; 24 int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt); 25}; 26 27struct iris_hfi_gen2_packet_handle { 28 enum hfi_buffer_type type; 29 int (*handle)(struct iris_inst *inst, struct iris_hfi_packet *pkt); 30}; 31 32static u32 iris_hfi_gen2_buf_type_to_driver(struct iris_inst *inst, 33 enum hfi_buffer_type buf_type) 34{ 35 switch (buf_type) { 36 case HFI_BUFFER_BITSTREAM: 37 return BUF_INPUT; 38 case HFI_BUFFER_RAW: 39 return BUF_OUTPUT; 40 case HFI_BUFFER_BIN: 41 return BUF_BIN; 42 case HFI_BUFFER_ARP: 43 return BUF_ARP; 44 case HFI_BUFFER_COMV: 45 return BUF_COMV; 46 case HFI_BUFFER_NON_COMV: 47 return BUF_NON_COMV; 48 case HFI_BUFFER_LINE: 49 return BUF_LINE; 50 case HFI_BUFFER_DPB: 51 if (inst->domain == DECODER) 52 return BUF_DPB; 53 else 54 return BUF_SCRATCH_2; 55 case HFI_BUFFER_PERSIST: 56 return BUF_PERSIST; 57 default: 58 return 0; 59 } 60} 61 62static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type) 63{ 64 switch (buffer_type) { 65 case HFI_BUFFER_BITSTREAM: 66 case HFI_BUFFER_RAW: 67 case HFI_BUFFER_BIN: 68 case HFI_BUFFER_ARP: 69 case HFI_BUFFER_COMV: 70 case HFI_BUFFER_NON_COMV: 71 case HFI_BUFFER_LINE: 72 case HFI_BUFFER_DPB: 73 case HFI_BUFFER_PERSIST: 74 case HFI_BUFFER_VPSS: 75 return true; 76 default: 77 return false; 78 } 79} 80 81static bool iris_hfi_gen2_is_valid_hfi_port(u32 port, u32 buffer_type) 82{ 83 if (port == HFI_PORT_NONE && buffer_type != HFI_BUFFER_PERSIST) 84 return false; 85 86 if (port != HFI_PORT_BITSTREAM && port != HFI_PORT_RAW) 87 return false; 88 89 return true; 90} 91 92static int iris_hfi_gen2_get_driver_buffer_flags(struct iris_inst *inst, u32 hfi_flags) 93{ 94 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 95 u32 keyframe = HFI_GEN2_PICTURE_IDR | HFI_GEN2_PICTURE_I | 96 HFI_GEN2_PICTURE_CRA | HFI_GEN2_PICTURE_BLA; 97 u32 driver_flags = 0; 98 99 if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_NOSHOW) 100 driver_flags |= V4L2_BUF_FLAG_ERROR; 101 else if (inst_hfi_gen2->hfi_frame_info.picture_type & keyframe) 102 driver_flags |= V4L2_BUF_FLAG_KEYFRAME; 103 else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_P) 104 driver_flags |= V4L2_BUF_FLAG_PFRAME; 105 else if (inst_hfi_gen2->hfi_frame_info.picture_type & HFI_GEN2_PICTURE_B) 106 driver_flags |= V4L2_BUF_FLAG_BFRAME; 107 108 if (inst_hfi_gen2->hfi_frame_info.data_corrupt || inst_hfi_gen2->hfi_frame_info.overflow) 109 driver_flags |= V4L2_BUF_FLAG_ERROR; 110 111 if (hfi_flags & HFI_BUF_FW_FLAG_LAST || 112 hfi_flags & HFI_BUF_FW_FLAG_PSC_LAST) 113 driver_flags |= V4L2_BUF_FLAG_LAST; 114 115 return driver_flags; 116} 117 118static bool iris_hfi_gen2_validate_packet_payload(struct iris_hfi_packet *pkt) 119{ 120 u32 payload_size = 0; 121 122 switch (pkt->payload_info) { 123 case HFI_PAYLOAD_U32: 124 case HFI_PAYLOAD_S32: 125 case HFI_PAYLOAD_Q16: 126 case HFI_PAYLOAD_U32_ENUM: 127 case HFI_PAYLOAD_32_PACKED: 128 payload_size = 4; 129 break; 130 case HFI_PAYLOAD_U64: 131 case HFI_PAYLOAD_S64: 132 case HFI_PAYLOAD_64_PACKED: 133 payload_size = 8; 134 break; 135 case HFI_PAYLOAD_STRUCTURE: 136 if (pkt->type == HFI_CMD_BUFFER) 137 payload_size = sizeof(struct iris_hfi_buffer); 138 break; 139 default: 140 payload_size = 0; 141 break; 142 } 143 144 if (pkt->size < sizeof(struct iris_hfi_packet) + payload_size) 145 return false; 146 147 return true; 148} 149 150static int iris_hfi_gen2_validate_packet(u8 *response_pkt, u8 *core_resp_pkt) 151{ 152 u8 *response_limit = core_resp_pkt + IFACEQ_CORE_PKT_SIZE; 153 u32 response_pkt_size = *(u32 *)response_pkt; 154 155 if (!response_pkt_size) 156 return -EINVAL; 157 158 if (response_pkt_size < sizeof(struct iris_hfi_packet)) 159 return -EINVAL; 160 161 if (response_pkt + response_pkt_size > response_limit) 162 return -EINVAL; 163 164 return 0; 165} 166 167static int iris_hfi_gen2_validate_hdr_packet(struct iris_core *core, struct iris_hfi_header *hdr) 168{ 169 struct iris_hfi_packet *packet; 170 int ret; 171 u8 *pkt; 172 u32 i; 173 174 if (hdr->size < sizeof(*hdr) + sizeof(*packet)) 175 return -EINVAL; 176 177 pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); 178 179 for (i = 0; i < hdr->num_packets; i++) { 180 packet = (struct iris_hfi_packet *)pkt; 181 ret = iris_hfi_gen2_validate_packet(pkt, core->response_packet); 182 if (ret) 183 return ret; 184 185 pkt += packet->size; 186 } 187 188 return 0; 189} 190 191static int iris_hfi_gen2_handle_session_info(struct iris_inst *inst, 192 struct iris_hfi_packet *pkt) 193{ 194 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 195 struct iris_core *core = inst->core; 196 int ret = 0; 197 char *info; 198 199 switch (pkt->type) { 200 case HFI_INFO_UNSUPPORTED: 201 info = "unsupported"; 202 break; 203 case HFI_INFO_DATA_CORRUPT: 204 info = "data corrupt"; 205 inst_hfi_gen2->hfi_frame_info.data_corrupt = 1; 206 break; 207 case HFI_INFO_BUFFER_OVERFLOW: 208 info = "buffer overflow"; 209 inst_hfi_gen2->hfi_frame_info.overflow = 1; 210 break; 211 case HFI_INFO_HFI_FLAG_DRAIN_LAST: 212 info = "drain last flag"; 213 ret = iris_inst_sub_state_change_drain_last(inst); 214 break; 215 case HFI_INFO_HFI_FLAG_PSC_LAST: 216 info = "drc last flag"; 217 ret = iris_inst_sub_state_change_drc_last(inst); 218 break; 219 default: 220 info = "unknown"; 221 break; 222 } 223 224 dev_dbg(core->dev, "session info received %#x: %s\n", 225 pkt->type, info); 226 227 return ret; 228} 229 230static int iris_hfi_gen2_handle_session_error(struct iris_inst *inst, 231 struct iris_hfi_packet *pkt) 232{ 233 struct iris_core *core = inst->core; 234 char *error; 235 236 switch (pkt->type) { 237 case HFI_ERROR_MAX_SESSIONS: 238 error = "exceeded max sessions"; 239 break; 240 case HFI_ERROR_UNKNOWN_SESSION: 241 error = "unknown session id"; 242 break; 243 case HFI_ERROR_INVALID_STATE: 244 error = "invalid operation for current state"; 245 break; 246 case HFI_ERROR_INSUFFICIENT_RESOURCES: 247 error = "insufficient resources"; 248 break; 249 case HFI_ERROR_BUFFER_NOT_SET: 250 error = "internal buffers not set"; 251 break; 252 case HFI_ERROR_FATAL: 253 error = "fatal error"; 254 break; 255 case HFI_ERROR_STREAM_UNSUPPORTED: 256 error = "unsupported stream"; 257 break; 258 default: 259 error = "unknown"; 260 break; 261 } 262 263 dev_err(core->dev, "session error received %#x: %s\n", pkt->type, error); 264 iris_vb2_queue_error(inst); 265 iris_inst_change_state(inst, IRIS_INST_ERROR); 266 267 return 0; 268} 269 270static int iris_hfi_gen2_handle_system_error(struct iris_core *core, 271 struct iris_hfi_packet *pkt) 272{ 273 struct iris_inst *instance; 274 275 if (pkt) 276 dev_err(core->dev, "received system error of type %#x\n", pkt->type); 277 278 core->state = IRIS_CORE_ERROR; 279 280 mutex_lock(&core->lock); 281 list_for_each_entry(instance, &core->instances, list) 282 iris_inst_change_state(instance, IRIS_INST_ERROR); 283 mutex_unlock(&core->lock); 284 285 schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); 286 287 return 0; 288} 289 290static int iris_hfi_gen2_handle_system_init(struct iris_core *core, 291 struct iris_hfi_packet *pkt) 292{ 293 if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { 294 core->state = IRIS_CORE_ERROR; 295 return 0; 296 } 297 298 complete(&core->core_init_done); 299 300 return 0; 301} 302 303static void iris_hfi_gen2_handle_session_close(struct iris_inst *inst, 304 struct iris_hfi_packet *pkt) 305{ 306 if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { 307 iris_inst_change_state(inst, IRIS_INST_ERROR); 308 return; 309 } 310 311 complete(&inst->completion); 312} 313 314static int iris_hfi_gen2_handle_input_buffer(struct iris_inst *inst, 315 struct iris_hfi_buffer *buffer) 316{ 317 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 318 struct v4l2_m2m_buffer *m2m_buffer, *n; 319 struct iris_buffer *buf; 320 bool found = false; 321 322 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) { 323 buf = to_iris_buffer(&m2m_buffer->vb); 324 if (buf->index == buffer->index) { 325 found = true; 326 break; 327 } 328 } 329 if (!found) 330 return -EINVAL; 331 332 if (!(buf->attr & BUF_ATTR_QUEUED)) 333 return -EINVAL; 334 335 buf->attr &= ~BUF_ATTR_QUEUED; 336 buf->attr |= BUF_ATTR_DEQUEUED; 337 338 buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, buffer->flags); 339 340 return 0; 341} 342 343static int iris_hfi_gen2_handle_output_buffer(struct iris_inst *inst, 344 struct iris_hfi_buffer *hfi_buffer) 345{ 346 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 347 struct v4l2_m2m_buffer *m2m_buffer, *n; 348 struct iris_buffer *buf; 349 bool found = false; 350 int ret; 351 352 if (hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST) { 353 ret = iris_inst_sub_state_change_drain_last(inst); 354 if (ret) 355 return ret; 356 } 357 358 if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) { 359 ret = iris_inst_sub_state_change_drc_last(inst); 360 if (ret) 361 return ret; 362 } 363 364 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) { 365 buf = to_iris_buffer(&m2m_buffer->vb); 366 if (buf->index == hfi_buffer->index && 367 buf->device_addr == hfi_buffer->base_address && 368 buf->data_offset == hfi_buffer->data_offset) { 369 found = true; 370 break; 371 } 372 } 373 if (!found) 374 return -EINVAL; 375 376 if (!(buf->attr & BUF_ATTR_QUEUED)) 377 return -EINVAL; 378 379 buf->data_offset = hfi_buffer->data_offset; 380 buf->data_size = hfi_buffer->data_size; 381 buf->timestamp = hfi_buffer->timestamp; 382 383 buf->attr &= ~BUF_ATTR_QUEUED; 384 buf->attr |= BUF_ATTR_DEQUEUED; 385 386 buf->flags = iris_hfi_gen2_get_driver_buffer_flags(inst, hfi_buffer->flags); 387 388 if (!buf->data_size && inst->state == IRIS_INST_STREAMING && 389 !(hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST)) { 390 buf->flags |= V4L2_BUF_FLAG_ERROR; 391 } 392 393 return 0; 394} 395 396static void iris_hfi_gen2_handle_dequeue_buffers(struct iris_inst *inst) 397{ 398 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 399 struct v4l2_m2m_buffer *buffer, *n; 400 struct iris_buffer *buf = NULL; 401 402 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buffer, n) { 403 buf = to_iris_buffer(&buffer->vb); 404 if (buf->attr & BUF_ATTR_DEQUEUED) { 405 buf->attr &= ~BUF_ATTR_DEQUEUED; 406 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 407 buf->attr |= BUF_ATTR_BUFFER_DONE; 408 iris_vb2_buffer_done(inst, buf); 409 } 410 } 411 } 412 413 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buffer, n) { 414 buf = to_iris_buffer(&buffer->vb); 415 if (buf->attr & BUF_ATTR_DEQUEUED) { 416 buf->attr &= ~BUF_ATTR_DEQUEUED; 417 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 418 buf->attr |= BUF_ATTR_BUFFER_DONE; 419 iris_vb2_buffer_done(inst, buf); 420 } 421 } 422 } 423} 424 425static int iris_hfi_gen2_handle_release_internal_buffer(struct iris_inst *inst, 426 struct iris_hfi_buffer *buffer) 427{ 428 u32 buf_type = iris_hfi_gen2_buf_type_to_driver(inst, buffer->type); 429 struct iris_buffers *buffers = &inst->buffers[buf_type]; 430 struct iris_buffer *buf, *iter; 431 bool found = false; 432 433 list_for_each_entry(iter, &buffers->list, list) { 434 if (iter->device_addr == buffer->base_address) { 435 found = true; 436 buf = iter; 437 break; 438 } 439 } 440 if (!found) 441 return -EINVAL; 442 443 buf->attr &= ~BUF_ATTR_QUEUED; 444 445 return iris_destroy_internal_buffer(inst, buf); 446} 447 448static int iris_hfi_gen2_handle_session_stop(struct iris_inst *inst, 449 struct iris_hfi_packet *pkt) 450{ 451 int ret = 0; 452 453 if (pkt->port == HFI_PORT_RAW) 454 ret = iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 455 else if (pkt->port == HFI_PORT_BITSTREAM) 456 ret = iris_inst_sub_state_change_pause(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 457 458 complete(&inst->completion); 459 460 return ret; 461} 462 463static int iris_hfi_gen2_handle_session_buffer(struct iris_inst *inst, 464 struct iris_hfi_packet *pkt) 465{ 466 struct iris_hfi_buffer *buffer; 467 468 if (pkt->payload_info == HFI_PAYLOAD_NONE) 469 return 0; 470 471 if (!iris_hfi_gen2_validate_packet_payload(pkt)) { 472 iris_inst_change_state(inst, IRIS_INST_ERROR); 473 return 0; 474 } 475 476 buffer = (struct iris_hfi_buffer *)((u8 *)pkt + sizeof(*pkt)); 477 if (!iris_hfi_gen2_is_valid_hfi_buffer_type(buffer->type)) 478 return 0; 479 480 if (!iris_hfi_gen2_is_valid_hfi_port(pkt->port, buffer->type)) 481 return 0; 482 483 if (inst->domain == DECODER) { 484 if (buffer->type == HFI_BUFFER_BITSTREAM) 485 return iris_hfi_gen2_handle_input_buffer(inst, buffer); 486 else if (buffer->type == HFI_BUFFER_RAW) 487 return iris_hfi_gen2_handle_output_buffer(inst, buffer); 488 else 489 return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); 490 } else { 491 if (buffer->type == HFI_BUFFER_RAW) 492 return iris_hfi_gen2_handle_input_buffer(inst, buffer); 493 else if (buffer->type == HFI_BUFFER_BITSTREAM) 494 return iris_hfi_gen2_handle_output_buffer(inst, buffer); 495 else 496 return iris_hfi_gen2_handle_release_internal_buffer(inst, buffer); 497 } 498 return 0; 499} 500 501static int iris_hfi_gen2_handle_session_drain(struct iris_inst *inst, 502 struct iris_hfi_packet *pkt) 503{ 504 int ret = 0; 505 506 if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS)) { 507 iris_inst_change_state(inst, IRIS_INST_ERROR); 508 return 0; 509 } 510 511 if (inst->sub_state & IRIS_INST_SUB_DRAIN) 512 ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_INPUT_PAUSE); 513 514 return ret; 515} 516 517static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) 518{ 519 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 520 struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; 521 struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; 522 u32 primaries, matrix_coeff, transfer_char; 523 struct hfi_subscription_params subsc_params; 524 u32 colour_description_present_flag; 525 u32 video_signal_type_present_flag; 526 struct iris_core *core = inst->core; 527 u32 full_range, width, height; 528 struct vb2_queue *dst_q; 529 struct v4l2_ctrl *ctrl; 530 531 subsc_params = inst_hfi_gen2->src_subcr_params; 532 width = (subsc_params.bitstream_resolution & 533 HFI_BITMASK_BITSTREAM_WIDTH) >> 16; 534 height = subsc_params.bitstream_resolution & 535 HFI_BITMASK_BITSTREAM_HEIGHT; 536 537 pixmp_ip->width = width; 538 pixmp_ip->height = height; 539 540 pixmp_op->width = ALIGN(width, 128); 541 pixmp_op->height = ALIGN(height, 32); 542 pixmp_op->plane_fmt[0].bytesperline = ALIGN(width, 128); 543 pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 544 545 matrix_coeff = subsc_params.color_info & 0xFF; 546 transfer_char = (subsc_params.color_info & 0xFF00) >> 8; 547 primaries = (subsc_params.color_info & 0xFF0000) >> 16; 548 colour_description_present_flag = 549 (subsc_params.color_info & 0x1000000) >> 24; 550 full_range = (subsc_params.color_info & 0x2000000) >> 25; 551 video_signal_type_present_flag = 552 (subsc_params.color_info & 0x20000000) >> 29; 553 554 pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT; 555 pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT; 556 pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 557 pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT; 558 559 if (video_signal_type_present_flag) { 560 pixmp_op->quantization = 561 full_range ? 562 V4L2_QUANTIZATION_FULL_RANGE : 563 V4L2_QUANTIZATION_LIM_RANGE; 564 if (colour_description_present_flag) { 565 pixmp_op->colorspace = 566 iris_hfi_get_v4l2_color_primaries(primaries); 567 pixmp_op->xfer_func = 568 iris_hfi_get_v4l2_transfer_char(transfer_char); 569 pixmp_op->ycbcr_enc = 570 iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff); 571 } 572 } 573 574 pixmp_ip->colorspace = pixmp_op->colorspace; 575 pixmp_ip->xfer_func = pixmp_op->xfer_func; 576 pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc; 577 pixmp_ip->quantization = pixmp_op->quantization; 578 579 inst->crop.top = subsc_params.crop_offsets[0] & 0xFFFF; 580 inst->crop.left = (subsc_params.crop_offsets[0] >> 16) & 0xFFFF; 581 inst->crop.height = pixmp_ip->height - 582 (subsc_params.crop_offsets[1] & 0xFFFF) - inst->crop.top; 583 inst->crop.width = pixmp_ip->width - 584 ((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left; 585 586 switch (inst->codec) { 587 case V4L2_PIX_FMT_HEVC: 588 inst->fw_caps[PROFILE_HEVC].value = subsc_params.profile; 589 inst->fw_caps[LEVEL_HEVC].value = subsc_params.level; 590 break; 591 case V4L2_PIX_FMT_VP9: 592 inst->fw_caps[PROFILE_VP9].value = subsc_params.profile; 593 inst->fw_caps[LEVEL_VP9].value = subsc_params.level; 594 break; 595 case V4L2_PIX_FMT_H264: 596 inst->fw_caps[PROFILE_H264].value = subsc_params.profile; 597 inst->fw_caps[LEVEL_H264].value = subsc_params.level; 598 break; 599 } 600 601 inst->fw_caps[POC].value = subsc_params.pic_order_cnt; 602 inst->fw_caps[TIER].value = subsc_params.tier; 603 604 if (subsc_params.bit_depth != BIT_DEPTH_8 || 605 !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) { 606 dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n", 607 subsc_params.bit_depth, subsc_params.coded_frames); 608 iris_inst_change_state(inst, IRIS_INST_ERROR); 609 } 610 611 inst->fw_min_count = subsc_params.fw_min_count; 612 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 613 inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; 614 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE); 615 if (ctrl) 616 v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count); 617 618 dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 619 dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count; 620} 621 622static int iris_hfi_gen2_handle_src_change(struct iris_inst *inst, 623 struct iris_hfi_packet *pkt) 624{ 625 int ret; 626 627 if (pkt->port != HFI_PORT_BITSTREAM) 628 return 0; 629 630 ret = iris_inst_sub_state_change_drc(inst); 631 if (ret) 632 return ret; 633 634 iris_hfi_gen2_read_input_subcr_params(inst); 635 iris_vdec_src_change(inst); 636 637 return 0; 638} 639 640static int iris_hfi_gen2_handle_session_command(struct iris_inst *inst, 641 struct iris_hfi_packet *pkt) 642{ 643 int ret = 0; 644 645 switch (pkt->type) { 646 case HFI_CMD_CLOSE: 647 iris_hfi_gen2_handle_session_close(inst, pkt); 648 break; 649 case HFI_CMD_STOP: 650 iris_hfi_gen2_handle_session_stop(inst, pkt); 651 break; 652 case HFI_CMD_BUFFER: 653 ret = iris_hfi_gen2_handle_session_buffer(inst, pkt); 654 break; 655 case HFI_CMD_SETTINGS_CHANGE: 656 ret = iris_hfi_gen2_handle_src_change(inst, pkt); 657 break; 658 case HFI_CMD_DRAIN: 659 ret = iris_hfi_gen2_handle_session_drain(inst, pkt); 660 break; 661 default: 662 break; 663 } 664 665 return ret; 666} 667 668static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, 669 struct iris_hfi_packet *pkt) 670{ 671 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 672 673 if (pkt->flags & HFI_FW_FLAGS_INFORMATION) 674 return 0; 675 676 switch (pkt->type) { 677 case HFI_PROP_BITSTREAM_RESOLUTION: 678 inst_hfi_gen2->src_subcr_params.bitstream_resolution = pkt->payload[0]; 679 break; 680 case HFI_PROP_CROP_OFFSETS: 681 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = pkt->payload[0]; 682 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = pkt->payload[1]; 683 break; 684 case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: 685 inst_hfi_gen2->src_subcr_params.bit_depth = pkt->payload[0]; 686 break; 687 case HFI_PROP_CODED_FRAMES: 688 inst_hfi_gen2->src_subcr_params.coded_frames = pkt->payload[0]; 689 break; 690 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: 691 inst_hfi_gen2->src_subcr_params.fw_min_count = pkt->payload[0]; 692 break; 693 case HFI_PROP_PIC_ORDER_CNT_TYPE: 694 inst_hfi_gen2->src_subcr_params.pic_order_cnt = pkt->payload[0]; 695 break; 696 case HFI_PROP_SIGNAL_COLOR_INFO: 697 inst_hfi_gen2->src_subcr_params.color_info = pkt->payload[0]; 698 break; 699 case HFI_PROP_PROFILE: 700 inst_hfi_gen2->src_subcr_params.profile = pkt->payload[0]; 701 break; 702 case HFI_PROP_LEVEL: 703 inst_hfi_gen2->src_subcr_params.level = pkt->payload[0]; 704 break; 705 case HFI_PROP_TIER: 706 inst_hfi_gen2->src_subcr_params.tier = pkt->payload[0]; 707 break; 708 case HFI_PROP_PICTURE_TYPE: 709 inst_hfi_gen2->hfi_frame_info.picture_type = pkt->payload[0]; 710 break; 711 case HFI_PROP_NO_OUTPUT: 712 inst_hfi_gen2->hfi_frame_info.no_output = 1; 713 break; 714 case HFI_PROP_QUALITY_MODE: 715 case HFI_PROP_STAGE: 716 case HFI_PROP_PIPE: 717 default: 718 break; 719 } 720 721 return 0; 722} 723 724static int iris_hfi_gen2_handle_image_version_property(struct iris_core *core, 725 struct iris_hfi_packet *pkt) 726{ 727 u8 *str_image_version = (u8 *)pkt + sizeof(*pkt); 728 u32 req_bytes = pkt->size - sizeof(*pkt); 729 char fw_version[IRIS_FW_VERSION_LENGTH]; 730 u32 i; 731 732 if (req_bytes < IRIS_FW_VERSION_LENGTH - 1) 733 return -EINVAL; 734 735 for (i = 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) { 736 if (str_image_version[i] != '\0') 737 fw_version[i] = str_image_version[i]; 738 else 739 fw_version[i] = ' '; 740 } 741 fw_version[i] = '\0'; 742 dev_dbg(core->dev, "firmware version: %s\n", fw_version); 743 744 return 0; 745} 746 747static int iris_hfi_gen2_handle_system_property(struct iris_core *core, 748 struct iris_hfi_packet *pkt) 749{ 750 switch (pkt->type) { 751 case HFI_PROP_IMAGE_VERSION: 752 return iris_hfi_gen2_handle_image_version_property(core, pkt); 753 default: 754 return 0; 755 } 756} 757 758static int iris_hfi_gen2_handle_system_response(struct iris_core *core, 759 struct iris_hfi_header *hdr) 760{ 761 u8 *start_pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); 762 struct iris_hfi_packet *packet; 763 u32 i, j; 764 u8 *pkt; 765 int ret; 766 static const struct iris_hfi_gen2_core_hfi_range range[] = { 767 {HFI_SYSTEM_ERROR_BEGIN, HFI_SYSTEM_ERROR_END, iris_hfi_gen2_handle_system_error }, 768 {HFI_PROP_BEGIN, HFI_PROP_END, iris_hfi_gen2_handle_system_property }, 769 {HFI_CMD_BEGIN, HFI_CMD_END, iris_hfi_gen2_handle_system_init }, 770 }; 771 772 for (i = 0; i < ARRAY_SIZE(range); i++) { 773 pkt = start_pkt; 774 for (j = 0; j < hdr->num_packets; j++) { 775 packet = (struct iris_hfi_packet *)pkt; 776 if (packet->flags & HFI_FW_FLAGS_SYSTEM_ERROR) { 777 ret = iris_hfi_gen2_handle_system_error(core, packet); 778 return ret; 779 } 780 781 if (packet->type > range[i].begin && packet->type < range[i].end) { 782 ret = range[i].handle(core, packet); 783 if (ret) 784 return ret; 785 786 if (packet->type > HFI_SYSTEM_ERROR_BEGIN && 787 packet->type < HFI_SYSTEM_ERROR_END) 788 return 0; 789 } 790 pkt += packet->size; 791 } 792 } 793 794 return 0; 795} 796 797static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) 798{ 799 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 800 struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; 801 struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; 802 u32 bottom_offset = (pixmp_ip->height - inst->crop.height); 803 u32 right_offset = (pixmp_ip->width - inst->crop.width); 804 struct hfi_subscription_params *subsc_params; 805 u32 primaries, matrix_coeff, transfer_char; 806 u32 colour_description_present_flag = 0; 807 u32 video_signal_type_present_flag = 0; 808 u32 full_range, video_format = 0; 809 u32 left_offset = inst->crop.left; 810 u32 top_offset = inst->crop.top; 811 812 subsc_params = &inst_hfi_gen2->src_subcr_params; 813 subsc_params->bitstream_resolution = 814 pixmp_ip->width << 16 | pixmp_ip->height; 815 subsc_params->crop_offsets[0] = 816 left_offset << 16 | top_offset; 817 subsc_params->crop_offsets[1] = 818 right_offset << 16 | bottom_offset; 819 subsc_params->fw_min_count = inst->buffers[BUF_OUTPUT].min_count; 820 821 primaries = iris_hfi_gen2_get_color_primaries(pixmp_op->colorspace); 822 matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp_op->ycbcr_enc); 823 transfer_char = iris_hfi_gen2_get_transfer_char(pixmp_op->xfer_func); 824 full_range = pixmp_op->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0; 825 subsc_params->color_info = 826 iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries, 827 colour_description_present_flag, 828 full_range, video_format, 829 video_signal_type_present_flag); 830 831 switch (inst->codec) { 832 case V4L2_PIX_FMT_HEVC: 833 subsc_params->profile = inst->fw_caps[PROFILE_HEVC].value; 834 subsc_params->level = inst->fw_caps[LEVEL_HEVC].value; 835 break; 836 case V4L2_PIX_FMT_VP9: 837 subsc_params->profile = inst->fw_caps[PROFILE_VP9].value; 838 subsc_params->level = inst->fw_caps[LEVEL_VP9].value; 839 break; 840 case V4L2_PIX_FMT_H264: 841 subsc_params->profile = inst->fw_caps[PROFILE_H264].value; 842 subsc_params->level = inst->fw_caps[LEVEL_H264].value; 843 break; 844 } 845 846 subsc_params->pic_order_cnt = inst->fw_caps[POC].value; 847 subsc_params->bit_depth = inst->fw_caps[BIT_DEPTH].value; 848 if (inst->fw_caps[CODED_FRAMES].value == 849 CODED_FRAMES_PROGRESSIVE) 850 subsc_params->coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG; 851 else 852 subsc_params->coded_frames = 0; 853} 854 855static int iris_hfi_gen2_handle_session_response(struct iris_core *core, 856 struct iris_hfi_header *hdr) 857{ 858 u8 *pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); 859 struct iris_inst_hfi_gen2 *inst_hfi_gen2; 860 struct iris_hfi_packet *packet; 861 struct iris_inst *inst; 862 bool dequeue = false; 863 int ret = 0; 864 u32 i, j; 865 static const struct iris_hfi_gen2_inst_hfi_range range[] = { 866 {HFI_SESSION_ERROR_BEGIN, HFI_SESSION_ERROR_END, 867 iris_hfi_gen2_handle_session_error}, 868 {HFI_INFORMATION_BEGIN, HFI_INFORMATION_END, 869 iris_hfi_gen2_handle_session_info}, 870 {HFI_PROP_BEGIN, HFI_PROP_END, 871 iris_hfi_gen2_handle_session_property}, 872 {HFI_CMD_BEGIN, HFI_CMD_END, 873 iris_hfi_gen2_handle_session_command }, 874 }; 875 876 inst = iris_get_instance(core, hdr->session_id); 877 if (!inst) 878 return -EINVAL; 879 880 mutex_lock(&inst->lock); 881 inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 882 memset(&inst_hfi_gen2->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_info)); 883 884 for (i = 0; i < hdr->num_packets; i++) { 885 packet = (struct iris_hfi_packet *)pkt; 886 if (packet->type == HFI_CMD_SETTINGS_CHANGE) { 887 if (packet->port == HFI_PORT_BITSTREAM) { 888 iris_hfi_gen2_init_src_change_param(inst); 889 break; 890 } 891 } 892 pkt += packet->size; 893 } 894 895 pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); 896 for (i = 0; i < ARRAY_SIZE(range); i++) { 897 pkt = (u8 *)((u8 *)hdr + sizeof(*hdr)); 898 for (j = 0; j < hdr->num_packets; j++) { 899 packet = (struct iris_hfi_packet *)pkt; 900 if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR) 901 iris_hfi_gen2_handle_session_error(inst, packet); 902 903 if (packet->type > range[i].begin && packet->type < range[i].end) { 904 dequeue |= (packet->type == HFI_CMD_BUFFER); 905 ret = range[i].handle(inst, packet); 906 if (ret) 907 iris_inst_change_state(inst, IRIS_INST_ERROR); 908 } 909 pkt += packet->size; 910 } 911 } 912 913 if (dequeue) 914 iris_hfi_gen2_handle_dequeue_buffers(inst); 915 916 mutex_unlock(&inst->lock); 917 918 return ret; 919} 920 921static int iris_hfi_gen2_handle_response(struct iris_core *core, void *response) 922{ 923 struct iris_hfi_header *hdr = (struct iris_hfi_header *)response; 924 int ret; 925 926 ret = iris_hfi_gen2_validate_hdr_packet(core, hdr); 927 if (ret) 928 return iris_hfi_gen2_handle_system_error(core, NULL); 929 930 if (!hdr->session_id) 931 return iris_hfi_gen2_handle_system_response(core, hdr); 932 else 933 return iris_hfi_gen2_handle_session_response(core, hdr); 934} 935 936static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet) 937{ 938 struct hfi_debug_header *pkt; 939 u8 *log; 940 941 while (!iris_hfi_queue_dbg_read(core, packet)) { 942 pkt = (struct hfi_debug_header *)packet; 943 944 if (pkt->size < sizeof(*pkt)) 945 continue; 946 947 if (pkt->size >= IFACEQ_CORE_PKT_SIZE) 948 continue; 949 950 packet[pkt->size] = '\0'; 951 log = (u8 *)packet + sizeof(*pkt) + 1; 952 dev_dbg(core->dev, "%s", log); 953 } 954} 955 956static void iris_hfi_gen2_response_handler(struct iris_core *core) 957{ 958 if (iris_vpu_watchdog(core, core->intr_status)) { 959 struct iris_hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT}; 960 961 dev_err(core->dev, "cpu watchdog error received\n"); 962 core->state = IRIS_CORE_ERROR; 963 iris_hfi_gen2_handle_system_error(core, &pkt); 964 965 return; 966 } 967 968 memset(core->response_packet, 0, sizeof(struct iris_hfi_header)); 969 while (!iris_hfi_queue_msg_read(core, core->response_packet)) { 970 iris_hfi_gen2_handle_response(core, core->response_packet); 971 memset(core->response_packet, 0, sizeof(struct iris_hfi_header)); 972 } 973 974 iris_hfi_gen2_flush_debug_queue(core, core->response_packet); 975} 976 977static const struct iris_hfi_response_ops iris_hfi_gen2_response_ops = { 978 .hfi_response_handler = iris_hfi_gen2_response_handler, 979}; 980 981void iris_hfi_gen2_response_ops_init(struct iris_core *core) 982{ 983 core->hfi_response_ops = &iris_hfi_gen2_response_ops; 984}
~/
Read-only file preview.