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