hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/platform/qcom/venus/vdec.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
34 * 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
- *
145 */
156 #include <linux/clk.h>
167 #include <linux/module.h>
....@@ -29,6 +20,7 @@
2920 #include "core.h"
3021 #include "helpers.h"
3122 #include "vdec.h"
23
+#include "pm_helpers.h"
3224
3325 /*
3426 * Three resons to keep MPLANE formats (despite that the number of planes
....@@ -46,42 +38,52 @@
4638 .pixfmt = V4L2_PIX_FMT_MPEG4,
4739 .num_planes = 1,
4840 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
41
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
4942 }, {
5043 .pixfmt = V4L2_PIX_FMT_MPEG2,
5144 .num_planes = 1,
5245 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
46
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
5347 }, {
5448 .pixfmt = V4L2_PIX_FMT_H263,
5549 .num_planes = 1,
5650 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
51
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
5752 }, {
5853 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
5954 .num_planes = 1,
6055 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
56
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
6157 }, {
6258 .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
6359 .num_planes = 1,
6460 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
61
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
6562 }, {
6663 .pixfmt = V4L2_PIX_FMT_H264,
6764 .num_planes = 1,
6865 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
66
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
6967 }, {
7068 .pixfmt = V4L2_PIX_FMT_VP8,
7169 .num_planes = 1,
7270 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
71
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
7372 }, {
7473 .pixfmt = V4L2_PIX_FMT_VP9,
7574 .num_planes = 1,
7675 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
76
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
7777 }, {
7878 .pixfmt = V4L2_PIX_FMT_XVID,
7979 .num_planes = 1,
8080 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
81
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
8182 }, {
8283 .pixfmt = V4L2_PIX_FMT_HEVC,
8384 .num_planes = 1,
8485 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
86
+ .flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
8587 },
8688 };
8789
....@@ -142,6 +144,7 @@
142144 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
143145 struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
144146 const struct venus_format *fmt;
147
+ u32 szimage;
145148
146149 memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
147150 memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
....@@ -155,6 +158,8 @@
155158 else
156159 return NULL;
157160 fmt = find_format(inst, pixmp->pixelformat, f->type);
161
+ if (!fmt)
162
+ return NULL;
158163 }
159164
160165 pixmp->width = clamp(pixmp->width, frame_width_min(inst),
....@@ -170,14 +175,17 @@
170175 pixmp->num_planes = fmt->num_planes;
171176 pixmp->flags = 0;
172177
173
- pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
174
- pixmp->width,
175
- pixmp->height);
178
+ szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width,
179
+ pixmp->height);
176180
177
- if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
181
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
182
+ pfmt[0].sizeimage = szimage;
178183 pfmt[0].bytesperline = ALIGN(pixmp->width, 128);
179
- else
184
+ } else {
185
+ pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_8M);
186
+ pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage);
180187 pfmt[0].bytesperline = 0;
188
+ }
181189
182190 return fmt;
183191 }
....@@ -191,33 +199,56 @@
191199 return 0;
192200 }
193201
202
+static int vdec_check_src_change(struct venus_inst *inst)
203
+{
204
+ int ret;
205
+
206
+ if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE &&
207
+ inst->codec_state == VENUS_DEC_STATE_INIT &&
208
+ !inst->reconfig)
209
+ return -EINVAL;
210
+
211
+ if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE)
212
+ return 0;
213
+
214
+ /*
215
+ * The code snippet below is a workaround for backward compatibility
216
+ * with applications which doesn't support V4L2 events. It will be
217
+ * dropped in future once those applications are fixed.
218
+ */
219
+
220
+ if (inst->codec_state != VENUS_DEC_STATE_INIT)
221
+ goto done;
222
+
223
+ ret = wait_event_timeout(inst->reconf_wait, inst->reconfig,
224
+ msecs_to_jiffies(100));
225
+ if (!ret)
226
+ return -EINVAL;
227
+
228
+ if (!(inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) ||
229
+ !inst->reconfig)
230
+ dev_dbg(inst->core->dev, VDBGH "wrong state\n");
231
+
232
+done:
233
+ return 0;
234
+}
235
+
194236 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
195237 {
196238 struct venus_inst *inst = to_inst(file);
197239 const struct venus_format *fmt = NULL;
198240 struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
241
+ int ret;
199242
200243 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
201244 fmt = inst->fmt_cap;
202245 else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
203246 fmt = inst->fmt_out;
204247
205
- if (inst->reconfig) {
206
- struct v4l2_format format = {};
207
-
208
- inst->out_width = inst->reconfig_width;
209
- inst->out_height = inst->reconfig_height;
210
- inst->reconfig = false;
211
-
212
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
213
- format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
214
- format.fmt.pix_mp.width = inst->out_width;
215
- format.fmt.pix_mp.height = inst->out_height;
216
-
217
- vdec_try_fmt_common(inst, &format);
218
-
219
- inst->width = format.fmt.pix_mp.width;
220
- inst->height = format.fmt.pix_mp.height;
248
+ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
249
+ ret = vdec_check_src_change(inst);
250
+ if (ret)
251
+ return ret;
221252 }
222253
223254 pixmp->pixelformat = fmt->pixfmt;
....@@ -247,6 +278,14 @@
247278 const struct venus_format *fmt;
248279 struct v4l2_format format;
249280 u32 pixfmt_out = 0, pixfmt_cap = 0;
281
+ struct vb2_queue *q;
282
+
283
+ q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
284
+ if (!q)
285
+ return -EINVAL;
286
+
287
+ if (vb2_is_busy(q))
288
+ return -EBUSY;
250289
251290 orig_pixmp = *pixmp;
252291
....@@ -275,6 +314,7 @@
275314 inst->ycbcr_enc = pixmp->ycbcr_enc;
276315 inst->quantization = pixmp->quantization;
277316 inst->xfer_func = pixmp->xfer_func;
317
+ inst->input_buf_size = pixmp->plane_fmt[0].sizeimage;
278318 }
279319
280320 memset(&format, 0, sizeof(format));
....@@ -341,9 +381,9 @@
341381 static int
342382 vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
343383 {
344
- strlcpy(cap->driver, "qcom-venus", sizeof(cap->driver));
345
- strlcpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
346
- strlcpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
384
+ strscpy(cap->driver, "qcom-venus", sizeof(cap->driver));
385
+ strscpy(cap->card, "Qualcomm Venus video decoder", sizeof(cap->card));
386
+ strscpy(cap->bus_info, "platform:qcom-venus", sizeof(cap->bus_info));
347387
348388 return 0;
349389 }
....@@ -360,6 +400,7 @@
360400 return -EINVAL;
361401
362402 f->pixelformat = fmt->pixfmt;
403
+ f->flags = fmt->flags;
363404
364405 return 0;
365406 }
....@@ -431,11 +472,18 @@
431472 static int vdec_subscribe_event(struct v4l2_fh *fh,
432473 const struct v4l2_event_subscription *sub)
433474 {
475
+ struct venus_inst *inst = container_of(fh, struct venus_inst, fh);
476
+ int ret;
477
+
434478 switch (sub->type) {
435479 case V4L2_EVENT_EOS:
436480 return v4l2_event_subscribe(fh, sub, 2, NULL);
437481 case V4L2_EVENT_SOURCE_CHANGE:
438
- return v4l2_src_change_event_subscribe(fh, sub);
482
+ ret = v4l2_src_change_event_subscribe(fh, sub);
483
+ if (ret)
484
+ return ret;
485
+ inst->subscriptions |= V4L2_EVENT_SOURCE_CHANGE;
486
+ return 0;
439487 case V4L2_EVENT_CTRL:
440488 return v4l2_ctrl_subscribe_event(fh, sub);
441489 default:
....@@ -444,45 +492,45 @@
444492 }
445493
446494 static int
447
-vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
448
-{
449
- switch (cmd->cmd) {
450
- case V4L2_DEC_CMD_STOP:
451
- if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
452
- return -EINVAL;
453
- break;
454
- default:
455
- return -EINVAL;
456
- }
457
-
458
- return 0;
459
-}
460
-
461
-static int
462495 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
463496 {
464497 struct venus_inst *inst = to_inst(file);
498
+ struct vb2_queue *dst_vq;
465499 struct hfi_frame_data fdata = {0};
466500 int ret;
467501
468
- ret = vdec_try_decoder_cmd(file, fh, cmd);
502
+ ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
469503 if (ret)
470504 return ret;
471505
472506 mutex_lock(&inst->lock);
473507
474
- /*
475
- * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
476
- * input to signal EOS.
477
- */
478
- if (!(inst->streamon_out & inst->streamon_cap))
479
- goto unlock;
508
+ if (cmd->cmd == V4L2_DEC_CMD_STOP) {
509
+ /*
510
+ * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on
511
+ * decoder input to signal EOS.
512
+ */
513
+ if (!(inst->streamon_out && inst->streamon_cap))
514
+ goto unlock;
480515
481
- fdata.buffer_type = HFI_BUFFER_INPUT;
482
- fdata.flags |= HFI_BUFFERFLAG_EOS;
483
- fdata.device_addr = 0xdeadbeef;
516
+ fdata.buffer_type = HFI_BUFFER_INPUT;
517
+ fdata.flags |= HFI_BUFFERFLAG_EOS;
518
+ fdata.device_addr = 0xdeadb000;
484519
485
- ret = hfi_session_process_buf(inst, &fdata);
520
+ ret = hfi_session_process_buf(inst, &fdata);
521
+
522
+ if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) {
523
+ inst->codec_state = VENUS_DEC_STATE_DRAIN;
524
+ inst->drain_active = true;
525
+ }
526
+ } else if (cmd->cmd == V4L2_DEC_CMD_START &&
527
+ inst->codec_state == VENUS_DEC_STATE_STOPPED) {
528
+ dst_vq = v4l2_m2m_get_vq(inst->fh.m2m_ctx,
529
+ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
530
+ vb2_clear_last_buffer_dequeued(dst_vq);
531
+
532
+ inst->codec_state = VENUS_DEC_STATE_DECODING;
533
+ }
486534
487535 unlock:
488536 mutex_unlock(&inst->lock);
....@@ -491,8 +539,8 @@
491539
492540 static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
493541 .vidioc_querycap = vdec_querycap,
494
- .vidioc_enum_fmt_vid_cap_mplane = vdec_enum_fmt,
495
- .vidioc_enum_fmt_vid_out_mplane = vdec_enum_fmt,
542
+ .vidioc_enum_fmt_vid_cap = vdec_enum_fmt,
543
+ .vidioc_enum_fmt_vid_out = vdec_enum_fmt,
496544 .vidioc_s_fmt_vid_cap_mplane = vdec_s_fmt,
497545 .vidioc_s_fmt_vid_out_mplane = vdec_s_fmt,
498546 .vidioc_g_fmt_vid_cap_mplane = vdec_g_fmt,
....@@ -513,9 +561,67 @@
513561 .vidioc_enum_framesizes = vdec_enum_framesizes,
514562 .vidioc_subscribe_event = vdec_subscribe_event,
515563 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
516
- .vidioc_try_decoder_cmd = vdec_try_decoder_cmd,
564
+ .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
517565 .vidioc_decoder_cmd = vdec_decoder_cmd,
518566 };
567
+
568
+static int vdec_pm_get(struct venus_inst *inst)
569
+{
570
+ struct venus_core *core = inst->core;
571
+ struct device *dev = core->dev_dec;
572
+ int ret;
573
+
574
+ mutex_lock(&core->pm_lock);
575
+ ret = pm_runtime_get_sync(dev);
576
+ mutex_unlock(&core->pm_lock);
577
+
578
+ return ret < 0 ? ret : 0;
579
+}
580
+
581
+static int vdec_pm_put(struct venus_inst *inst, bool autosuspend)
582
+{
583
+ struct venus_core *core = inst->core;
584
+ struct device *dev = core->dev_dec;
585
+ int ret;
586
+
587
+ mutex_lock(&core->pm_lock);
588
+
589
+ if (autosuspend)
590
+ ret = pm_runtime_put_autosuspend(dev);
591
+ else
592
+ ret = pm_runtime_put_sync(dev);
593
+
594
+ mutex_unlock(&core->pm_lock);
595
+
596
+ return ret < 0 ? ret : 0;
597
+}
598
+
599
+static int vdec_pm_get_put(struct venus_inst *inst)
600
+{
601
+ struct venus_core *core = inst->core;
602
+ struct device *dev = core->dev_dec;
603
+ int ret = 0;
604
+
605
+ mutex_lock(&core->pm_lock);
606
+
607
+ if (pm_runtime_suspended(dev)) {
608
+ ret = pm_runtime_get_sync(dev);
609
+ if (ret < 0)
610
+ goto error;
611
+
612
+ ret = pm_runtime_put_autosuspend(dev);
613
+ }
614
+
615
+error:
616
+ mutex_unlock(&core->pm_lock);
617
+
618
+ return ret < 0 ? ret : 0;
619
+}
620
+
621
+static void vdec_pm_touch(struct venus_inst *inst)
622
+{
623
+ pm_runtime_mark_last_busy(inst->core->dev_dec);
624
+}
519625
520626 static int vdec_set_properties(struct venus_inst *inst)
521627 {
....@@ -540,6 +646,7 @@
540646 {
541647 struct venus_core *core = inst->core;
542648 struct hfi_enable en = { .enable = 1 };
649
+ struct hfi_buffer_requirements bufreq;
543650 u32 width = inst->out_width;
544651 u32 height = inst->out_height;
545652 u32 out_fmt, out2_fmt;
....@@ -548,10 +655,6 @@
548655 int ret;
549656
550657 ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2);
551
- if (ret)
552
- return ret;
553
-
554
- ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_1);
555658 if (ret)
556659 return ret;
557660
....@@ -619,6 +722,23 @@
619722 }
620723
621724 if (IS_V3(core) || IS_V4(core)) {
725
+ ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
726
+ if (ret)
727
+ return ret;
728
+
729
+ if (bufreq.size > inst->output_buf_size)
730
+ return -EINVAL;
731
+
732
+ if (inst->dpb_fmt) {
733
+ ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT2,
734
+ &bufreq);
735
+ if (ret)
736
+ return ret;
737
+
738
+ if (bufreq.size > inst->output2_buf_size)
739
+ return -EINVAL;
740
+ }
741
+
622742 if (inst->output2_buf_size) {
623743 ret = venus_helper_set_bufsize(inst,
624744 inst->output2_buf_size,
....@@ -643,20 +763,22 @@
643763 return 0;
644764 }
645765
646
-static int vdec_init_session(struct venus_inst *inst)
766
+static int vdec_session_init(struct venus_inst *inst)
647767 {
648768 int ret;
649769
650770 ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
651
- if (ret)
771
+ if (ret == -EINVAL)
772
+ return 0;
773
+ else if (ret)
652774 return ret;
653775
654
- ret = venus_helper_set_input_resolution(inst, inst->out_width,
655
- inst->out_height);
776
+ ret = venus_helper_set_input_resolution(inst, frame_width_min(inst),
777
+ frame_height_min(inst));
656778 if (ret)
657779 goto deinit;
658780
659
- ret = venus_helper_set_color_format(inst, inst->fmt_cap->pixfmt);
781
+ ret = venus_helper_init_codec_freq_data(inst);
660782 if (ret)
661783 goto deinit;
662784
....@@ -675,26 +797,19 @@
675797
676798 *in_num = *out_num = 0;
677799
678
- ret = vdec_init_session(inst);
679
- if (ret)
680
- return ret;
681
-
682800 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
683801 if (ret)
684
- goto deinit;
802
+ return ret;
685803
686804 *in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
687805
688806 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
689807 if (ret)
690
- goto deinit;
808
+ return ret;
691809
692810 *out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
693811
694
-deinit:
695
- hfi_session_deinit(inst);
696
-
697
- return ret;
812
+ return 0;
698813 }
699814
700815 static int vdec_queue_setup(struct vb2_queue *q,
....@@ -727,7 +842,19 @@
727842 return 0;
728843 }
729844
845
+ ret = vdec_pm_get(inst);
846
+ if (ret)
847
+ return ret;
848
+
849
+ ret = vdec_session_init(inst);
850
+ if (ret)
851
+ goto put_power;
852
+
730853 ret = vdec_num_buffers(inst, &in_num, &out_num);
854
+ if (ret)
855
+ goto put_power;
856
+
857
+ ret = vdec_pm_put(inst, false);
731858 if (ret)
732859 return ret;
733860
....@@ -737,6 +864,7 @@
737864 sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,
738865 inst->out_width,
739866 inst->out_height);
867
+ sizes[0] = max(sizes[0], inst->input_buf_size);
740868 inst->input_buf_size = sizes[0];
741869 *num_buffers = max(*num_buffers, in_num);
742870 inst->num_input_bufs = *num_buffers;
....@@ -750,12 +878,21 @@
750878 inst->output_buf_size = sizes[0];
751879 *num_buffers = max(*num_buffers, out_num);
752880 inst->num_output_bufs = *num_buffers;
881
+
882
+ mutex_lock(&inst->lock);
883
+ if (inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP)
884
+ inst->codec_state = VENUS_DEC_STATE_STOPPED;
885
+ mutex_unlock(&inst->lock);
753886 break;
754887 default:
755888 ret = -EINVAL;
756889 break;
757890 }
758891
892
+ return ret;
893
+
894
+put_power:
895
+ vdec_pm_put(inst, false);
759896 return ret;
760897 }
761898
....@@ -786,6 +923,137 @@
786923 return 0;
787924 }
788925
926
+static int vdec_start_capture(struct venus_inst *inst)
927
+{
928
+ int ret;
929
+
930
+ if (!inst->streamon_out)
931
+ return 0;
932
+
933
+ if (inst->codec_state == VENUS_DEC_STATE_DECODING) {
934
+ if (inst->reconfig)
935
+ goto reconfigure;
936
+
937
+ venus_helper_queue_dpb_bufs(inst);
938
+ venus_helper_process_initial_cap_bufs(inst);
939
+ inst->streamon_cap = 1;
940
+ return 0;
941
+ }
942
+
943
+ if (inst->codec_state != VENUS_DEC_STATE_STOPPED)
944
+ return 0;
945
+
946
+reconfigure:
947
+ ret = vdec_output_conf(inst);
948
+ if (ret)
949
+ return ret;
950
+
951
+ ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
952
+ VB2_MAX_FRAME, VB2_MAX_FRAME);
953
+ if (ret)
954
+ return ret;
955
+
956
+ ret = venus_helper_intbufs_realloc(inst);
957
+ if (ret)
958
+ goto err;
959
+
960
+ ret = venus_helper_alloc_dpb_bufs(inst);
961
+ if (ret)
962
+ goto err;
963
+
964
+ ret = venus_helper_queue_dpb_bufs(inst);
965
+ if (ret)
966
+ goto free_dpb_bufs;
967
+
968
+ ret = venus_helper_process_initial_cap_bufs(inst);
969
+ if (ret)
970
+ goto free_dpb_bufs;
971
+
972
+ venus_pm_load_scale(inst);
973
+
974
+ inst->next_buf_last = false;
975
+
976
+ ret = hfi_session_continue(inst);
977
+ if (ret)
978
+ goto free_dpb_bufs;
979
+
980
+ inst->codec_state = VENUS_DEC_STATE_DECODING;
981
+
982
+ if (inst->drain_active)
983
+ inst->codec_state = VENUS_DEC_STATE_DRAIN;
984
+
985
+ inst->streamon_cap = 1;
986
+ inst->sequence_cap = 0;
987
+ inst->reconfig = false;
988
+ inst->drain_active = false;
989
+
990
+ return 0;
991
+
992
+free_dpb_bufs:
993
+ venus_helper_free_dpb_bufs(inst);
994
+err:
995
+ return ret;
996
+}
997
+
998
+static int vdec_start_output(struct venus_inst *inst)
999
+{
1000
+ int ret;
1001
+
1002
+ if (inst->codec_state == VENUS_DEC_STATE_SEEK) {
1003
+ ret = venus_helper_process_initial_out_bufs(inst);
1004
+ if (inst->next_buf_last)
1005
+ inst->codec_state = VENUS_DEC_STATE_DRC;
1006
+ else
1007
+ inst->codec_state = VENUS_DEC_STATE_DECODING;
1008
+ goto done;
1009
+ }
1010
+
1011
+ if (inst->codec_state == VENUS_DEC_STATE_INIT ||
1012
+ inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) {
1013
+ ret = venus_helper_process_initial_out_bufs(inst);
1014
+ goto done;
1015
+ }
1016
+
1017
+ if (inst->codec_state != VENUS_DEC_STATE_DEINIT)
1018
+ return -EINVAL;
1019
+
1020
+ venus_helper_init_instance(inst);
1021
+ inst->sequence_out = 0;
1022
+ inst->reconfig = false;
1023
+ inst->next_buf_last = false;
1024
+
1025
+ ret = vdec_set_properties(inst);
1026
+ if (ret)
1027
+ return ret;
1028
+
1029
+ ret = vdec_output_conf(inst);
1030
+ if (ret)
1031
+ return ret;
1032
+
1033
+ ret = vdec_verify_conf(inst);
1034
+ if (ret)
1035
+ return ret;
1036
+
1037
+ ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
1038
+ VB2_MAX_FRAME, VB2_MAX_FRAME);
1039
+ if (ret)
1040
+ return ret;
1041
+
1042
+ ret = venus_helper_vb2_start_streaming(inst);
1043
+ if (ret)
1044
+ return ret;
1045
+
1046
+ ret = venus_helper_process_initial_out_bufs(inst);
1047
+ if (ret)
1048
+ return ret;
1049
+
1050
+ inst->codec_state = VENUS_DEC_STATE_INIT;
1051
+
1052
+done:
1053
+ inst->streamon_out = 1;
1054
+ return ret;
1055
+}
1056
+
7891057 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
7901058 {
7911059 struct venus_inst *inst = vb2_get_drv_priv(q);
....@@ -793,74 +1061,220 @@
7931061
7941062 mutex_lock(&inst->lock);
7951063
796
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
797
- inst->streamon_out = 1;
798
- else
799
- inst->streamon_cap = 1;
1064
+ if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1065
+ ret = vdec_start_capture(inst);
1066
+ } else {
1067
+ ret = vdec_pm_get(inst);
1068
+ if (ret)
1069
+ goto error;
8001070
801
- if (!(inst->streamon_out & inst->streamon_cap)) {
802
- mutex_unlock(&inst->lock);
803
- return 0;
1071
+ ret = venus_pm_acquire_core(inst);
1072
+ if (ret)
1073
+ goto put_power;
1074
+
1075
+ ret = vdec_pm_put(inst, true);
1076
+ if (ret)
1077
+ goto error;
1078
+
1079
+ ret = vdec_start_output(inst);
8041080 }
8051081
806
- venus_helper_init_instance(inst);
807
-
808
- inst->reconfig = false;
809
- inst->sequence_cap = 0;
810
- inst->sequence_out = 0;
811
-
812
- ret = vdec_init_session(inst);
8131082 if (ret)
814
- goto bufs_done;
815
-
816
- ret = vdec_set_properties(inst);
817
- if (ret)
818
- goto deinit_sess;
819
-
820
- ret = vdec_output_conf(inst);
821
- if (ret)
822
- goto deinit_sess;
823
-
824
- ret = vdec_verify_conf(inst);
825
- if (ret)
826
- goto deinit_sess;
827
-
828
- ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
829
- VB2_MAX_FRAME, VB2_MAX_FRAME);
830
- if (ret)
831
- goto deinit_sess;
832
-
833
- ret = venus_helper_alloc_dpb_bufs(inst);
834
- if (ret)
835
- goto deinit_sess;
836
-
837
- ret = venus_helper_vb2_start_streaming(inst);
838
- if (ret)
839
- goto deinit_sess;
1083
+ goto error;
8401084
8411085 mutex_unlock(&inst->lock);
842
-
8431086 return 0;
8441087
845
-deinit_sess:
846
- hfi_session_deinit(inst);
847
-bufs_done:
848
- venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
849
- if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
850
- inst->streamon_out = 0;
851
- else
852
- inst->streamon_cap = 0;
1088
+put_power:
1089
+ vdec_pm_put(inst, false);
1090
+error:
1091
+ venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
8531092 mutex_unlock(&inst->lock);
8541093 return ret;
8551094 }
8561095
1096
+static void vdec_cancel_dst_buffers(struct venus_inst *inst)
1097
+{
1098
+ struct vb2_v4l2_buffer *buf;
1099
+
1100
+ while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
1101
+ v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
1102
+}
1103
+
1104
+static int vdec_stop_capture(struct venus_inst *inst)
1105
+{
1106
+ int ret = 0;
1107
+
1108
+ switch (inst->codec_state) {
1109
+ case VENUS_DEC_STATE_DECODING:
1110
+ ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
1111
+ fallthrough;
1112
+ case VENUS_DEC_STATE_DRAIN:
1113
+ inst->codec_state = VENUS_DEC_STATE_STOPPED;
1114
+ inst->drain_active = false;
1115
+ fallthrough;
1116
+ case VENUS_DEC_STATE_SEEK:
1117
+ vdec_cancel_dst_buffers(inst);
1118
+ break;
1119
+ case VENUS_DEC_STATE_DRC:
1120
+ ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, true);
1121
+ inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
1122
+ venus_helper_free_dpb_bufs(inst);
1123
+ break;
1124
+ default:
1125
+ break;
1126
+ }
1127
+
1128
+ return ret;
1129
+}
1130
+
1131
+static int vdec_stop_output(struct venus_inst *inst)
1132
+{
1133
+ int ret = 0;
1134
+
1135
+ switch (inst->codec_state) {
1136
+ case VENUS_DEC_STATE_DECODING:
1137
+ case VENUS_DEC_STATE_DRAIN:
1138
+ case VENUS_DEC_STATE_STOPPED:
1139
+ case VENUS_DEC_STATE_DRC:
1140
+ ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
1141
+ inst->codec_state = VENUS_DEC_STATE_SEEK;
1142
+ break;
1143
+ case VENUS_DEC_STATE_INIT:
1144
+ case VENUS_DEC_STATE_CAPTURE_SETUP:
1145
+ ret = hfi_session_flush(inst, HFI_FLUSH_INPUT, true);
1146
+ break;
1147
+ default:
1148
+ break;
1149
+ }
1150
+
1151
+ return ret;
1152
+}
1153
+
1154
+static void vdec_stop_streaming(struct vb2_queue *q)
1155
+{
1156
+ struct venus_inst *inst = vb2_get_drv_priv(q);
1157
+ int ret = -EINVAL;
1158
+
1159
+ mutex_lock(&inst->lock);
1160
+
1161
+ if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1162
+ ret = vdec_stop_capture(inst);
1163
+ else
1164
+ ret = vdec_stop_output(inst);
1165
+
1166
+ venus_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR);
1167
+
1168
+ if (ret)
1169
+ goto unlock;
1170
+
1171
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1172
+ inst->streamon_out = 0;
1173
+ else
1174
+ inst->streamon_cap = 0;
1175
+
1176
+unlock:
1177
+ mutex_unlock(&inst->lock);
1178
+}
1179
+
1180
+static void vdec_session_release(struct venus_inst *inst)
1181
+{
1182
+ struct venus_core *core = inst->core;
1183
+ int ret, abort = 0;
1184
+
1185
+ vdec_pm_get(inst);
1186
+
1187
+ mutex_lock(&inst->lock);
1188
+ inst->codec_state = VENUS_DEC_STATE_DEINIT;
1189
+
1190
+ ret = hfi_session_stop(inst);
1191
+ abort = (ret && ret != -EINVAL) ? 1 : 0;
1192
+ ret = hfi_session_unload_res(inst);
1193
+ abort = (ret && ret != -EINVAL) ? 1 : 0;
1194
+ ret = venus_helper_unregister_bufs(inst);
1195
+ abort = (ret && ret != -EINVAL) ? 1 : 0;
1196
+ ret = venus_helper_intbufs_free(inst);
1197
+ abort = (ret && ret != -EINVAL) ? 1 : 0;
1198
+ ret = hfi_session_deinit(inst);
1199
+ abort = (ret && ret != -EINVAL) ? 1 : 0;
1200
+
1201
+ if (inst->session_error || core->sys_error)
1202
+ abort = 1;
1203
+
1204
+ if (abort)
1205
+ hfi_session_abort(inst);
1206
+
1207
+ venus_helper_free_dpb_bufs(inst);
1208
+ venus_pm_load_scale(inst);
1209
+ INIT_LIST_HEAD(&inst->registeredbufs);
1210
+ mutex_unlock(&inst->lock);
1211
+
1212
+ venus_pm_release_core(inst);
1213
+ vdec_pm_put(inst, false);
1214
+}
1215
+
1216
+static int vdec_buf_init(struct vb2_buffer *vb)
1217
+{
1218
+ struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1219
+
1220
+ inst->buf_count++;
1221
+
1222
+ return venus_helper_vb2_buf_init(vb);
1223
+}
1224
+
1225
+static void vdec_buf_cleanup(struct vb2_buffer *vb)
1226
+{
1227
+ struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1228
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1229
+ struct venus_buffer *buf = to_venus_buffer(vbuf);
1230
+
1231
+ mutex_lock(&inst->lock);
1232
+ if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1233
+ if (!list_empty(&inst->registeredbufs))
1234
+ list_del_init(&buf->reg_list);
1235
+ mutex_unlock(&inst->lock);
1236
+
1237
+ inst->buf_count--;
1238
+ if (!inst->buf_count)
1239
+ vdec_session_release(inst);
1240
+}
1241
+
1242
+static void vdec_vb2_buf_queue(struct vb2_buffer *vb)
1243
+{
1244
+ struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
1245
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1246
+ static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS };
1247
+
1248
+ vdec_pm_get_put(inst);
1249
+
1250
+ mutex_lock(&inst->lock);
1251
+
1252
+ if (inst->next_buf_last && V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1253
+ inst->codec_state == VENUS_DEC_STATE_DRC) {
1254
+ vbuf->flags |= V4L2_BUF_FLAG_LAST;
1255
+ vbuf->sequence = inst->sequence_cap++;
1256
+ vbuf->field = V4L2_FIELD_NONE;
1257
+ vb2_set_plane_payload(vb, 0, 0);
1258
+ v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
1259
+ v4l2_event_queue_fh(&inst->fh, &eos);
1260
+ inst->next_buf_last = false;
1261
+ mutex_unlock(&inst->lock);
1262
+ return;
1263
+ }
1264
+
1265
+ mutex_unlock(&inst->lock);
1266
+
1267
+ venus_helper_vb2_buf_queue(vb);
1268
+}
1269
+
8571270 static const struct vb2_ops vdec_vb2_ops = {
8581271 .queue_setup = vdec_queue_setup,
859
- .buf_init = venus_helper_vb2_buf_init,
1272
+ .buf_init = vdec_buf_init,
1273
+ .buf_cleanup = vdec_buf_cleanup,
8601274 .buf_prepare = venus_helper_vb2_buf_prepare,
8611275 .start_streaming = vdec_start_streaming,
862
- .stop_streaming = venus_helper_vb2_stop_streaming,
863
- .buf_queue = venus_helper_vb2_buf_queue,
1276
+ .stop_streaming = vdec_stop_streaming,
1277
+ .buf_queue = vdec_vb2_buf_queue,
8641278 };
8651279
8661280 static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type,
....@@ -871,6 +1285,8 @@
8711285 struct vb2_v4l2_buffer *vbuf;
8721286 struct vb2_buffer *vb;
8731287 unsigned int type;
1288
+
1289
+ vdec_pm_touch(inst);
8741290
8751291 if (buf_type == HFI_BUFFER_INPUT)
8761292 type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
....@@ -883,12 +1299,10 @@
8831299
8841300 vbuf->flags = flags;
8851301 vbuf->field = V4L2_FIELD_NONE;
1302
+ vb = &vbuf->vb2_buf;
8861303
8871304 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
888
- unsigned int opb_sz = venus_helper_get_opb_size(inst);
889
-
890
- vb = &vbuf->vb2_buf;
891
- vb2_set_plane_payload(vb, 0, bytesused ? : opb_sz);
1305
+ vb2_set_plane_payload(vb, 0, bytesused);
8921306 vb->planes[0].data_offset = data_offset;
8931307 vb->timestamp = timestamp_us * NSEC_PER_USEC;
8941308 vbuf->sequence = inst->sequence_cap++;
....@@ -897,10 +1311,20 @@
8971311 const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
8981312
8991313 v4l2_event_queue_fh(&inst->fh, &ev);
1314
+
1315
+ if (inst->codec_state == VENUS_DEC_STATE_DRAIN) {
1316
+ inst->drain_active = false;
1317
+ inst->codec_state = VENUS_DEC_STATE_STOPPED;
1318
+ }
9001319 }
1320
+
1321
+ if (!bytesused)
1322
+ state = VB2_BUF_STATE_ERROR;
9011323 } else {
9021324 vbuf->sequence = inst->sequence_out++;
9031325 }
1326
+
1327
+ venus_helper_get_ts_metadata(inst, timestamp_us, vbuf);
9041328
9051329 if (hfi_flags & HFI_BUFFERFLAG_READONLY)
9061330 venus_helper_acquire_buf_ref(vbuf);
....@@ -908,7 +1332,79 @@
9081332 if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
9091333 state = VB2_BUF_STATE_ERROR;
9101334
1335
+ if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) {
1336
+ state = VB2_BUF_STATE_ERROR;
1337
+ vb2_set_plane_payload(vb, 0, 0);
1338
+ vb->timestamp = 0;
1339
+ }
1340
+
9111341 v4l2_m2m_buf_done(vbuf, state);
1342
+}
1343
+
1344
+static void vdec_event_change(struct venus_inst *inst,
1345
+ struct hfi_event_data *ev_data, bool sufficient)
1346
+{
1347
+ static const struct v4l2_event ev = {
1348
+ .type = V4L2_EVENT_SOURCE_CHANGE,
1349
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
1350
+ struct device *dev = inst->core->dev_dec;
1351
+ struct v4l2_format format = {};
1352
+
1353
+ mutex_lock(&inst->lock);
1354
+
1355
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1356
+ format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
1357
+ format.fmt.pix_mp.width = ev_data->width;
1358
+ format.fmt.pix_mp.height = ev_data->height;
1359
+
1360
+ vdec_try_fmt_common(inst, &format);
1361
+
1362
+ inst->width = format.fmt.pix_mp.width;
1363
+ inst->height = format.fmt.pix_mp.height;
1364
+
1365
+ inst->out_width = ev_data->width;
1366
+ inst->out_height = ev_data->height;
1367
+
1368
+ if (inst->bit_depth != ev_data->bit_depth)
1369
+ inst->bit_depth = ev_data->bit_depth;
1370
+
1371
+ dev_dbg(dev, VDBGM "event %s sufficient resources (%ux%u)\n",
1372
+ sufficient ? "" : "not", ev_data->width, ev_data->height);
1373
+
1374
+ switch (inst->codec_state) {
1375
+ case VENUS_DEC_STATE_INIT:
1376
+ inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
1377
+ break;
1378
+ case VENUS_DEC_STATE_DECODING:
1379
+ case VENUS_DEC_STATE_DRAIN:
1380
+ inst->codec_state = VENUS_DEC_STATE_DRC;
1381
+ break;
1382
+ default:
1383
+ break;
1384
+ }
1385
+
1386
+ /*
1387
+ * The assumption is that the firmware have to return the last buffer
1388
+ * before this event is received in the v4l2 driver. Also the firmware
1389
+ * itself doesn't mark the last decoder output buffer with HFI EOS flag.
1390
+ */
1391
+
1392
+ if (inst->codec_state == VENUS_DEC_STATE_DRC) {
1393
+ int ret;
1394
+
1395
+ inst->next_buf_last = true;
1396
+
1397
+ ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT, false);
1398
+ if (ret)
1399
+ dev_dbg(dev, VDBGH "flush output error %d\n", ret);
1400
+ }
1401
+
1402
+ inst->next_buf_last = true;
1403
+ inst->reconfig = true;
1404
+ v4l2_event_queue_fh(&inst->fh, &ev);
1405
+ wake_up(&inst->reconf_wait);
1406
+
1407
+ mutex_unlock(&inst->lock);
9121408 }
9131409
9141410 static void vdec_event_notify(struct venus_inst *inst, u32 event,
....@@ -916,9 +1412,8 @@
9161412 {
9171413 struct venus_core *core = inst->core;
9181414 struct device *dev = core->dev_dec;
919
- static const struct v4l2_event ev = {
920
- .type = V4L2_EVENT_SOURCE_CHANGE,
921
- .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
1415
+
1416
+ vdec_pm_touch(inst);
9221417
9231418 switch (event) {
9241419 case EVT_SESSION_ERROR:
....@@ -928,18 +1423,10 @@
9281423 case EVT_SYS_EVENT_CHANGE:
9291424 switch (data->event_type) {
9301425 case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
931
- hfi_session_continue(inst);
932
- dev_dbg(dev, "event sufficient resources\n");
1426
+ vdec_event_change(inst, data, true);
9331427 break;
9341428 case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
935
- inst->reconfig_height = data->height;
936
- inst->reconfig_width = data->width;
937
- inst->reconfig = true;
938
-
939
- v4l2_event_queue_fh(&inst->fh, &ev);
940
-
941
- dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
942
- data->width, data->height);
1429
+ vdec_event_change(inst, data, false);
9431430 break;
9441431 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
9451432 venus_helper_release_buf_ref(inst, data->tag);
....@@ -953,27 +1440,38 @@
9531440 }
9541441 }
9551442
1443
+static void vdec_flush_done(struct venus_inst *inst)
1444
+{
1445
+ dev_dbg(inst->core->dev_dec, VDBGH "flush done\n");
1446
+}
1447
+
9561448 static const struct hfi_inst_ops vdec_hfi_ops = {
9571449 .buf_done = vdec_buf_done,
9581450 .event_notify = vdec_event_notify,
1451
+ .flush_done = vdec_flush_done,
9591452 };
9601453
9611454 static void vdec_inst_init(struct venus_inst *inst)
9621455 {
1456
+ inst->hfi_codec = HFI_VIDEO_CODEC_H264;
9631457 inst->fmt_out = &vdec_formats[6];
9641458 inst->fmt_cap = &vdec_formats[0];
965
- inst->width = 1280;
966
- inst->height = ALIGN(720, 32);
967
- inst->out_width = 1280;
968
- inst->out_height = 720;
1459
+ inst->width = frame_width_min(inst);
1460
+ inst->height = ALIGN(frame_height_min(inst), 32);
1461
+ inst->out_width = frame_width_min(inst);
1462
+ inst->out_height = frame_height_min(inst);
9691463 inst->fps = 30;
9701464 inst->timeperframe.numerator = 1;
9711465 inst->timeperframe.denominator = 30;
972
- inst->hfi_codec = HFI_VIDEO_CODEC_H264;
1466
+ inst->opb_buftype = HFI_BUFFER_OUTPUT;
1467
+}
1468
+
1469
+static void vdec_m2m_device_run(void *priv)
1470
+{
9731471 }
9741472
9751473 static const struct v4l2_m2m_ops vdec_m2m_ops = {
976
- .device_run = venus_helper_m2m_device_run,
1474
+ .device_run = vdec_m2m_device_run,
9771475 .job_abort = venus_helper_m2m_job_abort,
9781476 };
9791477
....@@ -991,7 +1489,7 @@
9911489 src_vq->drv_priv = inst;
9921490 src_vq->buf_struct_size = sizeof(struct venus_buffer);
9931491 src_vq->allow_zero_bytesused = 1;
994
- src_vq->min_buffers_needed = 1;
1492
+ src_vq->min_buffers_needed = 0;
9951493 src_vq->dev = inst->core->dev;
9961494 ret = vb2_queue_init(src_vq);
9971495 if (ret)
....@@ -1005,15 +1503,9 @@
10051503 dst_vq->drv_priv = inst;
10061504 dst_vq->buf_struct_size = sizeof(struct venus_buffer);
10071505 dst_vq->allow_zero_bytesused = 1;
1008
- dst_vq->min_buffers_needed = 1;
1506
+ dst_vq->min_buffers_needed = 0;
10091507 dst_vq->dev = inst->core->dev;
1010
- ret = vb2_queue_init(dst_vq);
1011
- if (ret) {
1012
- vb2_queue_release(src_vq);
1013
- return ret;
1014
- }
1015
-
1016
- return 0;
1508
+ return vb2_queue_init(dst_vq);
10171509 }
10181510
10191511 static int vdec_open(struct file *file)
....@@ -1035,16 +1527,17 @@
10351527 inst->core = core;
10361528 inst->session_type = VIDC_SESSION_TYPE_DEC;
10371529 inst->num_output_bufs = 1;
1038
-
1530
+ inst->codec_state = VENUS_DEC_STATE_DEINIT;
1531
+ inst->buf_count = 0;
1532
+ inst->clk_data.core_id = VIDC_CORE_ID_DEFAULT;
1533
+ inst->core_acquired = false;
1534
+ inst->bit_depth = VIDC_BITDEPTH_8;
1535
+ init_waitqueue_head(&inst->reconf_wait);
10391536 venus_helper_init_instance(inst);
1040
-
1041
- ret = pm_runtime_get_sync(core->dev_dec);
1042
- if (ret < 0)
1043
- goto err_free_inst;
10441537
10451538 ret = vdec_ctrl_init(inst);
10461539 if (ret)
1047
- goto err_put_sync;
1540
+ goto err_free;
10481541
10491542 ret = hfi_session_create(inst, &vdec_hfi_ops);
10501543 if (ret)
....@@ -1083,9 +1576,7 @@
10831576 hfi_session_destroy(inst);
10841577 err_ctrl_deinit:
10851578 vdec_ctrl_deinit(inst);
1086
-err_put_sync:
1087
- pm_runtime_put_sync(core->dev_dec);
1088
-err_free_inst:
1579
+err_free:
10891580 kfree(inst);
10901581 return ret;
10911582 }
....@@ -1093,6 +1584,8 @@
10931584 static int vdec_close(struct file *file)
10941585 {
10951586 struct venus_inst *inst = to_inst(file);
1587
+
1588
+ vdec_pm_get(inst);
10961589
10971590 v4l2_m2m_ctx_release(inst->m2m_ctx);
10981591 v4l2_m2m_release(inst->m2m_dev);
....@@ -1102,7 +1595,7 @@
11021595 v4l2_fh_del(&inst->fh);
11031596 v4l2_fh_exit(&inst->fh);
11041597
1105
- pm_runtime_put_sync(inst->core->dev_dec);
1598
+ vdec_pm_put(inst, false);
11061599
11071600 kfree(inst);
11081601 return 0;
....@@ -1131,25 +1624,19 @@
11311624 if (!core)
11321625 return -EPROBE_DEFER;
11331626
1134
- if (IS_V3(core) || IS_V4(core)) {
1135
- core->core0_clk = devm_clk_get(dev, "core");
1136
- if (IS_ERR(core->core0_clk))
1137
- return PTR_ERR(core->core0_clk);
1138
- }
1139
-
1140
- if (IS_V4(core)) {
1141
- core->core0_bus_clk = devm_clk_get(dev, "bus");
1142
- if (IS_ERR(core->core0_bus_clk))
1143
- return PTR_ERR(core->core0_bus_clk);
1144
- }
1145
-
11461627 platform_set_drvdata(pdev, core);
1628
+
1629
+ if (core->pm_ops->vdec_get) {
1630
+ ret = core->pm_ops->vdec_get(dev);
1631
+ if (ret)
1632
+ return ret;
1633
+ }
11471634
11481635 vdev = video_device_alloc();
11491636 if (!vdev)
11501637 return -ENOMEM;
11511638
1152
- strlcpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
1639
+ strscpy(vdev->name, "qcom-venus-decoder", sizeof(vdev->name));
11531640 vdev->release = video_device_release;
11541641 vdev->fops = &vdec_fops;
11551642 vdev->ioctl_ops = &vdec_ioctl_ops;
....@@ -1157,7 +1644,7 @@
11571644 vdev->v4l2_dev = &core->v4l2_dev;
11581645 vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
11591646
1160
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1647
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
11611648 if (ret)
11621649 goto err_vdev_release;
11631650
....@@ -1165,6 +1652,8 @@
11651652 core->dev_dec = dev;
11661653
11671654 video_set_drvdata(vdev, core);
1655
+ pm_runtime_set_autosuspend_delay(dev, 2000);
1656
+ pm_runtime_use_autosuspend(dev);
11681657 pm_runtime_enable(dev);
11691658
11701659 return 0;
....@@ -1181,57 +1670,33 @@
11811670 video_unregister_device(core->vdev_dec);
11821671 pm_runtime_disable(core->dev_dec);
11831672
1673
+ if (core->pm_ops->vdec_put)
1674
+ core->pm_ops->vdec_put(core->dev_dec);
1675
+
11841676 return 0;
11851677 }
11861678
11871679 static __maybe_unused int vdec_runtime_suspend(struct device *dev)
11881680 {
11891681 struct venus_core *core = dev_get_drvdata(dev);
1190
- int ret;
1682
+ const struct venus_pm_ops *pm_ops = core->pm_ops;
1683
+ int ret = 0;
11911684
1192
- if (IS_V1(core))
1193
- return 0;
1685
+ if (pm_ops->vdec_power)
1686
+ ret = pm_ops->vdec_power(dev, POWER_OFF);
11941687
1195
- ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
1196
- if (ret)
1197
- return ret;
1198
-
1199
- if (IS_V4(core))
1200
- clk_disable_unprepare(core->core0_bus_clk);
1201
-
1202
- clk_disable_unprepare(core->core0_clk);
1203
-
1204
- return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
1688
+ return ret;
12051689 }
12061690
12071691 static __maybe_unused int vdec_runtime_resume(struct device *dev)
12081692 {
12091693 struct venus_core *core = dev_get_drvdata(dev);
1210
- int ret;
1694
+ const struct venus_pm_ops *pm_ops = core->pm_ops;
1695
+ int ret = 0;
12111696
1212
- if (IS_V1(core))
1213
- return 0;
1697
+ if (pm_ops->vdec_power)
1698
+ ret = pm_ops->vdec_power(dev, POWER_ON);
12141699
1215
- ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
1216
- if (ret)
1217
- return ret;
1218
-
1219
- ret = clk_prepare_enable(core->core0_clk);
1220
- if (ret)
1221
- goto err_power_disable;
1222
-
1223
- if (IS_V4(core))
1224
- ret = clk_prepare_enable(core->core0_bus_clk);
1225
-
1226
- if (ret)
1227
- goto err_unprepare_core0;
1228
-
1229
- return venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
1230
-
1231
-err_unprepare_core0:
1232
- clk_disable_unprepare(core->core0_clk);
1233
-err_power_disable:
1234
- venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
12351700 return ret;
12361701 }
12371702