FILE
iris_hfi_gen1_command.c
File preview with syntax highlighting.
linux-6.19.14/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.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 "iris_hfi_gen1.h" 7#include "iris_hfi_gen1_defines.h" 8#include "iris_instance.h" 9#include "iris_vpu_buffer.h" 10 11static 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 case BUF_SCRATCH_2: 25 return HFI_BUFFER_INTERNAL_SCRATCH_2; 26 case BUF_ARP: 27 return HFI_BUFFER_INTERNAL_PERSIST; 28 default: 29 return -EINVAL; 30 } 31} 32 33static int iris_hfi_gen1_sys_init(struct iris_core *core) 34{ 35 struct hfi_sys_init_pkt sys_init_pkt; 36 37 sys_init_pkt.hdr.size = sizeof(sys_init_pkt); 38 sys_init_pkt.hdr.pkt_type = HFI_CMD_SYS_INIT; 39 sys_init_pkt.arch_type = HFI_VIDEO_ARCH_OX; 40 41 return iris_hfi_queue_cmd_write_locked(core, &sys_init_pkt, sys_init_pkt.hdr.size); 42} 43 44static int iris_hfi_gen1_sys_image_version(struct iris_core *core) 45{ 46 struct hfi_sys_get_property_pkt packet; 47 48 packet.hdr.size = sizeof(packet); 49 packet.hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY; 50 packet.num_properties = 1; 51 packet.data = HFI_PROPERTY_SYS_IMAGE_VERSION; 52 53 return iris_hfi_queue_cmd_write_locked(core, &packet, packet.hdr.size); 54} 55 56static int iris_hfi_gen1_sys_interframe_powercollapse(struct iris_core *core) 57{ 58 struct hfi_sys_set_property_pkt *pkt; 59 struct hfi_enable *hfi; 60 u32 packet_size; 61 int ret; 62 63 packet_size = struct_size(pkt, data, 1) + sizeof(*hfi); 64 pkt = kzalloc(packet_size, GFP_KERNEL); 65 if (!pkt) 66 return -ENOMEM; 67 68 hfi = (struct hfi_enable *)&pkt->data[1]; 69 70 pkt->hdr.size = packet_size; 71 pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY; 72 pkt->num_properties = 1; 73 pkt->data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; 74 hfi->enable = true; 75 76 ret = iris_hfi_queue_cmd_write_locked(core, pkt, pkt->hdr.size); 77 kfree(pkt); 78 79 return ret; 80} 81 82static int iris_hfi_gen1_sys_pc_prep(struct iris_core *core) 83{ 84 struct hfi_sys_pc_prep_pkt pkt; 85 86 pkt.hdr.size = sizeof(struct hfi_sys_pc_prep_pkt); 87 pkt.hdr.pkt_type = HFI_CMD_SYS_PC_PREP; 88 89 return iris_hfi_queue_cmd_write_locked(core, &pkt, pkt.hdr.size); 90} 91 92static int iris_hfi_gen1_session_open(struct iris_inst *inst) 93{ 94 struct hfi_session_open_pkt packet; 95 u32 codec = 0; 96 int ret; 97 98 if (inst->state != IRIS_INST_DEINIT) 99 return -EALREADY; 100 101 switch (inst->codec) { 102 case V4L2_PIX_FMT_H264: 103 codec = HFI_VIDEO_CODEC_H264; 104 break; 105 case V4L2_PIX_FMT_HEVC: 106 codec = HFI_VIDEO_CODEC_HEVC; 107 break; 108 case V4L2_PIX_FMT_VP9: 109 codec = HFI_VIDEO_CODEC_VP9; 110 break; 111 } 112 113 packet.shdr.hdr.size = sizeof(struct hfi_session_open_pkt); 114 packet.shdr.hdr.pkt_type = HFI_CMD_SYS_SESSION_INIT; 115 packet.shdr.session_id = inst->session_id; 116 117 if (inst->domain == DECODER) 118 packet.session_domain = HFI_SESSION_TYPE_DEC; 119 else 120 packet.session_domain = HFI_SESSION_TYPE_ENC; 121 122 packet.session_codec = codec; 123 124 reinit_completion(&inst->completion); 125 126 ret = iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 127 if (ret) 128 return ret; 129 130 return iris_wait_for_session_response(inst, false); 131} 132 133static void iris_hfi_gen1_packet_session_cmd(struct iris_inst *inst, 134 struct hfi_session_pkt *packet, 135 u32 ptype) 136{ 137 packet->shdr.hdr.size = sizeof(*packet); 138 packet->shdr.hdr.pkt_type = ptype; 139 packet->shdr.session_id = inst->session_id; 140} 141 142static int iris_hfi_gen1_session_close(struct iris_inst *inst) 143{ 144 struct hfi_session_pkt packet; 145 146 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SYS_SESSION_END); 147 148 return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 149} 150 151static int iris_hfi_gen1_session_start(struct iris_inst *inst, u32 plane) 152{ 153 struct iris_core *core = inst->core; 154 struct hfi_session_pkt packet; 155 int ret; 156 157 if (!V4L2_TYPE_IS_OUTPUT(plane)) 158 return 0; 159 160 if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) 161 return 0; 162 163 reinit_completion(&inst->completion); 164 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_LOAD_RESOURCES); 165 166 ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); 167 if (ret) 168 return ret; 169 170 ret = iris_wait_for_session_response(inst, false); 171 if (ret) 172 return ret; 173 174 reinit_completion(&inst->completion); 175 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_START); 176 177 ret = iris_hfi_queue_cmd_write(core, &packet, packet.shdr.hdr.size); 178 if (ret) 179 return ret; 180 181 ret = iris_wait_for_session_response(inst, false); 182 if (ret) 183 return ret; 184 185 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_LOAD_RESOURCES); 186} 187 188static int iris_hfi_gen1_session_stop(struct iris_inst *inst, u32 plane) 189{ 190 struct hfi_session_flush_pkt flush_pkt; 191 struct iris_core *core = inst->core; 192 struct hfi_session_pkt pkt; 193 u32 flush_type = 0; 194 int ret = 0; 195 196 if (inst->domain == DECODER) { 197 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 inst->flush_responses_pending++; 213 ret = iris_wait_for_session_response(inst, true); 214 } 215 } else if (inst->sub_state & IRIS_INST_SUB_LOAD_RESOURCES) { 216 reinit_completion(&inst->completion); 217 iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 218 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 219 if (!ret) 220 ret = iris_wait_for_session_response(inst, false); 221 222 reinit_completion(&inst->completion); 223 iris_hfi_gen1_packet_session_cmd(inst, &pkt, 224 HFI_CMD_SESSION_RELEASE_RESOURCES); 225 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 226 if (!ret) 227 ret = iris_wait_for_session_response(inst, false); 228 229 iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 230 231 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 232 VB2_BUF_STATE_ERROR); 233 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 234 VB2_BUF_STATE_ERROR); 235 } 236 } else { 237 if (inst->state == IRIS_INST_STREAMING || 238 inst->state == IRIS_INST_INPUT_STREAMING || 239 inst->state == IRIS_INST_ERROR) { 240 reinit_completion(&inst->completion); 241 iris_hfi_gen1_packet_session_cmd(inst, &pkt, HFI_CMD_SESSION_STOP); 242 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 243 if (!ret) 244 ret = iris_wait_for_session_response(inst, false); 245 246 reinit_completion(&inst->completion); 247 iris_hfi_gen1_packet_session_cmd(inst, &pkt, 248 HFI_CMD_SESSION_RELEASE_RESOURCES); 249 ret = iris_hfi_queue_cmd_write(core, &pkt, pkt.shdr.hdr.size); 250 if (!ret) 251 ret = iris_wait_for_session_response(inst, false); 252 253 iris_inst_change_sub_state(inst, IRIS_INST_SUB_LOAD_RESOURCES, 0); 254 } 255 256 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 257 VB2_BUF_STATE_ERROR); 258 iris_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 259 VB2_BUF_STATE_ERROR); 260 } 261 262 return ret; 263} 264 265static int iris_hfi_gen1_session_continue(struct iris_inst *inst, u32 plane) 266{ 267 struct hfi_session_pkt packet; 268 269 iris_hfi_gen1_packet_session_cmd(inst, &packet, HFI_CMD_SESSION_CONTINUE); 270 271 return iris_hfi_queue_cmd_write(inst->core, &packet, packet.shdr.hdr.size); 272} 273 274static int iris_hfi_gen1_queue_input_buffer(struct iris_inst *inst, struct iris_buffer *buf) 275{ 276 struct hfi_session_empty_buffer_compressed_pkt com_ip_pkt; 277 struct hfi_session_empty_buffer_uncompressed_pkt uncom_ip_pkt; 278 279 if (inst->domain == DECODER) { 280 com_ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); 281 com_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 282 com_ip_pkt.shdr.session_id = inst->session_id; 283 com_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp); 284 com_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp); 285 com_ip_pkt.flags = 0; 286 com_ip_pkt.mark_target = 0; 287 com_ip_pkt.mark_data = 0; 288 com_ip_pkt.offset = buf->data_offset; 289 com_ip_pkt.alloc_len = buf->buffer_size; 290 com_ip_pkt.filled_len = buf->data_size; 291 com_ip_pkt.input_tag = buf->index; 292 com_ip_pkt.packet_buffer = buf->device_addr; 293 return iris_hfi_queue_cmd_write(inst->core, &com_ip_pkt, 294 com_ip_pkt.shdr.hdr.size); 295 } else { 296 uncom_ip_pkt.shdr.hdr.size = 297 sizeof(struct hfi_session_empty_buffer_uncompressed_pkt); 298 uncom_ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 299 uncom_ip_pkt.shdr.session_id = inst->session_id; 300 uncom_ip_pkt.time_stamp_hi = upper_32_bits(buf->timestamp); 301 uncom_ip_pkt.time_stamp_lo = lower_32_bits(buf->timestamp); 302 uncom_ip_pkt.view_id = 0; 303 uncom_ip_pkt.flags = buf->flags; 304 uncom_ip_pkt.mark_target = 0; 305 uncom_ip_pkt.mark_data = 0; 306 uncom_ip_pkt.offset = buf->data_offset; 307 uncom_ip_pkt.alloc_len = buf->buffer_size; 308 uncom_ip_pkt.filled_len = buf->data_size; 309 uncom_ip_pkt.input_tag = buf->index; 310 uncom_ip_pkt.packet_buffer = buf->device_addr; 311 return iris_hfi_queue_cmd_write(inst->core, &uncom_ip_pkt, 312 uncom_ip_pkt.shdr.hdr.size); 313 } 314} 315 316static int iris_hfi_gen1_queue_output_buffer(struct iris_inst *inst, struct iris_buffer *buf) 317{ 318 struct hfi_session_fill_buffer_pkt op_pkt; 319 320 op_pkt.shdr.hdr.size = sizeof(struct hfi_session_fill_buffer_pkt); 321 op_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_FILL_BUFFER; 322 op_pkt.shdr.session_id = inst->session_id; 323 op_pkt.output_tag = buf->index; 324 op_pkt.packet_buffer = buf->device_addr; 325 op_pkt.extradata_buffer = 0; 326 op_pkt.alloc_len = buf->buffer_size; 327 op_pkt.filled_len = buf->data_size; 328 op_pkt.offset = buf->data_offset; 329 op_pkt.data = 0; 330 331 if (buf->type == BUF_OUTPUT && iris_split_mode_enabled(inst)) 332 op_pkt.stream_id = 1; 333 else 334 op_pkt.stream_id = 0; 335 336 return iris_hfi_queue_cmd_write(inst->core, &op_pkt, op_pkt.shdr.hdr.size); 337} 338 339static int iris_hfi_gen1_queue_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf) 340{ 341 struct hfi_session_set_buffers_pkt *int_pkt; 342 u32 buffer_type, i; 343 u32 packet_size; 344 int ret; 345 346 packet_size = struct_size(int_pkt, buffer_info, 1); 347 int_pkt = kzalloc(packet_size, GFP_KERNEL); 348 if (!int_pkt) 349 return -ENOMEM; 350 351 int_pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_BUFFERS; 352 int_pkt->shdr.session_id = inst->session_id; 353 int_pkt->buffer_size = buf->buffer_size; 354 int_pkt->min_buffer_size = buf->buffer_size; 355 int_pkt->num_buffers = 1; 356 int_pkt->extradata_size = 0; 357 int_pkt->shdr.hdr.size = packet_size; 358 for (i = 0; i < int_pkt->num_buffers; i++) 359 int_pkt->buffer_info[i] = buf->device_addr; 360 buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); 361 if (buffer_type == -EINVAL) { 362 ret = -EINVAL; 363 goto exit; 364 } 365 366 int_pkt->buffer_type = buffer_type; 367 ret = iris_hfi_queue_cmd_write(inst->core, int_pkt, int_pkt->shdr.hdr.size); 368 369exit: 370 kfree(int_pkt); 371 372 return ret; 373} 374 375static int iris_hfi_gen1_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) 376{ 377 switch (buf->type) { 378 case BUF_INPUT: 379 return iris_hfi_gen1_queue_input_buffer(inst, buf); 380 case BUF_OUTPUT: 381 case BUF_DPB: 382 return iris_hfi_gen1_queue_output_buffer(inst, buf); 383 case BUF_PERSIST: 384 case BUF_BIN: 385 case BUF_SCRATCH_1: 386 case BUF_SCRATCH_2: 387 case BUF_ARP: 388 return iris_hfi_gen1_queue_internal_buffer(inst, buf); 389 default: 390 return -EINVAL; 391 } 392} 393 394static int iris_hfi_gen1_session_unset_buffers(struct iris_inst *inst, struct iris_buffer *buf) 395{ 396 struct hfi_session_release_buffer_pkt *pkt; 397 u32 packet_size, buffer_type, i; 398 int ret; 399 400 buffer_type = iris_hfi_gen1_buf_type_from_driver(buf->type); 401 if (buffer_type == -EINVAL) 402 return -EINVAL; 403 404 if (buffer_type == HFI_BUFFER_INPUT) 405 return 0; 406 407 packet_size = sizeof(*pkt) + sizeof(struct hfi_buffer_info); 408 pkt = kzalloc(packet_size, GFP_KERNEL); 409 if (!pkt) 410 return -ENOMEM; 411 412 pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_RELEASE_BUFFERS; 413 pkt->shdr.session_id = inst->session_id; 414 pkt->buffer_size = buf->buffer_size; 415 pkt->num_buffers = 1; 416 417 if (buffer_type == HFI_BUFFER_OUTPUT || 418 buffer_type == HFI_BUFFER_OUTPUT2) { 419 struct hfi_buffer_info *bi; 420 421 bi = (struct hfi_buffer_info *)pkt->buffer_info; 422 for (i = 0; i < pkt->num_buffers; i++) { 423 bi->buffer_addr = buf->device_addr; 424 bi->extradata_addr = 0; 425 } 426 pkt->shdr.hdr.size = packet_size; 427 } else { 428 for (i = 0; i < pkt->num_buffers; i++) 429 pkt->buffer_info[i] = buf->device_addr; 430 pkt->extradata_size = 0; 431 pkt->shdr.hdr.size = 432 sizeof(struct hfi_session_set_buffers_pkt) + 433 ((pkt->num_buffers) * sizeof(u32)); 434 } 435 436 pkt->response_req = true; 437 pkt->buffer_type = buffer_type; 438 439 ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); 440 if (ret) 441 goto exit; 442 443 ret = iris_wait_for_session_response(inst, false); 444 if (!ret) 445 ret = iris_destroy_internal_buffer(inst, buf); 446 447exit: 448 kfree(pkt); 449 450 return ret; 451} 452 453static int iris_hfi_gen1_session_drain(struct iris_inst *inst, u32 plane) 454{ 455 if (inst->domain == DECODER) { 456 struct hfi_session_empty_buffer_compressed_pkt ip_pkt = {0}; 457 458 ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_compressed_pkt); 459 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 460 ip_pkt.shdr.session_id = inst->session_id; 461 ip_pkt.flags = HFI_BUFFERFLAG_EOS; 462 ip_pkt.packet_buffer = 0xdeadb000; 463 464 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); 465 } 466 467 if (inst->domain == ENCODER) { 468 struct hfi_session_empty_buffer_uncompressed_pkt ip_pkt = {0}; 469 470 ip_pkt.shdr.hdr.size = sizeof(struct hfi_session_empty_buffer_uncompressed_pkt); 471 ip_pkt.shdr.hdr.pkt_type = HFI_CMD_SESSION_EMPTY_BUFFER; 472 ip_pkt.shdr.session_id = inst->session_id; 473 ip_pkt.flags = HFI_BUFFERFLAG_EOS; 474 ip_pkt.packet_buffer = 0xdeadb000; 475 476 return iris_hfi_queue_cmd_write(inst->core, &ip_pkt, ip_pkt.shdr.hdr.size); 477 } 478 479 return -EINVAL; 480} 481 482static int 483iris_hfi_gen1_packet_session_set_property(struct hfi_session_set_property_pkt *packet, 484 struct iris_inst *inst, u32 ptype, void *pdata) 485{ 486 void *prop_data = &packet->data[1]; 487 488 packet->shdr.hdr.size = sizeof(*packet); 489 packet->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY; 490 packet->shdr.session_id = inst->session_id; 491 packet->num_properties = 1; 492 packet->data[0] = ptype; 493 494 switch (ptype) { 495 case HFI_PROPERTY_PARAM_FRAME_SIZE: { 496 struct hfi_framesize *in = pdata, *fsize = prop_data; 497 498 fsize->buffer_type = in->buffer_type; 499 fsize->height = in->height; 500 fsize->width = in->width; 501 packet->shdr.hdr.size += sizeof(u32) + sizeof(*fsize); 502 break; 503 } 504 case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: { 505 struct hfi_videocores_usage_type *in = pdata, *cu = prop_data; 506 507 cu->video_core_enable_mask = in->video_core_enable_mask; 508 packet->shdr.hdr.size += sizeof(u32) + sizeof(*cu); 509 break; 510 } 511 case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT: { 512 struct hfi_uncompressed_format_select *in = pdata; 513 struct hfi_uncompressed_format_select *hfi = prop_data; 514 515 hfi->buffer_type = in->buffer_type; 516 hfi->format = in->format; 517 packet->shdr.hdr.size += sizeof(u32) + sizeof(*hfi); 518 break; 519 } 520 case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO: { 521 struct hfi_uncompressed_plane_actual_constraints_info *info = prop_data; 522 523 info->buffer_type = HFI_BUFFER_OUTPUT2; 524 info->num_planes = 2; 525 info->plane_format[0].stride_multiples = 128; 526 info->plane_format[0].max_stride = 8192; 527 info->plane_format[0].min_plane_buffer_height_multiple = 32; 528 info->plane_format[0].buffer_alignment = 256; 529 if (info->num_planes > 1) { 530 info->plane_format[1].stride_multiples = 128; 531 info->plane_format[1].max_stride = 8192; 532 info->plane_format[1].min_plane_buffer_height_multiple = 16; 533 info->plane_format[1].buffer_alignment = 256; 534 } 535 536 packet->shdr.hdr.size += sizeof(u32) + sizeof(*info); 537 break; 538 } 539 case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: { 540 struct hfi_buffer_count_actual *in = pdata; 541 struct hfi_buffer_count_actual *count = prop_data; 542 543 count->type = in->type; 544 count->count_actual = in->count_actual; 545 count->count_min_host = in->count_min_host; 546 packet->shdr.hdr.size += sizeof(u32) + sizeof(*count); 547 break; 548 } 549 case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: { 550 struct hfi_multi_stream *in = pdata; 551 struct hfi_multi_stream *multi = prop_data; 552 553 multi->buffer_type = in->buffer_type; 554 multi->enable = in->enable; 555 packet->shdr.hdr.size += sizeof(u32) + sizeof(*multi); 556 break; 557 } 558 case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: { 559 struct hfi_buffer_size_actual *in = pdata, *sz = prop_data; 560 561 sz->size = in->size; 562 sz->type = in->type; 563 packet->shdr.hdr.size += sizeof(u32) + sizeof(*sz); 564 break; 565 } 566 case HFI_PROPERTY_PARAM_WORK_ROUTE: { 567 struct hfi_video_work_route *wr = prop_data; 568 u32 *in = pdata; 569 570 wr->video_work_route = *in; 571 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wr); 572 break; 573 } 574 case HFI_PROPERTY_PARAM_WORK_MODE: { 575 struct hfi_video_work_mode *wm = prop_data; 576 u32 *in = pdata; 577 578 wm->video_work_mode = *in; 579 packet->shdr.hdr.size += sizeof(u32) + sizeof(*wm); 580 break; 581 } 582 case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: { 583 struct hfi_profile_level *in = pdata, *pl = prop_data; 584 585 pl->level = in->level; 586 pl->profile = in->profile; 587 if (pl->profile <= 0) 588 /* Profile not supported, falling back to high */ 589 pl->profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; 590 591 if (!pl->level) 592 /* Level not supported, falling back to 1 */ 593 pl->level = 1; 594 595 packet->shdr.hdr.size += sizeof(u32) + sizeof(*pl); 596 break; 597 } 598 case HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER: { 599 struct hfi_enable *en = prop_data; 600 u32 *in = pdata; 601 602 en->enable = *in; 603 packet->shdr.hdr.size += sizeof(u32) + sizeof(*en); 604 break; 605 } 606 case HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE: { 607 struct hfi_bitrate *brate = prop_data; 608 u32 *in = pdata; 609 610 brate->bitrate = *in; 611 brate->layer_id = 0; 612 packet->shdr.hdr.size += sizeof(u32) + sizeof(*brate); 613 break; 614 } 615 case HFI_PROPERTY_PARAM_VENC_RATE_CONTROL: { 616 u32 *in = pdata; 617 618 switch (*in) { 619 case HFI_RATE_CONTROL_OFF: 620 case HFI_RATE_CONTROL_CBR_CFR: 621 case HFI_RATE_CONTROL_CBR_VFR: 622 case HFI_RATE_CONTROL_VBR_CFR: 623 case HFI_RATE_CONTROL_VBR_VFR: 624 case HFI_RATE_CONTROL_CQ: 625 break; 626 default: 627 return -EINVAL; 628 } 629 630 packet->data[1] = *in; 631 packet->shdr.hdr.size += sizeof(u32) * 2; 632 break; 633 } 634 case HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL: { 635 struct hfi_h264_entropy_control *entropy = prop_data; 636 u32 *in = pdata; 637 638 entropy->entropy_mode = *in; 639 if (entropy->entropy_mode == HFI_H264_ENTROPY_CABAC) 640 entropy->cabac_model = HFI_H264_CABAC_MODEL_0; 641 packet->shdr.hdr.size += sizeof(u32) + sizeof(*entropy); 642 break; 643 } 644 case HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2: { 645 struct hfi_quantization_range_v2 *range = prop_data; 646 struct hfi_quantization_range_v2 *in = pdata; 647 u32 min_qp, max_qp; 648 649 min_qp = in->min_qp.qp_packed; 650 max_qp = in->max_qp.qp_packed; 651 652 /* We'll be packing in the qp, so make sure we 653 * won't be losing data when masking 654 */ 655 if (min_qp > 0xff || max_qp > 0xff) 656 return -ERANGE; 657 658 range->min_qp.layer_id = 0xFF; 659 range->max_qp.layer_id = 0xFF; 660 range->min_qp.qp_packed = (min_qp & 0xFF) | ((min_qp & 0xFF) << 8) | 661 ((min_qp & 0xFF) << 16); 662 range->max_qp.qp_packed = (max_qp & 0xFF) | ((max_qp & 0xFF) << 8) | 663 ((max_qp & 0xFF) << 16); 664 range->min_qp.enable = 7; 665 range->max_qp.enable = 7; 666 packet->shdr.hdr.size += sizeof(u32) + sizeof(*range); 667 break; 668 } 669 case HFI_PROPERTY_CONFIG_FRAME_RATE: { 670 struct hfi_framerate *frate = prop_data; 671 struct hfi_framerate *in = pdata; 672 673 frate->buffer_type = in->buffer_type; 674 frate->framerate = in->framerate; 675 packet->shdr.hdr.size += sizeof(u32) + sizeof(*frate); 676 break; 677 } 678 case HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO: { 679 struct hfi_uncompressed_plane_actual_info *plane_actual_info = prop_data; 680 struct hfi_uncompressed_plane_actual_info *in = pdata; 681 682 plane_actual_info->buffer_type = in->buffer_type; 683 plane_actual_info->num_planes = in->num_planes; 684 plane_actual_info->plane_format[0] = in->plane_format[0]; 685 if (in->num_planes > 1) 686 plane_actual_info->plane_format[1] = in->plane_format[1]; 687 packet->shdr.hdr.size += sizeof(u32) + sizeof(*plane_actual_info); 688 break; 689 } 690 default: 691 return -EINVAL; 692 } 693 694 return 0; 695} 696 697static int hfi_gen1_set_property(struct iris_inst *inst, u32 packet_type, 698 void *payload, u32 payload_size) 699{ 700 struct hfi_session_set_property_pkt *pkt; 701 u32 packet_size; 702 int ret; 703 704 packet_size = sizeof(*pkt) + sizeof(u32) + payload_size; 705 pkt = kzalloc(packet_size, GFP_KERNEL); 706 if (!pkt) 707 return -ENOMEM; 708 709 ret = iris_hfi_gen1_packet_session_set_property(pkt, inst, packet_type, payload); 710 if (ret == -EOPNOTSUPP) { 711 ret = 0; 712 goto exit; 713 } 714 if (ret) 715 goto exit; 716 717 ret = iris_hfi_queue_cmd_write(inst->core, pkt, pkt->shdr.hdr.size); 718 719exit: 720 kfree(pkt); 721 722 return ret; 723} 724 725static int iris_hfi_gen1_session_set_property(struct iris_inst *inst, u32 packet_type, 726 u32 flag, u32 plane, u32 payload_type, 727 void *payload, u32 payload_size) 728{ 729 return hfi_gen1_set_property(inst, packet_type, payload, payload_size); 730} 731 732static int iris_hfi_gen1_set_resolution(struct iris_inst *inst, u32 plane) 733{ 734 u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE; 735 struct hfi_framesize fs; 736 int ret; 737 738 if (!iris_drc_pending(inst) && !(inst->sub_state & IRIS_INST_SUB_FIRST_IPSC)) { 739 fs.buffer_type = HFI_BUFFER_INPUT; 740 fs.width = inst->fmt_src->fmt.pix_mp.width; 741 fs.height = inst->fmt_src->fmt.pix_mp.height; 742 743 ret = hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 744 if (ret) 745 return ret; 746 } 747 if (inst->domain == DECODER) 748 fs.buffer_type = HFI_BUFFER_OUTPUT2; 749 else 750 fs.buffer_type = HFI_BUFFER_OUTPUT; 751 752 fs.width = inst->fmt_dst->fmt.pix_mp.width; 753 fs.height = inst->fmt_dst->fmt.pix_mp.height; 754 755 return hfi_gen1_set_property(inst, ptype, &fs, sizeof(fs)); 756} 757 758static int iris_hfi_gen1_decide_core(struct iris_inst *inst, u32 plane) 759{ 760 const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE; 761 struct hfi_videocores_usage_type cu; 762 763 cu.video_core_enable_mask = HFI_CORE_ID_1; 764 765 return hfi_gen1_set_property(inst, ptype, &cu, sizeof(cu)); 766} 767 768static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane) 769{ 770 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT; 771 struct hfi_uncompressed_format_select fmt; 772 u32 pixelformat; 773 int ret; 774 775 if (inst->domain == DECODER) { 776 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 777 if (iris_split_mode_enabled(inst)) { 778 fmt.buffer_type = HFI_BUFFER_OUTPUT; 779 fmt.format = HFI_COLOR_FORMAT_NV12_UBWC; 780 781 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 782 if (ret) 783 return ret; 784 785 fmt.buffer_type = HFI_BUFFER_OUTPUT2; 786 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 787 HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; 788 789 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 790 } else { 791 fmt.buffer_type = HFI_BUFFER_OUTPUT; 792 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 793 HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; 794 795 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 796 } 797 } else { 798 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 799 fmt.buffer_type = HFI_BUFFER_INPUT; 800 fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? 801 HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; 802 ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); 803 } 804 805 return ret; 806} 807 808static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst, u32 plane) 809{ 810 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; 811 struct hfi_uncompressed_plane_actual_constraints_info pconstraint; 812 813 if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) 814 return 0; 815 816 pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; 817 pconstraint.num_planes = 2; 818 pconstraint.plane_format[0].stride_multiples = 128; 819 pconstraint.plane_format[0].max_stride = 8192; 820 pconstraint.plane_format[0].min_plane_buffer_height_multiple = 32; 821 pconstraint.plane_format[0].buffer_alignment = 256; 822 823 pconstraint.plane_format[1].stride_multiples = 128; 824 pconstraint.plane_format[1].max_stride = 8192; 825 pconstraint.plane_format[1].min_plane_buffer_height_multiple = 16; 826 pconstraint.plane_format[1].buffer_alignment = 256; 827 828 return hfi_gen1_set_property(inst, ptype, &pconstraint, sizeof(pconstraint)); 829} 830 831static int iris_hfi_gen1_set_num_bufs(struct iris_inst *inst, u32 plane) 832{ 833 u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL; 834 struct hfi_buffer_count_actual buf_count; 835 int ret; 836 837 buf_count.type = HFI_BUFFER_INPUT; 838 buf_count.count_actual = VIDEO_MAX_FRAME; 839 buf_count.count_min_host = VIDEO_MAX_FRAME; 840 841 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 842 if (ret) 843 return ret; 844 845 if (inst->domain == DECODER) { 846 if (iris_split_mode_enabled(inst)) { 847 buf_count.type = HFI_BUFFER_OUTPUT; 848 buf_count.count_actual = VIDEO_MAX_FRAME; 849 buf_count.count_min_host = VIDEO_MAX_FRAME; 850 851 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 852 if (ret) 853 return ret; 854 855 buf_count.type = HFI_BUFFER_OUTPUT2; 856 buf_count.count_actual = iris_vpu_buf_count(inst, BUF_DPB); 857 buf_count.count_min_host = iris_vpu_buf_count(inst, BUF_DPB); 858 859 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 860 } else { 861 buf_count.type = HFI_BUFFER_OUTPUT; 862 buf_count.count_actual = VIDEO_MAX_FRAME; 863 buf_count.count_min_host = VIDEO_MAX_FRAME; 864 865 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 866 } 867 } else { 868 buf_count.type = HFI_BUFFER_OUTPUT; 869 buf_count.count_actual = VIDEO_MAX_FRAME; 870 buf_count.count_min_host = VIDEO_MAX_FRAME; 871 872 ret = hfi_gen1_set_property(inst, ptype, &buf_count, sizeof(buf_count)); 873 } 874 875 return ret; 876} 877 878static int iris_hfi_gen1_set_multistream(struct iris_inst *inst, u32 plane) 879{ 880 u32 ptype = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM; 881 struct hfi_multi_stream multi = {0}; 882 int ret; 883 884 if (iris_split_mode_enabled(inst)) { 885 multi.buffer_type = HFI_BUFFER_OUTPUT; 886 multi.enable = 0; 887 888 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 889 if (ret) 890 return ret; 891 892 multi.buffer_type = HFI_BUFFER_OUTPUT2; 893 multi.enable = 1; 894 895 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 896 } else { 897 multi.buffer_type = HFI_BUFFER_OUTPUT; 898 multi.enable = 1; 899 900 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 901 if (ret) 902 return ret; 903 904 multi.buffer_type = HFI_BUFFER_OUTPUT2; 905 multi.enable = 0; 906 907 ret = hfi_gen1_set_property(inst, ptype, &multi, sizeof(multi)); 908 } 909 910 return ret; 911} 912 913static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane) 914{ 915 const u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL; 916 struct hfi_buffer_size_actual bufsz; 917 int ret; 918 919 if (iris_split_mode_enabled(inst)) { 920 bufsz.type = HFI_BUFFER_OUTPUT; 921 bufsz.size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, BUF_DPB); 922 923 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 924 if (ret) 925 return ret; 926 927 bufsz.type = HFI_BUFFER_OUTPUT2; 928 bufsz.size = inst->buffers[BUF_OUTPUT].size; 929 930 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 931 } else { 932 bufsz.type = HFI_BUFFER_OUTPUT; 933 bufsz.size = inst->buffers[BUF_OUTPUT].size; 934 935 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 936 if (ret) 937 return ret; 938 939 bufsz.type = HFI_BUFFER_OUTPUT2; 940 bufsz.size = 0; 941 942 ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); 943 } 944 945 return ret; 946} 947 948static int iris_hfi_gen1_set_frame_rate(struct iris_inst *inst, u32 plane) 949{ 950 const u32 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; 951 struct hfi_framerate frate; 952 953 if (V4L2_TYPE_IS_OUTPUT(plane)) 954 return 0; 955 956 frate.buffer_type = HFI_BUFFER_OUTPUT; 957 frate.framerate = inst->frame_rate << 16; 958 959 return hfi_gen1_set_property(inst, ptype, &frate, sizeof(frate)); 960} 961 962static int iris_hfi_gen1_set_stride(struct iris_inst *inst, u32 plane) 963{ 964 const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO; 965 struct hfi_uncompressed_plane_actual_info plane_actual_info; 966 967 plane_actual_info.buffer_type = HFI_BUFFER_INPUT; 968 plane_actual_info.num_planes = 2; 969 plane_actual_info.plane_format[0].actual_stride = 970 ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 971 plane_actual_info.plane_format[0].actual_plane_buffer_height = 972 ALIGN(inst->fmt_src->fmt.pix_mp.height, 32); 973 plane_actual_info.plane_format[1].actual_stride = 974 ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 975 plane_actual_info.plane_format[1].actual_plane_buffer_height = 976 (ALIGN(inst->fmt_src->fmt.pix_mp.height, 32)) / 2; 977 978 return hfi_gen1_set_property(inst, ptype, &plane_actual_info, sizeof(plane_actual_info)); 979} 980 981static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 plane) 982{ 983 struct iris_hfi_prop_type_handle const *handler = NULL; 984 u32 handler_size = 0; 985 struct iris_core *core = inst->core; 986 u32 config_params_size, i, j; 987 const u32 *config_params; 988 int ret; 989 990 static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_inp_arr[] = { 991 {HFI_PROPERTY_PARAM_FRAME_SIZE, 992 iris_hfi_gen1_set_resolution}, 993 {HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, 994 iris_hfi_gen1_decide_core}, 995 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 996 iris_hfi_gen1_set_raw_format}, 997 {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 998 iris_hfi_gen1_set_format_constraints}, 999 {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 1000 iris_hfi_gen1_set_num_bufs}, 1001 {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 1002 iris_hfi_gen1_set_multistream}, 1003 {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 1004 iris_hfi_gen1_set_bufsize}, 1005 }; 1006 1007 static const struct iris_hfi_prop_type_handle vdec_prop_type_handle_out_arr[] = { 1008 {HFI_PROPERTY_PARAM_FRAME_SIZE, 1009 iris_hfi_gen1_set_resolution}, 1010 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 1011 iris_hfi_gen1_set_raw_format}, 1012 {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO, 1013 iris_hfi_gen1_set_format_constraints}, 1014 {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 1015 iris_hfi_gen1_set_num_bufs}, 1016 {HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM, 1017 iris_hfi_gen1_set_multistream}, 1018 {HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL, 1019 iris_hfi_gen1_set_bufsize}, 1020 }; 1021 1022 static const struct iris_hfi_prop_type_handle venc_prop_type_handle_inp_arr[] = { 1023 {HFI_PROPERTY_CONFIG_FRAME_RATE, 1024 iris_hfi_gen1_set_frame_rate}, 1025 {HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_INFO, 1026 iris_hfi_gen1_set_stride}, 1027 {HFI_PROPERTY_PARAM_FRAME_SIZE, 1028 iris_hfi_gen1_set_resolution}, 1029 {HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, 1030 iris_hfi_gen1_set_raw_format}, 1031 {HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL, 1032 iris_hfi_gen1_set_num_bufs}, 1033 }; 1034 1035 if (inst->domain == DECODER) { 1036 config_params = core->iris_platform_data->dec_input_config_params_default; 1037 config_params_size = core->iris_platform_data->dec_input_config_params_default_size; 1038 if (V4L2_TYPE_IS_OUTPUT(plane)) { 1039 handler = vdec_prop_type_handle_inp_arr; 1040 handler_size = ARRAY_SIZE(vdec_prop_type_handle_inp_arr); 1041 } else if (V4L2_TYPE_IS_CAPTURE(plane)) { 1042 handler = vdec_prop_type_handle_out_arr; 1043 handler_size = ARRAY_SIZE(vdec_prop_type_handle_out_arr); 1044 } 1045 } else { 1046 config_params = core->iris_platform_data->enc_input_config_params; 1047 config_params_size = core->iris_platform_data->enc_input_config_params_size; 1048 handler = venc_prop_type_handle_inp_arr; 1049 handler_size = ARRAY_SIZE(venc_prop_type_handle_inp_arr); 1050 } 1051 1052 for (i = 0; i < config_params_size; i++) { 1053 for (j = 0; j < handler_size; j++) { 1054 if (handler[j].type == config_params[i]) { 1055 ret = handler[j].handle(inst, plane); 1056 if (ret) 1057 return ret; 1058 break; 1059 } 1060 } 1061 } 1062 1063 return 0; 1064} 1065 1066static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { 1067 .sys_init = iris_hfi_gen1_sys_init, 1068 .sys_image_version = iris_hfi_gen1_sys_image_version, 1069 .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, 1070 .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, 1071 .session_open = iris_hfi_gen1_session_open, 1072 .session_set_config_params = iris_hfi_gen1_session_set_config_params, 1073 .session_set_property = iris_hfi_gen1_session_set_property, 1074 .session_start = iris_hfi_gen1_session_start, 1075 .session_queue_buf = iris_hfi_gen1_session_queue_buffer, 1076 .session_release_buf = iris_hfi_gen1_session_unset_buffers, 1077 .session_resume_drc = iris_hfi_gen1_session_continue, 1078 .session_stop = iris_hfi_gen1_session_stop, 1079 .session_drain = iris_hfi_gen1_session_drain, 1080 .session_close = iris_hfi_gen1_session_close, 1081}; 1082 1083void iris_hfi_gen1_command_ops_init(struct iris_core *core) 1084{ 1085 core->hfi_ops = &iris_hfi_gen1_command_ops; 1086} 1087 1088struct iris_inst *iris_hfi_gen1_get_instance(void) 1089{ 1090 return kzalloc(sizeof(struct iris_inst), GFP_KERNEL); 1091}
~/
Read-only file preview.