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 u32 sizeimage; 298 299 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); 300 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 301 302 fmt = find_format(inst, pixmp->pixelformat, f->type); 303 if (!fmt) { 304 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 305 pixmp->pixelformat = V4L2_PIX_FMT_H264; 306 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 307 pixmp->pixelformat = V4L2_PIX_FMT_NV12; 308 else 309 return NULL; 310 fmt = find_format(inst, pixmp->pixelformat, f->type); 311 } 312 313 pixmp->width = clamp(pixmp->width, frame_width_min(inst), 314 frame_width_max(inst)); 315 pixmp->height = clamp(pixmp->height, frame_height_min(inst), 316 frame_height_max(inst)); 317 318 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 319 pixmp->height = ALIGN(pixmp->height, 32); 320 321 pixmp->width = ALIGN(pixmp->width, 2); 322 pixmp->height = ALIGN(pixmp->height, 2); 323 324 if (pixmp->field == V4L2_FIELD_ANY) 325 pixmp->field = V4L2_FIELD_NONE; 326 pixmp->num_planes = fmt->num_planes; 327 pixmp->flags = 0; 328 329 sizeimage = venus_helper_get_framesz(pixmp->pixelformat, 330 pixmp->width, 331 pixmp->height); 332 pfmt[0].sizeimage = max(ALIGN(pfmt[0].sizeimage, SZ_4K), sizeimage); 333 334 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 335 pfmt[0].bytesperline = ALIGN(pixmp->width, 128); 336 else 337 pfmt[0].bytesperline = 0; 338 339 return fmt; 340 } 341 342 static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 343 { 344 struct venus_inst *inst = to_inst(file); 345 346 venc_try_fmt_common(inst, f); 347 348 return 0; 349 } 350 351 static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 352 { 353 struct venus_inst *inst = to_inst(file); 354 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 355 struct v4l2_pix_format_mplane orig_pixmp; 356 const struct venus_format *fmt; 357 struct v4l2_format format; 358 u32 pixfmt_out = 0, pixfmt_cap = 0; 359 360 orig_pixmp = *pixmp; 361 362 fmt = venc_try_fmt_common(inst, f); 363 if (!fmt) 364 return -EINVAL; 365 366 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 367 pixfmt_out = pixmp->pixelformat; 368 pixfmt_cap = inst->fmt_cap->pixfmt; 369 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 370 pixfmt_cap = pixmp->pixelformat; 371 pixfmt_out = inst->fmt_out->pixfmt; 372 } 373 374 memset(&format, 0, sizeof(format)); 375 376 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 377 format.fmt.pix_mp.pixelformat = pixfmt_out; 378 format.fmt.pix_mp.width = orig_pixmp.width; 379 format.fmt.pix_mp.height = orig_pixmp.height; 380 venc_try_fmt_common(inst, &format); 381 382 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 383 inst->out_width = format.fmt.pix_mp.width; 384 inst->out_height = format.fmt.pix_mp.height; 385 inst->colorspace = pixmp->colorspace; 386 inst->ycbcr_enc = pixmp->ycbcr_enc; 387 inst->quantization = pixmp->quantization; 388 inst->xfer_func = pixmp->xfer_func; 389 } 390 391 memset(&format, 0, sizeof(format)); 392 393 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 394 format.fmt.pix_mp.pixelformat = pixfmt_cap; 395 format.fmt.pix_mp.width = orig_pixmp.width; 396 format.fmt.pix_mp.height = orig_pixmp.height; 397 venc_try_fmt_common(inst, &format); 398 399 inst->width = format.fmt.pix_mp.width; 400 inst->height = format.fmt.pix_mp.height; 401 402 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 403 inst->fmt_out = fmt; 404 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 405 inst->fmt_cap = fmt; 406 inst->output_buf_size = pixmp->plane_fmt[0].sizeimage; 407 } 408 409 return 0; 410 } 411 412 static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 413 { 414 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 415 struct venus_inst *inst = to_inst(file); 416 const struct venus_format *fmt; 417 418 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 419 fmt = inst->fmt_cap; 420 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 421 fmt = inst->fmt_out; 422 else 423 return -EINVAL; 424 425 pixmp->pixelformat = fmt->pixfmt; 426 427 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 428 pixmp->width = inst->width; 429 pixmp->height = inst->height; 430 pixmp->colorspace = inst->colorspace; 431 pixmp->ycbcr_enc = inst->ycbcr_enc; 432 pixmp->quantization = inst->quantization; 433 pixmp->xfer_func = inst->xfer_func; 434 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 435 pixmp->width = inst->out_width; 436 pixmp->height = inst->out_height; 437 } 438 439 venc_try_fmt_common(inst, f); 440 441 return 0; 442 } 443 444 static int 445 venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 446 { 447 struct venus_inst *inst = to_inst(file); 448 449 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 450 return -EINVAL; 451 452 switch (s->target) { 453 case V4L2_SEL_TGT_CROP_DEFAULT: 454 case V4L2_SEL_TGT_CROP_BOUNDS: 455 s->r.width = inst->width; 456 s->r.height = inst->height; 457 break; 458 case V4L2_SEL_TGT_CROP: 459 s->r.width = inst->out_width; 460 s->r.height = inst->out_height; 461 break; 462 default: 463 return -EINVAL; 464 } 465 466 s->r.top = 0; 467 s->r.left = 0; 468 469 return 0; 470 } 471 472 static int 473 venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 474 { 475 struct venus_inst *inst = to_inst(file); 476 477 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 478 return -EINVAL; 479 480 switch (s->target) { 481 case V4L2_SEL_TGT_CROP: 482 if (s->r.width != inst->out_width || 483 s->r.height != inst->out_height || 484 s->r.top != 0 || s->r.left != 0) 485 return -EINVAL; 486 break; 487 default: 488 return -EINVAL; 489 } 490 491 return 0; 492 } 493 494 static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 495 { 496 struct venus_inst *inst = to_inst(file); 497 struct v4l2_outputparm *out = &a->parm.output; 498 struct v4l2_fract *timeperframe = &out->timeperframe; 499 u64 us_per_frame, fps; 500 501 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 502 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 503 return -EINVAL; 504 505 memset(out->reserved, 0, sizeof(out->reserved)); 506 507 if (!timeperframe->denominator) 508 timeperframe->denominator = inst->timeperframe.denominator; 509 if (!timeperframe->numerator) 510 timeperframe->numerator = inst->timeperframe.numerator; 511 512 out->capability = V4L2_CAP_TIMEPERFRAME; 513 514 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; 515 do_div(us_per_frame, timeperframe->denominator); 516 517 if (!us_per_frame) 518 return -EINVAL; 519 520 fps = (u64)USEC_PER_SEC; 521 do_div(fps, us_per_frame); 522 523 inst->timeperframe = *timeperframe; 524 inst->fps = fps; 525 526 return 0; 527 } 528 529 static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 530 { 531 struct venus_inst *inst = to_inst(file); 532 533 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 534 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 535 return -EINVAL; 536 537 a->parm.output.capability |= V4L2_CAP_TIMEPERFRAME; 538 a->parm.output.timeperframe = inst->timeperframe; 539 540 return 0; 541 } 542 543 static int venc_enum_framesizes(struct file *file, void *fh, 544 struct v4l2_frmsizeenum *fsize) 545 { 546 struct venus_inst *inst = to_inst(file); 547 const struct venus_format *fmt; 548 549 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 550 551 fmt = find_format(inst, fsize->pixel_format, 552 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 553 if (!fmt) { 554 fmt = find_format(inst, fsize->pixel_format, 555 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 556 if (!fmt) 557 return -EINVAL; 558 } 559 560 if (fsize->index) 561 return -EINVAL; 562 563 fsize->stepwise.min_width = frame_width_min(inst); 564 fsize->stepwise.max_width = frame_width_max(inst); 565 fsize->stepwise.step_width = frame_width_step(inst); 566 fsize->stepwise.min_height = frame_height_min(inst); 567 fsize->stepwise.max_height = frame_height_max(inst); 568 fsize->stepwise.step_height = frame_height_step(inst); 569 570 return 0; 571 } 572 573 static int venc_enum_frameintervals(struct file *file, void *fh, 574 struct v4l2_frmivalenum *fival) 575 { 576 struct venus_inst *inst = to_inst(file); 577 const struct venus_format *fmt; 578 579 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 580 581 fmt = find_format(inst, fival->pixel_format, 582 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 583 if (!fmt) { 584 fmt = find_format(inst, fival->pixel_format, 585 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 586 if (!fmt) 587 return -EINVAL; 588 } 589 590 if (fival->index) 591 return -EINVAL; 592 593 if (!fival->width || !fival->height) 594 return -EINVAL; 595 596 if (fival->width > frame_width_max(inst) || 597 fival->width < frame_width_min(inst) || 598 fival->height > frame_height_max(inst) || 599 fival->height < frame_height_min(inst)) 600 return -EINVAL; 601 602 fival->stepwise.min.numerator = 1; 603 fival->stepwise.min.denominator = frate_max(inst); 604 fival->stepwise.max.numerator = 1; 605 fival->stepwise.max.denominator = frate_min(inst); 606 fival->stepwise.step.numerator = 1; 607 fival->stepwise.step.denominator = frate_max(inst); 608 609 return 0; 610 } 611 612 static const struct v4l2_ioctl_ops venc_ioctl_ops = { 613 .vidioc_querycap = venc_querycap, 614 .vidioc_enum_fmt_vid_cap = venc_enum_fmt, 615 .vidioc_enum_fmt_vid_out = venc_enum_fmt, 616 .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt, 617 .vidioc_s_fmt_vid_out_mplane = venc_s_fmt, 618 .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt, 619 .vidioc_g_fmt_vid_out_mplane = venc_g_fmt, 620 .vidioc_try_fmt_vid_cap_mplane = venc_try_fmt, 621 .vidioc_try_fmt_vid_out_mplane = venc_try_fmt, 622 .vidioc_g_selection = venc_g_selection, 623 .vidioc_s_selection = venc_s_selection, 624 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 625 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 626 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 627 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 628 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 629 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 630 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 631 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 632 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 633 .vidioc_s_parm = venc_s_parm, 634 .vidioc_g_parm = venc_g_parm, 635 .vidioc_enum_framesizes = venc_enum_framesizes, 636 .vidioc_enum_frameintervals = venc_enum_frameintervals, 637 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 638 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 639 }; 640 641 static int venc_set_properties(struct venus_inst *inst) 642 { 643 struct venc_controls *ctr = &inst->controls.enc; 644 struct hfi_intra_period intra_period; 645 struct hfi_profile_level pl; 646 struct hfi_framerate frate; 647 struct hfi_bitrate brate; 648 struct hfi_idr_period idrp; 649 struct hfi_quantization quant; 650 struct hfi_quantization_range quant_range; 651 u32 ptype, rate_control, bitrate, profile = 0, level = 0; 652 int ret; 653 654 ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); 655 if (ret) 656 return ret; 657 658 ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2); 659 if (ret) 660 return ret; 661 662 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; 663 frate.buffer_type = HFI_BUFFER_OUTPUT; 664 frate.framerate = inst->fps * (1 << 16); 665 666 ret = hfi_session_set_property(inst, ptype, &frate); 667 if (ret) 668 return ret; 669 670 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { 671 struct hfi_h264_vui_timing_info info; 672 struct hfi_h264_entropy_control entropy; 673 struct hfi_h264_db_control deblock; 674 675 ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO; 676 info.enable = 1; 677 info.fixed_framerate = 1; 678 info.time_scale = NSEC_PER_SEC; 679 680 ret = hfi_session_set_property(inst, ptype, &info); 681 if (ret) 682 return ret; 683 684 ptype = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL; 685 entropy.entropy_mode = venc_v4l2_to_hfi( 686 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, 687 ctr->h264_entropy_mode); 688 entropy.cabac_model = HFI_H264_CABAC_MODEL_0; 689 690 ret = hfi_session_set_property(inst, ptype, &entropy); 691 if (ret) 692 return ret; 693 694 ptype = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL; 695 deblock.mode = venc_v4l2_to_hfi( 696 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, 697 ctr->h264_loop_filter_mode); 698 deblock.slice_alpha_offset = ctr->h264_loop_filter_alpha; 699 deblock.slice_beta_offset = ctr->h264_loop_filter_beta; 700 701 ret = hfi_session_set_property(inst, ptype, &deblock); 702 if (ret) 703 return ret; 704 } 705 706 /* IDR periodicity, n: 707 * n = 0 - only the first I-frame is IDR frame 708 * n = 1 - all I-frames will be IDR frames 709 * n > 1 - every n-th I-frame will be IDR frame 710 */ 711 ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD; 712 idrp.idr_period = 0; 713 ret = hfi_session_set_property(inst, ptype, &idrp); 714 if (ret) 715 return ret; 716 717 if (ctr->num_b_frames) { 718 u32 max_num_b_frames = NUM_B_FRAMES_MAX; 719 720 ptype = HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES; 721 ret = hfi_session_set_property(inst, ptype, &max_num_b_frames); 722 if (ret) 723 return ret; 724 } 725 726 ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD; 727 intra_period.pframes = ctr->num_p_frames; 728 intra_period.bframes = ctr->num_b_frames; 729 730 ret = hfi_session_set_property(inst, ptype, &intra_period); 731 if (ret) 732 return ret; 733 734 if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) 735 rate_control = HFI_RATE_CONTROL_VBR_CFR; 736 else 737 rate_control = HFI_RATE_CONTROL_CBR_CFR; 738 739 ptype = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL; 740 ret = hfi_session_set_property(inst, ptype, &rate_control); 741 if (ret) 742 return ret; 743 744 if (!ctr->bitrate) 745 bitrate = 64000; 746 else 747 bitrate = ctr->bitrate; 748 749 ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; 750 brate.bitrate = bitrate; 751 brate.layer_id = 0; 752 753 ret = hfi_session_set_property(inst, ptype, &brate); 754 if (ret) 755 return ret; 756 757 if (!ctr->bitrate_peak) 758 bitrate *= 2; 759 else 760 bitrate = ctr->bitrate_peak; 761 762 ptype = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE; 763 brate.bitrate = bitrate; 764 brate.layer_id = 0; 765 766 ret = hfi_session_set_property(inst, ptype, &brate); 767 if (ret) 768 return ret; 769 770 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP; 771 quant.qp_i = ctr->h264_i_qp; 772 quant.qp_p = ctr->h264_p_qp; 773 quant.qp_b = ctr->h264_b_qp; 774 quant.layer_id = 0; 775 ret = hfi_session_set_property(inst, ptype, &quant); 776 if (ret) 777 return ret; 778 779 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; 780 quant_range.min_qp = ctr->h264_min_qp; 781 quant_range.max_qp = ctr->h264_max_qp; 782 quant_range.layer_id = 0; 783 ret = hfi_session_set_property(inst, ptype, &quant_range); 784 if (ret) 785 return ret; 786 787 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { 788 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_PROFILE, 789 ctr->profile.h264); 790 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_LEVEL, 791 ctr->level.h264); 792 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { 793 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_VP8_PROFILE, 794 ctr->profile.vpx); 795 level = 0; 796 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_MPEG4) { 797 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, 798 ctr->profile.mpeg4); 799 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, 800 ctr->level.mpeg4); 801 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H263) { 802 profile = 0; 803 level = 0; 804 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 805 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, 806 ctr->profile.hevc); 807 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, 808 ctr->level.hevc); 809 } 810 811 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 812 pl.profile = profile; 813 pl.level = level; 814 815 ret = hfi_session_set_property(inst, ptype, &pl); 816 if (ret) 817 return ret; 818 819 return 0; 820 } 821 822 static int venc_init_session(struct venus_inst *inst) 823 { 824 int ret; 825 826 ret = hfi_session_init(inst, inst->fmt_cap->pixfmt); 827 if (ret) 828 return ret; 829 830 ret = venus_helper_set_input_resolution(inst, inst->width, 831 inst->height); 832 if (ret) 833 goto deinit; 834 835 ret = venus_helper_set_output_resolution(inst, inst->width, 836 inst->height, 837 HFI_BUFFER_OUTPUT); 838 if (ret) 839 goto deinit; 840 841 ret = venus_helper_set_color_format(inst, inst->fmt_out->pixfmt); 842 if (ret) 843 goto deinit; 844 845 ret = venc_set_properties(inst); 846 if (ret) 847 goto deinit; 848 849 return 0; 850 deinit: 851 hfi_session_deinit(inst); 852 return ret; 853 } 854 855 static int venc_out_num_buffers(struct venus_inst *inst, unsigned int *num) 856 { 857 struct hfi_buffer_requirements bufreq; 858 int ret; 859 860 ret = venc_init_session(inst); 861 if (ret) 862 return ret; 863 864 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 865 866 *num = bufreq.count_actual; 867 868 hfi_session_deinit(inst); 869 870 return ret; 871 } 872 873 static int venc_queue_setup(struct vb2_queue *q, 874 unsigned int *num_buffers, unsigned int *num_planes, 875 unsigned int sizes[], struct device *alloc_devs[]) 876 { 877 struct venus_inst *inst = vb2_get_drv_priv(q); 878 unsigned int num, min = 4; 879 int ret = 0; 880 881 if (*num_planes) { 882 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 883 *num_planes != inst->fmt_out->num_planes) 884 return -EINVAL; 885 886 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 887 *num_planes != inst->fmt_cap->num_planes) 888 return -EINVAL; 889 890 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 891 sizes[0] < inst->input_buf_size) 892 return -EINVAL; 893 894 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 895 sizes[0] < inst->output_buf_size) 896 return -EINVAL; 897 898 return 0; 899 } 900 901 switch (q->type) { 902 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 903 *num_planes = inst->fmt_out->num_planes; 904 905 ret = venc_out_num_buffers(inst, &num); 906 if (ret) 907 break; 908 909 num = max(num, min); 910 *num_buffers = max(*num_buffers, num); 911 inst->num_input_bufs = *num_buffers; 912 913 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, 914 inst->width, 915 inst->height); 916 inst->input_buf_size = sizes[0]; 917 break; 918 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 919 *num_planes = inst->fmt_cap->num_planes; 920 *num_buffers = max(*num_buffers, min); 921 inst->num_output_bufs = *num_buffers; 922 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, 923 inst->width, 924 inst->height); 925 sizes[0] = max(sizes[0], inst->output_buf_size); 926 inst->output_buf_size = sizes[0]; 927 break; 928 default: 929 ret = -EINVAL; 930 break; 931 } 932 933 return ret; 934 } 935 936 static int venc_verify_conf(struct venus_inst *inst) 937 { 938 enum hfi_version ver = inst->core->res->hfi_version; 939 struct hfi_buffer_requirements bufreq; 940 int ret; 941 942 if (!inst->num_input_bufs || !inst->num_output_bufs) 943 return -EINVAL; 944 945 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 946 if (ret) 947 return ret; 948 949 if (inst->num_output_bufs < bufreq.count_actual || 950 inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 951 return -EINVAL; 952 953 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 954 if (ret) 955 return ret; 956 957 if (inst->num_input_bufs < bufreq.count_actual || 958 inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 959 return -EINVAL; 960 961 return 0; 962 } 963 964 static int venc_start_streaming(struct vb2_queue *q, unsigned int count) 965 { 966 struct venus_inst *inst = vb2_get_drv_priv(q); 967 int ret; 968 969 mutex_lock(&inst->lock); 970 971 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 972 inst->streamon_out = 1; 973 else 974 inst->streamon_cap = 1; 975 976 if (!(inst->streamon_out & inst->streamon_cap)) { 977 mutex_unlock(&inst->lock); 978 return 0; 979 } 980 981 venus_helper_init_instance(inst); 982 983 inst->sequence_cap = 0; 984 inst->sequence_out = 0; 985 986 ret = venc_init_session(inst); 987 if (ret) 988 goto bufs_done; 989 990 ret = venc_set_properties(inst); 991 if (ret) 992 goto deinit_sess; 993 994 ret = venc_verify_conf(inst); 995 if (ret) 996 goto deinit_sess; 997 998 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, 999 inst->num_output_bufs, 0); 1000 if (ret) 1001 goto deinit_sess; 1002 1003 ret = venus_helper_vb2_start_streaming(inst); 1004 if (ret) 1005 goto deinit_sess; 1006 1007 mutex_unlock(&inst->lock); 1008 1009 return 0; 1010 1011 deinit_sess: 1012 hfi_session_deinit(inst); 1013 bufs_done: 1014 venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED); 1015 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1016 inst->streamon_out = 0; 1017 else 1018 inst->streamon_cap = 0; 1019 mutex_unlock(&inst->lock); 1020 return ret; 1021 } 1022 1023 static const struct vb2_ops venc_vb2_ops = { 1024 .queue_setup = venc_queue_setup, 1025 .buf_init = venus_helper_vb2_buf_init, 1026 .buf_prepare = venus_helper_vb2_buf_prepare, 1027 .start_streaming = venc_start_streaming, 1028 .stop_streaming = venus_helper_vb2_stop_streaming, 1029 .buf_queue = venus_helper_vb2_buf_queue, 1030 }; 1031 1032 static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type, 1033 u32 tag, u32 bytesused, u32 data_offset, u32 flags, 1034 u32 hfi_flags, u64 timestamp_us) 1035 { 1036 struct vb2_v4l2_buffer *vbuf; 1037 struct vb2_buffer *vb; 1038 unsigned int type; 1039 1040 if (buf_type == HFI_BUFFER_INPUT) 1041 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1042 else 1043 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1044 1045 vbuf = venus_helper_find_buf(inst, type, tag); 1046 if (!vbuf) 1047 return; 1048 1049 vbuf->flags = flags; 1050 1051 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1052 vb = &vbuf->vb2_buf; 1053 vb2_set_plane_payload(vb, 0, bytesused + data_offset); 1054 vb->planes[0].data_offset = data_offset; 1055 vb->timestamp = timestamp_us * NSEC_PER_USEC; 1056 vbuf->sequence = inst->sequence_cap++; 1057 } else { 1058 vbuf->sequence = inst->sequence_out++; 1059 } 1060 1061 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 1062 } 1063 1064 static void venc_event_notify(struct venus_inst *inst, u32 event, 1065 struct hfi_event_data *data) 1066 { 1067 struct device *dev = inst->core->dev_enc; 1068 1069 if (event == EVT_SESSION_ERROR) { 1070 inst->session_error = true; 1071 dev_err(dev, "enc: event session error %x\n", inst->error); 1072 } 1073 } 1074 1075 static const struct hfi_inst_ops venc_hfi_ops = { 1076 .buf_done = venc_buf_done, 1077 .event_notify = venc_event_notify, 1078 }; 1079 1080 static const struct v4l2_m2m_ops venc_m2m_ops = { 1081 .device_run = venus_helper_m2m_device_run, 1082 .job_abort = venus_helper_m2m_job_abort, 1083 }; 1084 1085 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, 1086 struct vb2_queue *dst_vq) 1087 { 1088 struct venus_inst *inst = priv; 1089 int ret; 1090 1091 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1092 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1093 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1094 src_vq->ops = &venc_vb2_ops; 1095 src_vq->mem_ops = &vb2_dma_sg_memops; 1096 src_vq->drv_priv = inst; 1097 src_vq->buf_struct_size = sizeof(struct venus_buffer); 1098 src_vq->allow_zero_bytesused = 1; 1099 src_vq->min_buffers_needed = 1; 1100 src_vq->dev = inst->core->dev; 1101 if (inst->core->res->hfi_version == HFI_VERSION_1XX) 1102 src_vq->bidirectional = 1; 1103 ret = vb2_queue_init(src_vq); 1104 if (ret) 1105 return ret; 1106 1107 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1108 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1109 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1110 dst_vq->ops = &venc_vb2_ops; 1111 dst_vq->mem_ops = &vb2_dma_sg_memops; 1112 dst_vq->drv_priv = inst; 1113 dst_vq->buf_struct_size = sizeof(struct venus_buffer); 1114 dst_vq->allow_zero_bytesused = 1; 1115 dst_vq->min_buffers_needed = 1; 1116 dst_vq->dev = inst->core->dev; 1117 ret = vb2_queue_init(dst_vq); 1118 if (ret) { 1119 vb2_queue_release(src_vq); 1120 return ret; 1121 } 1122 1123 return 0; 1124 } 1125 1126 static void venc_inst_init(struct venus_inst *inst) 1127 { 1128 inst->fmt_cap = &venc_formats[2]; 1129 inst->fmt_out = &venc_formats[0]; 1130 inst->width = 1280; 1131 inst->height = ALIGN(720, 32); 1132 inst->out_width = 1280; 1133 inst->out_height = 720; 1134 inst->fps = 15; 1135 inst->timeperframe.numerator = 1; 1136 inst->timeperframe.denominator = 15; 1137 inst->hfi_codec = HFI_VIDEO_CODEC_H264; 1138 } 1139 1140 static int venc_open(struct file *file) 1141 { 1142 struct venus_core *core = video_drvdata(file); 1143 struct venus_inst *inst; 1144 int ret; 1145 1146 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 1147 if (!inst) 1148 return -ENOMEM; 1149 1150 INIT_LIST_HEAD(&inst->dpbbufs); 1151 INIT_LIST_HEAD(&inst->registeredbufs); 1152 INIT_LIST_HEAD(&inst->internalbufs); 1153 INIT_LIST_HEAD(&inst->list); 1154 mutex_init(&inst->lock); 1155 1156 inst->core = core; 1157 inst->session_type = VIDC_SESSION_TYPE_ENC; 1158 1159 venus_helper_init_instance(inst); 1160 1161 ret = pm_runtime_get_sync(core->dev_enc); 1162 if (ret < 0) 1163 goto err_free_inst; 1164 1165 ret = venc_ctrl_init(inst); 1166 if (ret) 1167 goto err_put_sync; 1168 1169 ret = hfi_session_create(inst, &venc_hfi_ops); 1170 if (ret) 1171 goto err_ctrl_deinit; 1172 1173 venc_inst_init(inst); 1174 1175 /* 1176 * create m2m device for every instance, the m2m context scheduling 1177 * is made by firmware side so we do not need to care about. 1178 */ 1179 inst->m2m_dev = v4l2_m2m_init(&venc_m2m_ops); 1180 if (IS_ERR(inst->m2m_dev)) { 1181 ret = PTR_ERR(inst->m2m_dev); 1182 goto err_session_destroy; 1183 } 1184 1185 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1186 if (IS_ERR(inst->m2m_ctx)) { 1187 ret = PTR_ERR(inst->m2m_ctx); 1188 goto err_m2m_release; 1189 } 1190 1191 v4l2_fh_init(&inst->fh, core->vdev_enc); 1192 1193 inst->fh.ctrl_handler = &inst->ctrl_handler; 1194 v4l2_fh_add(&inst->fh); 1195 inst->fh.m2m_ctx = inst->m2m_ctx; 1196 file->private_data = &inst->fh; 1197 1198 return 0; 1199 1200 err_m2m_release: 1201 v4l2_m2m_release(inst->m2m_dev); 1202 err_session_destroy: 1203 hfi_session_destroy(inst); 1204 err_ctrl_deinit: 1205 venc_ctrl_deinit(inst); 1206 err_put_sync: 1207 pm_runtime_put_sync(core->dev_enc); 1208 err_free_inst: 1209 kfree(inst); 1210 return ret; 1211 } 1212 1213 static int venc_close(struct file *file) 1214 { 1215 struct venus_inst *inst = to_inst(file); 1216 1217 v4l2_m2m_ctx_release(inst->m2m_ctx); 1218 v4l2_m2m_release(inst->m2m_dev); 1219 venc_ctrl_deinit(inst); 1220 hfi_session_destroy(inst); 1221 mutex_destroy(&inst->lock); 1222 v4l2_fh_del(&inst->fh); 1223 v4l2_fh_exit(&inst->fh); 1224 1225 pm_runtime_put_sync(inst->core->dev_enc); 1226 1227 kfree(inst); 1228 return 0; 1229 } 1230 1231 static const struct v4l2_file_operations venc_fops = { 1232 .owner = THIS_MODULE, 1233 .open = venc_open, 1234 .release = venc_close, 1235 .unlocked_ioctl = video_ioctl2, 1236 .poll = v4l2_m2m_fop_poll, 1237 .mmap = v4l2_m2m_fop_mmap, 1238 #ifdef CONFIG_COMPAT 1239 .compat_ioctl32 = v4l2_compat_ioctl32, 1240 #endif 1241 }; 1242 1243 static int venc_probe(struct platform_device *pdev) 1244 { 1245 struct device *dev = &pdev->dev; 1246 struct video_device *vdev; 1247 struct venus_core *core; 1248 int ret; 1249 1250 if (!dev->parent) 1251 return -EPROBE_DEFER; 1252 1253 core = dev_get_drvdata(dev->parent); 1254 if (!core) 1255 return -EPROBE_DEFER; 1256 1257 if (IS_V3(core) || IS_V4(core)) { 1258 core->core1_clk = devm_clk_get(dev, "core"); 1259 if (IS_ERR(core->core1_clk)) 1260 return PTR_ERR(core->core1_clk); 1261 } 1262 1263 if (IS_V4(core)) { 1264 core->core1_bus_clk = devm_clk_get(dev, "bus"); 1265 if (IS_ERR(core->core1_bus_clk)) 1266 return PTR_ERR(core->core1_bus_clk); 1267 } 1268 1269 platform_set_drvdata(pdev, core); 1270 1271 vdev = video_device_alloc(); 1272 if (!vdev) 1273 return -ENOMEM; 1274 1275 strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); 1276 vdev->release = video_device_release; 1277 vdev->fops = &venc_fops; 1278 vdev->ioctl_ops = &venc_ioctl_ops; 1279 vdev->vfl_dir = VFL_DIR_M2M; 1280 vdev->v4l2_dev = &core->v4l2_dev; 1281 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1282 1283 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 1284 if (ret) 1285 goto err_vdev_release; 1286 1287 core->vdev_enc = vdev; 1288 core->dev_enc = dev; 1289 1290 video_set_drvdata(vdev, core); 1291 pm_runtime_enable(dev); 1292 1293 return 0; 1294 1295 err_vdev_release: 1296 video_device_release(vdev); 1297 return ret; 1298 } 1299 1300 static int venc_remove(struct platform_device *pdev) 1301 { 1302 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); 1303 1304 video_unregister_device(core->vdev_enc); 1305 pm_runtime_disable(core->dev_enc); 1306 1307 return 0; 1308 } 1309 1310 static __maybe_unused int venc_runtime_suspend(struct device *dev) 1311 { 1312 struct venus_core *core = dev_get_drvdata(dev); 1313 int ret; 1314 1315 if (IS_V1(core)) 1316 return 0; 1317 1318 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1319 if (ret) 1320 return ret; 1321 1322 if (IS_V4(core)) 1323 clk_disable_unprepare(core->core1_bus_clk); 1324 1325 clk_disable_unprepare(core->core1_clk); 1326 1327 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1328 } 1329 1330 static __maybe_unused int venc_runtime_resume(struct device *dev) 1331 { 1332 struct venus_core *core = dev_get_drvdata(dev); 1333 int ret; 1334 1335 if (IS_V1(core)) 1336 return 0; 1337 1338 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1339 if (ret) 1340 return ret; 1341 1342 ret = clk_prepare_enable(core->core1_clk); 1343 if (ret) 1344 goto err_power_disable; 1345 1346 if (IS_V4(core)) 1347 ret = clk_prepare_enable(core->core1_bus_clk); 1348 1349 if (ret) 1350 goto err_unprepare_core1; 1351 1352 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1353 1354 err_unprepare_core1: 1355 clk_disable_unprepare(core->core1_clk); 1356 err_power_disable: 1357 venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1358 return ret; 1359 } 1360 1361 static const struct dev_pm_ops venc_pm_ops = { 1362 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1363 pm_runtime_force_resume) 1364 SET_RUNTIME_PM_OPS(venc_runtime_suspend, venc_runtime_resume, NULL) 1365 }; 1366 1367 static const struct of_device_id venc_dt_match[] = { 1368 { .compatible = "venus-encoder" }, 1369 { } 1370 }; 1371 MODULE_DEVICE_TABLE(of, venc_dt_match); 1372 1373 static struct platform_driver qcom_venus_enc_driver = { 1374 .probe = venc_probe, 1375 .remove = venc_remove, 1376 .driver = { 1377 .name = "qcom-venus-encoder", 1378 .of_match_table = venc_dt_match, 1379 .pm = &venc_pm_ops, 1380 }, 1381 }; 1382 module_platform_driver(qcom_venus_enc_driver); 1383 1384 MODULE_ALIAS("platform:qcom-venus-encoder"); 1385 MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); 1386 MODULE_LICENSE("GPL v2"); 1387