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 iris_vdec_try_fmt(inst, f); 220 221 switch (f->type) { 222 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 223 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 224 return -EINVAL; 225 226 fmt = inst->fmt_src; 227 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 228 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 229 inst->codec = fmt->fmt.pix_mp.pixelformat; 230 codec_align = inst->codec == V4L2_PIX_FMT_HEVC ? 32 : 16; 231 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align); 232 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align); 233 fmt->fmt.pix_mp.num_planes = 1; 234 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0; 235 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT); 236 inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT); 237 inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 238 239 fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 240 fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 241 fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 242 fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 243 244 output_fmt = inst->fmt_dst; 245 output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace; 246 output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func; 247 output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc; 248 output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization; 249 250 /* Update capture format based on new ip w/h */ 251 output_fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 252 output_fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 253 inst->buffers[BUF_OUTPUT].size = iris_get_buffer_size(inst, BUF_OUTPUT); 254 255 inst->crop.left = 0; 256 inst->crop.top = 0; 257 inst->crop.width = f->fmt.pix_mp.width; 258 inst->crop.height = f->fmt.pix_mp.height; 259 break; 260 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 261 if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) 262 return -EINVAL; 263 264 fmt = inst->fmt_dst; 265 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 266 fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; 267 fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); 268 fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); 269 fmt->fmt.pix_mp.num_planes = 1; 270 fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128); 271 fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); 272 inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); 273 inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; 274 275 inst->crop.top = 0; 276 inst->crop.left = 0; 277 inst->crop.width = f->fmt.pix_mp.width; 278 inst->crop.height = f->fmt.pix_mp.height; 279 break; 280 default: 281 return -EINVAL; 282 } 283 memcpy(f, fmt, sizeof(*fmt)); 284 285 return 0; 286 } 287 288 int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) 289 { 290 const struct iris_fmt *fmt = NULL; 291 292 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 293 if (!fmt) { 294 fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 295 if (!fmt) 296 return -EINVAL; 297 } 298 299 return 0; 300 } 301 302 int iris_vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub) 303 { 304 int ret = 0; 305 306 switch (sub->type) { 307 case V4L2_EVENT_EOS: 308 ret = v4l2_event_subscribe(&inst->fh, sub, 0, NULL); 309 break; 310 case V4L2_EVENT_SOURCE_CHANGE: 311 ret = v4l2_src_change_event_subscribe(&inst->fh, sub); 312 break; 313 case V4L2_EVENT_CTRL: 314 ret = v4l2_ctrl_subscribe_event(&inst->fh, sub); 315 break; 316 default: 317 return -EINVAL; 318 } 319 320 return ret; 321 } 322 323 void iris_vdec_src_change(struct iris_inst *inst) 324 { 325 struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; 326 struct v4l2_event event = {0}; 327 struct vb2_queue *src_q; 328 329 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 330 if (!vb2_is_streaming(src_q)) 331 return; 332 333 event.type = V4L2_EVENT_SOURCE_CHANGE; 334 event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION; 335 v4l2_event_queue_fh(&inst->fh, &event); 336 } 337 338 int iris_vdec_streamon_input(struct iris_inst *inst) 339 { 340 int ret; 341 342 ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 343 if (ret) 344 return ret; 345 346 ret = iris_alloc_and_queue_persist_bufs(inst, BUF_PERSIST); 347 if (ret) 348 return ret; 349 350 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 351 352 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 353 if (ret) 354 return ret; 355 356 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 357 if (ret) 358 return ret; 359 360 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 361 if (ret) 362 return ret; 363 364 return iris_process_streamon_input(inst); 365 } 366 367 int iris_vdec_streamon_output(struct iris_inst *inst) 368 { 369 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 370 int ret; 371 372 ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 373 if (ret) 374 return ret; 375 376 iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 377 378 ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 379 if (ret) 380 return ret; 381 382 ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 383 if (ret) 384 return ret; 385 386 ret = iris_process_streamon_output(inst); 387 if (ret) 388 goto error; 389 390 ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 391 if (ret) 392 goto error; 393 394 return ret; 395 396 error: 397 iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 398 399 return ret; 400 } 401 402 int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) 403 { 404 struct iris_buffer *buf = to_iris_buffer(vbuf); 405 struct vb2_buffer *vb2 = &vbuf->vb2_buf; 406 struct vb2_queue *q; 407 int ret; 408 409 ret = iris_vb2_buffer_to_driver(vb2, buf); 410 if (ret) 411 return ret; 412 413 if (buf->type == BUF_INPUT) 414 iris_set_ts_metadata(inst, vbuf); 415 416 q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type); 417 if (!vb2_is_streaming(q)) { 418 buf->attr |= BUF_ATTR_DEFERRED; 419 return 0; 420 } 421 422 iris_scale_power(inst); 423 424 return iris_queue_buffer(inst, buf); 425 } 426 427 int iris_vdec_start_cmd(struct iris_inst *inst) 428 { 429 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 430 enum iris_inst_sub_state clear_sub_state = 0; 431 struct vb2_queue *dst_vq; 432 int ret; 433 434 dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx); 435 436 if (inst->sub_state & IRIS_INST_SUB_DRC && 437 inst->sub_state & IRIS_INST_SUB_DRC_LAST) { 438 vb2_clear_last_buffer_dequeued(dst_vq); 439 clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST; 440 441 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 442 ret = hfi_ops->session_resume_drc(inst, 443 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 444 if (ret) 445 return ret; 446 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 447 } 448 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 449 ret = hfi_ops->session_resume_drc(inst, 450 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 451 if (ret) 452 return ret; 453 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 454 } 455 } else if (inst->sub_state & IRIS_INST_SUB_DRAIN && 456 inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) { 457 vb2_clear_last_buffer_dequeued(dst_vq); 458 clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; 459 if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { 460 if (hfi_ops->session_resume_drain) { 461 ret = 462 hfi_ops->session_resume_drain(inst, 463 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 464 if (ret) 465 return ret; 466 } 467 468 clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE; 469 } 470 if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) { 471 if (hfi_ops->session_resume_drain) { 472 ret = 473 hfi_ops->session_resume_drain(inst, 474 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 475 if (ret) 476 return ret; 477 } 478 479 clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE; 480 } 481 } else { 482 dev_err(inst->core->dev, "start called before receiving last_flag\n"); 483 iris_inst_change_state(inst, IRIS_INST_ERROR); 484 return -EBUSY; 485 } 486 487 return iris_inst_change_sub_state(inst, clear_sub_state, 0); 488 } 489 490 int iris_vdec_stop_cmd(struct iris_inst *inst) 491 { 492 const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; 493 int ret; 494 495 ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 496 if (ret) 497 return ret; 498 499 return iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN); 500 } 501