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