1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/bitfield.h> 7 8 #include "iris_hfi_gen2.h" 9 #include "iris_hfi_gen2_packet.h" 10 11 #define UNSPECIFIED_COLOR_FORMAT 5 12 #define NUM_SYS_INIT_PACKETS 8 13 14 #define SYS_INIT_PKT_SIZE (sizeof(struct iris_hfi_header) + \ 15 NUM_SYS_INIT_PACKETS * (sizeof(struct iris_hfi_packet) + sizeof(u32))) 16 17 #define SYS_IFPC_PKT_SIZE (sizeof(struct iris_hfi_header) + \ 18 sizeof(struct iris_hfi_packet) + sizeof(u32)) 19 20 #define SYS_NO_PAYLOAD_PKT_SIZE (sizeof(struct iris_hfi_header) + \ 21 sizeof(struct iris_hfi_packet)) 22 23 static int iris_hfi_gen2_sys_init(struct iris_core *core) 24 { 25 struct iris_hfi_header *hdr; 26 int ret; 27 28 hdr = kzalloc(SYS_INIT_PKT_SIZE, GFP_KERNEL); 29 if (!hdr) 30 return -ENOMEM; 31 32 iris_hfi_gen2_packet_sys_init(core, hdr); 33 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); 34 35 kfree(hdr); 36 37 return ret; 38 } 39 40 static int iris_hfi_gen2_sys_image_version(struct iris_core *core) 41 { 42 struct iris_hfi_header *hdr; 43 int ret; 44 45 hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL); 46 if (!hdr) 47 return -ENOMEM; 48 49 iris_hfi_gen2_packet_image_version(core, hdr); 50 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); 51 52 kfree(hdr); 53 54 return ret; 55 } 56 57 static int iris_hfi_gen2_sys_interframe_powercollapse(struct iris_core *core) 58 { 59 struct iris_hfi_header *hdr; 60 int ret; 61 62 hdr = kzalloc(SYS_IFPC_PKT_SIZE, GFP_KERNEL); 63 if (!hdr) 64 return -ENOMEM; 65 66 iris_hfi_gen2_packet_sys_interframe_powercollapse(core, hdr); 67 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); 68 69 kfree(hdr); 70 71 return ret; 72 } 73 74 static int iris_hfi_gen2_sys_pc_prep(struct iris_core *core) 75 { 76 struct iris_hfi_header *hdr; 77 int ret; 78 79 hdr = kzalloc(SYS_NO_PAYLOAD_PKT_SIZE, GFP_KERNEL); 80 if (!hdr) 81 return -ENOMEM; 82 83 iris_hfi_gen2_packet_sys_pc_prep(core, hdr); 84 ret = iris_hfi_queue_cmd_write_locked(core, hdr, hdr->size); 85 86 kfree(hdr); 87 88 return ret; 89 } 90 91 static u32 iris_hfi_gen2_get_port(struct iris_inst *inst, u32 plane) 92 { 93 if (inst->domain == DECODER) { 94 switch (plane) { 95 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 96 return HFI_PORT_BITSTREAM; 97 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 98 return HFI_PORT_RAW; 99 default: 100 return HFI_PORT_NONE; 101 } 102 } else { 103 switch (plane) { 104 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 105 return HFI_PORT_RAW; 106 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 107 return HFI_PORT_BITSTREAM; 108 default: 109 return HFI_PORT_NONE; 110 } 111 } 112 } 113 114 static u32 iris_hfi_gen2_get_port_from_buf_type(struct iris_inst *inst, 115 enum iris_buffer_type buffer_type) 116 { 117 if (inst->domain == DECODER) { 118 switch (buffer_type) { 119 case BUF_INPUT: 120 case BUF_BIN: 121 case BUF_COMV: 122 case BUF_NON_COMV: 123 case BUF_LINE: 124 case BUF_PARTIAL: 125 return HFI_PORT_BITSTREAM; 126 case BUF_OUTPUT: 127 case BUF_DPB: 128 return HFI_PORT_RAW; 129 case BUF_PERSIST: 130 default: 131 return HFI_PORT_NONE; 132 } 133 } else { 134 switch (buffer_type) { 135 case BUF_INPUT: 136 case BUF_VPSS: 137 return HFI_PORT_RAW; 138 case BUF_OUTPUT: 139 case BUF_BIN: 140 case BUF_COMV: 141 case BUF_NON_COMV: 142 case BUF_LINE: 143 case BUF_SCRATCH_2: 144 return HFI_PORT_BITSTREAM; 145 case BUF_ARP: 146 default: 147 return HFI_PORT_NONE; 148 } 149 } 150 } 151 152 static int iris_hfi_gen2_session_set_property(struct iris_inst *inst, u32 packet_type, u32 flag, 153 u32 plane, u32 payload_type, void *payload, 154 u32 payload_size) 155 { 156 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 157 158 iris_hfi_gen2_packet_session_property(inst, 159 packet_type, 160 flag, 161 plane, 162 payload_type, 163 payload, 164 payload_size); 165 166 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 167 inst_hfi_gen2->packet->size); 168 } 169 170 static int iris_hfi_gen2_set_raw_resolution(struct iris_inst *inst, u32 plane) 171 { 172 u32 resolution = inst->enc_raw_width << 16 | inst->enc_raw_height; 173 u32 port = iris_hfi_gen2_get_port(inst, plane); 174 175 return iris_hfi_gen2_session_set_property(inst, 176 HFI_PROP_RAW_RESOLUTION, 177 HFI_HOST_FLAGS_NONE, 178 port, 179 HFI_PAYLOAD_32_PACKED, 180 &resolution, 181 sizeof(u32)); 182 } 183 184 static inline u32 iris_hfi_get_aligned_resolution(struct iris_inst *inst, u32 width, u32 height) 185 { 186 u32 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 187 188 return (ALIGN(width, codec_align) << 16 | ALIGN(height, codec_align)); 189 } 190 191 static int iris_hfi_gen2_set_bitstream_resolution(struct iris_inst *inst, u32 plane) 192 { 193 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 194 u32 port = iris_hfi_gen2_get_port(inst, plane); 195 enum hfi_packet_payload_info payload_type; 196 u32 width, height; 197 u32 resolution; 198 199 if (inst->domain == DECODER) { 200 width = inst->fmt_src->fmt.pix_mp.width; 201 height = inst->fmt_src->fmt.pix_mp.height; 202 resolution = iris_hfi_get_aligned_resolution(inst, width, height); 203 inst_hfi_gen2->src_subcr_params.bitstream_resolution = resolution; 204 payload_type = HFI_PAYLOAD_U32; 205 } else { 206 if (is_rotation_90_or_270(inst)) { 207 width = inst->enc_scale_height; 208 height = inst->enc_scale_width; 209 } else { 210 width = inst->enc_scale_width; 211 height = inst->enc_scale_height; 212 } 213 resolution = iris_hfi_get_aligned_resolution(inst, width, height); 214 inst_hfi_gen2->dst_subcr_params.bitstream_resolution = resolution; 215 payload_type = HFI_PAYLOAD_32_PACKED; 216 } 217 218 return iris_hfi_gen2_session_set_property(inst, 219 HFI_PROP_BITSTREAM_RESOLUTION, 220 HFI_HOST_FLAGS_NONE, 221 port, 222 payload_type, 223 &resolution, 224 sizeof(u32)); 225 } 226 227 static int iris_hfi_gen2_set_crop_offsets(struct iris_inst *inst, u32 plane) 228 { 229 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 230 u32 port = iris_hfi_gen2_get_port(inst, plane); 231 u32 bottom_offset, right_offset; 232 u32 left_offset, top_offset; 233 u32 payload[2], codec_align; 234 235 if (inst->domain == DECODER) { 236 if (V4L2_TYPE_IS_OUTPUT(plane)) { 237 bottom_offset = (inst->fmt_src->fmt.pix_mp.height - inst->crop.height); 238 right_offset = (inst->fmt_src->fmt.pix_mp.width - inst->crop.width); 239 left_offset = inst->crop.left; 240 top_offset = inst->crop.top; 241 } else { 242 bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - inst->compose.height); 243 right_offset = (inst->fmt_dst->fmt.pix_mp.width - inst->compose.width); 244 left_offset = inst->compose.left; 245 top_offset = inst->compose.top; 246 } 247 } else { 248 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 249 if (V4L2_TYPE_IS_OUTPUT(plane)) { 250 bottom_offset = (inst->enc_raw_height - inst->crop.height); 251 right_offset = (inst->enc_raw_width - inst->crop.width); 252 left_offset = inst->crop.left; 253 top_offset = inst->crop.top; 254 } else { 255 if (is_rotation_90_or_270(inst)) { 256 bottom_offset = (ALIGN(inst->enc_scale_width, codec_align) - 257 inst->enc_scale_width); 258 right_offset = (ALIGN(inst->enc_scale_height, codec_align) - 259 inst->enc_scale_height); 260 } else { 261 bottom_offset = (ALIGN(inst->enc_scale_height, codec_align) - 262 inst->enc_scale_height); 263 right_offset = (ALIGN(inst->enc_scale_width, codec_align) - 264 inst->enc_scale_width); 265 } 266 left_offset = 0; 267 top_offset = 0; 268 } 269 } 270 271 payload[0] = FIELD_PREP(GENMASK(31, 16), left_offset) | top_offset; 272 payload[1] = FIELD_PREP(GENMASK(31, 16), right_offset) | bottom_offset; 273 inst_hfi_gen2->src_subcr_params.crop_offsets[0] = payload[0]; 274 inst_hfi_gen2->src_subcr_params.crop_offsets[1] = payload[1]; 275 276 return iris_hfi_gen2_session_set_property(inst, 277 HFI_PROP_CROP_OFFSETS, 278 HFI_HOST_FLAGS_NONE, 279 port, 280 HFI_PAYLOAD_64_PACKED, 281 &payload, 282 sizeof(u64)); 283 } 284 285 static int iris_hfi_gen2_set_bit_depth(struct iris_inst *inst, u32 plane) 286 { 287 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 288 u32 port = iris_hfi_gen2_get_port(inst, plane); 289 u32 bitdepth = BIT_DEPTH_8; 290 291 inst_hfi_gen2->src_subcr_params.bit_depth = bitdepth; 292 293 return iris_hfi_gen2_session_set_property(inst, 294 HFI_PROP_LUMA_CHROMA_BIT_DEPTH, 295 HFI_HOST_FLAGS_NONE, 296 port, 297 HFI_PAYLOAD_U32, 298 &bitdepth, 299 sizeof(u32)); 300 } 301 302 static int iris_hfi_gen2_set_coded_frames(struct iris_inst *inst, u32 plane) 303 { 304 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 305 u32 port = iris_hfi_gen2_get_port(inst, plane); 306 u32 coded_frames = 0; 307 308 if (inst->fw_caps[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE) 309 coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG; 310 inst_hfi_gen2->src_subcr_params.coded_frames = coded_frames; 311 312 return iris_hfi_gen2_session_set_property(inst, 313 HFI_PROP_CODED_FRAMES, 314 HFI_HOST_FLAGS_NONE, 315 port, 316 HFI_PAYLOAD_U32, 317 &coded_frames, 318 sizeof(u32)); 319 } 320 321 static int iris_hfi_gen2_set_min_output_count(struct iris_inst *inst, u32 plane) 322 { 323 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 324 u32 min_output = inst->buffers[BUF_OUTPUT].min_count; 325 u32 port = iris_hfi_gen2_get_port(inst, plane); 326 327 inst_hfi_gen2->src_subcr_params.fw_min_count = min_output; 328 329 return iris_hfi_gen2_session_set_property(inst, 330 HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, 331 HFI_HOST_FLAGS_NONE, 332 port, 333 HFI_PAYLOAD_U32, 334 &min_output, 335 sizeof(u32)); 336 } 337 338 static int iris_hfi_gen2_set_picture_order_count(struct iris_inst *inst, u32 plane) 339 { 340 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 341 u32 port = iris_hfi_gen2_get_port(inst, plane); 342 u32 poc = 0; 343 344 inst_hfi_gen2->src_subcr_params.pic_order_cnt = poc; 345 346 return iris_hfi_gen2_session_set_property(inst, 347 HFI_PROP_PIC_ORDER_CNT_TYPE, 348 HFI_HOST_FLAGS_NONE, 349 port, 350 HFI_PAYLOAD_U32, 351 &poc, 352 sizeof(u32)); 353 } 354 355 static int iris_hfi_gen2_set_colorspace(struct iris_inst *inst, u32 plane) 356 { 357 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 358 struct v4l2_pix_format_mplane *pixmp = &inst->fmt_src->fmt.pix_mp; 359 u32 video_signal_type_present_flag = 0, color_info; 360 u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED; 361 u32 video_format = UNSPECIFIED_COLOR_FORMAT; 362 u32 full_range = V4L2_QUANTIZATION_DEFAULT; 363 u32 transfer_char = HFI_TRANSFER_RESERVED; 364 u32 port = iris_hfi_gen2_get_port(inst, plane); 365 u32 colour_description_present_flag = 0; 366 u32 primaries = HFI_PRIMARIES_RESERVED; 367 368 if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT || 369 pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT || 370 pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) { 371 colour_description_present_flag = 1; 372 video_signal_type_present_flag = 1; 373 primaries = iris_hfi_gen2_get_color_primaries(pixmp->colorspace); 374 matrix_coeff = iris_hfi_gen2_get_matrix_coefficients(pixmp->ycbcr_enc); 375 transfer_char = iris_hfi_gen2_get_transfer_char(pixmp->xfer_func); 376 } 377 378 if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) { 379 video_signal_type_present_flag = 1; 380 full_range = pixmp->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0; 381 } 382 383 color_info = iris_hfi_gen2_get_color_info(matrix_coeff, transfer_char, primaries, 384 colour_description_present_flag, full_range, 385 video_format, video_signal_type_present_flag); 386 387 inst_hfi_gen2->src_subcr_params.color_info = color_info; 388 389 return iris_hfi_gen2_session_set_property(inst, 390 HFI_PROP_SIGNAL_COLOR_INFO, 391 HFI_HOST_FLAGS_NONE, 392 port, 393 HFI_PAYLOAD_32_PACKED, 394 &color_info, 395 sizeof(u32)); 396 } 397 398 static int iris_hfi_gen2_set_profile(struct iris_inst *inst, u32 plane) 399 { 400 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 401 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 402 u32 profile = 0; 403 404 switch (inst->codec) { 405 case V4L2_PIX_FMT_HEVC: 406 profile = inst->fw_caps[PROFILE_HEVC].value; 407 break; 408 case V4L2_PIX_FMT_VP9: 409 profile = inst->fw_caps[PROFILE_VP9].value; 410 break; 411 case V4L2_PIX_FMT_H264: 412 profile = inst->fw_caps[PROFILE_H264].value; 413 break; 414 case V4L2_PIX_FMT_AV1: 415 profile = inst->fw_caps[PROFILE_AV1].value; 416 break; 417 } 418 419 inst_hfi_gen2->src_subcr_params.profile = profile; 420 421 return iris_hfi_gen2_session_set_property(inst, 422 HFI_PROP_PROFILE, 423 HFI_HOST_FLAGS_NONE, 424 port, 425 HFI_PAYLOAD_U32_ENUM, 426 &profile, 427 sizeof(u32)); 428 } 429 430 static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane) 431 { 432 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 433 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 434 u32 level = 0; 435 436 switch (inst->codec) { 437 case V4L2_PIX_FMT_HEVC: 438 level = inst->fw_caps[LEVEL_HEVC].value; 439 break; 440 case V4L2_PIX_FMT_VP9: 441 level = inst->fw_caps[LEVEL_VP9].value; 442 break; 443 case V4L2_PIX_FMT_H264: 444 level = inst->fw_caps[LEVEL_H264].value; 445 break; 446 case V4L2_PIX_FMT_AV1: 447 level = inst->fw_caps[LEVEL_AV1].value; 448 break; 449 } 450 451 inst_hfi_gen2->src_subcr_params.level = level; 452 453 return iris_hfi_gen2_session_set_property(inst, 454 HFI_PROP_LEVEL, 455 HFI_HOST_FLAGS_NONE, 456 port, 457 HFI_PAYLOAD_U32_ENUM, 458 &level, 459 sizeof(u32)); 460 } 461 462 static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane) 463 { 464 u32 port = iris_hfi_gen2_get_port(inst, plane); 465 u32 opb_enable = iris_split_mode_enabled(inst); 466 467 return iris_hfi_gen2_session_set_property(inst, 468 HFI_PROP_OPB_ENABLE, 469 HFI_HOST_FLAGS_NONE, 470 port, 471 HFI_PAYLOAD_U32, 472 &opb_enable, 473 sizeof(u32)); 474 } 475 476 static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane) 477 { 478 u32 port = iris_hfi_gen2_get_port(inst, plane); 479 u32 hfi_colorformat, pixelformat; 480 481 if (inst->domain == DECODER) { 482 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 483 switch (pixelformat) { 484 case V4L2_PIX_FMT_NV12: 485 hfi_colorformat = HFI_COLOR_FMT_NV12; 486 break; 487 case V4L2_PIX_FMT_QC08C: 488 hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC; 489 break; 490 case V4L2_PIX_FMT_P010: 491 hfi_colorformat = HFI_COLOR_FMT_P010; 492 break; 493 case V4L2_PIX_FMT_QC10C: 494 hfi_colorformat = HFI_COLOR_FMT_TP10_UBWC; 495 break; 496 } 497 } else { 498 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 499 hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? 500 HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC; 501 } 502 503 return iris_hfi_gen2_session_set_property(inst, 504 HFI_PROP_COLOR_FORMAT, 505 HFI_HOST_FLAGS_NONE, 506 port, 507 HFI_PAYLOAD_U32_ENUM, 508 &hfi_colorformat, 509 sizeof(u32)); 510 } 511 512 static int iris_hfi_gen2_set_linear_stride_scanline(struct iris_inst *inst, u32 plane) 513 { 514 u32 pixelformat, stride_y, stride_uv, scanline_y, scanline_uv; 515 u32 port = iris_hfi_gen2_get_port(inst, plane); 516 u32 payload[2]; 517 518 if (inst->domain == DECODER) { 519 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 520 stride_y = inst->fmt_dst->fmt.pix_mp.width; 521 scanline_y = inst->fmt_dst->fmt.pix_mp.height; 522 } else { 523 pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; 524 stride_y = ALIGN(inst->fmt_src->fmt.pix_mp.width, 128); 525 scanline_y = ALIGN(inst->fmt_src->fmt.pix_mp.height, 32); 526 } 527 528 stride_uv = stride_y; 529 scanline_uv = scanline_y / 2; 530 531 if (pixelformat != V4L2_PIX_FMT_NV12 && 532 pixelformat != V4L2_PIX_FMT_P010) 533 return 0; 534 535 payload[0] = stride_y << 16 | scanline_y; 536 payload[1] = stride_uv << 16 | scanline_uv; 537 538 return iris_hfi_gen2_session_set_property(inst, 539 HFI_PROP_LINEAR_STRIDE_SCANLINE, 540 HFI_HOST_FLAGS_NONE, 541 port, 542 HFI_PAYLOAD_64_PACKED, 543 &payload, 544 sizeof(u64)); 545 } 546 547 static int iris_hfi_gen2_set_ubwc_stride_scanline(struct iris_inst *inst, u32 plane) 548 { 549 u32 meta_stride_y, meta_scanline_y, meta_stride_uv, meta_scanline_uv; 550 u32 stride_y, scanline_y, stride_uv, scanline_uv; 551 u32 port = iris_hfi_gen2_get_port(inst, plane); 552 u32 pixelformat, width, height; 553 u32 payload[4]; 554 555 if (inst->domain != DECODER || 556 inst->fmt_src->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_AV1) 557 return 0; 558 559 pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; 560 width = inst->fmt_dst->fmt.pix_mp.width; 561 height = inst->fmt_dst->fmt.pix_mp.height; 562 563 switch (pixelformat) { 564 case V4L2_PIX_FMT_QC08C: 565 stride_y = ALIGN(width, 128); 566 scanline_y = ALIGN(height, 32); 567 stride_uv = ALIGN(width, 128); 568 scanline_uv = ALIGN((height + 1) >> 1, 32); 569 meta_stride_y = ALIGN(DIV_ROUND_UP(width, 32), 64); 570 meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 8), 16); 571 meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64); 572 meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 8), 16); 573 break; 574 case V4L2_PIX_FMT_QC10C: 575 stride_y = ALIGN(width * 4 / 3, 256); 576 scanline_y = ALIGN(height, 16); 577 stride_uv = ALIGN(width * 4 / 3, 256); 578 scanline_uv = ALIGN((height + 1) >> 1, 16); 579 meta_stride_y = ALIGN(DIV_ROUND_UP(width, 48), 64); 580 meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 4), 16); 581 meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64); 582 meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16); 583 break; 584 default: 585 return 0; 586 } 587 588 payload[0] = stride_y << 16 | scanline_y; 589 payload[1] = stride_uv << 16 | scanline_uv; 590 payload[2] = meta_stride_y << 16 | meta_scanline_y; 591 payload[3] = meta_stride_uv << 16 | meta_scanline_uv; 592 593 return iris_hfi_gen2_session_set_property(inst, 594 HFI_PROP_UBWC_STRIDE_SCANLINE, 595 HFI_HOST_FLAGS_NONE, 596 port, 597 HFI_PAYLOAD_U32_ARRAY, 598 &payload[0], 599 sizeof(u32) * 4); 600 } 601 602 static int iris_hfi_gen2_set_tier(struct iris_inst *inst, u32 plane) 603 { 604 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 605 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 606 u32 tier = inst->fw_caps[TIER].value; 607 608 tier = (inst->codec == V4L2_PIX_FMT_AV1) ? inst->fw_caps[TIER_AV1].value : 609 inst->fw_caps[TIER].value; 610 inst_hfi_gen2->src_subcr_params.tier = tier; 611 612 return iris_hfi_gen2_session_set_property(inst, 613 HFI_PROP_TIER, 614 HFI_HOST_FLAGS_NONE, 615 port, 616 HFI_PAYLOAD_U32_ENUM, 617 &tier, 618 sizeof(u32)); 619 } 620 621 static int iris_hfi_gen2_set_frame_rate(struct iris_inst *inst, u32 plane) 622 { 623 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 624 u32 frame_rate = inst->frame_rate << 16; 625 626 return iris_hfi_gen2_session_set_property(inst, 627 HFI_PROP_FRAME_RATE, 628 HFI_HOST_FLAGS_NONE, 629 port, 630 HFI_PAYLOAD_Q16, 631 &frame_rate, 632 sizeof(u32)); 633 } 634 635 static int iris_hfi_gen2_set_film_grain(struct iris_inst *inst, u32 plane) 636 { 637 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 638 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 639 u32 film_grain = inst->fw_caps[FILM_GRAIN].value; 640 641 inst_hfi_gen2->src_subcr_params.film_grain = film_grain; 642 643 return iris_hfi_gen2_session_set_property(inst, 644 HFI_PROP_AV1_FILM_GRAIN_PRESENT, 645 HFI_HOST_FLAGS_NONE, 646 port, 647 HFI_PAYLOAD_U32_ENUM, 648 &film_grain, 649 sizeof(u32)); 650 } 651 652 static int iris_hfi_gen2_set_super_block(struct iris_inst *inst, u32 plane) 653 { 654 u32 port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 655 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 656 u32 super_block = inst->fw_caps[SUPER_BLOCK].value; 657 658 inst_hfi_gen2->src_subcr_params.super_block = super_block; 659 660 return iris_hfi_gen2_session_set_property(inst, 661 HFI_PROP_AV1_SUPER_BLOCK_ENABLED, 662 HFI_HOST_FLAGS_NONE, 663 port, 664 HFI_PAYLOAD_U32_ENUM, 665 &super_block, 666 sizeof(u32)); 667 } 668 669 static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) 670 { 671 const struct iris_firmware_data *fdata = inst->core->iris_firmware_data; 672 u32 config_params_size = 0, i, j; 673 const u32 *config_params = NULL; 674 int ret; 675 676 static const struct iris_hfi_prop_type_handle prop_type_handle_arr[] = { 677 {HFI_PROP_RAW_RESOLUTION, iris_hfi_gen2_set_raw_resolution }, 678 {HFI_PROP_BITSTREAM_RESOLUTION, iris_hfi_gen2_set_bitstream_resolution }, 679 {HFI_PROP_CROP_OFFSETS, iris_hfi_gen2_set_crop_offsets }, 680 {HFI_PROP_CODED_FRAMES, iris_hfi_gen2_set_coded_frames }, 681 {HFI_PROP_LUMA_CHROMA_BIT_DEPTH, iris_hfi_gen2_set_bit_depth }, 682 {HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT, iris_hfi_gen2_set_min_output_count }, 683 {HFI_PROP_PIC_ORDER_CNT_TYPE, iris_hfi_gen2_set_picture_order_count }, 684 {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace }, 685 {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile }, 686 {HFI_PROP_LEVEL, iris_hfi_gen2_set_level }, 687 {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable }, 688 {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, 689 {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, 690 {HFI_PROP_UBWC_STRIDE_SCANLINE, iris_hfi_gen2_set_ubwc_stride_scanline }, 691 {HFI_PROP_TIER, iris_hfi_gen2_set_tier }, 692 {HFI_PROP_FRAME_RATE, iris_hfi_gen2_set_frame_rate }, 693 {HFI_PROP_AV1_FILM_GRAIN_PRESENT, iris_hfi_gen2_set_film_grain }, 694 {HFI_PROP_AV1_SUPER_BLOCK_ENABLED, iris_hfi_gen2_set_super_block }, 695 {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable }, 696 }; 697 698 if (inst->domain == DECODER) { 699 if (V4L2_TYPE_IS_OUTPUT(plane)) { 700 if (inst->codec == V4L2_PIX_FMT_H264) { 701 config_params = fdata->dec_input_config_params_default; 702 config_params_size = fdata->dec_input_config_params_default_size; 703 } else if (inst->codec == V4L2_PIX_FMT_HEVC) { 704 config_params = fdata->dec_input_config_params_hevc; 705 config_params_size = fdata->dec_input_config_params_hevc_size; 706 } else if (inst->codec == V4L2_PIX_FMT_VP9) { 707 config_params = fdata->dec_input_config_params_vp9; 708 config_params_size = fdata->dec_input_config_params_vp9_size; 709 } else if (inst->codec == V4L2_PIX_FMT_AV1) { 710 config_params = fdata->dec_input_config_params_av1; 711 config_params_size = fdata->dec_input_config_params_av1_size; 712 } else { 713 return -EINVAL; 714 } 715 } else { 716 config_params = fdata->dec_output_config_params; 717 config_params_size = fdata->dec_output_config_params_size; 718 } 719 } else { 720 if (V4L2_TYPE_IS_OUTPUT(plane)) { 721 config_params = fdata->enc_input_config_params; 722 config_params_size = fdata->enc_input_config_params_size; 723 } else { 724 config_params = fdata->enc_output_config_params; 725 config_params_size = fdata->enc_output_config_params_size; 726 } 727 } 728 729 if (!config_params || !config_params_size) 730 return -EINVAL; 731 732 for (i = 0; i < config_params_size; i++) { 733 for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) { 734 if (prop_type_handle_arr[j].type == config_params[i]) { 735 ret = prop_type_handle_arr[j].handle(inst, plane); 736 if (ret) 737 return ret; 738 break; 739 } 740 } 741 } 742 743 return 0; 744 } 745 746 static int iris_hfi_gen2_session_set_codec(struct iris_inst *inst) 747 { 748 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 749 u32 codec = 0; 750 751 switch (inst->codec) { 752 case V4L2_PIX_FMT_H264: 753 if (inst->domain == ENCODER) 754 codec = HFI_CODEC_ENCODE_AVC; 755 else 756 codec = HFI_CODEC_DECODE_AVC; 757 break; 758 case V4L2_PIX_FMT_HEVC: 759 if (inst->domain == ENCODER) 760 codec = HFI_CODEC_ENCODE_HEVC; 761 else 762 codec = HFI_CODEC_DECODE_HEVC; 763 break; 764 case V4L2_PIX_FMT_VP9: 765 codec = HFI_CODEC_DECODE_VP9; 766 break; 767 case V4L2_PIX_FMT_AV1: 768 codec = HFI_CODEC_DECODE_AV1; 769 } 770 771 iris_hfi_gen2_packet_session_property(inst, 772 HFI_PROP_CODEC, 773 HFI_HOST_FLAGS_NONE, 774 HFI_PORT_NONE, 775 HFI_PAYLOAD_U32_ENUM, 776 &codec, 777 sizeof(u32)); 778 779 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 780 inst_hfi_gen2->packet->size); 781 } 782 783 static int iris_hfi_gen2_session_set_default_header(struct iris_inst *inst) 784 { 785 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 786 u32 default_header = false; 787 788 iris_hfi_gen2_packet_session_property(inst, 789 HFI_PROP_DEC_DEFAULT_HEADER, 790 HFI_HOST_FLAGS_NONE, 791 HFI_PORT_BITSTREAM, 792 HFI_PAYLOAD_U32, 793 &default_header, 794 sizeof(u32)); 795 796 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 797 inst_hfi_gen2->packet->size); 798 } 799 800 static int iris_hfi_gen2_session_open(struct iris_inst *inst) 801 { 802 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 803 int ret; 804 805 if (inst->state != IRIS_INST_DEINIT) 806 return -EALREADY; 807 808 inst_hfi_gen2->ipsc_properties_set = false; 809 inst_hfi_gen2->opsc_properties_set = false; 810 811 inst_hfi_gen2->packet = kzalloc(4096, GFP_KERNEL); 812 if (!inst_hfi_gen2->packet) 813 return -ENOMEM; 814 815 iris_hfi_gen2_packet_session_command(inst, 816 HFI_CMD_OPEN, 817 HFI_HOST_FLAGS_RESPONSE_REQUIRED | 818 HFI_HOST_FLAGS_INTR_REQUIRED, 819 HFI_PORT_NONE, 820 0, 821 HFI_PAYLOAD_U32, 822 &inst->session_id, 823 sizeof(u32)); 824 825 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 826 inst_hfi_gen2->packet->size); 827 if (ret) 828 goto fail_free_packet; 829 830 ret = iris_hfi_gen2_session_set_codec(inst); 831 if (ret) 832 goto fail_free_packet; 833 834 if (inst->domain == DECODER) { 835 ret = iris_hfi_gen2_session_set_default_header(inst); 836 if (ret) 837 goto fail_free_packet; 838 } 839 840 return 0; 841 842 fail_free_packet: 843 kfree(inst_hfi_gen2->packet); 844 inst_hfi_gen2->packet = NULL; 845 846 return ret; 847 } 848 849 static int iris_hfi_gen2_session_close(struct iris_inst *inst) 850 { 851 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 852 int ret; 853 854 if (!inst_hfi_gen2->packet) 855 return -EINVAL; 856 857 iris_hfi_gen2_packet_session_command(inst, 858 HFI_CMD_CLOSE, 859 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 860 HFI_HOST_FLAGS_INTR_REQUIRED | 861 HFI_HOST_FLAGS_NON_DISCARDABLE), 862 HFI_PORT_NONE, 863 inst->session_id, 864 HFI_PAYLOAD_NONE, 865 NULL, 866 0); 867 868 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 869 inst_hfi_gen2->packet->size); 870 871 kfree(inst_hfi_gen2->packet); 872 inst_hfi_gen2->packet = NULL; 873 874 return ret; 875 } 876 877 static int iris_hfi_gen2_session_subscribe_mode(struct iris_inst *inst, 878 u32 cmd, u32 plane, u32 payload_type, 879 void *payload, u32 payload_size) 880 { 881 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 882 883 iris_hfi_gen2_packet_session_command(inst, 884 cmd, 885 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 886 HFI_HOST_FLAGS_INTR_REQUIRED), 887 iris_hfi_gen2_get_port(inst, plane), 888 inst->session_id, 889 payload_type, 890 payload, 891 payload_size); 892 893 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 894 inst_hfi_gen2->packet->size); 895 } 896 897 static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plane) 898 { 899 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 900 struct hfi_subscription_params subsc_params; 901 u32 prop_type, payload_size, payload_type; 902 struct iris_core *core = inst->core; 903 const u32 *change_param = NULL; 904 u32 change_param_size = 0; 905 u32 payload[32] = {0}; 906 u32 hfi_port = 0, i; 907 int ret; 908 909 if (inst->domain == ENCODER) 910 return 0; 911 912 if ((V4L2_TYPE_IS_OUTPUT(plane) && inst_hfi_gen2->ipsc_properties_set) || 913 (V4L2_TYPE_IS_CAPTURE(plane) && inst_hfi_gen2->opsc_properties_set)) { 914 dev_dbg(core->dev, "%cPSC already set\n", V4L2_TYPE_IS_OUTPUT(plane) ? 'I' : 'O'); 915 return 0; 916 } 917 918 switch (inst->codec) { 919 case V4L2_PIX_FMT_H264: 920 change_param = core->iris_firmware_data->dec_input_config_params_default; 921 change_param_size = 922 core->iris_firmware_data->dec_input_config_params_default_size; 923 break; 924 case V4L2_PIX_FMT_HEVC: 925 change_param = core->iris_firmware_data->dec_input_config_params_hevc; 926 change_param_size = 927 core->iris_firmware_data->dec_input_config_params_hevc_size; 928 break; 929 case V4L2_PIX_FMT_VP9: 930 change_param = core->iris_firmware_data->dec_input_config_params_vp9; 931 change_param_size = 932 core->iris_firmware_data->dec_input_config_params_vp9_size; 933 break; 934 case V4L2_PIX_FMT_AV1: 935 change_param = core->iris_firmware_data->dec_input_config_params_av1; 936 change_param_size = 937 core->iris_firmware_data->dec_input_config_params_av1_size; 938 break; 939 } 940 941 payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE; 942 943 for (i = 0; i < change_param_size; i++) 944 payload[i + 1] = change_param[i]; 945 946 ret = iris_hfi_gen2_session_subscribe_mode(inst, 947 HFI_CMD_SUBSCRIBE_MODE, 948 plane, 949 HFI_PAYLOAD_U32_ARRAY, 950 &payload[0], 951 ((change_param_size + 1) * sizeof(u32))); 952 if (ret) 953 return ret; 954 955 if (V4L2_TYPE_IS_OUTPUT(plane)) { 956 inst_hfi_gen2->ipsc_properties_set = true; 957 } else { 958 hfi_port = iris_hfi_gen2_get_port(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 959 memcpy(&inst_hfi_gen2->dst_subcr_params, 960 &inst_hfi_gen2->src_subcr_params, 961 sizeof(inst_hfi_gen2->src_subcr_params)); 962 subsc_params = inst_hfi_gen2->dst_subcr_params; 963 for (i = 0; i < change_param_size; i++) { 964 payload[0] = 0; 965 payload[1] = 0; 966 payload_size = 0; 967 payload_type = 0; 968 prop_type = change_param[i]; 969 switch (prop_type) { 970 case HFI_PROP_BITSTREAM_RESOLUTION: 971 payload[0] = subsc_params.bitstream_resolution; 972 payload_size = sizeof(u32); 973 payload_type = HFI_PAYLOAD_U32; 974 break; 975 case HFI_PROP_CROP_OFFSETS: 976 payload[0] = subsc_params.crop_offsets[0]; 977 payload[1] = subsc_params.crop_offsets[1]; 978 payload_size = sizeof(u64); 979 payload_type = HFI_PAYLOAD_64_PACKED; 980 break; 981 case HFI_PROP_CODED_FRAMES: 982 payload[0] = subsc_params.coded_frames; 983 payload_size = sizeof(u32); 984 payload_type = HFI_PAYLOAD_U32; 985 break; 986 case HFI_PROP_LUMA_CHROMA_BIT_DEPTH: 987 payload[0] = subsc_params.bit_depth; 988 payload_size = sizeof(u32); 989 payload_type = HFI_PAYLOAD_U32; 990 break; 991 case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT: 992 payload[0] = subsc_params.fw_min_count; 993 payload_size = sizeof(u32); 994 payload_type = HFI_PAYLOAD_U32; 995 break; 996 case HFI_PROP_PIC_ORDER_CNT_TYPE: 997 payload[0] = subsc_params.pic_order_cnt; 998 payload_size = sizeof(u32); 999 payload_type = HFI_PAYLOAD_U32; 1000 break; 1001 case HFI_PROP_SIGNAL_COLOR_INFO: 1002 payload[0] = subsc_params.color_info; 1003 payload_size = sizeof(u32); 1004 payload_type = HFI_PAYLOAD_U32; 1005 break; 1006 case HFI_PROP_PROFILE: 1007 payload[0] = subsc_params.profile; 1008 payload_size = sizeof(u32); 1009 payload_type = HFI_PAYLOAD_U32; 1010 break; 1011 case HFI_PROP_LEVEL: 1012 payload[0] = subsc_params.level; 1013 payload_size = sizeof(u32); 1014 payload_type = HFI_PAYLOAD_U32; 1015 break; 1016 case HFI_PROP_TIER: 1017 payload[0] = subsc_params.tier; 1018 payload_size = sizeof(u32); 1019 payload_type = HFI_PAYLOAD_U32; 1020 break; 1021 case HFI_PROP_AV1_FILM_GRAIN_PRESENT: 1022 payload[0] = subsc_params.film_grain; 1023 payload_size = sizeof(u32); 1024 payload_type = HFI_PAYLOAD_U32; 1025 break; 1026 case HFI_PROP_AV1_SUPER_BLOCK_ENABLED: 1027 payload[0] = subsc_params.super_block; 1028 payload_size = sizeof(u32); 1029 payload_type = HFI_PAYLOAD_U32; 1030 break; 1031 default: 1032 prop_type = 0; 1033 ret = -EINVAL; 1034 break; 1035 } 1036 if (prop_type) { 1037 ret = iris_hfi_gen2_session_set_property(inst, 1038 prop_type, 1039 HFI_HOST_FLAGS_NONE, 1040 hfi_port, 1041 payload_type, 1042 &payload, 1043 payload_size); 1044 if (ret) 1045 return ret; 1046 } 1047 } 1048 inst_hfi_gen2->opsc_properties_set = true; 1049 } 1050 1051 return 0; 1052 } 1053 1054 static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) 1055 { 1056 struct iris_core *core = inst->core; 1057 u32 subscribe_prop_size = 0, i; 1058 const u32 *subcribe_prop = NULL; 1059 u32 payload[32] = {0}; 1060 1061 payload[0] = HFI_MODE_PROPERTY; 1062 1063 if (inst->domain == ENCODER) 1064 return 0; 1065 1066 if (V4L2_TYPE_IS_OUTPUT(plane)) { 1067 subscribe_prop_size = core->iris_firmware_data->dec_input_prop_size; 1068 subcribe_prop = core->iris_firmware_data->dec_input_prop; 1069 } else { 1070 switch (inst->codec) { 1071 case V4L2_PIX_FMT_H264: 1072 subcribe_prop = core->iris_firmware_data->dec_output_prop_avc; 1073 subscribe_prop_size = 1074 core->iris_firmware_data->dec_output_prop_avc_size; 1075 break; 1076 case V4L2_PIX_FMT_HEVC: 1077 subcribe_prop = core->iris_firmware_data->dec_output_prop_hevc; 1078 subscribe_prop_size = 1079 core->iris_firmware_data->dec_output_prop_hevc_size; 1080 break; 1081 case V4L2_PIX_FMT_VP9: 1082 subcribe_prop = core->iris_firmware_data->dec_output_prop_vp9; 1083 subscribe_prop_size = 1084 core->iris_firmware_data->dec_output_prop_vp9_size; 1085 break; 1086 case V4L2_PIX_FMT_AV1: 1087 subcribe_prop = core->iris_firmware_data->dec_output_prop_av1; 1088 subscribe_prop_size = 1089 core->iris_firmware_data->dec_output_prop_av1_size; 1090 break; 1091 } 1092 } 1093 1094 for (i = 0; i < subscribe_prop_size; i++) 1095 payload[i + 1] = subcribe_prop[i]; 1096 1097 return iris_hfi_gen2_session_subscribe_mode(inst, 1098 HFI_CMD_SUBSCRIBE_MODE, 1099 plane, 1100 HFI_PAYLOAD_U32_ARRAY, 1101 &payload[0], 1102 (subscribe_prop_size + 1) * sizeof(u32)); 1103 } 1104 1105 static int iris_hfi_gen2_session_start(struct iris_inst *inst, u32 plane) 1106 { 1107 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1108 int ret = 0; 1109 1110 ret = iris_hfi_gen2_subscribe_change_param(inst, plane); 1111 if (ret) 1112 return ret; 1113 1114 ret = iris_hfi_gen2_subscribe_property(inst, plane); 1115 if (ret) 1116 return ret; 1117 1118 iris_hfi_gen2_packet_session_command(inst, 1119 HFI_CMD_START, 1120 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1121 HFI_HOST_FLAGS_INTR_REQUIRED), 1122 iris_hfi_gen2_get_port(inst, plane), 1123 inst->session_id, 1124 HFI_PAYLOAD_NONE, 1125 NULL, 1126 0); 1127 1128 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1129 inst_hfi_gen2->packet->size); 1130 } 1131 1132 static int iris_hfi_gen2_session_stop(struct iris_inst *inst, u32 plane) 1133 { 1134 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1135 int ret = 0; 1136 1137 if (!inst_hfi_gen2->packet) 1138 return -EINVAL; 1139 1140 reinit_completion(&inst->completion); 1141 1142 iris_hfi_gen2_packet_session_command(inst, 1143 HFI_CMD_STOP, 1144 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1145 HFI_HOST_FLAGS_INTR_REQUIRED | 1146 HFI_HOST_FLAGS_NON_DISCARDABLE), 1147 iris_hfi_gen2_get_port(inst, plane), 1148 inst->session_id, 1149 HFI_PAYLOAD_NONE, 1150 NULL, 1151 0); 1152 1153 ret = iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1154 inst_hfi_gen2->packet->size); 1155 if (ret) 1156 return ret; 1157 1158 return iris_wait_for_session_response(inst, false); 1159 } 1160 1161 static int iris_hfi_gen2_session_pause(struct iris_inst *inst, u32 plane) 1162 { 1163 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1164 1165 iris_hfi_gen2_packet_session_command(inst, 1166 HFI_CMD_PAUSE, 1167 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1168 HFI_HOST_FLAGS_INTR_REQUIRED), 1169 iris_hfi_gen2_get_port(inst, plane), 1170 inst->session_id, 1171 HFI_PAYLOAD_NONE, 1172 NULL, 1173 0); 1174 1175 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1176 inst_hfi_gen2->packet->size); 1177 } 1178 1179 static int iris_hfi_gen2_session_resume_drc(struct iris_inst *inst, u32 plane) 1180 { 1181 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1182 u32 payload = HFI_CMD_SETTINGS_CHANGE; 1183 1184 iris_hfi_gen2_packet_session_command(inst, 1185 HFI_CMD_RESUME, 1186 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1187 HFI_HOST_FLAGS_INTR_REQUIRED), 1188 iris_hfi_gen2_get_port(inst, plane), 1189 inst->session_id, 1190 HFI_PAYLOAD_U32, 1191 &payload, 1192 sizeof(u32)); 1193 1194 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1195 inst_hfi_gen2->packet->size); 1196 } 1197 1198 static int iris_hfi_gen2_session_resume_drain(struct iris_inst *inst, u32 plane) 1199 { 1200 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1201 u32 payload = HFI_CMD_DRAIN; 1202 1203 iris_hfi_gen2_packet_session_command(inst, 1204 HFI_CMD_RESUME, 1205 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1206 HFI_HOST_FLAGS_INTR_REQUIRED), 1207 iris_hfi_gen2_get_port(inst, plane), 1208 inst->session_id, 1209 HFI_PAYLOAD_U32, 1210 &payload, 1211 sizeof(u32)); 1212 1213 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1214 inst_hfi_gen2->packet->size); 1215 } 1216 1217 static int iris_hfi_gen2_session_drain(struct iris_inst *inst, u32 plane) 1218 { 1219 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1220 1221 if (!V4L2_TYPE_IS_OUTPUT(plane)) 1222 return 0; 1223 1224 iris_hfi_gen2_packet_session_command(inst, 1225 HFI_CMD_DRAIN, 1226 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1227 HFI_HOST_FLAGS_INTR_REQUIRED | 1228 HFI_HOST_FLAGS_NON_DISCARDABLE), 1229 iris_hfi_gen2_get_port(inst, plane), 1230 inst->session_id, 1231 HFI_PAYLOAD_NONE, 1232 NULL, 1233 0); 1234 1235 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1236 inst_hfi_gen2->packet->size); 1237 } 1238 1239 static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type buffer_type) 1240 { 1241 switch (buffer_type) { 1242 case BUF_INPUT: 1243 if (domain == DECODER) 1244 return HFI_BUFFER_BITSTREAM; 1245 else 1246 return HFI_BUFFER_RAW; 1247 case BUF_OUTPUT: 1248 if (domain == DECODER) 1249 return HFI_BUFFER_RAW; 1250 else 1251 return HFI_BUFFER_BITSTREAM; 1252 case BUF_BIN: 1253 return HFI_BUFFER_BIN; 1254 case BUF_COMV: 1255 return HFI_BUFFER_COMV; 1256 case BUF_NON_COMV: 1257 return HFI_BUFFER_NON_COMV; 1258 case BUF_LINE: 1259 return HFI_BUFFER_LINE; 1260 case BUF_DPB: 1261 case BUF_SCRATCH_2: 1262 return HFI_BUFFER_DPB; 1263 case BUF_PERSIST: 1264 return HFI_BUFFER_PERSIST; 1265 case BUF_ARP: 1266 return HFI_BUFFER_ARP; 1267 case BUF_VPSS: 1268 return HFI_BUFFER_VPSS; 1269 case BUF_PARTIAL: 1270 return HFI_BUFFER_PARTIAL_DATA; 1271 default: 1272 return 0; 1273 } 1274 } 1275 1276 static int iris_hfi_gen2_set_num_comv(struct iris_inst *inst) 1277 { 1278 u32 num_comv = inst->buffers[BUF_OUTPUT].min_count; 1279 1280 if (inst->fw_min_count) 1281 num_comv = inst->fw_min_count; 1282 1283 return iris_hfi_gen2_session_set_property(inst, 1284 HFI_PROP_COMV_BUFFER_COUNT, 1285 HFI_HOST_FLAGS_NONE, 1286 HFI_PORT_BITSTREAM, 1287 HFI_PAYLOAD_U32, 1288 &num_comv, sizeof(u32)); 1289 } 1290 1291 static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer, 1292 struct iris_hfi_buffer *buf) 1293 { 1294 memset(buf, 0, sizeof(*buf)); 1295 buf->type = iris_hfi_gen2_buf_type_from_driver(domain, buffer->type); 1296 buf->index = buffer->index; 1297 buf->base_address = buffer->device_addr; 1298 buf->addr_offset = 0; 1299 buf->buffer_size = buffer->buffer_size; 1300 1301 if (domain == DECODER && buffer->type == BUF_INPUT) 1302 buf->buffer_size = ALIGN(buffer->buffer_size, 256); 1303 buf->data_offset = buffer->data_offset; 1304 buf->data_size = buffer->data_size; 1305 if (buffer->attr & BUF_ATTR_PENDING_RELEASE) 1306 buf->flags |= HFI_BUF_HOST_FLAG_RELEASE; 1307 buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE; 1308 buf->timestamp = buffer->timestamp; 1309 } 1310 1311 static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iris_buffer *buffer) 1312 { 1313 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1314 struct iris_hfi_buffer hfi_buffer; 1315 u32 port; 1316 int ret; 1317 1318 iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer); 1319 if (buffer->type == BUF_COMV) { 1320 ret = iris_hfi_gen2_set_num_comv(inst); 1321 if (ret) 1322 return ret; 1323 } 1324 1325 port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type); 1326 iris_hfi_gen2_packet_session_command(inst, 1327 HFI_CMD_BUFFER, 1328 HFI_HOST_FLAGS_INTR_REQUIRED, 1329 port, 1330 inst->session_id, 1331 HFI_PAYLOAD_STRUCTURE, 1332 &hfi_buffer, 1333 sizeof(hfi_buffer)); 1334 1335 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1336 inst_hfi_gen2->packet->size); 1337 } 1338 1339 static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct iris_buffer *buffer) 1340 { 1341 struct iris_inst_hfi_gen2 *inst_hfi_gen2 = to_iris_inst_hfi_gen2(inst); 1342 struct iris_hfi_buffer hfi_buffer; 1343 u32 port; 1344 1345 iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer); 1346 hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE; 1347 port = iris_hfi_gen2_get_port_from_buf_type(inst, buffer->type); 1348 1349 iris_hfi_gen2_packet_session_command(inst, 1350 HFI_CMD_BUFFER, 1351 (HFI_HOST_FLAGS_RESPONSE_REQUIRED | 1352 HFI_HOST_FLAGS_INTR_REQUIRED), 1353 port, 1354 inst->session_id, 1355 HFI_PAYLOAD_STRUCTURE, 1356 &hfi_buffer, 1357 sizeof(hfi_buffer)); 1358 1359 return iris_hfi_queue_cmd_write(inst->core, inst_hfi_gen2->packet, 1360 inst_hfi_gen2->packet->size); 1361 } 1362 1363 static const struct iris_hfi_session_ops iris_hfi_gen2_session_ops = { 1364 .session_open = iris_hfi_gen2_session_open, 1365 .session_set_config_params = iris_hfi_gen2_session_set_config_params, 1366 .session_set_property = iris_hfi_gen2_session_set_property, 1367 .session_start = iris_hfi_gen2_session_start, 1368 .session_queue_buf = iris_hfi_gen2_session_queue_buffer, 1369 .session_release_buf = iris_hfi_gen2_session_release_buffer, 1370 .session_pause = iris_hfi_gen2_session_pause, 1371 .session_resume_drc = iris_hfi_gen2_session_resume_drc, 1372 .session_stop = iris_hfi_gen2_session_stop, 1373 .session_drain = iris_hfi_gen2_session_drain, 1374 .session_resume_drain = iris_hfi_gen2_session_resume_drain, 1375 .session_close = iris_hfi_gen2_session_close, 1376 }; 1377 1378 static struct iris_inst *iris_hfi_gen2_get_instance(void) 1379 { 1380 struct iris_inst_hfi_gen2 *out; 1381 1382 /* The allocation is intentionally larger than struct iris_inst. */ 1383 out = kzalloc_obj(*out); 1384 if (!out) 1385 return NULL; 1386 1387 out->inst.hfi_session_ops = &iris_hfi_gen2_session_ops; 1388 1389 return &out->inst; 1390 } 1391 1392 static const struct iris_hfi_sys_ops iris_hfi_gen2_sys_ops = { 1393 .sys_init = iris_hfi_gen2_sys_init, 1394 .sys_image_version = iris_hfi_gen2_sys_image_version, 1395 .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, 1396 .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, 1397 1398 .sys_hfi_response_handler = iris_hfi_gen2_response_handler, 1399 1400 .sys_get_instance = iris_hfi_gen2_get_instance, 1401 }; 1402 1403 void iris_hfi_gen2_sys_ops_init(struct iris_core *core) 1404 { 1405 core->hfi_sys_ops = &iris_hfi_gen2_sys_ops; 1406 } 1407