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-mem2mem.h> 13 #include <media/videobuf2-dma-contig.h> 14 #include <media/v4l2-ioctl.h> 15 #include <media/v4l2-event.h> 16 #include <media/v4l2-ctrls.h> 17 18 #include "hfi_venus_io.h" 19 #include "hfi_parser.h" 20 #include "core.h" 21 #include "helpers.h" 22 #include "venc.h" 23 #include "pm_helpers.h" 24 25 #define NUM_B_FRAMES_MAX 4 26 27 /* 28 * Three resons to keep MPLANE formats (despite that the number of planes 29 * currently is one): 30 * - the MPLANE formats allow only one plane to be used 31 * - the downstream driver use MPLANE formats too 32 * - future firmware versions could add support for >1 planes 33 */ 34 static const struct venus_format venc_formats[] = { 35 [VENUS_FMT_NV12] = { 36 .pixfmt = V4L2_PIX_FMT_NV12, 37 .num_planes = 1, 38 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 39 }, 40 [VENUS_FMT_H264] = { 41 .pixfmt = V4L2_PIX_FMT_H264, 42 .num_planes = 1, 43 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 44 }, 45 [VENUS_FMT_VP8] = { 46 .pixfmt = V4L2_PIX_FMT_VP8, 47 .num_planes = 1, 48 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 49 }, 50 [VENUS_FMT_HEVC] = { 51 .pixfmt = V4L2_PIX_FMT_HEVC, 52 .num_planes = 1, 53 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 54 }, 55 [VENUS_FMT_MPEG4] = { 56 .pixfmt = V4L2_PIX_FMT_MPEG4, 57 .num_planes = 1, 58 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 59 }, 60 [VENUS_FMT_H263] = { 61 .pixfmt = V4L2_PIX_FMT_H263, 62 .num_planes = 1, 63 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 64 }, 65 }; 66 67 static const struct venus_format * 68 find_format(struct venus_inst *inst, u32 pixfmt, u32 type) 69 { 70 const struct venus_format *fmt = venc_formats; 71 unsigned int size = ARRAY_SIZE(venc_formats); 72 unsigned int i; 73 74 for (i = 0; i < size; i++) { 75 if (fmt[i].pixfmt == pixfmt) 76 break; 77 } 78 79 if (i == size || fmt[i].type != type) 80 return NULL; 81 82 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 83 !venus_helper_check_codec(inst, fmt[i].pixfmt)) 84 return NULL; 85 86 return &fmt[i]; 87 } 88 89 static const struct venus_format * 90 find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) 91 { 92 const struct venus_format *fmt = venc_formats; 93 unsigned int size = ARRAY_SIZE(venc_formats); 94 unsigned int i, k = 0; 95 96 if (index > size) 97 return NULL; 98 99 for (i = 0; i < size; i++) { 100 bool valid; 101 102 if (fmt[i].type != type) 103 continue; 104 valid = type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || 105 venus_helper_check_codec(inst, fmt[i].pixfmt); 106 if (k == index && valid) 107 break; 108 if (valid) 109 k++; 110 } 111 112 if (i == size) 113 return NULL; 114 115 return &fmt[i]; 116 } 117 118 static int venc_v4l2_to_hfi(int id, int value) 119 { 120 switch (id) { 121 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: 122 switch (value) { 123 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC: 124 default: 125 return HFI_H264_ENTROPY_CAVLC; 126 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC: 127 return HFI_H264_ENTROPY_CABAC; 128 } 129 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: 130 switch (value) { 131 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED: 132 default: 133 return HFI_H264_DB_MODE_ALL_BOUNDARY; 134 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED: 135 return HFI_H264_DB_MODE_DISABLE; 136 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: 137 return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; 138 } 139 } 140 141 return 0; 142 } 143 144 static int 145 venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 146 { 147 strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); 148 strscpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); 149 strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); 150 151 return 0; 152 } 153 154 static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 155 { 156 struct venus_inst *inst = to_inst(file); 157 const struct venus_format *fmt; 158 159 fmt = find_format_by_index(inst, f->index, f->type); 160 161 memset(f->reserved, 0, sizeof(f->reserved)); 162 163 if (!fmt) 164 return -EINVAL; 165 166 f->pixelformat = fmt->pixfmt; 167 168 return 0; 169 } 170 171 static const struct venus_format * 172 venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) 173 { 174 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 175 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; 176 const struct venus_format *fmt; 177 u32 sizeimage; 178 179 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); 180 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 181 182 fmt = find_format(inst, pixmp->pixelformat, f->type); 183 if (!fmt) { 184 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 185 pixmp->pixelformat = V4L2_PIX_FMT_H264; 186 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 187 pixmp->pixelformat = V4L2_PIX_FMT_NV12; 188 else 189 return NULL; 190 fmt = find_format(inst, pixmp->pixelformat, f->type); 191 if (!fmt) 192 return NULL; 193 } 194 195 pixmp->width = clamp(pixmp->width, frame_width_min(inst), 196 frame_width_max(inst)); 197 pixmp->height = clamp(pixmp->height, frame_height_min(inst), 198 frame_height_max(inst)); 199 200 pixmp->width = ALIGN(pixmp->width, 128); 201 pixmp->height = ALIGN(pixmp->height, 32); 202 203 pixmp->width = ALIGN(pixmp->width, 2); 204 pixmp->height = ALIGN(pixmp->height, 2); 205 206 if (pixmp->field == V4L2_FIELD_ANY) 207 pixmp->field = V4L2_FIELD_NONE; 208 pixmp->num_planes = fmt->num_planes; 209 pixmp->flags = 0; 210 211 sizeimage = venus_helper_get_framesz(pixmp->pixelformat, 212 pixmp->width, 213 pixmp->height); 214 pfmt[0].sizeimage = max(ALIGN(pfmt[0].sizeimage, SZ_4K), sizeimage); 215 216 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 217 pfmt[0].bytesperline = ALIGN(pixmp->width, 128); 218 else 219 pfmt[0].bytesperline = 0; 220 221 return fmt; 222 } 223 224 static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 225 { 226 struct venus_inst *inst = to_inst(file); 227 228 venc_try_fmt_common(inst, f); 229 230 return 0; 231 } 232 233 static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 234 { 235 struct venus_inst *inst = to_inst(file); 236 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 237 struct v4l2_pix_format_mplane orig_pixmp; 238 const struct venus_format *fmt; 239 struct v4l2_format format; 240 u32 pixfmt_out = 0, pixfmt_cap = 0; 241 struct vb2_queue *q; 242 243 q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); 244 245 if (vb2_is_busy(q)) 246 return -EBUSY; 247 248 orig_pixmp = *pixmp; 249 250 fmt = venc_try_fmt_common(inst, f); 251 if (!fmt) 252 return -EINVAL; 253 254 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 255 pixfmt_out = pixmp->pixelformat; 256 pixfmt_cap = inst->fmt_cap->pixfmt; 257 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 258 pixfmt_cap = pixmp->pixelformat; 259 pixfmt_out = inst->fmt_out->pixfmt; 260 } 261 262 memset(&format, 0, sizeof(format)); 263 264 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 265 format.fmt.pix_mp.pixelformat = pixfmt_out; 266 format.fmt.pix_mp.width = orig_pixmp.width; 267 format.fmt.pix_mp.height = orig_pixmp.height; 268 venc_try_fmt_common(inst, &format); 269 270 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 271 inst->out_width = format.fmt.pix_mp.width; 272 inst->out_height = format.fmt.pix_mp.height; 273 inst->colorspace = pixmp->colorspace; 274 inst->ycbcr_enc = pixmp->ycbcr_enc; 275 inst->quantization = pixmp->quantization; 276 inst->xfer_func = pixmp->xfer_func; 277 } 278 279 memset(&format, 0, sizeof(format)); 280 281 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 282 format.fmt.pix_mp.pixelformat = pixfmt_cap; 283 format.fmt.pix_mp.width = orig_pixmp.width; 284 format.fmt.pix_mp.height = orig_pixmp.height; 285 venc_try_fmt_common(inst, &format); 286 287 inst->width = format.fmt.pix_mp.width; 288 inst->height = format.fmt.pix_mp.height; 289 290 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 291 inst->fmt_out = fmt; 292 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 293 inst->fmt_cap = fmt; 294 inst->output_buf_size = pixmp->plane_fmt[0].sizeimage; 295 } 296 297 return 0; 298 } 299 300 static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 301 { 302 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 303 struct venus_inst *inst = to_inst(file); 304 const struct venus_format *fmt; 305 306 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 307 fmt = inst->fmt_cap; 308 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 309 fmt = inst->fmt_out; 310 else 311 return -EINVAL; 312 313 pixmp->pixelformat = fmt->pixfmt; 314 315 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 316 pixmp->width = inst->width; 317 pixmp->height = inst->height; 318 pixmp->colorspace = inst->colorspace; 319 pixmp->ycbcr_enc = inst->ycbcr_enc; 320 pixmp->quantization = inst->quantization; 321 pixmp->xfer_func = inst->xfer_func; 322 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 323 pixmp->width = inst->out_width; 324 pixmp->height = inst->out_height; 325 } 326 327 venc_try_fmt_common(inst, f); 328 329 return 0; 330 } 331 332 static int 333 venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 334 { 335 struct venus_inst *inst = to_inst(file); 336 337 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 338 return -EINVAL; 339 340 switch (s->target) { 341 case V4L2_SEL_TGT_CROP_DEFAULT: 342 case V4L2_SEL_TGT_CROP_BOUNDS: 343 s->r.width = inst->out_width; 344 s->r.height = inst->out_height; 345 break; 346 case V4L2_SEL_TGT_CROP: 347 s->r.width = inst->width; 348 s->r.height = inst->height; 349 break; 350 default: 351 return -EINVAL; 352 } 353 354 s->r.top = 0; 355 s->r.left = 0; 356 357 return 0; 358 } 359 360 static int 361 venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 362 { 363 struct venus_inst *inst = to_inst(file); 364 365 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 366 return -EINVAL; 367 368 if (s->r.width > inst->out_width || 369 s->r.height > inst->out_height) 370 return -EINVAL; 371 372 s->r.width = ALIGN(s->r.width, 2); 373 s->r.height = ALIGN(s->r.height, 2); 374 375 switch (s->target) { 376 case V4L2_SEL_TGT_CROP: 377 s->r.top = 0; 378 s->r.left = 0; 379 inst->width = s->r.width; 380 inst->height = s->r.height; 381 break; 382 default: 383 return -EINVAL; 384 } 385 386 return 0; 387 } 388 389 static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 390 { 391 struct venus_inst *inst = to_inst(file); 392 struct v4l2_outputparm *out = &a->parm.output; 393 struct v4l2_fract *timeperframe = &out->timeperframe; 394 u64 us_per_frame, fps; 395 396 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 397 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 398 return -EINVAL; 399 400 memset(out->reserved, 0, sizeof(out->reserved)); 401 402 if (!timeperframe->denominator) 403 timeperframe->denominator = inst->timeperframe.denominator; 404 if (!timeperframe->numerator) 405 timeperframe->numerator = inst->timeperframe.numerator; 406 407 out->capability = V4L2_CAP_TIMEPERFRAME; 408 409 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; 410 do_div(us_per_frame, timeperframe->denominator); 411 412 us_per_frame = clamp(us_per_frame, 1, USEC_PER_SEC); 413 fps = USEC_PER_SEC / (u32)us_per_frame; 414 fps = min(VENUS_MAX_FPS, fps); 415 416 inst->timeperframe = *timeperframe; 417 inst->fps = fps; 418 419 return 0; 420 } 421 422 static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 423 { 424 struct venus_inst *inst = to_inst(file); 425 426 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 427 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 428 return -EINVAL; 429 430 a->parm.output.capability |= V4L2_CAP_TIMEPERFRAME; 431 a->parm.output.timeperframe = inst->timeperframe; 432 433 return 0; 434 } 435 436 static int venc_enum_framesizes(struct file *file, void *fh, 437 struct v4l2_frmsizeenum *fsize) 438 { 439 struct venus_inst *inst = to_inst(file); 440 const struct venus_format *fmt; 441 442 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 443 444 fmt = find_format(inst, fsize->pixel_format, 445 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 446 if (!fmt) { 447 fmt = find_format(inst, fsize->pixel_format, 448 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 449 if (!fmt) 450 return -EINVAL; 451 } 452 453 if (fsize->index) 454 return -EINVAL; 455 456 fsize->stepwise.min_width = frame_width_min(inst); 457 fsize->stepwise.max_width = frame_width_max(inst); 458 fsize->stepwise.step_width = frame_width_step(inst); 459 fsize->stepwise.min_height = frame_height_min(inst); 460 fsize->stepwise.max_height = frame_height_max(inst); 461 fsize->stepwise.step_height = frame_height_step(inst); 462 463 return 0; 464 } 465 466 static int venc_enum_frameintervals(struct file *file, void *fh, 467 struct v4l2_frmivalenum *fival) 468 { 469 struct venus_inst *inst = to_inst(file); 470 const struct venus_format *fmt; 471 unsigned int framerate_factor = 1; 472 473 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 474 475 fmt = find_format(inst, fival->pixel_format, 476 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 477 if (!fmt) { 478 fmt = find_format(inst, fival->pixel_format, 479 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 480 if (!fmt) 481 return -EINVAL; 482 } 483 484 if (fival->index) 485 return -EINVAL; 486 487 if (!fival->width || !fival->height) 488 return -EINVAL; 489 490 if (fival->width > frame_width_max(inst) || 491 fival->width < frame_width_min(inst) || 492 fival->height > frame_height_max(inst) || 493 fival->height < frame_height_min(inst)) 494 return -EINVAL; 495 496 if (IS_V1(inst->core)) { 497 /* framerate is reported in 1/65535 fps unit */ 498 framerate_factor = (1 << 16); 499 } 500 501 fival->stepwise.min.numerator = 1; 502 fival->stepwise.min.denominator = frate_max(inst) / framerate_factor; 503 fival->stepwise.max.numerator = 1; 504 fival->stepwise.max.denominator = frate_min(inst) / framerate_factor; 505 fival->stepwise.step.numerator = 1; 506 fival->stepwise.step.denominator = frate_max(inst) / framerate_factor; 507 508 return 0; 509 } 510 511 static int venc_subscribe_event(struct v4l2_fh *fh, 512 const struct v4l2_event_subscription *sub) 513 { 514 switch (sub->type) { 515 case V4L2_EVENT_EOS: 516 return v4l2_event_subscribe(fh, sub, 2, NULL); 517 case V4L2_EVENT_CTRL: 518 return v4l2_ctrl_subscribe_event(fh, sub); 519 default: 520 return -EINVAL; 521 } 522 } 523 524 static int 525 venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd) 526 { 527 struct venus_inst *inst = to_inst(file); 528 struct hfi_frame_data fdata = {0}; 529 int ret = 0; 530 531 ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); 532 if (ret) 533 return ret; 534 535 mutex_lock(&inst->lock); 536 537 if (cmd->cmd == V4L2_ENC_CMD_STOP && 538 inst->enc_state == VENUS_ENC_STATE_ENCODING) { 539 /* 540 * Implement V4L2_ENC_CMD_STOP by enqueue an empty buffer on 541 * encoder 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 fdata.device_addr = 0xdeadb000; 549 550 ret = hfi_session_process_buf(inst, &fdata); 551 552 inst->enc_state = VENUS_ENC_STATE_DRAIN; 553 } else if (cmd->cmd == V4L2_ENC_CMD_START) { 554 if (inst->enc_state == VENUS_ENC_STATE_DRAIN) { 555 ret = -EBUSY; 556 goto unlock; 557 } 558 if (inst->enc_state == VENUS_ENC_STATE_STOPPED) { 559 vb2_clear_last_buffer_dequeued(&inst->fh.m2m_ctx->cap_q_ctx.q); 560 inst->enc_state = VENUS_ENC_STATE_ENCODING; 561 } 562 } 563 564 unlock: 565 mutex_unlock(&inst->lock); 566 return ret; 567 } 568 569 static const struct v4l2_ioctl_ops venc_ioctl_ops = { 570 .vidioc_querycap = venc_querycap, 571 .vidioc_enum_fmt_vid_cap = venc_enum_fmt, 572 .vidioc_enum_fmt_vid_out = venc_enum_fmt, 573 .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt, 574 .vidioc_s_fmt_vid_out_mplane = venc_s_fmt, 575 .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt, 576 .vidioc_g_fmt_vid_out_mplane = venc_g_fmt, 577 .vidioc_try_fmt_vid_cap_mplane = venc_try_fmt, 578 .vidioc_try_fmt_vid_out_mplane = venc_try_fmt, 579 .vidioc_g_selection = venc_g_selection, 580 .vidioc_s_selection = venc_s_selection, 581 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 582 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 583 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 584 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 585 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 586 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 587 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 588 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 589 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 590 .vidioc_s_parm = venc_s_parm, 591 .vidioc_g_parm = venc_g_parm, 592 .vidioc_enum_framesizes = venc_enum_framesizes, 593 .vidioc_enum_frameintervals = venc_enum_frameintervals, 594 .vidioc_subscribe_event = venc_subscribe_event, 595 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 596 .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, 597 .vidioc_encoder_cmd = venc_encoder_cmd, 598 }; 599 600 static int venc_pm_get(struct venus_inst *inst) 601 { 602 struct venus_core *core = inst->core; 603 struct device *dev = core->dev_enc; 604 int ret; 605 606 mutex_lock(&core->pm_lock); 607 ret = pm_runtime_resume_and_get(dev); 608 mutex_unlock(&core->pm_lock); 609 610 return ret < 0 ? ret : 0; 611 } 612 613 static int venc_pm_put(struct venus_inst *inst, bool autosuspend) 614 { 615 struct venus_core *core = inst->core; 616 struct device *dev = core->dev_enc; 617 int ret; 618 619 mutex_lock(&core->pm_lock); 620 621 if (autosuspend) 622 ret = pm_runtime_put_autosuspend(dev); 623 else 624 ret = pm_runtime_put_sync(dev); 625 626 mutex_unlock(&core->pm_lock); 627 628 return ret < 0 ? ret : 0; 629 } 630 631 static int venc_pm_get_put(struct venus_inst *inst) 632 { 633 struct venus_core *core = inst->core; 634 struct device *dev = core->dev_enc; 635 int ret = 0; 636 637 mutex_lock(&core->pm_lock); 638 639 if (pm_runtime_suspended(dev)) { 640 ret = pm_runtime_resume_and_get(dev); 641 if (ret < 0) 642 goto error; 643 644 ret = pm_runtime_put_autosuspend(dev); 645 } 646 647 error: 648 mutex_unlock(&core->pm_lock); 649 650 return ret < 0 ? ret : 0; 651 } 652 653 static void venc_pm_touch(struct venus_inst *inst) 654 { 655 pm_runtime_mark_last_busy(inst->core->dev_enc); 656 } 657 658 static int venc_set_properties(struct venus_inst *inst) 659 { 660 struct venc_controls *ctr = &inst->controls.enc; 661 struct hfi_intra_period intra_period; 662 struct hfi_framerate frate; 663 struct hfi_bitrate brate; 664 struct hfi_idr_period idrp; 665 struct hfi_quantization quant; 666 struct hfi_quantization_range quant_range; 667 struct hfi_quantization_range_v2 quant_range_v2; 668 struct hfi_enable en; 669 struct hfi_ltr_mode ltr_mode; 670 struct hfi_intra_refresh intra_refresh = {}; 671 u32 ptype, rate_control, bitrate; 672 u32 profile, level; 673 int ret; 674 675 ret = venus_helper_set_work_mode(inst); 676 if (ret) 677 return ret; 678 679 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; 680 frate.buffer_type = HFI_BUFFER_OUTPUT; 681 frate.framerate = inst->fps * (1 << 16); 682 683 ret = hfi_session_set_property(inst, ptype, &frate); 684 if (ret) 685 return ret; 686 687 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { 688 struct hfi_h264_vui_timing_info info; 689 struct hfi_h264_entropy_control entropy; 690 struct hfi_h264_db_control deblock; 691 struct hfi_h264_8x8_transform h264_transform; 692 693 ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO; 694 info.enable = 1; 695 info.fixed_framerate = 1; 696 info.time_scale = NSEC_PER_SEC; 697 698 ret = hfi_session_set_property(inst, ptype, &info); 699 if (ret) 700 return ret; 701 702 ptype = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL; 703 entropy.entropy_mode = venc_v4l2_to_hfi( 704 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, 705 ctr->h264_entropy_mode); 706 entropy.cabac_model = HFI_H264_CABAC_MODEL_0; 707 708 ret = hfi_session_set_property(inst, ptype, &entropy); 709 if (ret) 710 return ret; 711 712 ptype = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL; 713 deblock.mode = venc_v4l2_to_hfi( 714 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, 715 ctr->h264_loop_filter_mode); 716 deblock.slice_alpha_offset = ctr->h264_loop_filter_alpha; 717 deblock.slice_beta_offset = ctr->h264_loop_filter_beta; 718 719 ret = hfi_session_set_property(inst, ptype, &deblock); 720 if (ret) 721 return ret; 722 723 ptype = HFI_PROPERTY_PARAM_VENC_H264_TRANSFORM_8X8; 724 h264_transform.enable_type = 0; 725 if (ctr->profile.h264 == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH || 726 ctr->profile.h264 == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) 727 h264_transform.enable_type = ctr->h264_8x8_transform; 728 729 ret = hfi_session_set_property(inst, ptype, &h264_transform); 730 if (ret) 731 return ret; 732 733 if (ctr->layer_bitrate) { 734 unsigned int i; 735 736 ptype = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER; 737 ret = hfi_session_set_property(inst, ptype, &ctr->h264_hier_layers); 738 if (ret) 739 return ret; 740 741 ptype = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER; 742 ret = hfi_session_set_property(inst, ptype, &ctr->layer_bitrate); 743 if (ret) 744 return ret; 745 746 for (i = 0; i < ctr->h264_hier_layers; ++i) { 747 ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; 748 brate.bitrate = ctr->h264_hier_layer_bitrate[i]; 749 brate.layer_id = i; 750 751 ret = hfi_session_set_property(inst, ptype, &brate); 752 if (ret) 753 return ret; 754 } 755 } 756 } 757 758 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || 759 inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 760 /* IDR periodicity, n: 761 * n = 0 - only the first I-frame is IDR frame 762 * n = 1 - all I-frames will be IDR frames 763 * n > 1 - every n-th I-frame will be IDR frame 764 */ 765 ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD; 766 idrp.idr_period = 0; 767 ret = hfi_session_set_property(inst, ptype, &idrp); 768 if (ret) 769 return ret; 770 } 771 772 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC && 773 ctr->profile.hevc == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) { 774 struct hfi_hdr10_pq_sei hdr10; 775 unsigned int c; 776 777 ptype = HFI_PROPERTY_PARAM_VENC_HDR10_PQ_SEI; 778 779 for (c = 0; c < 3; c++) { 780 hdr10.mastering.display_primaries_x[c] = 781 ctr->mastering.display_primaries_x[c]; 782 hdr10.mastering.display_primaries_y[c] = 783 ctr->mastering.display_primaries_y[c]; 784 } 785 786 hdr10.mastering.white_point_x = ctr->mastering.white_point_x; 787 hdr10.mastering.white_point_y = ctr->mastering.white_point_y; 788 hdr10.mastering.max_display_mastering_luminance = 789 ctr->mastering.max_display_mastering_luminance; 790 hdr10.mastering.min_display_mastering_luminance = 791 ctr->mastering.min_display_mastering_luminance; 792 793 hdr10.cll.max_content_light = ctr->cll.max_content_light_level; 794 hdr10.cll.max_pic_average_light = 795 ctr->cll.max_pic_average_light_level; 796 797 ret = hfi_session_set_property(inst, ptype, &hdr10); 798 if (ret) 799 return ret; 800 } 801 802 if (ctr->num_b_frames) { 803 u32 max_num_b_frames = NUM_B_FRAMES_MAX; 804 805 ptype = HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES; 806 ret = hfi_session_set_property(inst, ptype, &max_num_b_frames); 807 if (ret) 808 return ret; 809 } 810 811 ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD; 812 intra_period.pframes = ctr->num_p_frames; 813 intra_period.bframes = ctr->num_b_frames; 814 815 ret = hfi_session_set_property(inst, ptype, &intra_period); 816 if (ret) 817 return ret; 818 819 if (!ctr->rc_enable) 820 rate_control = HFI_RATE_CONTROL_OFF; 821 else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) 822 rate_control = ctr->frame_skip_mode ? HFI_RATE_CONTROL_VBR_VFR : 823 HFI_RATE_CONTROL_VBR_CFR; 824 else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) 825 rate_control = ctr->frame_skip_mode ? HFI_RATE_CONTROL_CBR_VFR : 826 HFI_RATE_CONTROL_CBR_CFR; 827 else if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) 828 rate_control = HFI_RATE_CONTROL_CQ; 829 830 ptype = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL; 831 ret = hfi_session_set_property(inst, ptype, &rate_control); 832 if (ret) 833 return ret; 834 835 if (rate_control == HFI_RATE_CONTROL_CQ && ctr->const_quality) { 836 struct hfi_heic_frame_quality quality = {}; 837 838 ptype = HFI_PROPERTY_CONFIG_HEIC_FRAME_QUALITY; 839 quality.frame_quality = ctr->const_quality; 840 ret = hfi_session_set_property(inst, ptype, &quality); 841 if (ret) 842 return ret; 843 } 844 845 if (!ctr->layer_bitrate) { 846 if (!ctr->bitrate) 847 bitrate = 64000; 848 else 849 bitrate = ctr->bitrate; 850 851 ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; 852 brate.bitrate = bitrate; 853 brate.layer_id = 0; 854 855 ret = hfi_session_set_property(inst, ptype, &brate); 856 if (ret) 857 return ret; 858 859 if (!ctr->bitrate_peak) 860 bitrate *= 2; 861 else 862 bitrate = ctr->bitrate_peak; 863 864 ptype = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE; 865 brate.bitrate = bitrate; 866 brate.layer_id = 0; 867 868 ret = hfi_session_set_property(inst, ptype, &brate); 869 if (ret) 870 return ret; 871 } 872 873 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || 874 inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 875 ptype = HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER; 876 if (ctr->header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) 877 en.enable = 0; 878 else 879 en.enable = 1; 880 881 ret = hfi_session_set_property(inst, ptype, &en); 882 if (ret) 883 return ret; 884 } 885 886 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP; 887 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 888 quant.qp_i = ctr->hevc_i_qp; 889 quant.qp_p = ctr->hevc_p_qp; 890 quant.qp_b = ctr->hevc_b_qp; 891 } else { 892 quant.qp_i = ctr->h264_i_qp; 893 quant.qp_p = ctr->h264_p_qp; 894 quant.qp_b = ctr->h264_b_qp; 895 } 896 quant.layer_id = 0; 897 ret = hfi_session_set_property(inst, ptype, &quant); 898 if (ret) 899 return ret; 900 901 if (inst->core->res->hfi_version == HFI_VERSION_4XX || 902 inst->core->res->hfi_version == HFI_VERSION_6XX) { 903 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE_V2; 904 905 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 906 quant_range_v2.min_qp.qp_packed = ctr->hevc_min_qp; 907 quant_range_v2.max_qp.qp_packed = ctr->hevc_max_qp; 908 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { 909 quant_range_v2.min_qp.qp_packed = ctr->vp8_min_qp; 910 quant_range_v2.max_qp.qp_packed = ctr->vp8_max_qp; 911 } else { 912 quant_range_v2.min_qp.qp_packed = ctr->h264_min_qp; 913 quant_range_v2.max_qp.qp_packed = ctr->h264_max_qp; 914 } 915 916 ret = hfi_session_set_property(inst, ptype, &quant_range_v2); 917 } else { 918 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; 919 920 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 921 quant_range.min_qp = ctr->hevc_min_qp; 922 quant_range.max_qp = ctr->hevc_max_qp; 923 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { 924 quant_range.min_qp = ctr->vp8_min_qp; 925 quant_range.max_qp = ctr->vp8_max_qp; 926 } else { 927 quant_range.min_qp = ctr->h264_min_qp; 928 quant_range.max_qp = ctr->h264_max_qp; 929 } 930 931 quant_range.layer_id = 0; 932 ret = hfi_session_set_property(inst, ptype, &quant_range); 933 } 934 935 if (ret) 936 return ret; 937 938 ptype = HFI_PROPERTY_PARAM_VENC_LTRMODE; 939 ltr_mode.ltr_count = ctr->ltr_count; 940 ltr_mode.ltr_mode = HFI_LTR_MODE_MANUAL; 941 ltr_mode.trust_mode = 1; 942 ret = hfi_session_set_property(inst, ptype, <r_mode); 943 if (ret) 944 return ret; 945 946 switch (inst->hfi_codec) { 947 case HFI_VIDEO_CODEC_H264: 948 profile = ctr->profile.h264; 949 level = ctr->level.h264; 950 break; 951 case HFI_VIDEO_CODEC_MPEG4: 952 profile = ctr->profile.mpeg4; 953 level = ctr->level.mpeg4; 954 break; 955 case HFI_VIDEO_CODEC_VP8: 956 profile = ctr->profile.vp8; 957 level = 0; 958 break; 959 case HFI_VIDEO_CODEC_VP9: 960 profile = ctr->profile.vp9; 961 level = ctr->level.vp9; 962 break; 963 case HFI_VIDEO_CODEC_HEVC: 964 profile = ctr->profile.hevc; 965 level = ctr->level.hevc; 966 break; 967 case HFI_VIDEO_CODEC_MPEG2: 968 default: 969 profile = 0; 970 level = 0; 971 break; 972 } 973 974 ret = venus_helper_set_profile_level(inst, profile, level); 975 if (ret) 976 return ret; 977 978 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || 979 inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 980 struct hfi_enable en = {}; 981 982 ptype = HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL; 983 984 if (ctr->aud_enable) 985 en.enable = 1; 986 987 ret = hfi_session_set_property(inst, ptype, &en); 988 } 989 990 if ((inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264 || 991 inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) && 992 (rate_control == HFI_RATE_CONTROL_CBR_VFR || 993 rate_control == HFI_RATE_CONTROL_CBR_CFR)) { 994 intra_refresh.mode = HFI_INTRA_REFRESH_NONE; 995 intra_refresh.cir_mbs = 0; 996 997 if (ctr->intra_refresh_period) { 998 u32 mbs; 999 1000 mbs = ALIGN(inst->width, 16) * ALIGN(inst->height, 16); 1001 mbs /= 16 * 16; 1002 if (mbs % ctr->intra_refresh_period) 1003 mbs++; 1004 mbs /= ctr->intra_refresh_period; 1005 1006 intra_refresh.cir_mbs = mbs; 1007 if (ctr->intra_refresh_type == 1008 V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) 1009 intra_refresh.mode = HFI_INTRA_REFRESH_CYCLIC; 1010 else 1011 intra_refresh.mode = HFI_INTRA_REFRESH_RANDOM; 1012 } 1013 1014 ptype = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH; 1015 1016 ret = hfi_session_set_property(inst, ptype, &intra_refresh); 1017 if (ret) 1018 return ret; 1019 } 1020 1021 return 0; 1022 } 1023 1024 static int venc_init_session(struct venus_inst *inst) 1025 { 1026 int ret; 1027 1028 ret = venus_helper_session_init(inst); 1029 if (ret == -EALREADY) 1030 return 0; 1031 else if (ret) 1032 return ret; 1033 1034 ret = venus_helper_set_stride(inst, inst->out_width, 1035 inst->out_height); 1036 if (ret) 1037 goto deinit; 1038 1039 ret = venus_helper_set_input_resolution(inst, inst->width, 1040 inst->height); 1041 if (ret) 1042 goto deinit; 1043 1044 ret = venus_helper_set_output_resolution(inst, inst->width, 1045 inst->height, 1046 HFI_BUFFER_OUTPUT); 1047 if (ret) 1048 goto deinit; 1049 1050 ret = venus_helper_set_color_format(inst, inst->fmt_out->pixfmt); 1051 if (ret) 1052 goto deinit; 1053 1054 ret = venc_set_properties(inst); 1055 if (ret) 1056 goto deinit; 1057 1058 return 0; 1059 deinit: 1060 hfi_session_deinit(inst); 1061 return ret; 1062 } 1063 1064 static int venc_out_num_buffers(struct venus_inst *inst, unsigned int *num) 1065 { 1066 struct hfi_buffer_requirements bufreq; 1067 int ret; 1068 1069 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 1070 if (ret) 1071 return ret; 1072 1073 *num = bufreq.count_actual; 1074 1075 return 0; 1076 } 1077 1078 static int venc_queue_setup(struct vb2_queue *q, 1079 unsigned int *num_buffers, unsigned int *num_planes, 1080 unsigned int sizes[], struct device *alloc_devs[]) 1081 { 1082 struct venus_inst *inst = vb2_get_drv_priv(q); 1083 struct venus_core *core = inst->core; 1084 unsigned int num, min = 4; 1085 int ret; 1086 1087 if (*num_planes) { 1088 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 1089 *num_planes != inst->fmt_out->num_planes) 1090 return -EINVAL; 1091 1092 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 1093 *num_planes != inst->fmt_cap->num_planes) 1094 return -EINVAL; 1095 1096 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 1097 sizes[0] < inst->input_buf_size) 1098 return -EINVAL; 1099 1100 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 1101 sizes[0] < inst->output_buf_size) 1102 return -EINVAL; 1103 1104 return 0; 1105 } 1106 1107 if (test_bit(0, &core->sys_error)) { 1108 if (inst->nonblock) 1109 return -EAGAIN; 1110 1111 ret = wait_event_interruptible(core->sys_err_done, 1112 !test_bit(0, &core->sys_error)); 1113 if (ret) 1114 return ret; 1115 } 1116 1117 ret = venc_pm_get(inst); 1118 if (ret) 1119 return ret; 1120 1121 mutex_lock(&inst->lock); 1122 ret = venc_init_session(inst); 1123 mutex_unlock(&inst->lock); 1124 1125 if (ret) 1126 goto put_power; 1127 1128 ret = venc_pm_put(inst, false); 1129 if (ret) 1130 return ret; 1131 1132 switch (q->type) { 1133 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 1134 *num_planes = inst->fmt_out->num_planes; 1135 1136 ret = venc_out_num_buffers(inst, &num); 1137 if (ret) 1138 break; 1139 1140 num = max(num, min); 1141 *num_buffers = max(*num_buffers, num); 1142 inst->num_input_bufs = *num_buffers; 1143 1144 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, 1145 inst->out_width, 1146 inst->out_height); 1147 inst->input_buf_size = sizes[0]; 1148 break; 1149 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 1150 *num_planes = inst->fmt_cap->num_planes; 1151 *num_buffers = max(*num_buffers, min); 1152 inst->num_output_bufs = *num_buffers; 1153 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, 1154 inst->width, 1155 inst->height); 1156 sizes[0] = max(sizes[0], inst->output_buf_size); 1157 inst->output_buf_size = sizes[0]; 1158 break; 1159 default: 1160 ret = -EINVAL; 1161 break; 1162 } 1163 1164 return ret; 1165 put_power: 1166 venc_pm_put(inst, false); 1167 return ret; 1168 } 1169 1170 static int venc_buf_init(struct vb2_buffer *vb) 1171 { 1172 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1173 1174 inst->buf_count++; 1175 1176 return venus_helper_vb2_buf_init(vb); 1177 } 1178 1179 static void venc_release_session(struct venus_inst *inst) 1180 { 1181 int ret; 1182 1183 venc_pm_get(inst); 1184 1185 mutex_lock(&inst->lock); 1186 1187 ret = hfi_session_deinit(inst); 1188 if (ret || inst->session_error) 1189 hfi_session_abort(inst); 1190 1191 mutex_unlock(&inst->lock); 1192 1193 venus_pm_load_scale(inst); 1194 INIT_LIST_HEAD(&inst->registeredbufs); 1195 venus_pm_release_core(inst); 1196 1197 venc_pm_put(inst, false); 1198 } 1199 1200 static void venc_buf_cleanup(struct vb2_buffer *vb) 1201 { 1202 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1203 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1204 struct venus_buffer *buf = to_venus_buffer(vbuf); 1205 1206 mutex_lock(&inst->lock); 1207 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 1208 if (!list_empty(&inst->registeredbufs)) 1209 list_del_init(&buf->reg_list); 1210 mutex_unlock(&inst->lock); 1211 1212 inst->buf_count--; 1213 if (!inst->buf_count) 1214 venc_release_session(inst); 1215 } 1216 1217 static int venc_verify_conf(struct venus_inst *inst) 1218 { 1219 enum hfi_version ver = inst->core->res->hfi_version; 1220 struct hfi_buffer_requirements bufreq; 1221 int ret; 1222 1223 if (!inst->num_input_bufs || !inst->num_output_bufs) 1224 return -EINVAL; 1225 1226 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 1227 if (ret) 1228 return ret; 1229 1230 if (inst->num_output_bufs < bufreq.count_actual || 1231 inst->num_output_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) 1232 return -EINVAL; 1233 1234 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 1235 if (ret) 1236 return ret; 1237 1238 if (inst->num_input_bufs < bufreq.count_actual || 1239 inst->num_input_bufs < hfi_bufreq_get_count_min(&bufreq, ver)) 1240 return -EINVAL; 1241 1242 return 0; 1243 } 1244 1245 static int venc_start_streaming(struct vb2_queue *q, unsigned int count) 1246 { 1247 struct venus_inst *inst = vb2_get_drv_priv(q); 1248 int ret; 1249 1250 mutex_lock(&inst->lock); 1251 1252 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1253 inst->streamon_out = 1; 1254 else 1255 inst->streamon_cap = 1; 1256 1257 if (!(inst->streamon_out & inst->streamon_cap)) { 1258 mutex_unlock(&inst->lock); 1259 return 0; 1260 } 1261 1262 venus_helper_init_instance(inst); 1263 1264 inst->sequence_cap = 0; 1265 inst->sequence_out = 0; 1266 1267 ret = venc_pm_get(inst); 1268 if (ret) 1269 goto error; 1270 1271 ret = venus_pm_acquire_core(inst); 1272 if (ret) 1273 goto put_power; 1274 1275 ret = venc_pm_put(inst, true); 1276 if (ret) 1277 goto error; 1278 1279 ret = venc_set_properties(inst); 1280 if (ret) 1281 goto error; 1282 1283 ret = venc_verify_conf(inst); 1284 if (ret) 1285 goto error; 1286 1287 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, 1288 inst->num_output_bufs, 0); 1289 if (ret) 1290 goto error; 1291 1292 ret = venus_helper_vb2_start_streaming(inst); 1293 if (ret) 1294 goto error; 1295 1296 inst->enc_state = VENUS_ENC_STATE_ENCODING; 1297 1298 mutex_unlock(&inst->lock); 1299 1300 return 0; 1301 1302 put_power: 1303 venc_pm_put(inst, false); 1304 error: 1305 venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED); 1306 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1307 inst->streamon_out = 0; 1308 else 1309 inst->streamon_cap = 0; 1310 mutex_unlock(&inst->lock); 1311 return ret; 1312 } 1313 1314 static void venc_vb2_buf_queue(struct vb2_buffer *vb) 1315 { 1316 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); 1317 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1318 1319 venc_pm_get_put(inst); 1320 1321 mutex_lock(&inst->lock); 1322 1323 if (inst->enc_state == VENUS_ENC_STATE_STOPPED) { 1324 vbuf->sequence = inst->sequence_cap++; 1325 vbuf->field = V4L2_FIELD_NONE; 1326 vb2_set_plane_payload(vb, 0, 0); 1327 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 1328 mutex_unlock(&inst->lock); 1329 return; 1330 } 1331 1332 venus_helper_vb2_buf_queue(vb); 1333 mutex_unlock(&inst->lock); 1334 } 1335 1336 static const struct vb2_ops venc_vb2_ops = { 1337 .queue_setup = venc_queue_setup, 1338 .buf_init = venc_buf_init, 1339 .buf_cleanup = venc_buf_cleanup, 1340 .buf_prepare = venus_helper_vb2_buf_prepare, 1341 .start_streaming = venc_start_streaming, 1342 .stop_streaming = venus_helper_vb2_stop_streaming, 1343 .buf_queue = venc_vb2_buf_queue, 1344 }; 1345 1346 static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type, 1347 u32 tag, u32 bytesused, u32 data_offset, u32 flags, 1348 u32 hfi_flags, u64 timestamp_us) 1349 { 1350 struct vb2_v4l2_buffer *vbuf; 1351 struct vb2_buffer *vb; 1352 unsigned int type; 1353 1354 venc_pm_touch(inst); 1355 1356 if (buf_type == HFI_BUFFER_INPUT) 1357 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1358 else 1359 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1360 1361 vbuf = venus_helper_find_buf(inst, type, tag); 1362 if (!vbuf) 1363 return; 1364 1365 vbuf->flags = flags; 1366 1367 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1368 vb = &vbuf->vb2_buf; 1369 vb2_set_plane_payload(vb, 0, bytesused + data_offset); 1370 vb->planes[0].data_offset = data_offset; 1371 vb->timestamp = timestamp_us * NSEC_PER_USEC; 1372 vbuf->sequence = inst->sequence_cap++; 1373 if ((vbuf->flags & V4L2_BUF_FLAG_LAST) && 1374 inst->enc_state == VENUS_ENC_STATE_DRAIN) { 1375 inst->enc_state = VENUS_ENC_STATE_STOPPED; 1376 } 1377 } else { 1378 vbuf->sequence = inst->sequence_out++; 1379 } 1380 1381 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 1382 } 1383 1384 static void venc_event_notify(struct venus_inst *inst, u32 event, 1385 struct hfi_event_data *data) 1386 { 1387 struct device *dev = inst->core->dev_enc; 1388 1389 venc_pm_touch(inst); 1390 1391 if (event == EVT_SESSION_ERROR) { 1392 inst->session_error = true; 1393 venus_helper_vb2_queue_error(inst); 1394 dev_err(dev, "enc: event session error %x\n", inst->error); 1395 } 1396 } 1397 1398 static const struct hfi_inst_ops venc_hfi_ops = { 1399 .buf_done = venc_buf_done, 1400 .event_notify = venc_event_notify, 1401 }; 1402 1403 static const struct v4l2_m2m_ops venc_m2m_ops = { 1404 .device_run = venus_helper_m2m_device_run, 1405 .job_abort = venus_helper_m2m_job_abort, 1406 }; 1407 1408 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, 1409 struct vb2_queue *dst_vq) 1410 { 1411 struct venus_inst *inst = priv; 1412 int ret; 1413 1414 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1415 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1416 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1417 src_vq->ops = &venc_vb2_ops; 1418 src_vq->mem_ops = &vb2_dma_contig_memops; 1419 src_vq->drv_priv = inst; 1420 src_vq->buf_struct_size = sizeof(struct venus_buffer); 1421 src_vq->allow_zero_bytesused = 1; 1422 src_vq->min_queued_buffers = 1; 1423 src_vq->dev = inst->core->dev; 1424 src_vq->lock = &inst->ctx_q_lock; 1425 if (inst->core->res->hfi_version == HFI_VERSION_1XX) 1426 src_vq->bidirectional = 1; 1427 ret = vb2_queue_init(src_vq); 1428 if (ret) 1429 return ret; 1430 1431 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1432 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1433 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1434 dst_vq->ops = &venc_vb2_ops; 1435 dst_vq->mem_ops = &vb2_dma_contig_memops; 1436 dst_vq->drv_priv = inst; 1437 dst_vq->buf_struct_size = sizeof(struct venus_buffer); 1438 dst_vq->allow_zero_bytesused = 1; 1439 dst_vq->min_queued_buffers = 1; 1440 dst_vq->dev = inst->core->dev; 1441 dst_vq->lock = &inst->ctx_q_lock; 1442 return vb2_queue_init(dst_vq); 1443 } 1444 1445 static void venc_inst_init(struct venus_inst *inst) 1446 { 1447 inst->fmt_cap = &venc_formats[VENUS_FMT_H264]; 1448 inst->fmt_out = &venc_formats[VENUS_FMT_NV12]; 1449 inst->width = 1280; 1450 inst->height = ALIGN(720, 32); 1451 inst->out_width = 1280; 1452 inst->out_height = 720; 1453 inst->fps = 15; 1454 inst->timeperframe.numerator = 1; 1455 inst->timeperframe.denominator = 15; 1456 inst->hfi_codec = HFI_VIDEO_CODEC_H264; 1457 } 1458 1459 static int venc_open(struct file *file) 1460 { 1461 struct venus_core *core = video_drvdata(file); 1462 struct venus_inst *inst; 1463 int ret; 1464 1465 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 1466 if (!inst) 1467 return -ENOMEM; 1468 1469 INIT_LIST_HEAD(&inst->dpbbufs); 1470 INIT_LIST_HEAD(&inst->registeredbufs); 1471 INIT_LIST_HEAD(&inst->internalbufs); 1472 INIT_LIST_HEAD(&inst->list); 1473 mutex_init(&inst->lock); 1474 mutex_init(&inst->ctx_q_lock); 1475 1476 inst->core = core; 1477 inst->session_type = VIDC_SESSION_TYPE_ENC; 1478 inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT; 1479 inst->core_acquired = false; 1480 inst->nonblock = file->f_flags & O_NONBLOCK; 1481 1482 if (inst->enc_state == VENUS_ENC_STATE_DEINIT) 1483 inst->enc_state = VENUS_ENC_STATE_INIT; 1484 1485 venus_helper_init_instance(inst); 1486 1487 ret = venc_ctrl_init(inst); 1488 if (ret) 1489 goto err_free; 1490 1491 venc_inst_init(inst); 1492 1493 /* 1494 * create m2m device for every instance, the m2m context scheduling 1495 * is made by firmware side so we do not need to care about. 1496 */ 1497 inst->m2m_dev = v4l2_m2m_init(&venc_m2m_ops); 1498 if (IS_ERR(inst->m2m_dev)) { 1499 ret = PTR_ERR(inst->m2m_dev); 1500 goto err_ctrl_deinit; 1501 } 1502 1503 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1504 if (IS_ERR(inst->m2m_ctx)) { 1505 ret = PTR_ERR(inst->m2m_ctx); 1506 goto err_m2m_dev_release; 1507 } 1508 1509 ret = hfi_session_create(inst, &venc_hfi_ops); 1510 if (ret) 1511 goto err_m2m_ctx_release; 1512 1513 v4l2_fh_init(&inst->fh, core->vdev_enc); 1514 1515 inst->fh.ctrl_handler = &inst->ctrl_handler; 1516 v4l2_fh_add(&inst->fh, file); 1517 inst->fh.m2m_ctx = inst->m2m_ctx; 1518 1519 return 0; 1520 1521 err_m2m_ctx_release: 1522 v4l2_m2m_ctx_release(inst->m2m_ctx); 1523 err_m2m_dev_release: 1524 v4l2_m2m_release(inst->m2m_dev); 1525 err_ctrl_deinit: 1526 v4l2_ctrl_handler_free(&inst->ctrl_handler); 1527 err_free: 1528 kfree(inst); 1529 return ret; 1530 } 1531 1532 static int venc_close(struct file *file) 1533 { 1534 struct venus_inst *inst = to_inst(file); 1535 1536 venc_pm_get(inst); 1537 venus_close_common(inst, file); 1538 inst->enc_state = VENUS_ENC_STATE_DEINIT; 1539 venc_pm_put(inst, false); 1540 1541 kfree(inst); 1542 return 0; 1543 } 1544 1545 static const struct v4l2_file_operations venc_fops = { 1546 .owner = THIS_MODULE, 1547 .open = venc_open, 1548 .release = venc_close, 1549 .unlocked_ioctl = video_ioctl2, 1550 .poll = v4l2_m2m_fop_poll, 1551 .mmap = v4l2_m2m_fop_mmap, 1552 }; 1553 1554 static int venc_probe(struct platform_device *pdev) 1555 { 1556 struct device *dev = &pdev->dev; 1557 struct video_device *vdev; 1558 struct venus_core *core; 1559 int ret; 1560 1561 core = dev_get_drvdata(dev->parent); 1562 if (!core) 1563 return -EINVAL; 1564 1565 platform_set_drvdata(pdev, core); 1566 1567 if (core->pm_ops->venc_get) { 1568 ret = core->pm_ops->venc_get(dev); 1569 if (ret) 1570 return ret; 1571 } 1572 1573 vdev = video_device_alloc(); 1574 if (!vdev) 1575 return -ENOMEM; 1576 1577 strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); 1578 vdev->release = video_device_release; 1579 vdev->fops = &venc_fops; 1580 vdev->ioctl_ops = &venc_ioctl_ops; 1581 vdev->vfl_dir = VFL_DIR_M2M; 1582 vdev->v4l2_dev = &core->v4l2_dev; 1583 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1584 1585 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 1586 if (ret) 1587 goto err_vdev_release; 1588 1589 core->vdev_enc = vdev; 1590 core->dev_enc = dev; 1591 1592 video_set_drvdata(vdev, core); 1593 pm_runtime_set_autosuspend_delay(dev, 2000); 1594 pm_runtime_use_autosuspend(dev); 1595 pm_runtime_enable(dev); 1596 1597 return 0; 1598 1599 err_vdev_release: 1600 video_device_release(vdev); 1601 return ret; 1602 } 1603 1604 static void venc_remove(struct platform_device *pdev) 1605 { 1606 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); 1607 1608 video_unregister_device(core->vdev_enc); 1609 pm_runtime_disable(core->dev_enc); 1610 1611 if (core->pm_ops->venc_put) 1612 core->pm_ops->venc_put(core->dev_enc); 1613 } 1614 1615 static __maybe_unused int venc_runtime_suspend(struct device *dev) 1616 { 1617 struct venus_core *core = dev_get_drvdata(dev); 1618 const struct venus_pm_ops *pm_ops = core->pm_ops; 1619 int ret = 0; 1620 1621 if (pm_ops->venc_power) 1622 ret = pm_ops->venc_power(dev, POWER_OFF); 1623 1624 return ret; 1625 } 1626 1627 static __maybe_unused int venc_runtime_resume(struct device *dev) 1628 { 1629 struct venus_core *core = dev_get_drvdata(dev); 1630 const struct venus_pm_ops *pm_ops = core->pm_ops; 1631 int ret = 0; 1632 1633 if (pm_ops->venc_power) 1634 ret = pm_ops->venc_power(dev, POWER_ON); 1635 1636 return ret; 1637 } 1638 1639 static const struct dev_pm_ops venc_pm_ops = { 1640 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1641 pm_runtime_force_resume) 1642 SET_RUNTIME_PM_OPS(venc_runtime_suspend, venc_runtime_resume, NULL) 1643 }; 1644 1645 static const struct of_device_id venc_dt_match[] = { 1646 { .compatible = "venus-encoder" }, 1647 { } 1648 }; 1649 MODULE_DEVICE_TABLE(of, venc_dt_match); 1650 1651 static struct platform_driver qcom_venus_enc_driver = { 1652 .probe = venc_probe, 1653 .remove = venc_remove, 1654 .driver = { 1655 .name = "qcom-venus-encoder", 1656 .of_match_table = venc_dt_match, 1657 .pm = &venc_pm_ops, 1658 }, 1659 }; 1660 module_platform_driver(qcom_venus_enc_driver); 1661 1662 MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); 1663 MODULE_LICENSE("GPL v2"); 1664