1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <media/v4l2-event.h> 7 #include <media/v4l2-mem2mem.h> 8 9 #include "iris_buffer.h" 10 #include "iris_common.h" 11 #include "iris_ctrls.h" 12 #include "iris_instance.h" 13 #include "iris_power.h" 14 #include "iris_vdec.h" 15 #include "iris_vpu_buffer.h" 16 17 #define DEFAULT_CODEC_ALIGNMENT 16 18 19 int iris_vdec_inst_init(struct iris_inst *inst) 20 { 21 struct iris_core *core = inst->core; 22 struct v4l2_format *f; 23 24 inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); 25 inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); 26 27 inst->fw_min_count = MIN_BUFFERS; 28 29 f = inst->fmt_src; 30 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 31 f->fmt.pix_mp.width = DEFAULT_WIDTH; 32 f->fmt.pix_mp.height = DEFAULT_HEIGHT; 33 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264; 34 inst->codec = f->fmt.pix_mp.pixelformat; 35 f->fmt.pix_mp.num_planes = 1; 36 f->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 37 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 38 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 39 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 40 inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 41 42 f = inst->fmt_dst; 43 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 44 f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; 45 f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128); 46 f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32); 47 f->fmt.pix_mp.num_planes = 1; 48 f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128); 49 f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 50 f->fmt.pix_mp.field = V4L2_FIELD_NONE; 51 f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT; 52 f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT; 53 f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 54 f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; 55 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 56 inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; 57 58 memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0], 59 INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); 60 61 return iris_ctrls_init(inst); 62 } 63 64 void iris_vdec_inst_deinit(struct iris_inst *inst) 65 { 66 kfree(inst->fmt_dst); 67 kfree(inst->fmt_src); 68 } 69 70 static const struct iris_fmt iris_vdec_formats_out[] = { 71 [IRIS_FMT_H264] = { 72 .pixfmt = V4L2_PIX_FMT_H264, 73 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 74 }, 75 [IRIS_FMT_HEVC] = { 76 .pixfmt = V4L2_PIX_FMT_HEVC, 77 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 78 }, 79 [IRIS_FMT_VP9] = { 80 .pixfmt = V4L2_PIX_FMT_VP9, 81 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 82 }, 83 }; 84 85 static const struct iris_fmt iris_vdec_formats_cap[] = { 86 [IRIS_FMT_NV12] = { 87 .pixfmt = V4L2_PIX_FMT_NV12, 88 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 89 }, 90 [IRIS_FMT_QC08C] = { 91 .pixfmt = V4L2_PIX_FMT_QC08C, 92 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 93 }, 94 }; 95 96 static const struct iris_fmt * 97 find_format(struct iris_inst *inst, u32 pixfmt, u32 type) 98 { 99 const struct iris_fmt *fmt = NULL; 100 unsigned int size = 0; 101 unsigned int i; 102 switch (type) { 103 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 104 fmt = iris_vdec_formats_out; 105 size = ARRAY_SIZE(iris_vdec_formats_out); 106 break; 107 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 108 fmt = iris_vdec_formats_cap; 109 size = ARRAY_SIZE(iris_vdec_formats_cap); 110 break; 111 default: 112 return NULL; 113 } 114 115 for (i = 0; i < size; i++) { 116 if (fmt[i].pixfmt == pixfmt) 117 break; 118 } 119 120 if (i == size || fmt[i].type != type) 121 return NULL; 122 123 return &fmt[i]; 124 } 125 126 static const struct iris_fmt * 127 find_format_by_index(struct iris_inst *inst, u32 index, u32 type) 128 { 129 const struct iris_fmt *fmt = NULL; 130 unsigned int size = 0; 131 132 switch (type) { 133 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 134 fmt = iris_vdec_formats_out; 135 size = ARRAY_SIZE(iris_vdec_formats_out); 136 break; 137 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 138 fmt = iris_vdec_formats_cap; 139 size = ARRAY_SIZE(iris_vdec_formats_cap); 140 break; 141 default: 142 return NULL; 143 } 144 145 if (index >= size || fmt[index].type != type) 146 return NULL; 147 148 return &fmt[index]; 149 } 150 151 int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) 152 { 153 const struct iris_fmt *fmt; 154 155 switch (f->type) { 156 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 157 fmt = find_format_by_index(inst, f->index, f->type); 158 if (!fmt) 159 return -EINVAL; 160 161 f->pixelformat = fmt->pixfmt; 162 f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; 163 break; 164 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 165 fmt = find_format_by_index(inst, f->index, f->type); 166 if (!fmt) 167 return -EINVAL; 168 f->pixelformat = fmt->pixfmt; 169 break; 170 default: 171 return -EINVAL; 172 } 173 174 return 0; 175 } 176 177 int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) 178 { 179 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 180 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 181 const struct iris_fmt *fmt; 182 struct v4l2_format *f_inst; 183 struct vb2_queue *src_q; 184 185 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 186 fmt = find_format(inst, pixmp->pixelformat, f->type); 187 switch (f->type) { 188 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 189 if (!fmt) { 190 f_inst = inst->fmt_src; 191 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 192 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 193 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 194 } 195 break; 196 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 197 if (!fmt) { 198 f_inst = inst->fmt_dst; 199 f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; 200 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 201 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 202 } 203 204 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 205 if (vb2_is_streaming(src_q)) { 206 f_inst = inst->fmt_src; 207 f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; 208 f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; 209 } 210 break; 211 default: 212 return -EINVAL; 213 } 214 215 if (pixmp->field == V4L2_FIELD_ANY) 216 pixmp->field = V4L2_FIELD_NONE; 217 218 pixmp->num_planes = 1; 219 220 return 0; 221 } 222 223 int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) 224 { 225 struct v4l2_format *fmt, *output_fmt; 226 struct vb2_queue *q; 227 u32 codec_align; 228 229 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 230 231 if (vb2_is_busy(q)) 232 return -EBUSY; 233 234 iris_vdec_try_fmt(inst, f); 235 236 switch (f->type) { 237 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 238 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 239 return -EINVAL; 240 241 fmt = inst->fmt_src; 242 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 243 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 244 inst->codec = fmt->fmt.pix_mp.pixelformat; 245 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 246 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 247 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 248 fmt->fmt.pix_mp.num_planes = 1; 249 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 250 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 251 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 252 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 253 254 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 255 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 256 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 257 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 258 259 output_fmt = inst->fmt_dst; 260 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 261 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 262 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 263 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 264 265 /* Update capture format based on new ip w/h */ 266 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 267 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 268 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 269 270 inst->crop.left = 0; 271 inst->crop.top = 0; 272 inst->crop.width = f->fmt.pix_mp.width; 273 inst->crop.height = f->fmt.pix_mp.height; 274 break; 275 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 276 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 277 return -EINVAL; 278 279 fmt = inst->fmt_dst; 280 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 281 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 282 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 283 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 284 fmt->fmt.pix_mp.num_planes = 1; 285 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 286 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 287 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 288 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 289 290 inst->crop.top = 0; 291 inst->crop.left = 0; 292 inst->crop.width = f->fmt.pix_mp.width; 293 inst->crop.height = f->fmt.pix_mp.height; 294 break; 295 default: 296 return -EINVAL; 297 } 298 memcpy(f, fmt, sizeof(*fmt)); 299 300 return 0; 301 } 302 303 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) 304 { 305 const struct iris_fmt *fmt = NULL; 306 307 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 308 if (!fmt) { 309 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 310 if (!fmt) 311 return -EINVAL; 312 } 313 314 return 0; 315 } 316 317 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 318 { 319 int ret = 0; 320 321 switch (sub->type) { 322 case V4L2_EVENT_EOS: 323 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 324 break; 325 case V4L2_EVENT_SOURCE_CHANGE: 326 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 327 break; 328 case V4L2_EVENT_CTRL: 329 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 330 break; 331 default: 332 return -EINVAL; 333 } 334 335 return ret; 336 } 337 338 void iris_vdec_src_change(struct iris_inst *inst) 339 { 340 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 341 struct v4l2_event event = {0}; 342 struct vb2_queue *src_q; 343 344 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 345 if (!vb2_is_streaming(src_q)) 346 return; 347 348 event.type = V4L2_EVENT_SOURCE_CHANGE; 349 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 350 v4l2_event_queue_fh(&inst->fh, &event); 351 } 352 353 int iris_vdec_streamon_input(struct iris_inst *inst) 354 { 355 int ret; 356 357 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 358 if (ret) 359 return ret; 360 361 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST); 362 if (ret) 363 return ret; 364 365 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 366 367 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 368 if (ret) 369 return ret; 370 371 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 372 if (ret) 373 return ret; 374 375 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 376 if (ret) 377 return ret; 378 379 return iris_process_streamon_input(inst); 380 } 381 382 int iris_vdec_streamon_output(struct iris_inst *inst) 383 { 384 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 385 int ret; 386 387 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 388 if (ret) 389 return ret; 390 391 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 392 393 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 394 if (ret) 395 return ret; 396 397 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 398 if (ret) 399 return ret; 400 401 ret = iris_process_streamon_output(inst); 402 if (ret) 403 goto error; 404 405 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 406 if (ret) 407 goto error; 408 409 return ret; 410 411 error: 412 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 413 414 return ret; 415 } 416 417 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 418 { 419 struct iris_buffer *buf = to_iris_buffer(vbuf); 420 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 421 struct vb2_queue *q; 422 int ret; 423 424 ret = iris_vb2_buffer_to_driver(vb2, buf); 425 if (ret) 426 return ret; 427 428 if (buf->type == BUF_INPUT) 429 iris_set_ts_metadata(inst, vbuf); 430 431 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 432 if (!vb2_is_streaming(q)) { 433 buf->attr |= BUF_ATTR_DEFERRED; 434 return 0; 435 } 436 437 iris_scale_power(inst); 438 439 return iris_queue_buffer(inst, buf); 440 } 441 442 int iris_vdec_start_cmd(struct iris_inst *inst) 443 { 444 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 445 enum iris_inst_sub_state clear_sub_state = 0; 446 struct vb2_queue *dst_vq; 447 int ret; 448 449 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 450 451 if (inst->sub_state & IRIS_INST_SUB_DRC && 452 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 453 vb2_clear_last_buffer_dequeued(dst_vq); 454 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 455 456 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 457 ret = hfi_ops->session_resume_drc(inst, 458 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 459 if (ret) 460 return ret; 461 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 462 } 463 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 464 ret = hfi_ops->session_resume_drc(inst, 465 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 466 if (ret) 467 return ret; 468 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 469 } 470 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 471 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 472 vb2_clear_last_buffer_dequeued(dst_vq); 473 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 474 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 475 if (hfi_ops->session_resume_drain) { 476 ret = 477 hfi_ops->session_resume_drain(inst, 478 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 479 if (ret) 480 return ret; 481 } 482 483 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 484 } 485 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 486 if (hfi_ops->session_resume_drain) { 487 ret = 488 hfi_ops->session_resume_drain(inst, 489 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 490 if (ret) 491 return ret; 492 } 493 494 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 495 } 496 } else { 497 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 498 iris_inst_change_state(inst, IRIS_INST_ERROR); 499 return -EBUSY; 500 } 501 502 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 503 } 504 505 int iris_vdec_stop_cmd(struct iris_inst *inst) 506 { 507 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 508 int ret; 509 510 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 511 if (ret) 512 return ret; 513 514 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 515 } 516