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 = venus_helper_init_codec_freq_data(inst); 846 if (ret) 847 goto deinit; 848 849 ret = venc_set_properties(inst); 850 if (ret) 851 goto deinit; 852 853 return 0; 854 deinit: 855 hfi_session_deinit(inst); 856 return ret; 857 } 858 859 static int venc_out_num_buffers(struct venus_inst *inst, unsigned int *num) 860 { 861 struct hfi_buffer_requirements bufreq; 862 int ret; 863 864 ret = venc_init_session(inst); 865 if (ret) 866 return ret; 867 868 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 869 870 *num = bufreq.count_actual; 871 872 hfi_session_deinit(inst); 873 874 return ret; 875 } 876 877 static int venc_queue_setup(struct vb2_queue *q, 878 unsigned int *num_buffers, unsigned int *num_planes, 879 unsigned int sizes[], struct device *alloc_devs[]) 880 { 881 struct venus_inst *inst = vb2_get_drv_priv(q); 882 unsigned int num, min = 4; 883 int ret = 0; 884 885 if (*num_planes) { 886 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 887 *num_planes != inst->fmt_out->num_planes) 888 return -EINVAL; 889 890 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 891 *num_planes != inst->fmt_cap->num_planes) 892 return -EINVAL; 893 894 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 895 sizes[0] < inst->input_buf_size) 896 return -EINVAL; 897 898 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 899 sizes[0] < inst->output_buf_size) 900 return -EINVAL; 901 902 return 0; 903 } 904 905 switch (q->type) { 906 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 907 *num_planes = inst->fmt_out->num_planes; 908 909 ret = venc_out_num_buffers(inst, &num); 910 if (ret) 911 break; 912 913 num = max(num, min); 914 *num_buffers = max(*num_buffers, num); 915 inst->num_input_bufs = *num_buffers; 916 917 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, 918 inst->width, 919 inst->height); 920 inst->input_buf_size = sizes[0]; 921 break; 922 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 923 *num_planes = inst->fmt_cap->num_planes; 924 *num_buffers = max(*num_buffers, min); 925 inst->num_output_bufs = *num_buffers; 926 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, 927 inst->width, 928 inst->height); 929 sizes[0] = max(sizes[0], inst->output_buf_size); 930 inst->output_buf_size = sizes[0]; 931 break; 932 default: 933 ret = -EINVAL; 934 break; 935 } 936 937 return ret; 938 } 939 940 static int venc_verify_conf(struct venus_inst *inst) 941 { 942 enum hfi_version ver = inst->core->res->hfi_version; 943 struct hfi_buffer_requirements bufreq; 944 int ret; 945 946 if (!inst->num_input_bufs || !inst->num_output_bufs) 947 return -EINVAL; 948 949 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 950 if (ret) 951 return ret; 952 953 if (inst->num_output_bufs < bufreq.count_actual || 954 inst->num_output_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 955 return -EINVAL; 956 957 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 958 if (ret) 959 return ret; 960 961 if (inst->num_input_bufs < bufreq.count_actual || 962 inst->num_input_bufs < HFI_BUFREQ_COUNT_MIN(&bufreq, ver)) 963 return -EINVAL; 964 965 return 0; 966 } 967 968 static int venc_start_streaming(struct vb2_queue *q, unsigned int count) 969 { 970 struct venus_inst *inst = vb2_get_drv_priv(q); 971 int ret; 972 973 mutex_lock(&inst->lock); 974 975 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 976 inst->streamon_out = 1; 977 else 978 inst->streamon_cap = 1; 979 980 if (!(inst->streamon_out & inst->streamon_cap)) { 981 mutex_unlock(&inst->lock); 982 return 0; 983 } 984 985 venus_helper_init_instance(inst); 986 987 inst->sequence_cap = 0; 988 inst->sequence_out = 0; 989 990 ret = venc_init_session(inst); 991 if (ret) 992 goto bufs_done; 993 994 ret = venc_set_properties(inst); 995 if (ret) 996 goto deinit_sess; 997 998 ret = venc_verify_conf(inst); 999 if (ret) 1000 goto deinit_sess; 1001 1002 ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, 1003 inst->num_output_bufs, 0); 1004 if (ret) 1005 goto deinit_sess; 1006 1007 ret = venus_helper_vb2_start_streaming(inst); 1008 if (ret) 1009 goto deinit_sess; 1010 1011 mutex_unlock(&inst->lock); 1012 1013 return 0; 1014 1015 deinit_sess: 1016 hfi_session_deinit(inst); 1017 bufs_done: 1018 venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED); 1019 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 1020 inst->streamon_out = 0; 1021 else 1022 inst->streamon_cap = 0; 1023 mutex_unlock(&inst->lock); 1024 return ret; 1025 } 1026 1027 static const struct vb2_ops venc_vb2_ops = { 1028 .queue_setup = venc_queue_setup, 1029 .buf_init = venus_helper_vb2_buf_init, 1030 .buf_prepare = venus_helper_vb2_buf_prepare, 1031 .start_streaming = venc_start_streaming, 1032 .stop_streaming = venus_helper_vb2_stop_streaming, 1033 .buf_queue = venus_helper_vb2_buf_queue, 1034 }; 1035 1036 static void venc_buf_done(struct venus_inst *inst, unsigned int buf_type, 1037 u32 tag, u32 bytesused, u32 data_offset, u32 flags, 1038 u32 hfi_flags, u64 timestamp_us) 1039 { 1040 struct vb2_v4l2_buffer *vbuf; 1041 struct vb2_buffer *vb; 1042 unsigned int type; 1043 1044 if (buf_type == HFI_BUFFER_INPUT) 1045 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1046 else 1047 type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1048 1049 vbuf = venus_helper_find_buf(inst, type, tag); 1050 if (!vbuf) 1051 return; 1052 1053 vbuf->flags = flags; 1054 1055 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 1056 vb = &vbuf->vb2_buf; 1057 vb2_set_plane_payload(vb, 0, bytesused + data_offset); 1058 vb->planes[0].data_offset = data_offset; 1059 vb->timestamp = timestamp_us * NSEC_PER_USEC; 1060 vbuf->sequence = inst->sequence_cap++; 1061 } else { 1062 vbuf->sequence = inst->sequence_out++; 1063 } 1064 1065 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); 1066 } 1067 1068 static void venc_event_notify(struct venus_inst *inst, u32 event, 1069 struct hfi_event_data *data) 1070 { 1071 struct device *dev = inst->core->dev_enc; 1072 1073 if (event == EVT_SESSION_ERROR) { 1074 inst->session_error = true; 1075 dev_err(dev, "enc: event session error %x\n", inst->error); 1076 } 1077 } 1078 1079 static const struct hfi_inst_ops venc_hfi_ops = { 1080 .buf_done = venc_buf_done, 1081 .event_notify = venc_event_notify, 1082 }; 1083 1084 static const struct v4l2_m2m_ops venc_m2m_ops = { 1085 .device_run = venus_helper_m2m_device_run, 1086 .job_abort = venus_helper_m2m_job_abort, 1087 }; 1088 1089 static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, 1090 struct vb2_queue *dst_vq) 1091 { 1092 struct venus_inst *inst = priv; 1093 int ret; 1094 1095 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 1096 src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1097 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1098 src_vq->ops = &venc_vb2_ops; 1099 src_vq->mem_ops = &vb2_dma_sg_memops; 1100 src_vq->drv_priv = inst; 1101 src_vq->buf_struct_size = sizeof(struct venus_buffer); 1102 src_vq->allow_zero_bytesused = 1; 1103 src_vq->min_buffers_needed = 1; 1104 src_vq->dev = inst->core->dev; 1105 if (inst->core->res->hfi_version == HFI_VERSION_1XX) 1106 src_vq->bidirectional = 1; 1107 ret = vb2_queue_init(src_vq); 1108 if (ret) 1109 return ret; 1110 1111 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 1112 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; 1113 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1114 dst_vq->ops = &venc_vb2_ops; 1115 dst_vq->mem_ops = &vb2_dma_sg_memops; 1116 dst_vq->drv_priv = inst; 1117 dst_vq->buf_struct_size = sizeof(struct venus_buffer); 1118 dst_vq->allow_zero_bytesused = 1; 1119 dst_vq->min_buffers_needed = 1; 1120 dst_vq->dev = inst->core->dev; 1121 ret = vb2_queue_init(dst_vq); 1122 if (ret) { 1123 vb2_queue_release(src_vq); 1124 return ret; 1125 } 1126 1127 return 0; 1128 } 1129 1130 static void venc_inst_init(struct venus_inst *inst) 1131 { 1132 inst->fmt_cap = &venc_formats[2]; 1133 inst->fmt_out = &venc_formats[0]; 1134 inst->width = 1280; 1135 inst->height = ALIGN(720, 32); 1136 inst->out_width = 1280; 1137 inst->out_height = 720; 1138 inst->fps = 15; 1139 inst->timeperframe.numerator = 1; 1140 inst->timeperframe.denominator = 15; 1141 inst->hfi_codec = HFI_VIDEO_CODEC_H264; 1142 } 1143 1144 static int venc_open(struct file *file) 1145 { 1146 struct venus_core *core = video_drvdata(file); 1147 struct venus_inst *inst; 1148 int ret; 1149 1150 inst = kzalloc(sizeof(*inst), GFP_KERNEL); 1151 if (!inst) 1152 return -ENOMEM; 1153 1154 INIT_LIST_HEAD(&inst->dpbbufs); 1155 INIT_LIST_HEAD(&inst->registeredbufs); 1156 INIT_LIST_HEAD(&inst->internalbufs); 1157 INIT_LIST_HEAD(&inst->list); 1158 mutex_init(&inst->lock); 1159 1160 inst->core = core; 1161 inst->session_type = VIDC_SESSION_TYPE_ENC; 1162 1163 venus_helper_init_instance(inst); 1164 1165 ret = pm_runtime_get_sync(core->dev_enc); 1166 if (ret < 0) 1167 goto err_free_inst; 1168 1169 ret = venc_ctrl_init(inst); 1170 if (ret) 1171 goto err_put_sync; 1172 1173 ret = hfi_session_create(inst, &venc_hfi_ops); 1174 if (ret) 1175 goto err_ctrl_deinit; 1176 1177 venc_inst_init(inst); 1178 1179 /* 1180 * create m2m device for every instance, the m2m context scheduling 1181 * is made by firmware side so we do not need to care about. 1182 */ 1183 inst->m2m_dev = v4l2_m2m_init(&venc_m2m_ops); 1184 if (IS_ERR(inst->m2m_dev)) { 1185 ret = PTR_ERR(inst->m2m_dev); 1186 goto err_session_destroy; 1187 } 1188 1189 inst->m2m_ctx = v4l2_m2m_ctx_init(inst->m2m_dev, inst, m2m_queue_init); 1190 if (IS_ERR(inst->m2m_ctx)) { 1191 ret = PTR_ERR(inst->m2m_ctx); 1192 goto err_m2m_release; 1193 } 1194 1195 v4l2_fh_init(&inst->fh, core->vdev_enc); 1196 1197 inst->fh.ctrl_handler = &inst->ctrl_handler; 1198 v4l2_fh_add(&inst->fh); 1199 inst->fh.m2m_ctx = inst->m2m_ctx; 1200 file->private_data = &inst->fh; 1201 1202 return 0; 1203 1204 err_m2m_release: 1205 v4l2_m2m_release(inst->m2m_dev); 1206 err_session_destroy: 1207 hfi_session_destroy(inst); 1208 err_ctrl_deinit: 1209 venc_ctrl_deinit(inst); 1210 err_put_sync: 1211 pm_runtime_put_sync(core->dev_enc); 1212 err_free_inst: 1213 kfree(inst); 1214 return ret; 1215 } 1216 1217 static int venc_close(struct file *file) 1218 { 1219 struct venus_inst *inst = to_inst(file); 1220 1221 v4l2_m2m_ctx_release(inst->m2m_ctx); 1222 v4l2_m2m_release(inst->m2m_dev); 1223 venc_ctrl_deinit(inst); 1224 hfi_session_destroy(inst); 1225 mutex_destroy(&inst->lock); 1226 v4l2_fh_del(&inst->fh); 1227 v4l2_fh_exit(&inst->fh); 1228 1229 pm_runtime_put_sync(inst->core->dev_enc); 1230 1231 kfree(inst); 1232 return 0; 1233 } 1234 1235 static const struct v4l2_file_operations venc_fops = { 1236 .owner = THIS_MODULE, 1237 .open = venc_open, 1238 .release = venc_close, 1239 .unlocked_ioctl = video_ioctl2, 1240 .poll = v4l2_m2m_fop_poll, 1241 .mmap = v4l2_m2m_fop_mmap, 1242 }; 1243 1244 static int venc_probe(struct platform_device *pdev) 1245 { 1246 struct device *dev = &pdev->dev; 1247 struct video_device *vdev; 1248 struct venus_core *core; 1249 int ret; 1250 1251 if (!dev->parent) 1252 return -EPROBE_DEFER; 1253 1254 core = dev_get_drvdata(dev->parent); 1255 if (!core) 1256 return -EPROBE_DEFER; 1257 1258 if (IS_V3(core) || IS_V4(core)) { 1259 core->core1_clk = devm_clk_get(dev, "core"); 1260 if (IS_ERR(core->core1_clk)) 1261 return PTR_ERR(core->core1_clk); 1262 } 1263 1264 if (IS_V4(core)) { 1265 core->core1_bus_clk = devm_clk_get(dev, "bus"); 1266 if (IS_ERR(core->core1_bus_clk)) 1267 return PTR_ERR(core->core1_bus_clk); 1268 } 1269 1270 platform_set_drvdata(pdev, core); 1271 1272 vdev = video_device_alloc(); 1273 if (!vdev) 1274 return -ENOMEM; 1275 1276 strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); 1277 vdev->release = video_device_release; 1278 vdev->fops = &venc_fops; 1279 vdev->ioctl_ops = &venc_ioctl_ops; 1280 vdev->vfl_dir = VFL_DIR_M2M; 1281 vdev->v4l2_dev = &core->v4l2_dev; 1282 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1283 1284 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 1285 if (ret) 1286 goto err_vdev_release; 1287 1288 core->vdev_enc = vdev; 1289 core->dev_enc = dev; 1290 1291 video_set_drvdata(vdev, core); 1292 pm_runtime_enable(dev); 1293 1294 return 0; 1295 1296 err_vdev_release: 1297 video_device_release(vdev); 1298 return ret; 1299 } 1300 1301 static int venc_remove(struct platform_device *pdev) 1302 { 1303 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); 1304 1305 video_unregister_device(core->vdev_enc); 1306 pm_runtime_disable(core->dev_enc); 1307 1308 return 0; 1309 } 1310 1311 static __maybe_unused int venc_runtime_suspend(struct device *dev) 1312 { 1313 struct venus_core *core = dev_get_drvdata(dev); 1314 int ret; 1315 1316 if (IS_V1(core)) 1317 return 0; 1318 1319 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1320 if (ret) 1321 return ret; 1322 1323 if (IS_V4(core)) 1324 clk_disable_unprepare(core->core1_bus_clk); 1325 1326 clk_disable_unprepare(core->core1_clk); 1327 1328 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1329 } 1330 1331 static __maybe_unused int venc_runtime_resume(struct device *dev) 1332 { 1333 struct venus_core *core = dev_get_drvdata(dev); 1334 int ret; 1335 1336 if (IS_V1(core)) 1337 return 0; 1338 1339 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1340 if (ret) 1341 return ret; 1342 1343 ret = clk_prepare_enable(core->core1_clk); 1344 if (ret) 1345 goto err_power_disable; 1346 1347 if (IS_V4(core)) 1348 ret = clk_prepare_enable(core->core1_bus_clk); 1349 1350 if (ret) 1351 goto err_unprepare_core1; 1352 1353 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1354 1355 err_unprepare_core1: 1356 clk_disable_unprepare(core->core1_clk); 1357 err_power_disable: 1358 venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1359 return ret; 1360 } 1361 1362 static const struct dev_pm_ops venc_pm_ops = { 1363 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1364 pm_runtime_force_resume) 1365 SET_RUNTIME_PM_OPS(venc_runtime_suspend, venc_runtime_resume, NULL) 1366 }; 1367 1368 static const struct of_device_id venc_dt_match[] = { 1369 { .compatible = "venus-encoder" }, 1370 { } 1371 }; 1372 MODULE_DEVICE_TABLE(of, venc_dt_match); 1373 1374 static struct platform_driver qcom_venus_enc_driver = { 1375 .probe = venc_probe, 1376 .remove = venc_remove, 1377 .driver = { 1378 .name = "qcom-venus-encoder", 1379 .of_match_table = venc_dt_match, 1380 .pm = &venc_pm_ops, 1381 }, 1382 }; 1383 module_platform_driver(qcom_venus_enc_driver); 1384 1385 MODULE_ALIAS("platform:qcom-venus-encoder"); 1386 MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); 1387 MODULE_LICENSE("GPL v2"); 1388