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