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