FILE
iris_hfi_gen1_response.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/qcom/iris/iris_hfi_gen1_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 <linux/bitfield.h> 7#include <media/v4l2-mem2mem.h> 8 9#include "iris_hfi_gen1.h" 10#include "iris_hfi_gen1_defines.h" 11#include "iris_instance.h" 12#include "iris_vdec.h" 13#include "iris_vpu_buffer.h" 14 15static void iris_hfi_gen1_read_changed_params(struct iris_inst *inst, 16 struct hfi_msg_event_notify_pkt *pkt) 17{ 18 struct v4l2_pix_format_mplane *pixmp_ip = &inst->fmt_src->fmt.pix_mp; 19 struct v4l2_pix_format_mplane *pixmp_op = &inst->fmt_dst->fmt.pix_mp; 20 u32 num_properties_changed = pkt->event_data2; 21 u8 *data_ptr = (u8 *)&pkt->ext_event_data[0]; 22 u32 primaries, matrix_coeff, transfer_char; 23 struct hfi_dpb_counts *iris_vpu_dpb_count; 24 struct hfi_profile_level *profile_level; 25 struct hfi_buffer_requirements *bufreq; 26 struct hfi_extradata_input_crop *crop; 27 struct hfi_colour_space *colour_info; 28 struct iris_core *core = inst->core; 29 u32 colour_description_present_flag; 30 u32 video_signal_type_present_flag; 31 struct hfi_event_data event = {0}; 32 struct hfi_bit_depth *pixel_depth; 33 struct hfi_pic_struct *pic_struct; 34 struct hfi_framesize *frame_sz; 35 struct vb2_queue *dst_q; 36 struct v4l2_ctrl *ctrl; 37 u32 full_range, ptype; 38 39 do { 40 ptype = *((u32 *)data_ptr); 41 switch (ptype) { 42 case HFI_PROPERTY_PARAM_FRAME_SIZE: 43 data_ptr += sizeof(u32); 44 frame_sz = (struct hfi_framesize *)data_ptr; 45 event.width = frame_sz->width; 46 event.height = frame_sz->height; 47 data_ptr += sizeof(*frame_sz); 48 break; 49 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: 50 data_ptr += sizeof(u32); 51 profile_level = (struct hfi_profile_level *)data_ptr; 52 event.profile = profile_level->profile; 53 event.level = profile_level->level; 54 data_ptr += sizeof(*profile_level); 55 break; 56 case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH: 57 data_ptr += sizeof(u32); 58 pixel_depth = (struct hfi_bit_depth *)data_ptr; 59 event.bit_depth = pixel_depth->bit_depth; 60 data_ptr += sizeof(*pixel_depth); 61 break; 62 case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT: 63 data_ptr += sizeof(u32); 64 pic_struct = (struct hfi_pic_struct *)data_ptr; 65 event.pic_struct = pic_struct->progressive_only; 66 data_ptr += sizeof(*pic_struct); 67 break; 68 case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE: 69 data_ptr += sizeof(u32); 70 colour_info = (struct hfi_colour_space *)data_ptr; 71 event.colour_space = colour_info->colour_space; 72 data_ptr += sizeof(*colour_info); 73 break; 74 case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: 75 data_ptr += sizeof(u32); 76 event.entropy_mode = *(u32 *)data_ptr; 77 data_ptr += sizeof(u32); 78 break; 79 case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS: 80 data_ptr += sizeof(u32); 81 bufreq = (struct hfi_buffer_requirements *)data_ptr; 82 event.buf_count = bufreq->count_min; 83 data_ptr += sizeof(*bufreq); 84 break; 85 case HFI_INDEX_EXTRADATA_INPUT_CROP: 86 data_ptr += sizeof(u32); 87 crop = (struct hfi_extradata_input_crop *)data_ptr; 88 event.input_crop.left = crop->left; 89 event.input_crop.top = crop->top; 90 event.input_crop.width = crop->width; 91 event.input_crop.height = crop->height; 92 data_ptr += sizeof(*crop); 93 break; 94 case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS: 95 data_ptr += sizeof(u32); 96 iris_vpu_dpb_count = (struct hfi_dpb_counts *)data_ptr; 97 event.buf_count = iris_vpu_dpb_count->fw_min_count; 98 data_ptr += sizeof(*iris_vpu_dpb_count); 99 break; 100 default: 101 break; 102 } 103 num_properties_changed--; 104 } while (num_properties_changed > 0); 105 106 pixmp_ip->width = event.width; 107 pixmp_ip->height = event.height; 108 109 pixmp_op->width = ALIGN(event.width, 128); 110 pixmp_op->height = ALIGN(event.height, 32); 111 pixmp_op->plane_fmt[0].bytesperline = ALIGN(event.width, 128); 112 pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 113 114 matrix_coeff = FIELD_GET(GENMASK(7, 0), event.colour_space); 115 transfer_char = FIELD_GET(GENMASK(15, 8), event.colour_space); 116 primaries = FIELD_GET(GENMASK(23, 16), event.colour_space); 117 colour_description_present_flag = FIELD_GET(GENMASK(24, 24), event.colour_space); 118 full_range = FIELD_GET(GENMASK(25, 25), event.colour_space); 119 video_signal_type_present_flag = FIELD_GET(GENMASK(29, 29), event.colour_space); 120 121 pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT; 122 pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT; 123 pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 124 pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT; 125 126 if (video_signal_type_present_flag) { 127 pixmp_op->quantization = 128 full_range ? 129 V4L2_QUANTIZATION_FULL_RANGE : 130 V4L2_QUANTIZATION_LIM_RANGE; 131 if (colour_description_present_flag) { 132 pixmp_op->colorspace = 133 iris_hfi_get_v4l2_color_primaries(primaries); 134 pixmp_op->xfer_func = 135 iris_hfi_get_v4l2_transfer_char(transfer_char); 136 pixmp_op->ycbcr_enc = 137 iris_hfi_get_v4l2_matrix_coefficients(matrix_coeff); 138 } 139 } 140 141 pixmp_ip->colorspace = pixmp_op->colorspace; 142 pixmp_ip->xfer_func = pixmp_op->xfer_func; 143 pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc; 144 pixmp_ip->quantization = pixmp_op->quantization; 145 146 if (event.input_crop.width > 0 && event.input_crop.height > 0) { 147 inst->crop.left = event.input_crop.left; 148 inst->crop.top = event.input_crop.top; 149 inst->crop.width = event.input_crop.width; 150 inst->crop.height = event.input_crop.height; 151 } else { 152 inst->crop.left = 0; 153 inst->crop.top = 0; 154 inst->crop.width = event.width; 155 inst->crop.height = event.height; 156 } 157 158 inst->fw_min_count = event.buf_count; 159 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 160 inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; 161 ctrl = v4l2_ctrl_find(&inst->ctrl_handler, V4L2_CID_MIN_BUFFERS_FOR_CAPTURE); 162 if (ctrl) 163 v4l2_ctrl_s_ctrl(ctrl, inst->buffers[BUF_OUTPUT].min_count); 164 165 dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 166 dst_q->min_reqbufs_allocation = inst->buffers[BUF_OUTPUT].min_count; 167 168 if (event.bit_depth || !event.pic_struct) { 169 dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n", 170 event.bit_depth, event.pic_struct); 171 iris_inst_change_state(inst, IRIS_INST_ERROR); 172 } 173} 174 175static void iris_hfi_gen1_event_seq_changed(struct iris_inst *inst, 176 struct hfi_msg_event_notify_pkt *pkt) 177{ 178 struct hfi_session_flush_pkt flush_pkt; 179 u32 num_properties_changed; 180 int ret; 181 182 ret = iris_inst_sub_state_change_drc(inst); 183 if (ret) 184 return; 185 186 switch (pkt->event_data1) { 187 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES: 188 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES: 189 break; 190 default: 191 iris_inst_change_state(inst, IRIS_INST_ERROR); 192 return; 193 } 194 195 num_properties_changed = pkt->event_data2; 196 if (!num_properties_changed) { 197 iris_inst_change_state(inst, IRIS_INST_ERROR); 198 return; 199 } 200 201 iris_hfi_gen1_read_changed_params(inst, pkt); 202 203 if (inst->state != IRIS_INST_ERROR && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) { 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 = HFI_FLUSH_OUTPUT; 209 if (!iris_hfi_queue_cmd_write(inst->core, &flush_pkt, flush_pkt.shdr.hdr.size)) 210 inst->flush_responses_pending++; 211 } 212 213 iris_vdec_src_change(inst); 214 iris_inst_sub_state_change_drc_last(inst); 215} 216 217static void 218iris_hfi_gen1_sys_event_notify(struct iris_core *core, void *packet) 219{ 220 struct hfi_msg_event_notify_pkt *pkt = packet; 221 struct iris_inst *instance; 222 223 if (pkt->event_id == HFI_EVENT_SYS_ERROR) 224 dev_err(core->dev, "sys error (type: %x, session id:%x, data1:%x, data2:%x)\n", 225 pkt->event_id, pkt->shdr.session_id, pkt->event_data1, 226 pkt->event_data2); 227 228 core->state = IRIS_CORE_ERROR; 229 230 mutex_lock(&core->lock); 231 list_for_each_entry(instance, &core->instances, list) 232 iris_inst_change_state(instance, IRIS_INST_ERROR); 233 mutex_unlock(&core->lock); 234 235 schedule_delayed_work(&core->sys_error_handler, msecs_to_jiffies(10)); 236} 237 238static void 239iris_hfi_gen1_event_session_error(struct iris_inst *inst, struct hfi_msg_event_notify_pkt *pkt) 240{ 241 switch (pkt->event_data1) { 242 /* non fatal session errors */ 243 case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: 244 case HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE: 245 case HFI_ERR_SESSION_UNSUPPORTED_SETTING: 246 case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: 247 dev_dbg(inst->core->dev, "session error: event id:%x, session id:%x\n", 248 pkt->event_data1, pkt->shdr.session_id); 249 break; 250 /* fatal session errors */ 251 default: 252 /* 253 * firmware fills event_data2 as an additional information about the 254 * hfi command for which session error has ouccured. 255 */ 256 dev_err(inst->core->dev, 257 "session error for command: %x, event id:%x, session id:%x\n", 258 pkt->event_data2, pkt->event_data1, 259 pkt->shdr.session_id); 260 iris_vb2_queue_error(inst); 261 iris_inst_change_state(inst, IRIS_INST_ERROR); 262 break; 263 } 264} 265 266static void iris_hfi_gen1_session_event_notify(struct iris_inst *inst, void *packet) 267{ 268 struct hfi_msg_event_notify_pkt *pkt = packet; 269 270 switch (pkt->event_id) { 271 case HFI_EVENT_SESSION_ERROR: 272 iris_hfi_gen1_event_session_error(inst, pkt); 273 break; 274 case HFI_EVENT_SESSION_SEQUENCE_CHANGED: 275 iris_hfi_gen1_event_seq_changed(inst, pkt); 276 break; 277 default: 278 break; 279 } 280} 281 282static void iris_hfi_gen1_sys_init_done(struct iris_core *core, void *packet) 283{ 284 struct hfi_msg_sys_init_done_pkt *pkt = packet; 285 286 if (pkt->error_type != HFI_ERR_NONE) { 287 core->state = IRIS_CORE_ERROR; 288 return; 289 } 290 291 complete(&core->core_init_done); 292} 293 294static void 295iris_hfi_gen1_sys_get_prop_image_version(struct iris_core *core, 296 struct hfi_msg_sys_property_info_pkt *pkt) 297{ 298 int req_bytes = pkt->hdr.size - sizeof(*pkt); 299 char fw_version[IRIS_FW_VERSION_LENGTH]; 300 u8 *str_image_version; 301 u32 i; 302 303 if (req_bytes < IRIS_FW_VERSION_LENGTH - 1 || !pkt->data[0] || pkt->num_properties > 1) { 304 dev_err(core->dev, "bad packet\n"); 305 return; 306 } 307 308 str_image_version = pkt->data; 309 if (!str_image_version) { 310 dev_err(core->dev, "firmware version not available\n"); 311 return; 312 } 313 314 for (i = 0; i < IRIS_FW_VERSION_LENGTH - 1; i++) { 315 if (str_image_version[i] != '\0') 316 fw_version[i] = str_image_version[i]; 317 else 318 fw_version[i] = ' '; 319 } 320 fw_version[i] = '\0'; 321 dev_dbg(core->dev, "firmware version: %s\n", fw_version); 322} 323 324static void iris_hfi_gen1_sys_property_info(struct iris_core *core, void *packet) 325{ 326 struct hfi_msg_sys_property_info_pkt *pkt = packet; 327 328 if (!pkt->num_properties) { 329 dev_dbg(core->dev, "no properties\n"); 330 return; 331 } 332 333 switch (pkt->property) { 334 case HFI_PROPERTY_SYS_IMAGE_VERSION: 335 iris_hfi_gen1_sys_get_prop_image_version(core, pkt); 336 break; 337 default: 338 dev_dbg(core->dev, "unknown property data\n"); 339 break; 340 } 341} 342 343static void iris_hfi_gen1_session_etb_done(struct iris_inst *inst, void *packet) 344{ 345 struct hfi_msg_session_empty_buffer_done_pkt *pkt = packet; 346 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 347 struct v4l2_m2m_buffer *m2m_buffer, *n; 348 struct iris_buffer *buf = NULL; 349 bool found = false; 350 351 /* EOS buffer sent via drain won't be in v4l2 buffer list */ 352 if (pkt->packet_buffer == 0xdeadb000) 353 return; 354 355 v4l2_m2m_for_each_src_buf_safe(m2m_ctx, m2m_buffer, n) { 356 buf = to_iris_buffer(&m2m_buffer->vb); 357 if (buf->index == pkt->input_tag) { 358 found = true; 359 break; 360 } 361 } 362 if (!found) 363 goto error; 364 365 if (pkt->shdr.error_type == HFI_ERR_SESSION_UNSUPPORTED_STREAM) { 366 buf->flags = V4L2_BUF_FLAG_ERROR; 367 iris_vb2_queue_error(inst); 368 iris_inst_change_state(inst, IRIS_INST_ERROR); 369 } 370 371 if (!(buf->attr & BUF_ATTR_QUEUED)) 372 return; 373 374 buf->attr &= ~BUF_ATTR_QUEUED; 375 376 if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) { 377 buf->attr |= BUF_ATTR_BUFFER_DONE; 378 iris_vb2_buffer_done(inst, buf); 379 } 380 381 return; 382 383error: 384 iris_inst_change_state(inst, IRIS_INST_ERROR); 385 dev_err(inst->core->dev, "error in etb done\n"); 386} 387 388static void iris_hfi_gen1_session_ftb_done(struct iris_inst *inst, void *packet) 389{ 390 struct hfi_msg_session_fbd_uncompressed_plane0_pkt *uncom_pkt = packet; 391 struct hfi_msg_session_fbd_compressed_pkt *com_pkt = packet; 392 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 393 struct v4l2_m2m_buffer *m2m_buffer, *n; 394 struct hfi_session_flush_pkt flush_pkt; 395 u32 timestamp_hi; 396 u32 timestamp_lo; 397 struct iris_core *core = inst->core; 398 u32 filled_len; 399 u32 pic_type; 400 u32 output_tag; 401 struct iris_buffer *buf, *iter; 402 struct iris_buffers *buffers; 403 u32 hfi_flags; 404 u32 offset; 405 u64 timestamp_us = 0; 406 bool found = false; 407 u32 flags = 0; 408 409 if (inst->domain == DECODER) { 410 timestamp_hi = uncom_pkt->time_stamp_hi; 411 timestamp_lo = uncom_pkt->time_stamp_lo; 412 filled_len = uncom_pkt->filled_len; 413 pic_type = uncom_pkt->picture_type; 414 output_tag = uncom_pkt->output_tag; 415 hfi_flags = uncom_pkt->flags; 416 offset = uncom_pkt->offset; 417 } else { 418 timestamp_hi = com_pkt->time_stamp_hi; 419 timestamp_lo = com_pkt->time_stamp_lo; 420 filled_len = com_pkt->filled_len; 421 pic_type = com_pkt->picture_type; 422 output_tag = com_pkt->output_tag; 423 hfi_flags = com_pkt->flags; 424 offset = com_pkt->offset; 425 } 426 427 if ((hfi_flags & HFI_BUFFERFLAG_EOS) && !filled_len) { 428 reinit_completion(&inst->flush_completion); 429 430 flush_pkt.shdr.hdr.size = sizeof(struct hfi_session_flush_pkt); 431 flush_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FLUSH; 432 flush_pkt.shdr.session_id = inst->session_id; 433 flush_pkt.flush_type = HFI_FLUSH_OUTPUT; 434 if (!iris_hfi_queue_cmd_write(core, &flush_pkt, flush_pkt.shdr.hdr.size)) 435 inst->flush_responses_pending++; 436 437 iris_inst_sub_state_change_drain_last(inst); 438 } 439 440 if (iris_split_mode_enabled(inst) && inst->domain == DECODER && 441 uncom_pkt->stream_id == 0) { 442 buffers = &inst->buffers[BUF_DPB]; 443 if (!buffers) 444 goto error; 445 446 found = false; 447 list_for_each_entry(iter, &buffers->list, list) { 448 if (!(iter->attr & BUF_ATTR_QUEUED)) 449 continue; 450 451 found = (iter->index == output_tag && 452 iter->data_offset == offset); 453 454 if (found) { 455 buf = iter; 456 break; 457 } 458 } 459 } else { 460 v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, m2m_buffer, n) { 461 buf = to_iris_buffer(&m2m_buffer->vb); 462 if (!(buf->attr & BUF_ATTR_QUEUED)) 463 continue; 464 465 found = (buf->index == output_tag && 466 buf->data_offset == offset); 467 468 if (found) 469 break; 470 } 471 } 472 if (!found) 473 goto error; 474 475 buf->data_offset = offset; 476 buf->data_size = filled_len; 477 478 if (filled_len) { 479 timestamp_us = timestamp_hi; 480 timestamp_us = (timestamp_us << 32) | timestamp_lo; 481 } else { 482 if (inst->domain == DECODER && uncom_pkt->stream_id == 1 && 483 !inst->last_buffer_dequeued) { 484 if (iris_drc_pending(inst) || iris_drain_pending(inst)) { 485 flags |= V4L2_BUF_FLAG_LAST; 486 inst->last_buffer_dequeued = true; 487 } 488 } else if (inst->domain == ENCODER) { 489 if (!inst->last_buffer_dequeued && iris_drain_pending(inst)) { 490 flags |= V4L2_BUF_FLAG_LAST; 491 inst->last_buffer_dequeued = true; 492 } 493 } 494 } 495 buf->timestamp = timestamp_us; 496 497 switch (pic_type) { 498 case HFI_GEN1_PICTURE_IDR: 499 case HFI_GEN1_PICTURE_I: 500 flags |= V4L2_BUF_FLAG_KEYFRAME; 501 break; 502 case HFI_GEN1_PICTURE_P: 503 flags |= V4L2_BUF_FLAG_PFRAME; 504 break; 505 case HFI_GEN1_PICTURE_B: 506 flags |= V4L2_BUF_FLAG_BFRAME; 507 break; 508 case HFI_FRAME_NOTCODED: 509 case HFI_UNUSED_PICT: 510 case HFI_FRAME_YUV: 511 default: 512 break; 513 } 514 515 buf->attr &= ~BUF_ATTR_QUEUED; 516 buf->attr |= BUF_ATTR_DEQUEUED; 517 buf->attr |= BUF_ATTR_BUFFER_DONE; 518 519 if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT) 520 flags |= V4L2_BUF_FLAG_ERROR; 521 522 if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) 523 flags |= V4L2_BUF_FLAG_ERROR; 524 525 buf->flags |= flags; 526 527 iris_vb2_buffer_done(inst, buf); 528 529 return; 530 531error: 532 iris_inst_change_state(inst, IRIS_INST_ERROR); 533 dev_err(core->dev, "error in ftb done\n"); 534} 535 536struct iris_hfi_gen1_response_pkt_info { 537 u32 pkt; 538 u32 pkt_sz; 539}; 540 541static const struct iris_hfi_gen1_response_pkt_info pkt_infos[] = { 542 { 543 .pkt = HFI_MSG_EVENT_NOTIFY, 544 .pkt_sz = sizeof(struct hfi_msg_event_notify_pkt), 545 }, 546 { 547 .pkt = HFI_MSG_SYS_INIT, 548 .pkt_sz = sizeof(struct hfi_msg_sys_init_done_pkt), 549 }, 550 { 551 .pkt = HFI_MSG_SYS_PROPERTY_INFO, 552 .pkt_sz = sizeof(struct hfi_msg_sys_property_info_pkt), 553 }, 554 { 555 .pkt = HFI_MSG_SYS_SESSION_INIT, 556 .pkt_sz = sizeof(struct hfi_msg_session_init_done_pkt), 557 }, 558 { 559 .pkt = HFI_MSG_SYS_SESSION_END, 560 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), 561 }, 562 { 563 .pkt = HFI_MSG_SESSION_LOAD_RESOURCES, 564 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), 565 }, 566 { 567 .pkt = HFI_MSG_SESSION_START, 568 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), 569 }, 570 { 571 .pkt = HFI_MSG_SESSION_STOP, 572 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), 573 }, 574 { 575 .pkt = HFI_MSG_SESSION_EMPTY_BUFFER, 576 .pkt_sz = sizeof(struct hfi_msg_session_empty_buffer_done_pkt), 577 }, 578 { 579 .pkt = HFI_MSG_SESSION_FILL_BUFFER, 580 .pkt_sz = sizeof(struct hfi_msg_session_fbd_compressed_pkt), 581 }, 582 { 583 .pkt = HFI_MSG_SESSION_FLUSH, 584 .pkt_sz = sizeof(struct hfi_msg_session_flush_done_pkt), 585 }, 586 { 587 .pkt = HFI_MSG_SESSION_RELEASE_RESOURCES, 588 .pkt_sz = sizeof(struct hfi_msg_session_hdr_pkt), 589 }, 590 { 591 .pkt = HFI_MSG_SESSION_RELEASE_BUFFERS, 592 .pkt_sz = sizeof(struct hfi_msg_session_release_buffers_done_pkt), 593 }, 594}; 595 596static void iris_hfi_gen1_handle_response(struct iris_core *core, void *response) 597{ 598 struct hfi_pkt_hdr *hdr = (struct hfi_pkt_hdr *)response; 599 const struct iris_hfi_gen1_response_pkt_info *pkt_info; 600 struct device *dev = core->dev; 601 struct hfi_session_pkt *pkt; 602 struct iris_inst *inst; 603 bool found = false; 604 u32 i; 605 606 for (i = 0; i < ARRAY_SIZE(pkt_infos); i++) { 607 pkt_info = &pkt_infos[i]; 608 if (pkt_info->pkt != hdr->pkt_type) 609 continue; 610 found = true; 611 break; 612 } 613 614 if (!found || hdr->size < pkt_info->pkt_sz) { 615 dev_err(dev, "bad packet size (%d should be %d, pkt type:%x, found %d)\n", 616 hdr->size, pkt_info->pkt_sz, hdr->pkt_type, found); 617 618 return; 619 } 620 621 switch (hdr->pkt_type) { 622 case HFI_MSG_SYS_INIT: 623 iris_hfi_gen1_sys_init_done(core, hdr); 624 break; 625 case HFI_MSG_SYS_PROPERTY_INFO: 626 iris_hfi_gen1_sys_property_info(core, hdr); 627 break; 628 case HFI_MSG_EVENT_NOTIFY: 629 pkt = (struct hfi_session_pkt *)hdr; 630 inst = iris_get_instance(core, pkt->shdr.session_id); 631 if (inst) { 632 mutex_lock(&inst->lock); 633 iris_hfi_gen1_session_event_notify(inst, hdr); 634 mutex_unlock(&inst->lock); 635 } else { 636 iris_hfi_gen1_sys_event_notify(core, hdr); 637 } 638 639 break; 640 default: 641 pkt = (struct hfi_session_pkt *)hdr; 642 inst = iris_get_instance(core, pkt->shdr.session_id); 643 if (!inst) { 644 dev_warn(dev, "no valid instance(pkt session_id:%x, pkt:%x)\n", 645 pkt->shdr.session_id, 646 pkt_info ? pkt_info->pkt : 0); 647 return; 648 } 649 650 mutex_lock(&inst->lock); 651 if (hdr->pkt_type == HFI_MSG_SESSION_EMPTY_BUFFER) { 652 iris_hfi_gen1_session_etb_done(inst, hdr); 653 } else if (hdr->pkt_type == HFI_MSG_SESSION_FILL_BUFFER) { 654 iris_hfi_gen1_session_ftb_done(inst, hdr); 655 } else { 656 struct hfi_msg_session_hdr_pkt *shdr; 657 658 shdr = (struct hfi_msg_session_hdr_pkt *)hdr; 659 if (shdr->error_type != HFI_ERR_NONE) 660 iris_inst_change_state(inst, IRIS_INST_ERROR); 661 662 if (pkt_info->pkt == HFI_MSG_SESSION_FLUSH) { 663 if (!(--inst->flush_responses_pending)) 664 complete(&inst->flush_completion); 665 } else { 666 complete(&inst->completion); 667 } 668 } 669 mutex_unlock(&inst->lock); 670 671 break; 672 } 673} 674 675static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet) 676{ 677 struct hfi_msg_sys_coverage_pkt *pkt; 678 679 while (!iris_hfi_queue_dbg_read(core, packet)) { 680 pkt = (struct hfi_msg_sys_coverage_pkt *)packet; 681 682 if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) { 683 struct hfi_msg_sys_debug_pkt *pkt = 684 (struct hfi_msg_sys_debug_pkt *)packet; 685 686 dev_dbg(core->dev, "%s", pkt->msg_data); 687 } 688 } 689} 690 691static void iris_hfi_gen1_response_handler(struct iris_core *core) 692{ 693 memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr)); 694 while (!iris_hfi_queue_msg_read(core, core->response_packet)) { 695 iris_hfi_gen1_handle_response(core, core->response_packet); 696 memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr)); 697 } 698 699 iris_hfi_gen1_flush_debug_queue(core, core->response_packet); 700} 701 702static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops = { 703 .hfi_response_handler = iris_hfi_gen1_response_handler, 704}; 705 706void iris_hfi_gen1_response_ops_init(struct iris_core *core) 707{ 708 core->hfi_response_ops = &iris_hfi_gen1_response_ops; 709}
~/
Read-only file preview.