1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2017 Linaro Ltd. 5 */ 6 #include <linux/clk.h> 7 #include <linux/module.h> 8 #include <linux/mod_devicetable.h> 9 #include <linux/platform_device.h> 10 #include <linux/pm_runtime.h> 11 #include <linux/slab.h> 12 #include <media/v4l2-ioctl.h> 13 #include <media/v4l2-event.h> 14 #include <media/v4l2-ctrls.h> 15 #include <media/v4l2-mem2mem.h> 16 #include <media/videobuf2-dma-contig.h> 17 18 #include "hfi_venus_io.h" 19 #include "hfi_parser.h" 20 #include "core.h" 21 #include "helpers.h" 22 #include "vdec.h" 23 #include "pm_helpers.h" 24 25 /* 26 * Three resons to keep MPLANE formats (despite that the number of planes 27 * currently is one): 28 * - the MPLANE formats allow only one plane to be used 29 * - the downstream driver use MPLANE formats too 30 * - future firmware versions could add support for >1 planes 31 */ 32 static const struct venus_format vdec_formats[] = { 33 { 34 .pixfmt = V4L2_PIX_FMT_NV12, 35 .num_planes = 1, 36 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 37 }, { 38 .pixfmt = V4L2_PIX_FMT_QC08C, 39 .num_planes = 1, 40 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 41 }, { 42 .pixfmt = V4L2_PIX_FMT_QC10C, 43 .num_planes = 1, 44 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 45 }, { 46 .pixfmt = V4L2_PIX_FMT_MPEG4, 47 .num_planes = 1, 48 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 49 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 50 }, { 51 .pixfmt = V4L2_PIX_FMT_MPEG2, 52 .num_planes = 1, 53 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 54 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 55 }, { 56 .pixfmt = V4L2_PIX_FMT_H263, 57 .num_planes = 1, 58 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 59 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 60 }, { 61 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G, 62 .num_planes = 1, 63 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 64 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 65 }, { 66 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L, 67 .num_planes = 1, 68 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 69 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 70 }, { 71 .pixfmt = V4L2_PIX_FMT_H264, 72 .num_planes = 1, 73 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 74 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 75 }, { 76 .pixfmt = V4L2_PIX_FMT_VP8, 77 .num_planes = 1, 78 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 79 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 80 }, { 81 .pixfmt = V4L2_PIX_FMT_VP9, 82 .num_planes = 1, 83 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 84 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 85 }, { 86 .pixfmt = V4L2_PIX_FMT_XVID, 87 .num_planes = 1, 88 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 89 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 90 }, { 91 .pixfmt = V4L2_PIX_FMT_HEVC, 92 .num_planes = 1, 93 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 94 .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, 95 }, 96 }; 97 98 static const struct venus_format * 99 find_format(struct venus_inst *inst, u32 pixfmt, u32 type) 100 { 101 const struct venus_format *fmt = vdec_formats; 102 unsigned int size = ARRAY_SIZE(vdec_formats); 103 unsigned int i; 104 105 for (i = 0; i < size; i++) { 106 if (fmt[i].pixfmt == pixfmt) 107 break; 108 } 109 110 if (i == size || fmt[i].type != type) 111 return NULL; 112 113 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 114 !venus_helper_check_codec(inst, fmt[i].pixfmt)) 115 return NULL; 116 117 if (V4L2_TYPE_IS_CAPTURE(type) && 118 !venus_helper_check_format(inst, fmt[i].pixfmt)) 119 return NULL; 120 121 if (V4L2_TYPE_IS_CAPTURE(type) && fmt[i].pixfmt == V4L2_PIX_FMT_QC10C && 122 !(inst->bit_depth == VIDC_BITDEPTH_10)) 123 return NULL; 124 125 return &fmt[i]; 126 } 127 128 static const struct venus_format * 129 find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) 130 { 131 const struct venus_format *fmt = vdec_formats; 132 unsigned int size = ARRAY_SIZE(vdec_formats); 133 unsigned int i, k = 0; 134 135 if (index > size) 136 return NULL; 137 138 for (i = 0; i < size; i++) { 139 bool valid; 140 141 if (fmt[i].type != type) 142 continue; 143 144 if (V4L2_TYPE_IS_OUTPUT(type)) { 145 valid = venus_helper_check_codec(inst, fmt[i].pixfmt); 146 } else if (V4L2_TYPE_IS_CAPTURE(type)) { 147 valid = venus_helper_check_format(inst, fmt[i].pixfmt); 148 149 if (fmt[i].pixfmt == V4L2_PIX_FMT_QC10C && 150 !(inst->bit_depth == VIDC_BITDEPTH_10)) 151 valid = false; 152 } 153 154 if (k == index && valid) 155 break; 156 if (valid) 157 k++; 158 } 159 160 if (i == size) 161 return NULL; 162 163 return &fmt[i]; 164 } 165 166 static const struct venus_format * 167 vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) 168 { 169 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 170 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; 171 const struct venus_format *fmt; 172 u32 szimage; 173 174 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); 175 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 176 177 fmt = find_format(inst, pixmp->pixelformat, f->type); 178 if (!fmt) { 179 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 180 pixmp->pixelformat = V4L2_PIX_FMT_NV12; 181 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 182 pixmp->pixelformat = V4L2_PIX_FMT_H264; 183 else 184 return NULL; 185 fmt = find_format(inst, pixmp->pixelformat, f->type); 186 if (!fmt) 187 return NULL; 188 } 189 190 pixmp->width = clamp(pixmp->width, frame_width_min(inst), 191 frame_width_max(inst)); 192 pixmp->height = clamp(pixmp->height, frame_height_min(inst), 193 frame_height_max(inst)); 194 195 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 196 pixmp->height = ALIGN(pixmp->height, 32); 197 198 if (pixmp->field == V4L2_FIELD_ANY) 199 pixmp->field = V4L2_FIELD_NONE; 200 pixmp->num_planes = fmt->num_planes; 201 pixmp->flags = 0; 202 203 szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width, 204 pixmp->height); 205 206 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 207 unsigned int stride = pixmp->width; 208 209 if (pixmp->pixelformat == V4L2_PIX_FMT_P010) 210 stride *= 2; 211 212 pfmt[0].sizeimage = szimage; 213 pfmt[0].bytesperline = ALIGN(stride, 128); 214 } else { 215 pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_8M); 216 pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage); 217 pfmt[0].bytesperline = 0; 218 } 219 220 return fmt; 221 } 222 223 static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 224 { 225 struct venus_inst *inst = to_inst(file); 226 227 vdec_try_fmt_common(inst, f); 228 229 return 0; 230 } 231 232 static int vdec_check_src_change(struct venus_inst *inst) 233 { 234 int ret; 235 236 if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE && 237 inst->codec_state == VENUS_DEC_STATE_INIT && 238 !inst->reconfig) 239 return -EINVAL; 240 241 if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE) 242 return 0; 243 244 /* 245 * The code snippet below is a workaround for backward compatibility 246 * with applications which doesn't support V4L2 events. It will be 247 * dropped in future once those applications are fixed. 248 */ 249 250 if (inst->codec_state != VENUS_DEC_STATE_INIT) 251 goto done; 252 253 ret = wait_event_timeout(inst->reconf_wait, inst->reconfig, 254 msecs_to_jiffies(100)); 255 if (!ret) 256 return -EINVAL; 257 258 if (!(inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) || 259 !inst->reconfig) 260 dev_dbg(inst->core->dev, VDBGH "wrong state\n"); 261 262 done: 263 return 0; 264 } 265 266 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 267 { 268 struct venus_inst *inst = to_inst(file); 269 const struct venus_format *fmt = NULL; 270 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 271 int ret; 272 273 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 274 fmt = inst->fmt_cap; 275 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 276 fmt = inst->fmt_out; 277 278 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 279 ret = vdec_check_src_change(inst); 280 if (ret) 281 return ret; 282 } 283 284 pixmp->pixelformat = fmt->pixfmt; 285 286 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 287 pixmp->width = inst->width; 288 pixmp->height = inst->height; 289 pixmp->colorspace = inst->colorspace; 290 pixmp->ycbcr_enc = inst->ycbcr_enc; 291 pixmp->quantization = inst->quantization; 292 pixmp->xfer_func = inst->xfer_func; 293 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 294 pixmp->width = inst->out_width; 295 pixmp->height = inst->out_height; 296 } 297 298 vdec_try_fmt_common(inst, f); 299 300 return 0; 301 } 302 303 static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 304 { 305 struct venus_inst *inst = to_inst(file); 306 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 307 struct v4l2_pix_format_mplane orig_pixmp; 308 const struct venus_format *fmt; 309 struct v4l2_format format; 310 u32 pixfmt_out = 0, pixfmt_cap = 0; 311 struct vb2_queue *q; 312 313 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 314 if (!q) 315 return -EINVAL; 316 317 if (vb2_is_busy(q)) 318 return -EBUSY; 319 320 orig_pixmp = *pixmp; 321 322 fmt = vdec_try_fmt_common(inst, f); 323 324 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 325 pixfmt_out = pixmp->pixelformat; 326 pixfmt_cap = inst->fmt_cap->pixfmt; 327 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 328 pixfmt_cap = pixmp->pixelformat; 329 pixfmt_out = inst->fmt_out->pixfmt; 330 } 331 332 memset(&format, 0, sizeof(format)); 333 334 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 335 format.fmt.pix_mp.pixelformat = pixfmt_out; 336 format.fmt.pix_mp.width = orig_pixmp.width; 337 format.fmt.pix_mp.height = orig_pixmp.height; 338 vdec_try_fmt_common(inst, &format); 339 340 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 341 inst->out_width = format.fmt.pix_mp.width; 342 inst->out_height = format.fmt.pix_mp.height; 343 inst->colorspace = pixmp->colorspace; 344 inst->ycbcr_enc = pixmp->ycbcr_enc; 345 inst->quantization = pixmp->quantization; 346 inst->xfer_func = pixmp->xfer_func; 347 inst->input_buf_size = pixmp->plane_fmt[0].sizeimage; 348 } 349 350 memset(&format, 0, sizeof(format)); 351 352 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 353 format.fmt.pix_mp.pixelformat = pixfmt_cap; 354 format.fmt.pix_mp.width = orig_pixmp.width; 355 format.fmt.pix_mp.height = orig_pixmp.height; 356 vdec_try_fmt_common(inst, &format); 357 358 inst->width = format.fmt.pix_mp.width; 359 inst->height = format.fmt.pix_mp.height; 360 inst->crop.top = 0; 361 inst->crop.left = 0; 362 inst->crop.width = inst->width; 363 inst->crop.height = inst->height; 364 365 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 366 inst->fmt_out = fmt; 367 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 368 inst->fmt_cap = fmt; 369 inst->output2_buf_size = 370 venus_helper_get_framesz(pixfmt_cap, orig_pixmp.width, orig_pixmp.height); 371 } 372 373 return 0; 374 } 375 376 static int 377 vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 378 { 379 struct venus_inst *inst = to_inst(file); 380 381 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && 382 s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 383 return -EINVAL; 384 385 s->r.top = 0; 386 s->r.left = 0; 387 388 switch (s->target) { 389 case V4L2_SEL_TGT_CROP_BOUNDS: 390 case V4L2_SEL_TGT_CROP_DEFAULT: 391 case V4L2_SEL_TGT_CROP: 392 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 393 return -EINVAL; 394 s->r.width = inst->out_width; 395 s->r.height = inst->out_height; 396 break; 397 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 398 case V4L2_SEL_TGT_COMPOSE_PADDED: 399 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 400 return -EINVAL; 401 s->r.width = inst->width; 402 s->r.height = inst->height; 403 break; 404 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 405 case V4L2_SEL_TGT_COMPOSE: 406 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 407 return -EINVAL; 408 s->r = inst->crop; 409 break; 410 default: 411 return -EINVAL; 412 } 413 414 return 0; 415 } 416 417 static int 418 vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 419 { 420 strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); 421 strscpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card)); 422 strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); 423 424 return 0; 425 } 426 427 static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 428 { 429 struct venus_inst *inst = to_inst(file); 430 const struct venus_format *fmt; 431 432 memset(f->reserved, 0, sizeof(f->reserved)); 433 434 fmt = find_format_by_index(inst, f->index, f->type); 435 if (!fmt) 436 return -EINVAL; 437 438 f->pixelformat = fmt->pixfmt; 439 f->flags = fmt->flags; 440 441 return 0; 442 } 443 444 static int vdec_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 445 { 446 struct venus_inst *inst = to_inst(file); 447 struct v4l2_captureparm *cap = &a->parm.capture; 448 struct v4l2_fract *timeperframe = &cap->timeperframe; 449 u64 us_per_frame, fps; 450 451 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 452 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 453 return -EINVAL; 454 455 memset(cap->reserved, 0, sizeof(cap->reserved)); 456 if (!timeperframe->denominator) 457 timeperframe->denominator = inst->timeperframe.denominator; 458 if (!timeperframe->numerator) 459 timeperframe->numerator = inst->timeperframe.numerator; 460 cap->readbuffers = 0; 461 cap->extendedmode = 0; 462 cap->capability = V4L2_CAP_TIMEPERFRAME; 463 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; 464 do_div(us_per_frame, timeperframe->denominator); 465 466 if (!us_per_frame) 467 return -EINVAL; 468 469 fps = (u64)USEC_PER_SEC; 470 do_div(fps, us_per_frame); 471 472 inst->fps = fps; 473 inst->timeperframe = *timeperframe; 474 475 return 0; 476 } 477 478 static int vdec_enum_framesizes(struct file *file, void *fh, 479 struct v4l2_frmsizeenum *fsize) 480 { 481 struct venus_inst *inst = to_inst(file); 482 const struct venus_format *fmt; 483 484 fmt = find_format(inst, fsize->pixel_format, 485 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 486 if (!fmt) { 487 fmt = find_format(inst, fsize->pixel_format, 488 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 489 if (!fmt) 490 return -EINVAL; 491 } 492 493 if (fsize->index) 494 return -EINVAL; 495 496 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 497 498 fsize->stepwise.min_width = frame_width_min(inst); 499 fsize->stepwise.max_width = frame_width_max(inst); 500 fsize->stepwise.step_width = frame_width_step(inst); 501 fsize->stepwise.min_height = frame_height_min(inst); 502 fsize->stepwise.max_height = frame_height_max(inst); 503 fsize->stepwise.step_height = frame_height_step(inst); 504 505 return 0; 506 } 507 508 static int vdec_subscribe_event(struct v4l2_fh *fh, 509 const struct v4l2_event_subscription *sub) 510 { 511 struct venus_inst *inst = container_of(fh, struct venus_inst, fh); 512 int ret; 513 514 switch (sub->type) { 515 case V4L2_EVENT_EOS: 516 return v4l2_event_subscribe(fh, sub, 2, NULL); 517 case V4L2_EVENT_SOURCE_CHANGE: 518 ret = v4l2_src_change_event_subscribe(fh, sub); 519 if (ret) 520 return ret; 521 inst->subscriptions |= V4L2_EVENT_SOURCE_CHANGE; 522 return 0; 523 case V4L2_EVENT_CTRL: 524 return v4l2_ctrl_subscribe_event(fh, sub); 525 default: 526 return -EINVAL; 527 } 528 } 529 530 static int 531 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) 532 { 533 struct venus_inst *inst = to_inst(file); 534 struct vb2_queue *dst_vq; 535 struct hfi_frame_data fdata = {0}; 536 int ret; 537 538 ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); 539 if (ret) 540 return ret; 541 542 mutex_lock(&inst->lock); 543 544 if (cmd->cmd == V4L2_DEC_CMD_STOP) { 545 /* 546 * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on 547 * decoder input to signal EOS. 548 */ 549 if (!(inst->streamon_out && inst->streamon_cap)) 550 goto unlock; 551 552 fdata.buffer_type = HFI_BUFFER_INPUT; 553 fdata.flags |= HFI_BUFFERFLAG_EOS; 554 if (IS_V6(inst->core)) 555 fdata.device_addr = 0; 556 else 557 fdata.device_addr = 0xdeadb000; 558 559 ret = hfi_session_process_buf(inst, &fdata); 560 561 if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) { 562 inst->codec_state = VENUS_DEC_STATE_DRAIN; 563 inst->drain_active = true; 564 } 565 } else if (cmd->cmd == V4L2_DEC_CMD_START && 566 inst->codec_state == VENUS_DEC_STATE_STOPPED) { 567 dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx, 568 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 569 vb2_clear_last_buffer_dequeued(dst_vq); 570 571 inst->codec_state = VENUS_DEC_STATE_DECODING; 572 } 573 574 unlock: 575 mutex_unlock(&inst->lock); 576 return ret; 577 } 578 579 static const struct v4l2_ioctl_ops vdec_ioctl_ops = { 580 .vidioc_querycap = vdec_querycap, 581 .vidioc_enum_fmt_vid_cap = vdec_enum_fmt, 582 .vidioc_enum_fmt_vid_out = vdec_enum_fmt, 583 .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt, 584 .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt, 585 .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt, 586 .vidioc_g_fmt_vid_out_mplane = vdec_g_fmt, 587 .vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt, 588 .vidioc_try_fmt_vid_out_mplane = vdec_try_fmt, 589 .vidioc_g_selection = vdec_g_selection, 590 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 591 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 592 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 593 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 594 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 595 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 596 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 597 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 598 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 599 .vidioc_s_parm = vdec_s_parm, 600 .vidioc_enum_framesizes = vdec_enum_framesizes, 601 .vidioc_subscribe_event = vdec_subscribe_event, 602 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 603 .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, 604 .vidioc_decoder_cmd = vdec_decoder_cmd, 605 }; 606 607 static int vdec_pm_get(struct venus_inst *inst) 608 { 609 struct venus_core *core = inst->core; 610 struct device *dev = core->dev_dec; 611 int ret; 612 613 mutex_lock(&core->pm_lock); 614 ret = pm_runtime_resume_and_get(dev); 615 mutex_unlock(&core->pm_lock); 616 617 return ret; 618 } 619 620 static int vdec_pm_put(struct venus_inst *inst, bool autosuspend) 621 { 622 struct venus_core *core = inst->core; 623 struct device *dev = core->dev_dec; 624 int ret; 625 626 mutex_lock(&core->pm_lock); 627 628 if (autosuspend) 629 ret = pm_runtime_put_autosuspend(dev); 630 else 631 ret = pm_runtime_put_sync(dev); 632 633 mutex_unlock(&core->pm_lock); 634 635 return ret < 0 ? ret : 0; 636 } 637 638 static int vdec_pm_get_put(struct venus_inst *inst) 639 { 640 struct venus_core *core = inst->core; 641 struct device *dev = core->dev_dec; 642 int ret = 0; 643 644 mutex_lock(&core->pm_lock); 645 646 if (pm_runtime_suspended(dev)) { 647 ret = pm_runtime_resume_and_get(dev); 648 if (ret < 0) 649 goto error; 650 651 ret = pm_runtime_put_autosuspend(dev); 652 } 653 654 error: 655 mutex_unlock(&core->pm_lock); 656 657 return ret < 0 ? ret : 0; 658 } 659 660 static void vdec_pm_touch(struct venus_inst *inst) 661 { 662 pm_runtime_mark_last_busy(inst->core->dev_dec); 663 } 664 665 static int vdec_set_properties(struct venus_inst *inst) 666 { 667 struct vdec_controls *ctr = &inst->controls.dec; 668 struct hfi_enable en = { .enable = 1 }; 669 u32 ptype, decode_order, conceal; 670 int ret; 671 672 if (ctr->post_loop_deb_mode) { 673 ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER; 674 ret = hfi_session_set_property(inst, ptype, &en); 675 if (ret) 676 return ret; 677 } 678 679 if (ctr->display_delay_enable && ctr->display_delay == 0) { 680 ptype = HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER; 681 decode_order = HFI_OUTPUT_ORDER_DECODE; 682 ret = hfi_session_set_property(inst, ptype, &decode_order); 683 if (ret) 684 return ret; 685 } 686 687 ptype = HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR; 688 conceal = ctr->conceal_color & 0xffff; 689 conceal |= ((ctr->conceal_color >> 16) & 0xffff) << 10; 690 conceal |= ((ctr->conceal_color >> 32) & 0xffff) << 20; 691 692 ret = hfi_session_set_property(inst, ptype, &conceal); 693 if (ret) 694 return ret; 695 696 return 0; 697 } 698 699 static int vdec_set_work_route(struct venus_inst *inst) 700 { 701 u32 ptype = HFI_PROPERTY_PARAM_WORK_ROUTE; 702 struct hfi_video_work_route wr; 703 704 if (!IS_V6(inst->core)) 705 return 0; 706 707 wr.video_work_route = inst->core->res->num_vpp_pipes; 708 709 return hfi_session_set_property(inst, ptype, &wr); 710 } 711 712 #define is_ubwc_fmt(fmt) (!!((fmt) & HFI_COLOR_FORMAT_UBWC_BASE)) 713 714 static int vdec_output_conf(struct venus_inst *inst) 715 { 716 struct venus_core *core = inst->core; 717 struct hfi_enable en = { .enable = 1 }; 718 struct hfi_buffer_requirements bufreq; 719 u32 width = inst->width; 720 u32 height = inst->height; 721 u32 out_fmt, out2_fmt; 722 bool ubwc = false; 723 u32 ptype; 724 int ret; 725 726 ret = venus_helper_set_work_mode(inst); 727 if (ret) 728 return ret; 729 730 if (core->res->hfi_version == HFI_VERSION_1XX) { 731 ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER; 732 ret = hfi_session_set_property(inst, ptype, &en); 733 if (ret) 734 return ret; 735 } 736 737 /* Force searching UBWC formats for bigger then HD resolutions */ 738 if (width > 1920 && height > ALIGN(1080, 32)) 739 ubwc = true; 740 741 /* For Venus v4/v6 UBWC format is mandatory */ 742 if (IS_V4(core) || IS_V6(core)) 743 ubwc = true; 744 745 ret = venus_helper_get_out_fmts(inst, inst->fmt_cap->pixfmt, &out_fmt, 746 &out2_fmt, ubwc); 747 if (ret) 748 return ret; 749 750 inst->output_buf_size = 751 venus_helper_get_framesz_raw(out_fmt, width, height); 752 inst->output2_buf_size = 753 venus_helper_get_framesz_raw(out2_fmt, width, height); 754 755 if (is_ubwc_fmt(out_fmt)) { 756 inst->opb_buftype = HFI_BUFFER_OUTPUT2; 757 inst->opb_fmt = out2_fmt; 758 inst->dpb_buftype = HFI_BUFFER_OUTPUT; 759 inst->dpb_fmt = out_fmt; 760 } else if (is_ubwc_fmt(out2_fmt)) { 761 inst->opb_buftype = HFI_BUFFER_OUTPUT; 762 inst->opb_fmt = out_fmt; 763 inst->dpb_buftype = HFI_BUFFER_OUTPUT2; 764 inst->dpb_fmt = out2_fmt; 765 } else { 766 inst->opb_buftype = HFI_BUFFER_OUTPUT; 767 inst->opb_fmt = out_fmt; 768 inst->dpb_buftype = 0; 769 inst->dpb_fmt = 0; 770 } 771 772 ret = venus_helper_set_raw_format(inst, inst->opb_fmt, 773 inst->opb_buftype); 774 if (ret) 775 return ret; 776 777 ret = venus_helper_set_format_constraints(inst); 778 if (ret) 779 return ret; 780 781 if (inst->dpb_fmt) { 782 ret = venus_helper_set_multistream(inst, false, true); 783 if (ret) 784 return ret; 785 786 ret = venus_helper_set_raw_format(inst, inst->dpb_fmt, 787 inst->dpb_buftype); 788 if (ret) 789 return ret; 790 791 ret = venus_helper_set_output_resolution(inst, width, height, 792 HFI_BUFFER_OUTPUT2); 793 if (ret) 794 return ret; 795 } 796 797 if (IS_V3(core) || IS_V4(core) || IS_V6(core)) { 798 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 799 if (ret) 800 return ret; 801 802 if (bufreq.size > inst->output_buf_size) 803 return -EINVAL; 804 805 if (inst->dpb_fmt) { 806 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT2, 807 &bufreq); 808 if (ret) 809 return ret; 810 811 if (bufreq.size > inst->output2_buf_size) 812 return -EINVAL; 813 } 814 815 if (inst->output2_buf_size) { 816 ret = venus_helper_set_bufsize(inst, 817 inst->output2_buf_size, 818 HFI_BUFFER_OUTPUT2); 819 if (ret) 820 return ret; 821 } 822 823 if (inst->output_buf_size) { 824 ret = venus_helper_set_bufsize(inst, 825 inst->output_buf_size, 826 HFI_BUFFER_OUTPUT); 827 if (ret) 828 return ret; 829 } 830 } 831 832 ret = venus_helper_set_dyn_bufmode(inst); 833 if (ret) 834 return ret; 835 836 return 0; 837 } 838 839 static int vdec_session_init(struct venus_inst *inst) 840 { 841 int ret; 842 843 ret = venus_helper_session_init(inst); 844 if (ret == -EALREADY) 845 return 0; 846 else if (ret) 847 return ret; 848 849 ret = venus_helper_set_input_resolution(inst, frame_width_min(inst), 850 frame_height_min(inst)); 851 if (ret) 852 goto deinit; 853 854 return 0; 855 deinit: 856 hfi_session_deinit(inst); 857 return ret; 858 } 859 860 static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num, 861 unsigned int *out_num) 862 { 863 enum hfi_version ver = inst->core->res->hfi_version; 864 struct hfi_buffer_requirements bufreq; 865 int ret; 866 867 *in_num = *out_num = 0; 868 869 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 870 if (ret) 871 return ret; 872 873 *in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 874 875 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 876 if (ret) 877 return ret; 878 879 *out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 880 881 return 0; 882 } 883 884 static int vdec_queue_setup(struct vb2_queue *q, 885 unsigned int *num_buffers, unsigned int *num_planes, 886 unsigned int sizes[], struct device *alloc_devs[]) 887 { 888 struct venus_inst *inst = vb2_get_drv_priv(q); 889 struct venus_core *core = inst->core; 890 unsigned int in_num, out_num; 891 int ret = 0; 892 893 if (*num_planes) { 894 unsigned int output_buf_size = venus_helper_get_opb_size(inst); 895 896 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 897 *num_planes != inst->fmt_out->num_planes) 898 return -EINVAL; 899 900 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 901 *num_planes != inst->fmt_cap->num_planes) 902 return -EINVAL; 903 904 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 905 sizes[0] < inst->input_buf_size) 906 return -EINVAL; 907 908 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 909 sizes[0] < output_buf_size) 910 return -EINVAL; 911 912 return 0; 913 } 914 915 if (test_bit(0, &core->sys_error)) { 916 if (inst->nonblock) 917 return -EAGAIN; 918 919 ret = wait_event_interruptible(core->sys_err_done, 920 !test_bit(0, &core->sys_error)); 921 if (ret) 922 return ret; 923 } 924 925 ret = vdec_pm_get(inst); 926 if (ret) 927 return ret; 928 929 ret = vdec_session_init(inst); 930 if (ret) 931 goto put_power; 932 933 ret = vdec_num_buffers(inst, &in_num, &out_num); 934 if (ret) 935 goto put_power; 936 937 ret = vdec_pm_put(inst, false); 938 if (ret) 939 return ret; 940 941 switch (q->type) { 942 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 943 *num_planes = inst->fmt_out->num_planes; 944 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, 945 inst->out_width, 946 inst->out_height); 947 sizes[0] = max(sizes[0], inst->input_buf_size); 948 inst->input_buf_size = sizes[0]; 949 *num_buffers = max(*num_buffers, in_num); 950 inst->num_input_bufs = *num_buffers; 951 inst->num_output_bufs = out_num; 952 break; 953 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 954 *num_planes = inst->fmt_cap->num_planes; 955 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, 956 inst->width, 957 inst->height); 958 inst->output_buf_size = sizes[0]; 959 *num_buffers = max(*num_buffers, out_num); 960 inst->num_output_bufs = *num_buffers; 961 962 mutex_lock(&inst->lock); 963 if (inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) 964 inst->codec_state = VENUS_DEC_STATE_STOPPED; 965 mutex_unlock(&inst->lock); 966 break; 967 default: 968 ret = -EINVAL; 969 break; 970 } 971 972 return ret; 973 974 put_power: 975 vdec_pm_put(inst, false); 976 return ret; 977 } 978 979 static int vdec_verify_conf(struct venus_inst *inst) 980 { 981 enum hfi_version ver = inst->core->res->hfi_version; 982 struct hfi_buffer_requirements bufreq; 983 int ret; 984 985 if (!inst->num_input_bufs || !inst->num_output_bufs) 986 return -EINVAL; 987 988 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 989 if (ret) 990 return ret; 991 992 if (inst->num_output_bufs < bufreq.count_actual || 993 inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 994 return -EINVAL; 995 996 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 997 if (ret) 998 return ret; 999 1000 if (inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 1001 return -EINVAL; 1002 1003 return 0; 1004 } 1005 1006 static int vdec_start_capture(struct venus_inst *inst) 1007 { 1008 int ret; 1009 1010 if (!inst->streamon_out) 1011 return 0; 1012 1013 if (inst->codec_state == VENUS_DEC_STATE_DECODING) { 1014 if (inst->reconfig) 1015 goto reconfigure; 1016 1017 venus_helper_queue_dpb_bufs(inst); 1018 venus_helper_process_initial_cap_bufs(inst); 1019 inst->streamon_cap = 1; 1020 return 0; 1021 } 1022 1023 if (inst->codec_state != VENUS_DEC_STATE_STOPPED) 1024 return 0; 1025 1026 reconfigure: 1027 ret = vdec_output_conf(inst); 1028 if (ret) 1029 return ret; 1030 1031 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, 1032 VB2_MAX_FRAME, VB2_MAX_FRAME); 1033 if (ret) 1034 return ret; 1035 1036 ret = venus_helper_intbufs_realloc(inst); 1037 if (ret) 1038 goto err; 1039 1040 venus_pm_load_scale(inst); 1041 1042 inst->next_buf_last = false; 1043 1044 ret = venus_helper_alloc_dpb_bufs(inst); 1045 if (ret) 1046 goto err; 1047 1048 ret = hfi_session_continue(inst); 1049 if (ret) 1050 goto free_dpb_bufs; 1051 1052 ret = venus_helper_queue_dpb_bufs(inst); 1053 if (ret) 1054 goto free_dpb_bufs; 1055 1056 ret = venus_helper_process_initial_cap_bufs(inst); 1057 if (ret) 1058 goto free_dpb_bufs; 1059 1060 inst->codec_state = VENUS_DEC_STATE_DECODING; 1061 1062 if (inst->drain_active) 1063 inst->codec_state = VENUS_DEC_STATE_DRAIN; 1064 1065 inst->streamon_cap = 1; 1066 inst->sequence_cap = 0; 1067 inst->reconfig = false; 1068 inst->drain_active = false; 1069 1070 return 0; 1071 1072 free_dpb_bufs: 1073 venus_helper_free_dpb_bufs(inst); 1074 err: 1075 return ret; 1076 } 1077 1078 static int vdec_start_output(struct venus_inst *inst) 1079 { 1080 int ret; 1081 1082 if (inst->codec_state == VENUS_DEC_STATE_SEEK) { 1083 ret = venus_helper_process_initial_out_bufs(inst); 1084 if (inst->next_buf_last) 1085 inst->codec_state = VENUS_DEC_STATE_DRC; 1086 else 1087 inst->codec_state = VENUS_DEC_STATE_DECODING; 1088 goto done; 1089 } 1090 1091 if (inst->codec_state == VENUS_DEC_STATE_INIT || 1092 inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) { 1093 ret = venus_helper_process_initial_out_bufs(inst); 1094 goto done; 1095 } 1096 1097 if (inst->codec_state != VENUS_DEC_STATE_DEINIT) 1098 return -EINVAL; 1099 1100 venus_helper_init_instance(inst); 1101 inst->sequence_out = 0; 1102 inst->reconfig = false; 1103 inst->next_buf_last = false; 1104 1105 ret = vdec_set_properties(inst); 1106 if (ret) 1107 return ret; 1108 1109 ret = vdec_set_work_route(inst); 1110 if (ret) 1111 return ret; 1112 1113 ret = vdec_output_conf(inst); 1114 if (ret) 1115 return ret; 1116 1117 ret = vdec_verify_conf(inst); 1118 if (ret) 1119 return ret; 1120 1121 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, 1122 VB2_MAX_FRAME, VB2_MAX_FRAME); 1123 if (ret) 1124 return ret; 1125 1126 ret = venus_helper_vb2_start_streaming(inst); 1127 if (ret) 1128 return ret; 1129 1130 ret = venus_helper_process_initial_out_bufs(inst); 1131 if (ret) 1132 return ret; 1133 1134 inst->codec_state = VENUS_DEC_STATE_INIT; 1135 1136 done: 1137 inst->streamon_out = 1; 1138 return ret; 1139 } 1140 1141 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) 1142 { 1143 struct venus_inst *inst = vb2_get_drv_priv(q); 1144 int ret; 1145 1146 mutex_lock(&inst->lock); 1147 1148 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1149 ret = vdec_start_capture(inst); 1150 } else { 1151 ret = vdec_pm_get(inst); 1152 if (ret) 1153 goto error; 1154 1155 ret = venus_pm_acquire_core(inst); 1156 if (ret) 1157 goto put_power; 1158 1159 ret = vdec_pm_put(inst, true); 1160 if (ret) 1161 goto error; 1162 1163 ret = vdec_start_output(inst); 1164 } 1165 1166 if (ret) 1167 goto error; 1168 1169 mutex_unlock(&inst->lock); 1170 return 0; 1171 1172 put_power: 1173 vdec_pm_put(inst, false); 1174 error: 1175 venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED); 1176 mutex_unlock(&inst->lock); 1177 return ret; 1178 } 1179 1180 static void vdec_cancel_dst_buffers(struct venus_inst *inst) 1181 { 1182 struct vb2_v4l2_buffer *buf; 1183 1184 while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx))) 1185 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 1186 } 1187 1188 static int vdec_stop_capture(struct venus_inst *inst) 1189 { 1190 int ret = 0; 1191 1192 switch (inst->codec_state) { 1193 case VENUS_DEC_STATE_DECODING: 1194 ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true); 1195 fallthrough; 1196 case VENUS_DEC_STATE_DRAIN: 1197 inst->codec_state = VENUS_DEC_STATE_STOPPED; 1198 inst->drain_active = false; 1199 fallthrough; 1200 case VENUS_DEC_STATE_SEEK: 1201 vdec_cancel_dst_buffers(inst); 1202 break; 1203 case VENUS_DEC_STATE_DRC: 1204 ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true); 1205 inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; 1206 venus_helper_free_dpb_bufs(inst); 1207 break; 1208 default: 1209 break; 1210 } 1211 1212 return ret; 1213 } 1214 1215 static int vdec_stop_output(struct venus_inst *inst) 1216 { 1217 int ret = 0; 1218 1219 switch (inst->codec_state) { 1220 case VENUS_DEC_STATE_DECODING: 1221 case VENUS_DEC_STATE_DRAIN: 1222 case VENUS_DEC_STATE_STOPPED: 1223 case VENUS_DEC_STATE_DRC: 1224 ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true); 1225 inst->codec_state = VENUS_DEC_STATE_SEEK; 1226 break; 1227 case VENUS_DEC_STATE_INIT: 1228 case VENUS_DEC_STATE_CAPTURE_SETUP: 1229 ret = hfi_session_flush(inst, HFI_FLUSH_INPUT, true); 1230 break; 1231 default: 1232 break; 1233 } 1234 1235 return ret; 1236 } 1237 1238 static void vdec_stop_streaming(struct vb2_queue *q) 1239 { 1240 struct venus_inst *inst = vb2_get_drv_priv(q); 1241 int ret = -EINVAL; 1242 1243 vdec_pm_get_put(inst); 1244 1245 mutex_lock(&inst->lock); 1246 1247 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1248 ret = vdec_stop_capture(inst); 1249 else 1250 ret = vdec_stop_output(inst); 1251 1252 venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); 1253 1254 inst->session_error = 0; 1255 1256 if (ret) 1257 goto unlock; 1258 1259 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1260 inst->streamon_out = 0; 1261 else 1262 inst->streamon_cap = 0; 1263 1264 unlock: 1265 mutex_unlock(&inst->lock); 1266 } 1267 1268 static void vdec_session_release(struct venus_inst *inst) 1269 { 1270 struct venus_core *core = inst->core; 1271 int ret, abort = 0; 1272 1273 vdec_pm_get(inst); 1274 1275 mutex_lock(&inst->lock); 1276 inst->codec_state = VENUS_DEC_STATE_DEINIT; 1277 1278 ret = hfi_session_stop(inst); 1279 abort = (ret && ret != -EINVAL) ? 1 : 0; 1280 ret = hfi_session_unload_res(inst); 1281 abort = (ret && ret != -EINVAL) ? 1 : 0; 1282 ret = venus_helper_unregister_bufs(inst); 1283 abort = (ret && ret != -EINVAL) ? 1 : 0; 1284 ret = venus_helper_intbufs_free(inst); 1285 abort = (ret && ret != -EINVAL) ? 1 : 0; 1286 ret = hfi_session_deinit(inst); 1287 abort = (ret && ret != -EINVAL) ? 1 : 0; 1288 1289 if (inst->session_error || test_bit(0, &core->sys_error)) 1290 abort = 1; 1291 1292 if (abort) 1293 hfi_session_abort(inst); 1294 1295 venus_helper_free_dpb_bufs(inst); 1296 venus_pm_load_scale(inst); 1297 INIT_LIST_HEAD(&inst->registeredbufs); 1298 mutex_unlock(&inst->lock); 1299 1300 venus_pm_release_core(inst); 1301 vdec_pm_put(inst, false); 1302 } 1303 1304 static int vdec_buf_init(struct vb2_buffer *vb) 1305 { 1306 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1307 1308 inst->buf_count++; 1309 1310 return venus_helper_vb2_buf_init(vb); 1311 } 1312 1313 static void vdec_buf_cleanup(struct vb2_buffer *vb) 1314 { 1315 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1316 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1317 struct venus_buffer *buf = to_venus_buffer(vbuf); 1318 1319 mutex_lock(&inst->lock); 1320 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1321 if (!list_empty(&inst->registeredbufs)) 1322 list_del_init(&buf->reg_list); 1323 mutex_unlock(&inst->lock); 1324 1325 inst->buf_count--; 1326 if (!inst->buf_count) 1327 vdec_session_release(inst); 1328 } 1329 1330 static void vdec_vb2_buf_queue(struct vb2_buffer *vb) 1331 { 1332 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1333 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1334 static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS }; 1335 1336 vdec_pm_get_put(inst); 1337 1338 mutex_lock(&inst->lock); 1339 1340 if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && 1341 inst->codec_state == VENUS_DEC_STATE_DRC) { 1342 vbuf->flags |= V4L2_BUF_FLAG_LAST; 1343 vbuf->sequence = inst->sequence_cap++; 1344 vbuf->field = V4L2_FIELD_NONE; 1345 vb2_set_plane_payload(vb, 0, 0); 1346 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 1347 v4l2_event_queue_fh(&inst->fh, &eos); 1348 inst->next_buf_last = false; 1349 mutex_unlock(&inst->lock); 1350 return; 1351 } 1352 1353 venus_helper_vb2_buf_queue(vb); 1354 mutex_unlock(&inst->lock); 1355 } 1356 1357 static const struct vb2_ops vdec_vb2_ops = { 1358 .queue_setup = vdec_queue_setup, 1359 .buf_init = vdec_buf_init, 1360 .buf_cleanup = vdec_buf_cleanup, 1361 .buf_prepare = venus_helper_vb2_buf_prepare, 1362 .start_streaming = vdec_start_streaming, 1363 .stop_streaming = vdec_stop_streaming, 1364 .buf_queue = vdec_vb2_buf_queue, 1365 }; 1366 1367 static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, 1368 u32 tag, u32 bytesused, u32 data_offset, u32 flags, 1369 u32 hfi_flags, u64 timestamp_us) 1370 { 1371 enum vb2_buffer_state state = VB2_BUF_STATE_DONE; 1372 struct vb2_v4l2_buffer *vbuf; 1373 struct vb2_buffer *vb; 1374 unsigned int type; 1375 1376 vdec_pm_touch(inst); 1377 1378 if (buf_type == HFI_BUFFER_INPUT) 1379 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1380 else 1381 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1382 1383 vbuf = venus_helper_find_buf(inst, type, tag); 1384 if (!vbuf) { 1385 venus_helper_change_dpb_owner(inst, vbuf, type, buf_type, tag); 1386 return; 1387 } 1388 1389 vbuf->flags = flags; 1390 vbuf->field = V4L2_FIELD_NONE; 1391 vb = &vbuf->vb2_buf; 1392 1393 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1394 vb2_set_plane_payload(vb, 0, bytesused); 1395 vb->planes[0].data_offset = data_offset; 1396 vb->timestamp = timestamp_us * NSEC_PER_USEC; 1397 vbuf->sequence = inst->sequence_cap++; 1398 1399 if (vbuf->flags & V4L2_BUF_FLAG_LAST) { 1400 const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; 1401 1402 v4l2_event_queue_fh(&inst->fh, &ev); 1403 1404 if (inst->codec_state == VENUS_DEC_STATE_DRAIN) { 1405 inst->drain_active = false; 1406 inst->codec_state = VENUS_DEC_STATE_STOPPED; 1407 } 1408 } 1409 1410 if (!bytesused) 1411 state = VB2_BUF_STATE_ERROR; 1412 } else { 1413 vbuf->sequence = inst->sequence_out++; 1414 } 1415 1416 venus_helper_get_ts_metadata(inst, timestamp_us, vbuf); 1417 1418 if (hfi_flags & HFI_BUFFERFLAG_READONLY) 1419 venus_helper_acquire_buf_ref(vbuf); 1420 1421 if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT) 1422 state = VB2_BUF_STATE_ERROR; 1423 1424 if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) { 1425 state = VB2_BUF_STATE_ERROR; 1426 vb2_set_plane_payload(vb, 0, 0); 1427 vb->timestamp = 0; 1428 } 1429 1430 v4l2_m2m_buf_done(vbuf, state); 1431 } 1432 1433 static void vdec_event_change(struct venus_inst *inst, 1434 struct hfi_event_data *ev_data, bool sufficient) 1435 { 1436 static const struct v4l2_event ev = { 1437 .type = V4L2_EVENT_SOURCE_CHANGE, 1438 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION }; 1439 struct device *dev = inst->core->dev_dec; 1440 struct v4l2_format format = {}; 1441 1442 mutex_lock(&inst->lock); 1443 1444 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1445 format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt; 1446 format.fmt.pix_mp.width = ev_data->width; 1447 format.fmt.pix_mp.height = ev_data->height; 1448 1449 vdec_try_fmt_common(inst, &format); 1450 1451 inst->width = format.fmt.pix_mp.width; 1452 inst->height = format.fmt.pix_mp.height; 1453 /* 1454 * Some versions of the firmware do not report crop information for 1455 * all codecs. For these cases, set the crop to the coded resolution. 1456 */ 1457 if (ev_data->input_crop.width > 0 && ev_data->input_crop.height > 0) { 1458 inst->crop.left = ev_data->input_crop.left; 1459 inst->crop.top = ev_data->input_crop.top; 1460 inst->crop.width = ev_data->input_crop.width; 1461 inst->crop.height = ev_data->input_crop.height; 1462 } else { 1463 inst->crop.left = 0; 1464 inst->crop.top = 0; 1465 inst->crop.width = ev_data->width; 1466 inst->crop.height = ev_data->height; 1467 } 1468 1469 inst->fw_min_cnt = ev_data->buf_count; 1470 /* overwriting this to 11 for vp9 due to fw bug */ 1471 if (inst->hfi_codec == HFI_VIDEO_CODEC_VP9) 1472 inst->fw_min_cnt = 11; 1473 1474 inst->out_width = ev_data->width; 1475 inst->out_height = ev_data->height; 1476 1477 if (inst->bit_depth != ev_data->bit_depth) 1478 inst->bit_depth = ev_data->bit_depth; 1479 1480 if (inst->pic_struct != ev_data->pic_struct) 1481 inst->pic_struct = ev_data->pic_struct; 1482 1483 dev_dbg(dev, VDBGM "event %s sufficient resources (%ux%u)\n", 1484 sufficient ? "" : "not", ev_data->width, ev_data->height); 1485 1486 switch (inst->codec_state) { 1487 case VENUS_DEC_STATE_INIT: 1488 inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; 1489 break; 1490 case VENUS_DEC_STATE_DECODING: 1491 case VENUS_DEC_STATE_DRAIN: 1492 inst->codec_state = VENUS_DEC_STATE_DRC; 1493 break; 1494 default: 1495 break; 1496 } 1497 1498 /* 1499 * The assumption is that the firmware have to return the last buffer 1500 * before this event is received in the v4l2 driver. Also the firmware 1501 * itself doesn't mark the last decoder output buffer with HFI EOS flag. 1502 */ 1503 1504 if (inst->codec_state == VENUS_DEC_STATE_DRC) { 1505 int ret; 1506 1507 inst->next_buf_last = true; 1508 1509 ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false); 1510 if (ret) 1511 dev_dbg(dev, VDBGH "flush output error %d\n", ret); 1512 } 1513 1514 inst->next_buf_last = true; 1515 inst->reconfig = true; 1516 v4l2_event_queue_fh(&inst->fh, &ev); 1517 wake_up(&inst->reconf_wait); 1518 1519 mutex_unlock(&inst->lock); 1520 } 1521 1522 static void vdec_event_notify(struct venus_inst *inst, u32 event, 1523 struct hfi_event_data *data) 1524 { 1525 struct venus_core *core = inst->core; 1526 struct device *dev = core->dev_dec; 1527 1528 vdec_pm_touch(inst); 1529 1530 switch (event) { 1531 case EVT_SESSION_ERROR: 1532 inst->session_error = true; 1533 venus_helper_vb2_queue_error(inst); 1534 dev_err(dev, "dec: event session error %x\n", inst->error); 1535 break; 1536 case EVT_SYS_EVENT_CHANGE: 1537 switch (data->event_type) { 1538 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES: 1539 vdec_event_change(inst, data, true); 1540 break; 1541 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES: 1542 vdec_event_change(inst, data, false); 1543 break; 1544 case HFI_EVENT_RELEASE_BUFFER_REFERENCE: 1545 venus_helper_release_buf_ref(inst, data->tag); 1546 break; 1547 default: 1548 break; 1549 } 1550 break; 1551 default: 1552 break; 1553 } 1554 } 1555 1556 static void vdec_flush_done(struct venus_inst *inst) 1557 { 1558 dev_dbg(inst->core->dev_dec, VDBGH "flush done\n"); 1559 } 1560 1561 static const struct hfi_inst_ops vdec_hfi_ops = { 1562 .buf_done = vdec_buf_done, 1563 .event_notify = vdec_event_notify, 1564 .flush_done = vdec_flush_done, 1565 }; 1566 1567 static void vdec_inst_init(struct venus_inst *inst) 1568 { 1569 inst->hfi_codec = HFI_VIDEO_CODEC_H264; 1570 inst->fmt_out = &vdec_formats[8]; 1571 inst->fmt_cap = &vdec_formats[0]; 1572 inst->width = frame_width_min(inst); 1573 inst->height = ALIGN(frame_height_min(inst), 32); 1574 inst->crop.left = 0; 1575 inst->crop.top = 0; 1576 inst->crop.width = inst->width; 1577 inst->crop.height = inst->height; 1578 inst->fw_min_cnt = 8; 1579 inst->out_width = frame_width_min(inst); 1580 inst->out_height = frame_height_min(inst); 1581 inst->fps = 30; 1582 inst->timeperframe.numerator = 1; 1583 inst->timeperframe.denominator = 30; 1584 inst->opb_buftype = HFI_BUFFER_OUTPUT; 1585 } 1586 1587 static void vdec_m2m_device_run(void *priv) 1588 { 1589 } 1590 1591 static const struct v4l2_m2m_ops vdec_m2m_ops = { 1592 .device_run = vdec_m2m_device_run, 1593 .job_abort = venus_helper_m2m_job_abort, 1594 }; 1595 1596 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, 1597 struct vb2_queue *dst_vq) 1598 { 1599 struct venus_inst *inst = priv; 1600 int ret; 1601 1602 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1603 src_vq->io_modes = VB2_MMAP | VB2_DMABUF; 1604 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1605 src_vq->ops = &vdec_vb2_ops; 1606 src_vq->mem_ops = &vb2_dma_contig_memops; 1607 src_vq->drv_priv = inst; 1608 src_vq->buf_struct_size = sizeof(struct venus_buffer); 1609 src_vq->allow_zero_bytesused = 1; 1610 src_vq->min_buffers_needed = 0; 1611 src_vq->dev = inst->core->dev; 1612 ret = vb2_queue_init(src_vq); 1613 if (ret) 1614 return ret; 1615 1616 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1617 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; 1618 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1619 dst_vq->ops = &vdec_vb2_ops; 1620 dst_vq->mem_ops = &vb2_dma_contig_memops; 1621 dst_vq->drv_priv = inst; 1622 dst_vq->buf_struct_size = sizeof(struct venus_buffer); 1623 dst_vq->allow_zero_bytesused = 1; 1624 dst_vq->min_buffers_needed = 0; 1625 dst_vq->dev = inst->core->dev; 1626 return vb2_queue_init(dst_vq); 1627 } 1628 1629 static int vdec_open(struct file *file) 1630 { 1631 struct venus_core *core = video_drvdata(file); 1632 struct venus_inst *inst; 1633 int ret; 1634 1635 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 1636 if (!inst) 1637 return -ENOMEM; 1638 1639 INIT_LIST_HEAD(&inst->dpbbufs); 1640 INIT_LIST_HEAD(&inst->registeredbufs); 1641 INIT_LIST_HEAD(&inst->internalbufs); 1642 INIT_LIST_HEAD(&inst->list); 1643 mutex_init(&inst->lock); 1644 1645 inst->core = core; 1646 inst->session_type = VIDC_SESSION_TYPE_DEC; 1647 inst->num_output_bufs = 1; 1648 inst->codec_state = VENUS_DEC_STATE_DEINIT; 1649 inst->buf_count = 0; 1650 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; 1651 inst->core_acquired = false; 1652 inst->bit_depth = VIDC_BITDEPTH_8; 1653 inst->pic_struct = HFI_INTERLACE_FRAME_PROGRESSIVE; 1654 init_waitqueue_head(&inst->reconf_wait); 1655 inst->nonblock = file->f_flags & O_NONBLOCK; 1656 1657 venus_helper_init_instance(inst); 1658 1659 ret = vdec_ctrl_init(inst); 1660 if (ret) 1661 goto err_free; 1662 1663 ret = hfi_session_create(inst, &vdec_hfi_ops); 1664 if (ret) 1665 goto err_ctrl_deinit; 1666 1667 vdec_inst_init(inst); 1668 1669 ida_init(&inst->dpb_ids); 1670 1671 /* 1672 * create m2m device for every instance, the m2m context scheduling 1673 * is made by firmware side so we do not need to care about. 1674 */ 1675 inst->m2m_dev = v4l2_m2m_init(&vdec_m2m_ops); 1676 if (IS_ERR(inst->m2m_dev)) { 1677 ret = PTR_ERR(inst->m2m_dev); 1678 goto err_session_destroy; 1679 } 1680 1681 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1682 if (IS_ERR(inst->m2m_ctx)) { 1683 ret = PTR_ERR(inst->m2m_ctx); 1684 goto err_m2m_release; 1685 } 1686 1687 v4l2_fh_init(&inst->fh, core->vdev_dec); 1688 1689 inst->fh.ctrl_handler = &inst->ctrl_handler; 1690 v4l2_fh_add(&inst->fh); 1691 inst->fh.m2m_ctx = inst->m2m_ctx; 1692 file->private_data = &inst->fh; 1693 1694 return 0; 1695 1696 err_m2m_release: 1697 v4l2_m2m_release(inst->m2m_dev); 1698 err_session_destroy: 1699 hfi_session_destroy(inst); 1700 err_ctrl_deinit: 1701 vdec_ctrl_deinit(inst); 1702 err_free: 1703 kfree(inst); 1704 return ret; 1705 } 1706 1707 static int vdec_close(struct file *file) 1708 { 1709 struct venus_inst *inst = to_inst(file); 1710 1711 vdec_pm_get(inst); 1712 1713 v4l2_m2m_ctx_release(inst->m2m_ctx); 1714 v4l2_m2m_release(inst->m2m_dev); 1715 vdec_ctrl_deinit(inst); 1716 ida_destroy(&inst->dpb_ids); 1717 hfi_session_destroy(inst); 1718 mutex_destroy(&inst->lock); 1719 v4l2_fh_del(&inst->fh); 1720 v4l2_fh_exit(&inst->fh); 1721 1722 vdec_pm_put(inst, false); 1723 1724 kfree(inst); 1725 return 0; 1726 } 1727 1728 static const struct v4l2_file_operations vdec_fops = { 1729 .owner = THIS_MODULE, 1730 .open = vdec_open, 1731 .release = vdec_close, 1732 .unlocked_ioctl = video_ioctl2, 1733 .poll = v4l2_m2m_fop_poll, 1734 .mmap = v4l2_m2m_fop_mmap, 1735 }; 1736 1737 static int vdec_probe(struct platform_device *pdev) 1738 { 1739 struct device *dev = &pdev->dev; 1740 struct video_device *vdev; 1741 struct venus_core *core; 1742 int ret; 1743 1744 if (!dev->parent) 1745 return -EPROBE_DEFER; 1746 1747 core = dev_get_drvdata(dev->parent); 1748 if (!core) 1749 return -EPROBE_DEFER; 1750 1751 platform_set_drvdata(pdev, core); 1752 1753 if (core->pm_ops->vdec_get) { 1754 ret = core->pm_ops->vdec_get(dev); 1755 if (ret) 1756 return ret; 1757 } 1758 1759 vdev = video_device_alloc(); 1760 if (!vdev) 1761 return -ENOMEM; 1762 1763 strscpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name)); 1764 vdev->release = video_device_release; 1765 vdev->fops = &vdec_fops; 1766 vdev->ioctl_ops = &vdec_ioctl_ops; 1767 vdev->vfl_dir = VFL_DIR_M2M; 1768 vdev->v4l2_dev = &core->v4l2_dev; 1769 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1770 1771 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 1772 if (ret) 1773 goto err_vdev_release; 1774 1775 core->vdev_dec = vdev; 1776 core->dev_dec = dev; 1777 1778 video_set_drvdata(vdev, core); 1779 pm_runtime_set_autosuspend_delay(dev, 2000); 1780 pm_runtime_use_autosuspend(dev); 1781 pm_runtime_enable(dev); 1782 1783 return 0; 1784 1785 err_vdev_release: 1786 video_device_release(vdev); 1787 return ret; 1788 } 1789 1790 static void vdec_remove(struct platform_device *pdev) 1791 { 1792 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); 1793 1794 video_unregister_device(core->vdev_dec); 1795 pm_runtime_disable(core->dev_dec); 1796 1797 if (core->pm_ops->vdec_put) 1798 core->pm_ops->vdec_put(core->dev_dec); 1799 } 1800 1801 static __maybe_unused int vdec_runtime_suspend(struct device *dev) 1802 { 1803 struct venus_core *core = dev_get_drvdata(dev); 1804 const struct venus_pm_ops *pm_ops = core->pm_ops; 1805 int ret = 0; 1806 1807 if (pm_ops->vdec_power) 1808 ret = pm_ops->vdec_power(dev, POWER_OFF); 1809 1810 return ret; 1811 } 1812 1813 static __maybe_unused int vdec_runtime_resume(struct device *dev) 1814 { 1815 struct venus_core *core = dev_get_drvdata(dev); 1816 const struct venus_pm_ops *pm_ops = core->pm_ops; 1817 int ret = 0; 1818 1819 if (pm_ops->vdec_power) 1820 ret = pm_ops->vdec_power(dev, POWER_ON); 1821 1822 return ret; 1823 } 1824 1825 static const struct dev_pm_ops vdec_pm_ops = { 1826 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1827 pm_runtime_force_resume) 1828 SET_RUNTIME_PM_OPS(vdec_runtime_suspend, vdec_runtime_resume, NULL) 1829 }; 1830 1831 static const struct of_device_id vdec_dt_match[] = { 1832 { .compatible = "venus-decoder" }, 1833 { } 1834 }; 1835 MODULE_DEVICE_TABLE(of, vdec_dt_match); 1836 1837 static struct platform_driver qcom_venus_dec_driver = { 1838 .probe = vdec_probe, 1839 .remove_new = vdec_remove, 1840 .driver = { 1841 .name = "qcom-venus-decoder", 1842 .of_match_table = vdec_dt_match, 1843 .pm = &vdec_pm_ops, 1844 }, 1845 }; 1846 module_platform_driver(qcom_venus_dec_driver); 1847 1848 MODULE_ALIAS("platform:qcom-venus-decoder"); 1849 MODULE_DESCRIPTION("Qualcomm Venus video decoder driver"); 1850 MODULE_LICENSE("GPL v2"); 1851