1 /* 2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 3 * Copyright (C) 2017 Linaro Ltd. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 and 7 * only version 2 as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 #include <linux/clk.h> 16 #include <linux/module.h> 17 #include <linux/mod_devicetable.h> 18 #include <linux/platform_device.h> 19 #include <linux/pm_runtime.h> 20 #include <linux/slab.h> 21 #include <media/v4l2-mem2mem.h> 22 #include <media/videobuf2-dma-sg.h> 23 #include <media/v4l2-ioctl.h> 24 #include <media/v4l2-event.h> 25 #include <media/v4l2-ctrls.h> 26 27 #include "hfi_venus_io.h" 28 #include "hfi_parser.h" 29 #include "core.h" 30 #include "helpers.h" 31 #include "venc.h" 32 33 #define NUM_B_FRAMES_MAX 4 34 35 /* 36 * Three resons to keep MPLANE formats (despite that the number of planes 37 * currently is one): 38 * - the MPLANE formats allow only one plane to be used 39 * - the downstream driver use MPLANE formats too 40 * - future firmware versions could add support for >1 planes 41 */ 42 static const struct venus_format venc_formats[] = { 43 { 44 .pixfmt = V4L2_PIX_FMT_NV12, 45 .num_planes = 1, 46 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 47 }, { 48 .pixfmt = V4L2_PIX_FMT_MPEG4, 49 .num_planes = 1, 50 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 51 }, { 52 .pixfmt = V4L2_PIX_FMT_H263, 53 .num_planes = 1, 54 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 55 }, { 56 .pixfmt = V4L2_PIX_FMT_H264, 57 .num_planes = 1, 58 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 59 }, { 60 .pixfmt = V4L2_PIX_FMT_VP8, 61 .num_planes = 1, 62 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 63 }, { 64 .pixfmt = V4L2_PIX_FMT_HEVC, 65 .num_planes = 1, 66 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 67 }, 68 }; 69 70 static const struct venus_format * 71 find_format(struct venus_inst *inst, u32 pixfmt, u32 type) 72 { 73 const struct venus_format *fmt = venc_formats; 74 unsigned int size = ARRAY_SIZE(venc_formats); 75 unsigned int i; 76 77 for (i = 0; i < size; i++) { 78 if (fmt[i].pixfmt == pixfmt) 79 break; 80 } 81 82 if (i == size || fmt[i].type != type) 83 return NULL; 84 85 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 86 !venus_helper_check_codec(inst, fmt[i].pixfmt)) 87 return NULL; 88 89 return &fmt[i]; 90 } 91 92 static const struct venus_format * 93 find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) 94 { 95 const struct venus_format *fmt = venc_formats; 96 unsigned int size = ARRAY_SIZE(venc_formats); 97 unsigned int i, k = 0; 98 99 if (index > size) 100 return NULL; 101 102 for (i = 0; i < size; i++) { 103 bool valid; 104 105 if (fmt[i].type != type) 106 continue; 107 valid = type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || 108 venus_helper_check_codec(inst, fmt[i].pixfmt); 109 if (k == index && valid) 110 break; 111 if (valid) 112 k++; 113 } 114 115 if (i == size) 116 return NULL; 117 118 return &fmt[i]; 119 } 120 121 static int venc_v4l2_to_hfi(int id, int value) 122 { 123 switch (id) { 124 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 125 switch (value) { 126 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: 127 default: 128 return HFI_MPEG4_LEVEL_0; 129 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: 130 return HFI_MPEG4_LEVEL_0b; 131 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: 132 return HFI_MPEG4_LEVEL_1; 133 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: 134 return HFI_MPEG4_LEVEL_2; 135 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: 136 return HFI_MPEG4_LEVEL_3; 137 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: 138 return HFI_MPEG4_LEVEL_4; 139 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: 140 return HFI_MPEG4_LEVEL_5; 141 } 142 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 143 switch (value) { 144 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: 145 default: 146 return HFI_MPEG4_PROFILE_SIMPLE; 147 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: 148 return HFI_MPEG4_PROFILE_ADVANCEDSIMPLE; 149 } 150 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 151 switch (value) { 152 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: 153 return HFI_H264_PROFILE_BASELINE; 154 case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE: 155 return HFI_H264_PROFILE_CONSTRAINED_BASE; 156 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: 157 return HFI_H264_PROFILE_MAIN; 158 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: 159 default: 160 return HFI_H264_PROFILE_HIGH; 161 } 162 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 163 switch (value) { 164 case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: 165 return HFI_H264_LEVEL_1; 166 case V4L2_MPEG_VIDEO_H264_LEVEL_1B: 167 return HFI_H264_LEVEL_1b; 168 case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: 169 return HFI_H264_LEVEL_11; 170 case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: 171 return HFI_H264_LEVEL_12; 172 case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: 173 return HFI_H264_LEVEL_13; 174 case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: 175 return HFI_H264_LEVEL_2; 176 case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: 177 return HFI_H264_LEVEL_21; 178 case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: 179 return HFI_H264_LEVEL_22; 180 case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: 181 return HFI_H264_LEVEL_3; 182 case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: 183 return HFI_H264_LEVEL_31; 184 case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: 185 return HFI_H264_LEVEL_32; 186 case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: 187 return HFI_H264_LEVEL_4; 188 case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: 189 return HFI_H264_LEVEL_41; 190 case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: 191 return HFI_H264_LEVEL_42; 192 case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: 193 default: 194 return HFI_H264_LEVEL_5; 195 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: 196 return HFI_H264_LEVEL_51; 197 } 198 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: 199 switch (value) { 200 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC: 201 default: 202 return HFI_H264_ENTROPY_CAVLC; 203 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC: 204 return HFI_H264_ENTROPY_CABAC; 205 } 206 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: 207 switch (value) { 208 case 0: 209 default: 210 return HFI_VPX_PROFILE_VERSION_0; 211 case 1: 212 return HFI_VPX_PROFILE_VERSION_1; 213 case 2: 214 return HFI_VPX_PROFILE_VERSION_2; 215 case 3: 216 return HFI_VPX_PROFILE_VERSION_3; 217 } 218 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: 219 switch (value) { 220 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED: 221 default: 222 return HFI_H264_DB_MODE_ALL_BOUNDARY; 223 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED: 224 return HFI_H264_DB_MODE_DISABLE; 225 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY: 226 return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY; 227 } 228 case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE: 229 switch (value) { 230 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN: 231 default: 232 return HFI_HEVC_PROFILE_MAIN; 233 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE: 234 return HFI_HEVC_PROFILE_MAIN_STILL_PIC; 235 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10: 236 return HFI_HEVC_PROFILE_MAIN10; 237 } 238 case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL: 239 switch (value) { 240 case V4L2_MPEG_VIDEO_HEVC_LEVEL_1: 241 default: 242 return HFI_HEVC_LEVEL_1; 243 case V4L2_MPEG_VIDEO_HEVC_LEVEL_2: 244 return HFI_HEVC_LEVEL_2; 245 case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1: 246 return HFI_HEVC_LEVEL_21; 247 case V4L2_MPEG_VIDEO_HEVC_LEVEL_3: 248 return HFI_HEVC_LEVEL_3; 249 case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1: 250 return HFI_HEVC_LEVEL_31; 251 case V4L2_MPEG_VIDEO_HEVC_LEVEL_4: 252 return HFI_HEVC_LEVEL_4; 253 case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1: 254 return HFI_HEVC_LEVEL_41; 255 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5: 256 return HFI_HEVC_LEVEL_5; 257 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1: 258 return HFI_HEVC_LEVEL_51; 259 case V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2: 260 return HFI_HEVC_LEVEL_52; 261 case V4L2_MPEG_VIDEO_HEVC_LEVEL_6: 262 return HFI_HEVC_LEVEL_6; 263 case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1: 264 return HFI_HEVC_LEVEL_61; 265 case V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2: 266 return HFI_HEVC_LEVEL_62; 267 } 268 } 269 270 return 0; 271 } 272 273 static int 274 venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 275 { 276 strscpy(cap->driver, "qcom-venus", sizeof(cap->driver)); 277 strscpy(cap->card, "Qualcomm Venus video encoder", sizeof(cap->card)); 278 strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info)); 279 280 return 0; 281 } 282 283 static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) 284 { 285 struct venus_inst *inst = to_inst(file); 286 const struct venus_format *fmt; 287 288 fmt = find_format_by_index(inst, f->index, f->type); 289 290 memset(f->reserved, 0, sizeof(f->reserved)); 291 292 if (!fmt) 293 return -EINVAL; 294 295 f->pixelformat = fmt->pixfmt; 296 297 return 0; 298 } 299 300 static const struct venus_format * 301 venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) 302 { 303 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 304 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; 305 const struct venus_format *fmt; 306 307 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); 308 memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); 309 310 fmt = find_format(inst, pixmp->pixelformat, f->type); 311 if (!fmt) { 312 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 313 pixmp->pixelformat = V4L2_PIX_FMT_H264; 314 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 315 pixmp->pixelformat = V4L2_PIX_FMT_NV12; 316 else 317 return NULL; 318 fmt = find_format(inst, pixmp->pixelformat, f->type); 319 } 320 321 pixmp->width = clamp(pixmp->width, frame_width_min(inst), 322 frame_width_max(inst)); 323 pixmp->height = clamp(pixmp->height, frame_height_min(inst), 324 frame_height_max(inst)); 325 326 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 327 pixmp->height = ALIGN(pixmp->height, 32); 328 329 pixmp->width = ALIGN(pixmp->width, 2); 330 pixmp->height = ALIGN(pixmp->height, 2); 331 332 if (pixmp->field == V4L2_FIELD_ANY) 333 pixmp->field = V4L2_FIELD_NONE; 334 pixmp->num_planes = fmt->num_planes; 335 pixmp->flags = 0; 336 337 pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat, 338 pixmp->width, 339 pixmp->height); 340 341 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 342 pfmt[0].bytesperline = ALIGN(pixmp->width, 128); 343 else 344 pfmt[0].bytesperline = 0; 345 346 return fmt; 347 } 348 349 static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f) 350 { 351 struct venus_inst *inst = to_inst(file); 352 353 venc_try_fmt_common(inst, f); 354 355 return 0; 356 } 357 358 static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) 359 { 360 struct venus_inst *inst = to_inst(file); 361 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 362 struct v4l2_pix_format_mplane orig_pixmp; 363 const struct venus_format *fmt; 364 struct v4l2_format format; 365 u32 pixfmt_out = 0, pixfmt_cap = 0; 366 367 orig_pixmp = *pixmp; 368 369 fmt = venc_try_fmt_common(inst, f); 370 if (!fmt) 371 return -EINVAL; 372 373 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 374 pixfmt_out = pixmp->pixelformat; 375 pixfmt_cap = inst->fmt_cap->pixfmt; 376 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 377 pixfmt_cap = pixmp->pixelformat; 378 pixfmt_out = inst->fmt_out->pixfmt; 379 } 380 381 memset(&format, 0, sizeof(format)); 382 383 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 384 format.fmt.pix_mp.pixelformat = pixfmt_out; 385 format.fmt.pix_mp.width = orig_pixmp.width; 386 format.fmt.pix_mp.height = orig_pixmp.height; 387 venc_try_fmt_common(inst, &format); 388 389 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 390 inst->out_width = format.fmt.pix_mp.width; 391 inst->out_height = format.fmt.pix_mp.height; 392 inst->colorspace = pixmp->colorspace; 393 inst->ycbcr_enc = pixmp->ycbcr_enc; 394 inst->quantization = pixmp->quantization; 395 inst->xfer_func = pixmp->xfer_func; 396 } 397 398 memset(&format, 0, sizeof(format)); 399 400 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 401 format.fmt.pix_mp.pixelformat = pixfmt_cap; 402 format.fmt.pix_mp.width = orig_pixmp.width; 403 format.fmt.pix_mp.height = orig_pixmp.height; 404 venc_try_fmt_common(inst, &format); 405 406 inst->width = format.fmt.pix_mp.width; 407 inst->height = format.fmt.pix_mp.height; 408 409 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 410 inst->fmt_out = fmt; 411 else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 412 inst->fmt_cap = fmt; 413 414 return 0; 415 } 416 417 static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f) 418 { 419 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; 420 struct venus_inst *inst = to_inst(file); 421 const struct venus_format *fmt; 422 423 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) 424 fmt = inst->fmt_cap; 425 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 426 fmt = inst->fmt_out; 427 else 428 return -EINVAL; 429 430 pixmp->pixelformat = fmt->pixfmt; 431 432 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { 433 pixmp->width = inst->width; 434 pixmp->height = inst->height; 435 pixmp->colorspace = inst->colorspace; 436 pixmp->ycbcr_enc = inst->ycbcr_enc; 437 pixmp->quantization = inst->quantization; 438 pixmp->xfer_func = inst->xfer_func; 439 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 440 pixmp->width = inst->out_width; 441 pixmp->height = inst->out_height; 442 } 443 444 venc_try_fmt_common(inst, f); 445 446 return 0; 447 } 448 449 static int 450 venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s) 451 { 452 struct venus_inst *inst = to_inst(file); 453 454 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 455 return -EINVAL; 456 457 switch (s->target) { 458 case V4L2_SEL_TGT_CROP_DEFAULT: 459 case V4L2_SEL_TGT_CROP_BOUNDS: 460 s->r.width = inst->width; 461 s->r.height = inst->height; 462 break; 463 case V4L2_SEL_TGT_CROP: 464 s->r.width = inst->out_width; 465 s->r.height = inst->out_height; 466 break; 467 default: 468 return -EINVAL; 469 } 470 471 s->r.top = 0; 472 s->r.left = 0; 473 474 return 0; 475 } 476 477 static int 478 venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 479 { 480 struct venus_inst *inst = to_inst(file); 481 482 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 483 return -EINVAL; 484 485 switch (s->target) { 486 case V4L2_SEL_TGT_CROP: 487 if (s->r.width != inst->out_width || 488 s->r.height != inst->out_height || 489 s->r.top != 0 || s->r.left != 0) 490 return -EINVAL; 491 break; 492 default: 493 return -EINVAL; 494 } 495 496 return 0; 497 } 498 499 static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 500 { 501 struct venus_inst *inst = to_inst(file); 502 struct v4l2_outputparm *out = &a->parm.output; 503 struct v4l2_fract *timeperframe = &out->timeperframe; 504 u64 us_per_frame, fps; 505 506 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 507 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 508 return -EINVAL; 509 510 memset(out->reserved, 0, sizeof(out->reserved)); 511 512 if (!timeperframe->denominator) 513 timeperframe->denominator = inst->timeperframe.denominator; 514 if (!timeperframe->numerator) 515 timeperframe->numerator = inst->timeperframe.numerator; 516 517 out->capability = V4L2_CAP_TIMEPERFRAME; 518 519 us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; 520 do_div(us_per_frame, timeperframe->denominator); 521 522 if (!us_per_frame) 523 return -EINVAL; 524 525 fps = (u64)USEC_PER_SEC; 526 do_div(fps, us_per_frame); 527 528 inst->timeperframe = *timeperframe; 529 inst->fps = fps; 530 531 return 0; 532 } 533 534 static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 535 { 536 struct venus_inst *inst = to_inst(file); 537 538 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 539 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 540 return -EINVAL; 541 542 a->parm.output.capability |= V4L2_CAP_TIMEPERFRAME; 543 a->parm.output.timeperframe = inst->timeperframe; 544 545 return 0; 546 } 547 548 static int venc_enum_framesizes(struct file *file, void *fh, 549 struct v4l2_frmsizeenum *fsize) 550 { 551 struct venus_inst *inst = to_inst(file); 552 const struct venus_format *fmt; 553 554 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; 555 556 fmt = find_format(inst, fsize->pixel_format, 557 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 558 if (!fmt) { 559 fmt = find_format(inst, fsize->pixel_format, 560 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 561 if (!fmt) 562 return -EINVAL; 563 } 564 565 if (fsize->index) 566 return -EINVAL; 567 568 fsize->stepwise.min_width = frame_width_min(inst); 569 fsize->stepwise.max_width = frame_width_max(inst); 570 fsize->stepwise.step_width = frame_width_step(inst); 571 fsize->stepwise.min_height = frame_height_min(inst); 572 fsize->stepwise.max_height = frame_height_max(inst); 573 fsize->stepwise.step_height = frame_height_step(inst); 574 575 return 0; 576 } 577 578 static int venc_enum_frameintervals(struct file *file, void *fh, 579 struct v4l2_frmivalenum *fival) 580 { 581 struct venus_inst *inst = to_inst(file); 582 const struct venus_format *fmt; 583 584 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; 585 586 fmt = find_format(inst, fival->pixel_format, 587 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 588 if (!fmt) { 589 fmt = find_format(inst, fival->pixel_format, 590 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); 591 if (!fmt) 592 return -EINVAL; 593 } 594 595 if (fival->index) 596 return -EINVAL; 597 598 if (!fival->width || !fival->height) 599 return -EINVAL; 600 601 if (fival->width > frame_width_max(inst) || 602 fival->width < frame_width_min(inst) || 603 fival->height > frame_height_max(inst) || 604 fival->height < frame_height_min(inst)) 605 return -EINVAL; 606 607 fival->stepwise.min.numerator = 1; 608 fival->stepwise.min.denominator = frate_max(inst); 609 fival->stepwise.max.numerator = 1; 610 fival->stepwise.max.denominator = frate_min(inst); 611 fival->stepwise.step.numerator = 1; 612 fival->stepwise.step.denominator = frate_max(inst); 613 614 return 0; 615 } 616 617 static const struct v4l2_ioctl_ops venc_ioctl_ops = { 618 .vidioc_querycap = venc_querycap, 619 .vidioc_enum_fmt_vid_cap_mplane = venc_enum_fmt, 620 .vidioc_enum_fmt_vid_out_mplane = venc_enum_fmt, 621 .vidioc_s_fmt_vid_cap_mplane = venc_s_fmt, 622 .vidioc_s_fmt_vid_out_mplane = venc_s_fmt, 623 .vidioc_g_fmt_vid_cap_mplane = venc_g_fmt, 624 .vidioc_g_fmt_vid_out_mplane = venc_g_fmt, 625 .vidioc_try_fmt_vid_cap_mplane = venc_try_fmt, 626 .vidioc_try_fmt_vid_out_mplane = venc_try_fmt, 627 .vidioc_g_selection = venc_g_selection, 628 .vidioc_s_selection = venc_s_selection, 629 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 630 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 631 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, 632 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, 633 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, 634 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, 635 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, 636 .vidioc_streamon = v4l2_m2m_ioctl_streamon, 637 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 638 .vidioc_s_parm = venc_s_parm, 639 .vidioc_g_parm = venc_g_parm, 640 .vidioc_enum_framesizes = venc_enum_framesizes, 641 .vidioc_enum_frameintervals = venc_enum_frameintervals, 642 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 643 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 644 }; 645 646 static int venc_set_properties(struct venus_inst *inst) 647 { 648 struct venc_controls *ctr = &inst->controls.enc; 649 struct hfi_intra_period intra_period; 650 struct hfi_profile_level pl; 651 struct hfi_framerate frate; 652 struct hfi_bitrate brate; 653 struct hfi_idr_period idrp; 654 struct hfi_quantization quant; 655 struct hfi_quantization_range quant_range; 656 u32 ptype, rate_control, bitrate, profile = 0, level = 0; 657 int ret; 658 659 ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2); 660 if (ret) 661 return ret; 662 663 ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2); 664 if (ret) 665 return ret; 666 667 ptype = HFI_PROPERTY_CONFIG_FRAME_RATE; 668 frate.buffer_type = HFI_BUFFER_OUTPUT; 669 frate.framerate = inst->fps * (1 << 16); 670 671 ret = hfi_session_set_property(inst, ptype, &frate); 672 if (ret) 673 return ret; 674 675 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { 676 struct hfi_h264_vui_timing_info info; 677 struct hfi_h264_entropy_control entropy; 678 struct hfi_h264_db_control deblock; 679 680 ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO; 681 info.enable = 1; 682 info.fixed_framerate = 1; 683 info.time_scale = NSEC_PER_SEC; 684 685 ret = hfi_session_set_property(inst, ptype, &info); 686 if (ret) 687 return ret; 688 689 ptype = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL; 690 entropy.entropy_mode = venc_v4l2_to_hfi( 691 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, 692 ctr->h264_entropy_mode); 693 entropy.cabac_model = HFI_H264_CABAC_MODEL_0; 694 695 ret = hfi_session_set_property(inst, ptype, &entropy); 696 if (ret) 697 return ret; 698 699 ptype = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL; 700 deblock.mode = venc_v4l2_to_hfi( 701 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, 702 ctr->h264_loop_filter_mode); 703 deblock.slice_alpha_offset = ctr->h264_loop_filter_alpha; 704 deblock.slice_beta_offset = ctr->h264_loop_filter_beta; 705 706 ret = hfi_session_set_property(inst, ptype, &deblock); 707 if (ret) 708 return ret; 709 } 710 711 /* IDR periodicity, n: 712 * n = 0 - only the first I-frame is IDR frame 713 * n = 1 - all I-frames will be IDR frames 714 * n > 1 - every n-th I-frame will be IDR frame 715 */ 716 ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD; 717 idrp.idr_period = 0; 718 ret = hfi_session_set_property(inst, ptype, &idrp); 719 if (ret) 720 return ret; 721 722 if (ctr->num_b_frames) { 723 u32 max_num_b_frames = NUM_B_FRAMES_MAX; 724 725 ptype = HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES; 726 ret = hfi_session_set_property(inst, ptype, &max_num_b_frames); 727 if (ret) 728 return ret; 729 } 730 731 ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD; 732 intra_period.pframes = ctr->num_p_frames; 733 intra_period.bframes = ctr->num_b_frames; 734 735 ret = hfi_session_set_property(inst, ptype, &intra_period); 736 if (ret) 737 return ret; 738 739 if (ctr->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) 740 rate_control = HFI_RATE_CONTROL_VBR_CFR; 741 else 742 rate_control = HFI_RATE_CONTROL_CBR_CFR; 743 744 ptype = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL; 745 ret = hfi_session_set_property(inst, ptype, &rate_control); 746 if (ret) 747 return ret; 748 749 if (!ctr->bitrate) 750 bitrate = 64000; 751 else 752 bitrate = ctr->bitrate; 753 754 ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; 755 brate.bitrate = bitrate; 756 brate.layer_id = 0; 757 758 ret = hfi_session_set_property(inst, ptype, &brate); 759 if (ret) 760 return ret; 761 762 if (!ctr->bitrate_peak) 763 bitrate *= 2; 764 else 765 bitrate = ctr->bitrate_peak; 766 767 ptype = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE; 768 brate.bitrate = bitrate; 769 brate.layer_id = 0; 770 771 ret = hfi_session_set_property(inst, ptype, &brate); 772 if (ret) 773 return ret; 774 775 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP; 776 quant.qp_i = ctr->h264_i_qp; 777 quant.qp_p = ctr->h264_p_qp; 778 quant.qp_b = ctr->h264_b_qp; 779 quant.layer_id = 0; 780 ret = hfi_session_set_property(inst, ptype, &quant); 781 if (ret) 782 return ret; 783 784 ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE; 785 quant_range.min_qp = ctr->h264_min_qp; 786 quant_range.max_qp = ctr->h264_max_qp; 787 quant_range.layer_id = 0; 788 ret = hfi_session_set_property(inst, ptype, &quant_range); 789 if (ret) 790 return ret; 791 792 if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) { 793 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_PROFILE, 794 ctr->profile.h264); 795 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_LEVEL, 796 ctr->level.h264); 797 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_VP8) { 798 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_VP8_PROFILE, 799 ctr->profile.vpx); 800 level = 0; 801 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_MPEG4) { 802 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, 803 ctr->profile.mpeg4); 804 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, 805 ctr->level.mpeg4); 806 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H263) { 807 profile = 0; 808 level = 0; 809 } else if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 810 profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_PROFILE, 811 ctr->profile.hevc); 812 level = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_LEVEL, 813 ctr->level.hevc); 814 } 815 816 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 817 pl.profile = profile; 818 pl.level = level; 819 820 ret = hfi_session_set_property(inst, ptype, &pl); 821 if (ret) 822 return ret; 823 824 return 0; 825 } 826 827 static int venc_init_session(struct venus_inst *inst) 828 { 829 int ret; 830 831 ret = hfi_session_init(inst, inst->fmt_cap->pixfmt); 832 if (ret) 833 return ret; 834 835 ret = venus_helper_set_input_resolution(inst, inst->width, 836 inst->height); 837 if (ret) 838 goto deinit; 839 840 ret = venus_helper_set_output_resolution(inst, inst->width, 841 inst->height, 842 HFI_BUFFER_OUTPUT); 843 if (ret) 844 goto deinit; 845 846 ret = venus_helper_set_color_format(inst, inst->fmt_out->pixfmt); 847 if (ret) 848 goto deinit; 849 850 ret = venc_set_properties(inst); 851 if (ret) 852 goto deinit; 853 854 return 0; 855 deinit: 856 hfi_session_deinit(inst); 857 return ret; 858 } 859 860 static int venc_out_num_buffers(struct venus_inst *inst, unsigned int *num) 861 { 862 struct hfi_buffer_requirements bufreq; 863 int ret; 864 865 ret = venc_init_session(inst); 866 if (ret) 867 return ret; 868 869 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 870 871 *num = bufreq.count_actual; 872 873 hfi_session_deinit(inst); 874 875 return ret; 876 } 877 878 static int venc_queue_setup(struct vb2_queue *q, 879 unsigned int *num_buffers, unsigned int *num_planes, 880 unsigned int sizes[], struct device *alloc_devs[]) 881 { 882 struct venus_inst *inst = vb2_get_drv_priv(q); 883 unsigned int num, min = 4; 884 int ret = 0; 885 886 if (*num_planes) { 887 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 888 *num_planes != inst->fmt_out->num_planes) 889 return -EINVAL; 890 891 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 892 *num_planes != inst->fmt_cap->num_planes) 893 return -EINVAL; 894 895 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && 896 sizes[0] < inst->input_buf_size) 897 return -EINVAL; 898 899 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 900 sizes[0] < inst->output_buf_size) 901 return -EINVAL; 902 903 return 0; 904 } 905 906 switch (q->type) { 907 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 908 *num_planes = inst->fmt_out->num_planes; 909 910 ret = venc_out_num_buffers(inst, &num); 911 if (ret) 912 break; 913 914 num = max(num, min); 915 *num_buffers = max(*num_buffers, num); 916 inst->num_input_bufs = *num_buffers; 917 918 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, 919 inst->width, 920 inst->height); 921 inst->input_buf_size = sizes[0]; 922 break; 923 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 924 *num_planes = inst->fmt_cap->num_planes; 925 *num_buffers = max(*num_buffers, min); 926 inst->num_output_bufs = *num_buffers; 927 sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, 928 inst->width, 929 inst->height); 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 #ifdef CONFIG_COMPAT 1243 .compat_ioctl32 = v4l2_compat_ioctl32, 1244 #endif 1245 }; 1246 1247 static int venc_probe(struct platform_device *pdev) 1248 { 1249 struct device *dev = &pdev->dev; 1250 struct video_device *vdev; 1251 struct venus_core *core; 1252 int ret; 1253 1254 if (!dev->parent) 1255 return -EPROBE_DEFER; 1256 1257 core = dev_get_drvdata(dev->parent); 1258 if (!core) 1259 return -EPROBE_DEFER; 1260 1261 if (IS_V3(core) || IS_V4(core)) { 1262 core->core1_clk = devm_clk_get(dev, "core"); 1263 if (IS_ERR(core->core1_clk)) 1264 return PTR_ERR(core->core1_clk); 1265 } 1266 1267 if (IS_V4(core)) { 1268 core->core1_bus_clk = devm_clk_get(dev, "bus"); 1269 if (IS_ERR(core->core1_bus_clk)) 1270 return PTR_ERR(core->core1_bus_clk); 1271 } 1272 1273 platform_set_drvdata(pdev, core); 1274 1275 vdev = video_device_alloc(); 1276 if (!vdev) 1277 return -ENOMEM; 1278 1279 strscpy(vdev->name, "qcom-venus-encoder", sizeof(vdev->name)); 1280 vdev->release = video_device_release; 1281 vdev->fops = &venc_fops; 1282 vdev->ioctl_ops = &venc_ioctl_ops; 1283 vdev->vfl_dir = VFL_DIR_M2M; 1284 vdev->v4l2_dev = &core->v4l2_dev; 1285 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING; 1286 1287 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 1288 if (ret) 1289 goto err_vdev_release; 1290 1291 core->vdev_enc = vdev; 1292 core->dev_enc = dev; 1293 1294 video_set_drvdata(vdev, core); 1295 pm_runtime_enable(dev); 1296 1297 return 0; 1298 1299 err_vdev_release: 1300 video_device_release(vdev); 1301 return ret; 1302 } 1303 1304 static int venc_remove(struct platform_device *pdev) 1305 { 1306 struct venus_core *core = dev_get_drvdata(pdev->dev.parent); 1307 1308 video_unregister_device(core->vdev_enc); 1309 pm_runtime_disable(core->dev_enc); 1310 1311 return 0; 1312 } 1313 1314 static __maybe_unused int venc_runtime_suspend(struct device *dev) 1315 { 1316 struct venus_core *core = dev_get_drvdata(dev); 1317 int ret; 1318 1319 if (IS_V1(core)) 1320 return 0; 1321 1322 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1323 if (ret) 1324 return ret; 1325 1326 if (IS_V4(core)) 1327 clk_disable_unprepare(core->core1_bus_clk); 1328 1329 clk_disable_unprepare(core->core1_clk); 1330 1331 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1332 } 1333 1334 static __maybe_unused int venc_runtime_resume(struct device *dev) 1335 { 1336 struct venus_core *core = dev_get_drvdata(dev); 1337 int ret; 1338 1339 if (IS_V1(core)) 1340 return 0; 1341 1342 ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, true); 1343 if (ret) 1344 return ret; 1345 1346 ret = clk_prepare_enable(core->core1_clk); 1347 if (ret) 1348 goto err_power_disable; 1349 1350 if (IS_V4(core)) 1351 ret = clk_prepare_enable(core->core1_bus_clk); 1352 1353 if (ret) 1354 goto err_unprepare_core1; 1355 1356 return venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1357 1358 err_unprepare_core1: 1359 clk_disable_unprepare(core->core1_clk); 1360 err_power_disable: 1361 venus_helper_power_enable(core, VIDC_SESSION_TYPE_ENC, false); 1362 return ret; 1363 } 1364 1365 static const struct dev_pm_ops venc_pm_ops = { 1366 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1367 pm_runtime_force_resume) 1368 SET_RUNTIME_PM_OPS(venc_runtime_suspend, venc_runtime_resume, NULL) 1369 }; 1370 1371 static const struct of_device_id venc_dt_match[] = { 1372 { .compatible = "venus-encoder" }, 1373 { } 1374 }; 1375 MODULE_DEVICE_TABLE(of, venc_dt_match); 1376 1377 static struct platform_driver qcom_venus_enc_driver = { 1378 .probe = venc_probe, 1379 .remove = venc_remove, 1380 .driver = { 1381 .name = "qcom-venus-encoder", 1382 .of_match_table = venc_dt_match, 1383 .pm = &venc_pm_ops, 1384 }, 1385 }; 1386 module_platform_driver(qcom_venus_enc_driver); 1387 1388 MODULE_ALIAS("platform:qcom-venus-encoder"); 1389 MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); 1390 MODULE_LICENSE("GPL v2"); 1391