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