2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3 * Copyright (C) 2017 Linaro Ltd.
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.
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.
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>
27 #include "hfi_venus_io.h"
28 #include "hfi_parser.h"
33 #define NUM_B_FRAMES_MAX 4
36 * Three resons to keep MPLANE formats (despite that the number of planes
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
42 static const struct venus_format venc_formats
[] = {
44 .pixfmt
= V4L2_PIX_FMT_NV12
,
46 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
48 .pixfmt
= V4L2_PIX_FMT_MPEG4
,
50 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
52 .pixfmt
= V4L2_PIX_FMT_H263
,
54 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
56 .pixfmt
= V4L2_PIX_FMT_H264
,
58 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
60 .pixfmt
= V4L2_PIX_FMT_VP8
,
62 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
64 .pixfmt
= V4L2_PIX_FMT_HEVC
,
66 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
70 static const struct venus_format
*
71 find_format(struct venus_inst
*inst
, u32 pixfmt
, u32 type
)
73 const struct venus_format
*fmt
= venc_formats
;
74 unsigned int size
= ARRAY_SIZE(venc_formats
);
77 for (i
= 0; i
< size
; i
++) {
78 if (fmt
[i
].pixfmt
== pixfmt
)
82 if (i
== size
|| fmt
[i
].type
!= type
)
85 if (type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
86 !venus_helper_check_codec(inst
, fmt
[i
].pixfmt
))
92 static const struct venus_format
*
93 find_format_by_index(struct venus_inst
*inst
, unsigned int index
, u32 type
)
95 const struct venus_format
*fmt
= venc_formats
;
96 unsigned int size
= ARRAY_SIZE(venc_formats
);
97 unsigned int i
, k
= 0;
102 for (i
= 0; i
< size
; i
++) {
105 if (fmt
[i
].type
!= type
)
107 valid
= type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
||
108 venus_helper_check_codec(inst
, fmt
[i
].pixfmt
);
109 if (k
== index
&& valid
)
121 static int venc_v4l2_to_hfi(int id
, int value
)
124 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL
:
126 case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0
:
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
;
142 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE
:
144 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE
:
146 return HFI_MPEG4_PROFILE_SIMPLE
;
147 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE
:
148 return HFI_MPEG4_PROFILE_ADVANCEDSIMPLE
;
150 case V4L2_CID_MPEG_VIDEO_H264_PROFILE
:
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
:
160 return HFI_H264_PROFILE_HIGH
;
162 case V4L2_CID_MPEG_VIDEO_H264_LEVEL
:
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
:
194 return HFI_H264_LEVEL_5
;
195 case V4L2_MPEG_VIDEO_H264_LEVEL_5_1
:
196 return HFI_H264_LEVEL_51
;
198 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE
:
200 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC
:
202 return HFI_H264_ENTROPY_CAVLC
;
203 case V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC
:
204 return HFI_H264_ENTROPY_CABAC
;
206 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE
:
210 return HFI_VPX_PROFILE_VERSION_0
;
212 return HFI_VPX_PROFILE_VERSION_1
;
214 return HFI_VPX_PROFILE_VERSION_2
;
216 return HFI_VPX_PROFILE_VERSION_3
;
218 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE
:
220 case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED
:
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
;
228 case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE
:
230 case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN
:
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
;
238 case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL
:
240 case V4L2_MPEG_VIDEO_HEVC_LEVEL_1
:
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
;
274 venc_querycap(struct file
*file
, void *fh
, struct v4l2_capability
*cap
)
276 strlcpy(cap
->driver
, "qcom-venus", sizeof(cap
->driver
));
277 strlcpy(cap
->card
, "Qualcomm Venus video encoder", sizeof(cap
->card
));
278 strlcpy(cap
->bus_info
, "platform:qcom-venus", sizeof(cap
->bus_info
));
283 static int venc_enum_fmt(struct file
*file
, void *fh
, struct v4l2_fmtdesc
*f
)
285 struct venus_inst
*inst
= to_inst(file
);
286 const struct venus_format
*fmt
;
288 fmt
= find_format_by_index(inst
, f
->index
, f
->type
);
290 memset(f
->reserved
, 0, sizeof(f
->reserved
));
295 f
->pixelformat
= fmt
->pixfmt
;
300 static const struct venus_format
*
301 venc_try_fmt_common(struct venus_inst
*inst
, struct v4l2_format
*f
)
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
;
307 memset(pfmt
[0].reserved
, 0, sizeof(pfmt
[0].reserved
));
308 memset(pixmp
->reserved
, 0, sizeof(pixmp
->reserved
));
310 fmt
= find_format(inst
, pixmp
->pixelformat
, f
->type
);
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
;
318 fmt
= find_format(inst
, pixmp
->pixelformat
, f
->type
);
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
));
326 if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
327 pixmp
->height
= ALIGN(pixmp
->height
, 32);
329 pixmp
->width
= ALIGN(pixmp
->width
, 2);
330 pixmp
->height
= ALIGN(pixmp
->height
, 2);
332 if (pixmp
->field
== V4L2_FIELD_ANY
)
333 pixmp
->field
= V4L2_FIELD_NONE
;
334 pixmp
->num_planes
= fmt
->num_planes
;
337 pfmt
[0].sizeimage
= venus_helper_get_framesz(pixmp
->pixelformat
,
341 if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
342 pfmt
[0].bytesperline
= ALIGN(pixmp
->width
, 128);
344 pfmt
[0].bytesperline
= 0;
349 static int venc_try_fmt(struct file
*file
, void *fh
, struct v4l2_format
*f
)
351 struct venus_inst
*inst
= to_inst(file
);
353 venc_try_fmt_common(inst
, f
);
358 static int venc_s_fmt(struct file
*file
, void *fh
, struct v4l2_format
*f
)
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;
369 fmt
= venc_try_fmt_common(inst
, f
);
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
;
381 memset(&format
, 0, sizeof(format
));
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
);
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
;
398 memset(&format
, 0, sizeof(format
));
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
);
406 inst
->width
= format
.fmt
.pix_mp
.width
;
407 inst
->height
= format
.fmt
.pix_mp
.height
;
409 if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
411 else if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
)
417 static int venc_g_fmt(struct file
*file
, void *fh
, struct v4l2_format
*f
)
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
;
423 if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
)
425 else if (f
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
430 pixmp
->pixelformat
= fmt
->pixfmt
;
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
;
444 venc_try_fmt_common(inst
, f
);
450 venc_g_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
452 struct venus_inst
*inst
= to_inst(file
);
454 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
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
;
463 case V4L2_SEL_TGT_CROP
:
464 s
->r
.width
= inst
->out_width
;
465 s
->r
.height
= inst
->out_height
;
478 venc_s_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
480 struct venus_inst
*inst
= to_inst(file
);
482 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
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)
499 static int venc_s_parm(struct file
*file
, void *fh
, struct v4l2_streamparm
*a
)
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
;
506 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
507 a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
510 memset(out
->reserved
, 0, sizeof(out
->reserved
));
512 if (!timeperframe
->denominator
)
513 timeperframe
->denominator
= inst
->timeperframe
.denominator
;
514 if (!timeperframe
->numerator
)
515 timeperframe
->numerator
= inst
->timeperframe
.numerator
;
517 out
->capability
= V4L2_CAP_TIMEPERFRAME
;
519 us_per_frame
= timeperframe
->numerator
* (u64
)USEC_PER_SEC
;
520 do_div(us_per_frame
, timeperframe
->denominator
);
525 fps
= (u64
)USEC_PER_SEC
;
526 do_div(fps
, us_per_frame
);
528 inst
->timeperframe
= *timeperframe
;
534 static int venc_g_parm(struct file
*file
, void *fh
, struct v4l2_streamparm
*a
)
536 struct venus_inst
*inst
= to_inst(file
);
538 if (a
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
539 a
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
542 a
->parm
.output
.capability
|= V4L2_CAP_TIMEPERFRAME
;
543 a
->parm
.output
.timeperframe
= inst
->timeperframe
;
548 static int venc_enum_framesizes(struct file
*file
, void *fh
,
549 struct v4l2_frmsizeenum
*fsize
)
551 struct venus_inst
*inst
= to_inst(file
);
552 const struct venus_format
*fmt
;
554 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
556 fmt
= find_format(inst
, fsize
->pixel_format
,
557 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
);
559 fmt
= find_format(inst
, fsize
->pixel_format
,
560 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
);
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
);
578 static int venc_enum_frameintervals(struct file
*file
, void *fh
,
579 struct v4l2_frmivalenum
*fival
)
581 struct venus_inst
*inst
= to_inst(file
);
582 const struct venus_format
*fmt
;
584 fival
->type
= V4L2_FRMIVAL_TYPE_STEPWISE
;
586 fmt
= find_format(inst
, fival
->pixel_format
,
587 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
);
589 fmt
= find_format(inst
, fival
->pixel_format
,
590 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
);
598 if (!fival
->width
|| !fival
->height
)
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
))
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
);
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
,
646 static int venc_set_properties(struct venus_inst
*inst
)
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 u32 ptype
, rate_control
, bitrate
, profile
= 0, level
= 0;
657 ret
= venus_helper_set_work_mode(inst
, VIDC_WORK_MODE_2
);
661 ret
= venus_helper_set_core_usage(inst
, VIDC_CORE_ID_2
);
665 ptype
= HFI_PROPERTY_CONFIG_FRAME_RATE
;
666 frate
.buffer_type
= HFI_BUFFER_OUTPUT
;
667 frate
.framerate
= inst
->fps
* (1 << 16);
669 ret
= hfi_session_set_property(inst
, ptype
, &frate
);
673 if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_H264
) {
674 struct hfi_h264_vui_timing_info info
;
675 struct hfi_h264_entropy_control entropy
;
676 struct hfi_h264_db_control deblock
;
678 ptype
= HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO
;
680 info
.fixed_framerate
= 1;
681 info
.time_scale
= NSEC_PER_SEC
;
683 ret
= hfi_session_set_property(inst
, ptype
, &info
);
687 ptype
= HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL
;
688 entropy
.entropy_mode
= venc_v4l2_to_hfi(
689 V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE
,
690 ctr
->h264_entropy_mode
);
691 entropy
.cabac_model
= HFI_H264_CABAC_MODEL_0
;
693 ret
= hfi_session_set_property(inst
, ptype
, &entropy
);
697 ptype
= HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL
;
698 deblock
.mode
= venc_v4l2_to_hfi(
699 V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE
,
700 ctr
->h264_loop_filter_mode
);
701 deblock
.slice_alpha_offset
= ctr
->h264_loop_filter_alpha
;
702 deblock
.slice_beta_offset
= ctr
->h264_loop_filter_beta
;
704 ret
= hfi_session_set_property(inst
, ptype
, &deblock
);
709 /* IDR periodicity, n:
710 * n = 0 - only the first I-frame is IDR frame
711 * n = 1 - all I-frames will be IDR frames
712 * n > 1 - every n-th I-frame will be IDR frame
714 ptype
= HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD
;
716 ret
= hfi_session_set_property(inst
, ptype
, &idrp
);
720 if (ctr
->num_b_frames
) {
721 u32 max_num_b_frames
= NUM_B_FRAMES_MAX
;
723 ptype
= HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES
;
724 ret
= hfi_session_set_property(inst
, ptype
, &max_num_b_frames
);
729 ptype
= HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD
;
730 intra_period
.pframes
= ctr
->num_p_frames
;
731 intra_period
.bframes
= ctr
->num_b_frames
;
733 ret
= hfi_session_set_property(inst
, ptype
, &intra_period
);
737 if (ctr
->bitrate_mode
== V4L2_MPEG_VIDEO_BITRATE_MODE_VBR
)
738 rate_control
= HFI_RATE_CONTROL_VBR_CFR
;
740 rate_control
= HFI_RATE_CONTROL_CBR_CFR
;
742 ptype
= HFI_PROPERTY_PARAM_VENC_RATE_CONTROL
;
743 ret
= hfi_session_set_property(inst
, ptype
, &rate_control
);
750 bitrate
= ctr
->bitrate
;
752 ptype
= HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE
;
753 brate
.bitrate
= bitrate
;
756 ret
= hfi_session_set_property(inst
, ptype
, &brate
);
760 if (!ctr
->bitrate_peak
)
763 bitrate
= ctr
->bitrate_peak
;
765 ptype
= HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE
;
766 brate
.bitrate
= bitrate
;
769 ret
= hfi_session_set_property(inst
, ptype
, &brate
);
773 if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_H264
) {
774 profile
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_PROFILE
,
776 level
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_LEVEL
,
778 } else if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_VP8
) {
779 profile
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_VP8_PROFILE
,
782 } else if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_MPEG4
) {
783 profile
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE
,
785 level
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL
,
787 } else if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_H263
) {
790 } else if (inst
->fmt_cap
->pixfmt
== V4L2_PIX_FMT_HEVC
) {
791 profile
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_PROFILE
,
793 level
= venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_HEVC_LEVEL
,
797 ptype
= HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT
;
798 pl
.profile
= profile
;
801 ret
= hfi_session_set_property(inst
, ptype
, &pl
);
808 static int venc_init_session(struct venus_inst
*inst
)
812 ret
= hfi_session_init(inst
, inst
->fmt_cap
->pixfmt
);
816 ret
= venus_helper_set_input_resolution(inst
, inst
->width
,
821 ret
= venus_helper_set_output_resolution(inst
, inst
->width
,
827 ret
= venus_helper_set_color_format(inst
, inst
->fmt_out
->pixfmt
);
831 ret
= venc_set_properties(inst
);
837 hfi_session_deinit(inst
);
841 static int venc_out_num_buffers(struct venus_inst
*inst
, unsigned int *num
)
843 struct hfi_buffer_requirements bufreq
;
846 ret
= venc_init_session(inst
);
850 ret
= venus_helper_get_bufreq(inst
, HFI_BUFFER_INPUT
, &bufreq
);
852 *num
= bufreq
.count_actual
;
854 hfi_session_deinit(inst
);
859 static int venc_queue_setup(struct vb2_queue
*q
,
860 unsigned int *num_buffers
, unsigned int *num_planes
,
861 unsigned int sizes
[], struct device
*alloc_devs
[])
863 struct venus_inst
*inst
= vb2_get_drv_priv(q
);
864 unsigned int num
, min
= 4;
868 if (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
&&
869 *num_planes
!= inst
->fmt_out
->num_planes
)
872 if (q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
873 *num_planes
!= inst
->fmt_cap
->num_planes
)
876 if (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
&&
877 sizes
[0] < inst
->input_buf_size
)
880 if (q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
&&
881 sizes
[0] < inst
->output_buf_size
)
888 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
889 *num_planes
= inst
->fmt_out
->num_planes
;
891 ret
= venc_out_num_buffers(inst
, &num
);
896 *num_buffers
= max(*num_buffers
, num
);
897 inst
->num_input_bufs
= *num_buffers
;
899 sizes
[0] = venus_helper_get_framesz(inst
->fmt_out
->pixfmt
,
902 inst
->input_buf_size
= sizes
[0];
904 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
905 *num_planes
= inst
->fmt_cap
->num_planes
;
906 *num_buffers
= max(*num_buffers
, min
);
907 inst
->num_output_bufs
= *num_buffers
;
908 sizes
[0] = venus_helper_get_framesz(inst
->fmt_cap
->pixfmt
,
911 inst
->output_buf_size
= sizes
[0];
921 static int venc_verify_conf(struct venus_inst
*inst
)
923 enum hfi_version ver
= inst
->core
->res
->hfi_version
;
924 struct hfi_buffer_requirements bufreq
;
927 if (!inst
->num_input_bufs
|| !inst
->num_output_bufs
)
930 ret
= venus_helper_get_bufreq(inst
, HFI_BUFFER_OUTPUT
, &bufreq
);
934 if (inst
->num_output_bufs
< bufreq
.count_actual
||
935 inst
->num_output_bufs
< HFI_BUFREQ_COUNT_MIN(&bufreq
, ver
))
938 ret
= venus_helper_get_bufreq(inst
, HFI_BUFFER_INPUT
, &bufreq
);
942 if (inst
->num_input_bufs
< bufreq
.count_actual
||
943 inst
->num_input_bufs
< HFI_BUFREQ_COUNT_MIN(&bufreq
, ver
))
949 static int venc_start_streaming(struct vb2_queue
*q
, unsigned int count
)
951 struct venus_inst
*inst
= vb2_get_drv_priv(q
);
954 mutex_lock(&inst
->lock
);
956 if (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
957 inst
->streamon_out
= 1;
959 inst
->streamon_cap
= 1;
961 if (!(inst
->streamon_out
& inst
->streamon_cap
)) {
962 mutex_unlock(&inst
->lock
);
966 venus_helper_init_instance(inst
);
968 inst
->sequence_cap
= 0;
969 inst
->sequence_out
= 0;
971 ret
= venc_init_session(inst
);
975 ret
= venc_set_properties(inst
);
979 ret
= venc_verify_conf(inst
);
983 ret
= venus_helper_set_num_bufs(inst
, inst
->num_input_bufs
,
984 inst
->num_output_bufs
, 0);
988 ret
= venus_helper_vb2_start_streaming(inst
);
992 mutex_unlock(&inst
->lock
);
997 hfi_session_deinit(inst
);
999 venus_helper_buffers_done(inst
, VB2_BUF_STATE_QUEUED
);
1000 if (q
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
)
1001 inst
->streamon_out
= 0;
1003 inst
->streamon_cap
= 0;
1004 mutex_unlock(&inst
->lock
);
1008 static const struct vb2_ops venc_vb2_ops
= {
1009 .queue_setup
= venc_queue_setup
,
1010 .buf_init
= venus_helper_vb2_buf_init
,
1011 .buf_prepare
= venus_helper_vb2_buf_prepare
,
1012 .start_streaming
= venc_start_streaming
,
1013 .stop_streaming
= venus_helper_vb2_stop_streaming
,
1014 .buf_queue
= venus_helper_vb2_buf_queue
,
1017 static void venc_buf_done(struct venus_inst
*inst
, unsigned int buf_type
,
1018 u32 tag
, u32 bytesused
, u32 data_offset
, u32 flags
,
1019 u32 hfi_flags
, u64 timestamp_us
)
1021 struct vb2_v4l2_buffer
*vbuf
;
1022 struct vb2_buffer
*vb
;
1025 if (buf_type
== HFI_BUFFER_INPUT
)
1026 type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1028 type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1030 vbuf
= venus_helper_find_buf(inst
, type
, tag
);
1034 vbuf
->flags
= flags
;
1036 if (type
== V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
) {
1037 vb
= &vbuf
->vb2_buf
;
1038 vb2_set_plane_payload(vb
, 0, bytesused
+ data_offset
);
1039 vb
->planes
[0].data_offset
= data_offset
;
1040 vb
->timestamp
= timestamp_us
* NSEC_PER_USEC
;
1041 vbuf
->sequence
= inst
->sequence_cap
++;
1043 vbuf
->sequence
= inst
->sequence_out
++;
1046 v4l2_m2m_buf_done(vbuf
, VB2_BUF_STATE_DONE
);
1049 static void venc_event_notify(struct venus_inst
*inst
, u32 event
,
1050 struct hfi_event_data
*data
)
1052 struct device
*dev
= inst
->core
->dev_enc
;
1054 if (event
== EVT_SESSION_ERROR
) {
1055 inst
->session_error
= true;
1056 dev_err(dev
, "enc: event session error %x\n", inst
->error
);
1060 static const struct hfi_inst_ops venc_hfi_ops
= {
1061 .buf_done
= venc_buf_done
,
1062 .event_notify
= venc_event_notify
,
1065 static const struct v4l2_m2m_ops venc_m2m_ops
= {
1066 .device_run
= venus_helper_m2m_device_run
,
1067 .job_abort
= venus_helper_m2m_job_abort
,
1070 static int m2m_queue_init(void *priv
, struct vb2_queue
*src_vq
,
1071 struct vb2_queue
*dst_vq
)
1073 struct venus_inst
*inst
= priv
;
1076 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
1077 src_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
1078 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1079 src_vq
->ops
= &venc_vb2_ops
;
1080 src_vq
->mem_ops
= &vb2_dma_sg_memops
;
1081 src_vq
->drv_priv
= inst
;
1082 src_vq
->buf_struct_size
= sizeof(struct venus_buffer
);
1083 src_vq
->allow_zero_bytesused
= 1;
1084 src_vq
->min_buffers_needed
= 1;
1085 src_vq
->dev
= inst
->core
->dev
;
1086 if (inst
->core
->res
->hfi_version
== HFI_VERSION_1XX
)
1087 src_vq
->bidirectional
= 1;
1088 ret
= vb2_queue_init(src_vq
);
1092 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
1093 dst_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
1094 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
1095 dst_vq
->ops
= &venc_vb2_ops
;
1096 dst_vq
->mem_ops
= &vb2_dma_sg_memops
;
1097 dst_vq
->drv_priv
= inst
;
1098 dst_vq
->buf_struct_size
= sizeof(struct venus_buffer
);
1099 dst_vq
->allow_zero_bytesused
= 1;
1100 dst_vq
->min_buffers_needed
= 1;
1101 dst_vq
->dev
= inst
->core
->dev
;
1102 ret
= vb2_queue_init(dst_vq
);
1104 vb2_queue_release(src_vq
);
1111 static void venc_inst_init(struct venus_inst
*inst
)
1113 inst
->fmt_cap
= &venc_formats
[2];
1114 inst
->fmt_out
= &venc_formats
[0];
1116 inst
->height
= ALIGN(720, 32);
1117 inst
->out_width
= 1280;
1118 inst
->out_height
= 720;
1120 inst
->timeperframe
.numerator
= 1;
1121 inst
->timeperframe
.denominator
= 15;
1122 inst
->hfi_codec
= HFI_VIDEO_CODEC_H264
;
1125 static int venc_open(struct file
*file
)
1127 struct venus_core
*core
= video_drvdata(file
);
1128 struct venus_inst
*inst
;
1131 inst
= kzalloc(sizeof(*inst
), GFP_KERNEL
);
1135 INIT_LIST_HEAD(&inst
->dpbbufs
);
1136 INIT_LIST_HEAD(&inst
->registeredbufs
);
1137 INIT_LIST_HEAD(&inst
->internalbufs
);
1138 INIT_LIST_HEAD(&inst
->list
);
1139 mutex_init(&inst
->lock
);
1142 inst
->session_type
= VIDC_SESSION_TYPE_ENC
;
1144 venus_helper_init_instance(inst
);
1146 ret
= pm_runtime_get_sync(core
->dev_enc
);
1150 ret
= venc_ctrl_init(inst
);
1154 ret
= hfi_session_create(inst
, &venc_hfi_ops
);
1156 goto err_ctrl_deinit
;
1158 venc_inst_init(inst
);
1161 * create m2m device for every instance, the m2m context scheduling
1162 * is made by firmware side so we do not need to care about.
1164 inst
->m2m_dev
= v4l2_m2m_init(&venc_m2m_ops
);
1165 if (IS_ERR(inst
->m2m_dev
)) {
1166 ret
= PTR_ERR(inst
->m2m_dev
);
1167 goto err_session_destroy
;
1170 inst
->m2m_ctx
= v4l2_m2m_ctx_init(inst
->m2m_dev
, inst
, m2m_queue_init
);
1171 if (IS_ERR(inst
->m2m_ctx
)) {
1172 ret
= PTR_ERR(inst
->m2m_ctx
);
1173 goto err_m2m_release
;
1176 v4l2_fh_init(&inst
->fh
, core
->vdev_enc
);
1178 inst
->fh
.ctrl_handler
= &inst
->ctrl_handler
;
1179 v4l2_fh_add(&inst
->fh
);
1180 inst
->fh
.m2m_ctx
= inst
->m2m_ctx
;
1181 file
->private_data
= &inst
->fh
;
1186 v4l2_m2m_release(inst
->m2m_dev
);
1187 err_session_destroy
:
1188 hfi_session_destroy(inst
);
1190 venc_ctrl_deinit(inst
);
1192 pm_runtime_put_sync(core
->dev_enc
);
1198 static int venc_close(struct file
*file
)
1200 struct venus_inst
*inst
= to_inst(file
);
1202 v4l2_m2m_ctx_release(inst
->m2m_ctx
);
1203 v4l2_m2m_release(inst
->m2m_dev
);
1204 venc_ctrl_deinit(inst
);
1205 hfi_session_destroy(inst
);
1206 mutex_destroy(&inst
->lock
);
1207 v4l2_fh_del(&inst
->fh
);
1208 v4l2_fh_exit(&inst
->fh
);
1210 pm_runtime_put_sync(inst
->core
->dev_enc
);
1216 static const struct v4l2_file_operations venc_fops
= {
1217 .owner
= THIS_MODULE
,
1219 .release
= venc_close
,
1220 .unlocked_ioctl
= video_ioctl2
,
1221 .poll
= v4l2_m2m_fop_poll
,
1222 .mmap
= v4l2_m2m_fop_mmap
,
1223 #ifdef CONFIG_COMPAT
1224 .compat_ioctl32
= v4l2_compat_ioctl32
,
1228 static int venc_probe(struct platform_device
*pdev
)
1230 struct device
*dev
= &pdev
->dev
;
1231 struct video_device
*vdev
;
1232 struct venus_core
*core
;
1236 return -EPROBE_DEFER
;
1238 core
= dev_get_drvdata(dev
->parent
);
1240 return -EPROBE_DEFER
;
1242 if (IS_V3(core
) || IS_V4(core
)) {
1243 core
->core1_clk
= devm_clk_get(dev
, "core");
1244 if (IS_ERR(core
->core1_clk
))
1245 return PTR_ERR(core
->core1_clk
);
1249 core
->core1_bus_clk
= devm_clk_get(dev
, "bus");
1250 if (IS_ERR(core
->core1_bus_clk
))
1251 return PTR_ERR(core
->core1_bus_clk
);
1254 platform_set_drvdata(pdev
, core
);
1256 vdev
= video_device_alloc();
1260 strlcpy(vdev
->name
, "qcom-venus-encoder", sizeof(vdev
->name
));
1261 vdev
->release
= video_device_release
;
1262 vdev
->fops
= &venc_fops
;
1263 vdev
->ioctl_ops
= &venc_ioctl_ops
;
1264 vdev
->vfl_dir
= VFL_DIR_M2M
;
1265 vdev
->v4l2_dev
= &core
->v4l2_dev
;
1266 vdev
->device_caps
= V4L2_CAP_VIDEO_M2M_MPLANE
| V4L2_CAP_STREAMING
;
1268 ret
= video_register_device(vdev
, VFL_TYPE_GRABBER
, -1);
1270 goto err_vdev_release
;
1272 core
->vdev_enc
= vdev
;
1273 core
->dev_enc
= dev
;
1275 video_set_drvdata(vdev
, core
);
1276 pm_runtime_enable(dev
);
1281 video_device_release(vdev
);
1285 static int venc_remove(struct platform_device
*pdev
)
1287 struct venus_core
*core
= dev_get_drvdata(pdev
->dev
.parent
);
1289 video_unregister_device(core
->vdev_enc
);
1290 pm_runtime_disable(core
->dev_enc
);
1295 static __maybe_unused
int venc_runtime_suspend(struct device
*dev
)
1297 struct venus_core
*core
= dev_get_drvdata(dev
);
1303 ret
= venus_helper_power_enable(core
, VIDC_SESSION_TYPE_ENC
, true);
1308 clk_disable_unprepare(core
->core1_bus_clk
);
1310 clk_disable_unprepare(core
->core1_clk
);
1312 return venus_helper_power_enable(core
, VIDC_SESSION_TYPE_ENC
, false);
1315 static __maybe_unused
int venc_runtime_resume(struct device
*dev
)
1317 struct venus_core
*core
= dev_get_drvdata(dev
);
1323 ret
= venus_helper_power_enable(core
, VIDC_SESSION_TYPE_ENC
, true);
1327 ret
= clk_prepare_enable(core
->core1_clk
);
1329 goto err_power_disable
;
1332 ret
= clk_prepare_enable(core
->core1_bus_clk
);
1335 goto err_unprepare_core1
;
1337 return venus_helper_power_enable(core
, VIDC_SESSION_TYPE_ENC
, false);
1339 err_unprepare_core1
:
1340 clk_disable_unprepare(core
->core1_clk
);
1342 venus_helper_power_enable(core
, VIDC_SESSION_TYPE_ENC
, false);
1346 static const struct dev_pm_ops venc_pm_ops
= {
1347 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
1348 pm_runtime_force_resume
)
1349 SET_RUNTIME_PM_OPS(venc_runtime_suspend
, venc_runtime_resume
, NULL
)
1352 static const struct of_device_id venc_dt_match
[] = {
1353 { .compatible
= "venus-encoder" },
1356 MODULE_DEVICE_TABLE(of
, venc_dt_match
);
1358 static struct platform_driver qcom_venus_enc_driver
= {
1359 .probe
= venc_probe
,
1360 .remove
= venc_remove
,
1362 .name
= "qcom-venus-encoder",
1363 .of_match_table
= venc_dt_match
,
1367 module_platform_driver(qcom_venus_enc_driver
);
1369 MODULE_ALIAS("platform:qcom-venus-encoder");
1370 MODULE_DESCRIPTION("Qualcomm Venus video encoder driver");
1371 MODULE_LICENSE("GPL v2");