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