hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/drivers/media/platform/qcom/venus/helpers.c
....@@ -1,23 +1,12 @@
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 */
15
-#include <linux/clk.h>
16
-#include <linux/iopoll.h>
176 #include <linux/list.h>
187 #include <linux/mutex.h>
19
-#include <linux/pm_runtime.h>
208 #include <linux/slab.h>
9
+#include <linux/kernel.h>
2110 #include <media/videobuf2-dma-sg.h>
2211 #include <media/v4l2-mem2mem.h>
2312 #include <asm/div64.h>
....@@ -25,7 +14,7 @@
2514 #include "core.h"
2615 #include "helpers.h"
2716 #include "hfi_helper.h"
28
-#include "hfi_venus_io.h"
17
+#include "pm_helpers.h"
2918
3019 struct intbuf {
3120 struct list_head list;
....@@ -88,7 +77,7 @@
8877 }
8978 EXPORT_SYMBOL_GPL(venus_helper_check_codec);
9079
91
-static int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
80
+int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
9281 {
9382 struct intbuf *buf;
9483 int ret = 0;
....@@ -109,6 +98,7 @@
10998 fail:
11099 return ret;
111100 }
101
+EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs);
112102
113103 int venus_helper_free_dpb_bufs(struct venus_inst *inst)
114104 {
....@@ -287,7 +277,7 @@
287277 HFI_BUFFER_INTERNAL_PERSIST_1,
288278 };
289279
290
-static int intbufs_alloc(struct venus_inst *inst)
280
+int venus_helper_intbufs_alloc(struct venus_inst *inst)
291281 {
292282 const unsigned int *intbuf;
293283 size_t arr_sz, i;
....@@ -313,90 +303,59 @@
313303 intbufs_unset_buffers(inst);
314304 return ret;
315305 }
306
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc);
316307
317
-static int intbufs_free(struct venus_inst *inst)
308
+int venus_helper_intbufs_free(struct venus_inst *inst)
318309 {
319310 return intbufs_unset_buffers(inst);
320311 }
312
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_free);
321313
322
-static u32 load_per_instance(struct venus_inst *inst)
314
+int venus_helper_intbufs_realloc(struct venus_inst *inst)
323315 {
324
- u32 mbs;
325
-
326
- if (!inst || !(inst->state >= INST_INIT && inst->state < INST_STOP))
327
- return 0;
328
-
329
- mbs = (ALIGN(inst->width, 16) / 16) * (ALIGN(inst->height, 16) / 16);
330
-
331
- return mbs * inst->fps;
332
-}
333
-
334
-static u32 load_per_type(struct venus_core *core, u32 session_type)
335
-{
336
- struct venus_inst *inst = NULL;
337
- u32 mbs_per_sec = 0;
338
-
339
- mutex_lock(&core->lock);
340
- list_for_each_entry(inst, &core->instances, list) {
341
- if (inst->session_type != session_type)
342
- continue;
343
-
344
- mbs_per_sec += load_per_instance(inst);
345
- }
346
- mutex_unlock(&core->lock);
347
-
348
- return mbs_per_sec;
349
-}
350
-
351
-static int load_scale_clocks(struct venus_core *core)
352
-{
353
- const struct freq_tbl *table = core->res->freq_tbl;
354
- unsigned int num_rows = core->res->freq_tbl_size;
355
- unsigned long freq = table[0].freq;
356
- struct clk *clk = core->clks[0];
357
- struct device *dev = core->dev;
358
- u32 mbs_per_sec;
359
- unsigned int i;
316
+ enum hfi_version ver = inst->core->res->hfi_version;
317
+ struct hfi_buffer_desc bd;
318
+ struct intbuf *buf, *n;
360319 int ret;
361320
362
- mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) +
363
- load_per_type(core, VIDC_SESSION_TYPE_DEC);
321
+ list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {
322
+ if (buf->type == HFI_BUFFER_INTERNAL_PERSIST ||
323
+ buf->type == HFI_BUFFER_INTERNAL_PERSIST_1)
324
+ continue;
364325
365
- if (mbs_per_sec > core->res->max_load)
366
- dev_warn(dev, "HW is overloaded, needed: %d max: %d\n",
367
- mbs_per_sec, core->res->max_load);
326
+ memset(&bd, 0, sizeof(bd));
327
+ bd.buffer_size = buf->size;
328
+ bd.buffer_type = buf->type;
329
+ bd.num_buffers = 1;
330
+ bd.device_addr = buf->da;
331
+ bd.response_required = true;
368332
369
- if (!mbs_per_sec && num_rows > 1) {
370
- freq = table[num_rows - 1].freq;
371
- goto set_freq;
333
+ ret = hfi_session_unset_buffers(inst, &bd);
334
+
335
+ dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
336
+ buf->attrs);
337
+
338
+ list_del_init(&buf->list);
339
+ kfree(buf);
372340 }
373341
374
- for (i = 0; i < num_rows; i++) {
375
- if (mbs_per_sec > table[i].load)
376
- break;
377
- freq = table[i].freq;
378
- }
379
-
380
-set_freq:
381
-
382
- ret = clk_set_rate(clk, freq);
342
+ ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver));
383343 if (ret)
384344 goto err;
385345
386
- ret = clk_set_rate(core->core0_clk, freq);
346
+ ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver));
387347 if (ret)
388348 goto err;
389349
390
- ret = clk_set_rate(core->core1_clk, freq);
350
+ ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver));
391351 if (ret)
392352 goto err;
393353
394354 return 0;
395
-
396355 err:
397
- dev_err(dev, "failed to set clock rate %lu (%d)\n", freq, ret);
398356 return ret;
399357 }
358
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);
400359
401360 static void fill_buffer_desc(const struct venus_buffer *buf,
402361 struct hfi_buffer_desc *bd, bool response)
....@@ -422,6 +381,57 @@
422381 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
423382 }
424383
384
+static void
385
+put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
386
+{
387
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
388
+ unsigned int i;
389
+ int slot = -1;
390
+ u64 ts_us = vb->timestamp;
391
+
392
+ for (i = 0; i < ARRAY_SIZE(inst->tss); i++) {
393
+ if (!inst->tss[i].used) {
394
+ slot = i;
395
+ break;
396
+ }
397
+ }
398
+
399
+ if (slot == -1) {
400
+ dev_dbg(inst->core->dev, VDBGL "no free slot\n");
401
+ return;
402
+ }
403
+
404
+ do_div(ts_us, NSEC_PER_USEC);
405
+
406
+ inst->tss[slot].used = true;
407
+ inst->tss[slot].flags = vbuf->flags;
408
+ inst->tss[slot].tc = vbuf->timecode;
409
+ inst->tss[slot].ts_us = ts_us;
410
+ inst->tss[slot].ts_ns = vb->timestamp;
411
+}
412
+
413
+void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
414
+ struct vb2_v4l2_buffer *vbuf)
415
+{
416
+ struct vb2_buffer *vb = &vbuf->vb2_buf;
417
+ unsigned int i;
418
+
419
+ for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) {
420
+ if (!inst->tss[i].used)
421
+ continue;
422
+
423
+ if (inst->tss[i].ts_us != timestamp_us)
424
+ continue;
425
+
426
+ inst->tss[i].used = false;
427
+ vbuf->flags |= inst->tss[i].flags;
428
+ vbuf->timecode = inst->tss[i].tc;
429
+ vb->timestamp = inst->tss[i].ts_ns;
430
+ break;
431
+ }
432
+}
433
+EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata);
434
+
425435 static int
426436 session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
427437 {
....@@ -439,9 +449,6 @@
439449 fdata.flags = 0;
440450 fdata.clnt_data = vbuf->vb2_buf.index;
441451
442
- if (!fdata.timestamp)
443
- fdata.flags |= HFI_BUFFERFLAG_TIMESTAMPINVALID;
444
-
445452 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
446453 fdata.buffer_type = HFI_BUFFER_INPUT;
447454 fdata.filled_len = vb2_get_plane_payload(vb, 0);
....@@ -449,6 +456,11 @@
449456
450457 if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
451458 fdata.flags |= HFI_BUFFERFLAG_EOS;
459
+
460
+ if (inst->session_type == VIDC_SESSION_TYPE_DEC)
461
+ put_ts_metadata(inst, vbuf);
462
+
463
+ venus_pm_load_scale(inst);
452464 } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
453465 if (inst->session_type == VIDC_SESSION_TYPE_ENC)
454466 fdata.buffer_type = HFI_BUFFER_OUTPUT;
....@@ -470,14 +482,21 @@
470482 struct venus_core *core = inst->core;
471483 struct venus_caps *caps;
472484
485
+ /*
486
+ * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports
487
+ * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2.
488
+ */
489
+ if (IS_V4(core))
490
+ return true;
491
+
473492 caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
474493 if (!caps)
475
- return 0;
494
+ return false;
476495
477496 return caps->cap_bufs_mode_dynamic;
478497 }
479498
480
-static int session_unregister_bufs(struct venus_inst *inst)
499
+int venus_helper_unregister_bufs(struct venus_inst *inst)
481500 {
482501 struct venus_buffer *buf, *n;
483502 struct hfi_buffer_desc bd;
....@@ -494,6 +513,7 @@
494513
495514 return ret;
496515 }
516
+EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs);
497517
498518 static int session_register_bufs(struct venus_inst *inst)
499519 {
....@@ -563,6 +583,244 @@
563583 }
564584 EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
565585
586
+struct id_mapping {
587
+ u32 hfi_id;
588
+ u32 v4l2_id;
589
+};
590
+
591
+static const struct id_mapping mpeg4_profiles[] = {
592
+ { HFI_MPEG4_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE },
593
+ { HFI_MPEG4_PROFILE_ADVANCEDSIMPLE, V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE },
594
+};
595
+
596
+static const struct id_mapping mpeg4_levels[] = {
597
+ { HFI_MPEG4_LEVEL_0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 },
598
+ { HFI_MPEG4_LEVEL_0b, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B },
599
+ { HFI_MPEG4_LEVEL_1, V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 },
600
+ { HFI_MPEG4_LEVEL_2, V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 },
601
+ { HFI_MPEG4_LEVEL_3, V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 },
602
+ { HFI_MPEG4_LEVEL_4, V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 },
603
+ { HFI_MPEG4_LEVEL_5, V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 },
604
+};
605
+
606
+static const struct id_mapping mpeg2_profiles[] = {
607
+ { HFI_MPEG2_PROFILE_SIMPLE, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SIMPLE },
608
+ { HFI_MPEG2_PROFILE_MAIN, V4L2_MPEG_VIDEO_MPEG2_PROFILE_MAIN },
609
+ { HFI_MPEG2_PROFILE_SNR, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SNR_SCALABLE },
610
+ { HFI_MPEG2_PROFILE_SPATIAL, V4L2_MPEG_VIDEO_MPEG2_PROFILE_SPATIALLY_SCALABLE },
611
+ { HFI_MPEG2_PROFILE_HIGH, V4L2_MPEG_VIDEO_MPEG2_PROFILE_HIGH },
612
+};
613
+
614
+static const struct id_mapping mpeg2_levels[] = {
615
+ { HFI_MPEG2_LEVEL_LL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_LOW },
616
+ { HFI_MPEG2_LEVEL_ML, V4L2_MPEG_VIDEO_MPEG2_LEVEL_MAIN },
617
+ { HFI_MPEG2_LEVEL_H14, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH_1440 },
618
+ { HFI_MPEG2_LEVEL_HL, V4L2_MPEG_VIDEO_MPEG2_LEVEL_HIGH },
619
+};
620
+
621
+static const struct id_mapping h264_profiles[] = {
622
+ { HFI_H264_PROFILE_BASELINE, V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE },
623
+ { HFI_H264_PROFILE_MAIN, V4L2_MPEG_VIDEO_H264_PROFILE_MAIN },
624
+ { HFI_H264_PROFILE_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH },
625
+ { HFI_H264_PROFILE_STEREO_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH },
626
+ { HFI_H264_PROFILE_MULTIVIEW_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH },
627
+ { HFI_H264_PROFILE_CONSTRAINED_BASE, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE },
628
+ { HFI_H264_PROFILE_CONSTRAINED_HIGH, V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH },
629
+};
630
+
631
+static const struct id_mapping h264_levels[] = {
632
+ { HFI_H264_LEVEL_1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0 },
633
+ { HFI_H264_LEVEL_1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B },
634
+ { HFI_H264_LEVEL_11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1 },
635
+ { HFI_H264_LEVEL_12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2 },
636
+ { HFI_H264_LEVEL_13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3 },
637
+ { HFI_H264_LEVEL_2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0 },
638
+ { HFI_H264_LEVEL_21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1 },
639
+ { HFI_H264_LEVEL_22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2 },
640
+ { HFI_H264_LEVEL_3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0 },
641
+ { HFI_H264_LEVEL_31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1 },
642
+ { HFI_H264_LEVEL_32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2 },
643
+ { HFI_H264_LEVEL_4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0 },
644
+ { HFI_H264_LEVEL_41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1 },
645
+ { HFI_H264_LEVEL_42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2 },
646
+ { HFI_H264_LEVEL_5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0 },
647
+ { HFI_H264_LEVEL_51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
648
+ { HFI_H264_LEVEL_52, V4L2_MPEG_VIDEO_H264_LEVEL_5_1 },
649
+};
650
+
651
+static const struct id_mapping hevc_profiles[] = {
652
+ { HFI_HEVC_PROFILE_MAIN, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN },
653
+ { HFI_HEVC_PROFILE_MAIN_STILL_PIC, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE },
654
+ { HFI_HEVC_PROFILE_MAIN10, V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10 },
655
+};
656
+
657
+static const struct id_mapping hevc_levels[] = {
658
+ { HFI_HEVC_LEVEL_1, V4L2_MPEG_VIDEO_HEVC_LEVEL_1 },
659
+ { HFI_HEVC_LEVEL_2, V4L2_MPEG_VIDEO_HEVC_LEVEL_2 },
660
+ { HFI_HEVC_LEVEL_21, V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1 },
661
+ { HFI_HEVC_LEVEL_3, V4L2_MPEG_VIDEO_HEVC_LEVEL_3 },
662
+ { HFI_HEVC_LEVEL_31, V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1 },
663
+ { HFI_HEVC_LEVEL_4, V4L2_MPEG_VIDEO_HEVC_LEVEL_4 },
664
+ { HFI_HEVC_LEVEL_41, V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1 },
665
+ { HFI_HEVC_LEVEL_5, V4L2_MPEG_VIDEO_HEVC_LEVEL_5 },
666
+ { HFI_HEVC_LEVEL_51, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1 },
667
+ { HFI_HEVC_LEVEL_52, V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2 },
668
+ { HFI_HEVC_LEVEL_6, V4L2_MPEG_VIDEO_HEVC_LEVEL_6 },
669
+ { HFI_HEVC_LEVEL_61, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1 },
670
+ { HFI_HEVC_LEVEL_62, V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2 },
671
+};
672
+
673
+static const struct id_mapping vp8_profiles[] = {
674
+ { HFI_VPX_PROFILE_VERSION_0, V4L2_MPEG_VIDEO_VP8_PROFILE_0 },
675
+ { HFI_VPX_PROFILE_VERSION_1, V4L2_MPEG_VIDEO_VP8_PROFILE_1 },
676
+ { HFI_VPX_PROFILE_VERSION_2, V4L2_MPEG_VIDEO_VP8_PROFILE_2 },
677
+ { HFI_VPX_PROFILE_VERSION_3, V4L2_MPEG_VIDEO_VP8_PROFILE_3 },
678
+};
679
+
680
+static const struct id_mapping vp9_profiles[] = {
681
+ { HFI_VP9_PROFILE_P0, V4L2_MPEG_VIDEO_VP9_PROFILE_0 },
682
+ { HFI_VP9_PROFILE_P2_10B, V4L2_MPEG_VIDEO_VP9_PROFILE_2 },
683
+};
684
+
685
+static const struct id_mapping vp9_levels[] = {
686
+ { HFI_VP9_LEVEL_1, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0 },
687
+ { HFI_VP9_LEVEL_11, V4L2_MPEG_VIDEO_VP9_LEVEL_1_1 },
688
+ { HFI_VP9_LEVEL_2, V4L2_MPEG_VIDEO_VP9_LEVEL_2_0},
689
+ { HFI_VP9_LEVEL_21, V4L2_MPEG_VIDEO_VP9_LEVEL_2_1 },
690
+ { HFI_VP9_LEVEL_3, V4L2_MPEG_VIDEO_VP9_LEVEL_3_0},
691
+ { HFI_VP9_LEVEL_31, V4L2_MPEG_VIDEO_VP9_LEVEL_3_1 },
692
+ { HFI_VP9_LEVEL_4, V4L2_MPEG_VIDEO_VP9_LEVEL_4_0 },
693
+ { HFI_VP9_LEVEL_41, V4L2_MPEG_VIDEO_VP9_LEVEL_4_1 },
694
+ { HFI_VP9_LEVEL_5, V4L2_MPEG_VIDEO_VP9_LEVEL_5_0 },
695
+ { HFI_VP9_LEVEL_51, V4L2_MPEG_VIDEO_VP9_LEVEL_5_1 },
696
+ { HFI_VP9_LEVEL_6, V4L2_MPEG_VIDEO_VP9_LEVEL_6_0 },
697
+ { HFI_VP9_LEVEL_61, V4L2_MPEG_VIDEO_VP9_LEVEL_6_1 },
698
+};
699
+
700
+static u32 find_v4l2_id(u32 hfi_id, const struct id_mapping *array, unsigned int array_sz)
701
+{
702
+ unsigned int i;
703
+
704
+ if (!array || !array_sz)
705
+ return 0;
706
+
707
+ for (i = 0; i < array_sz; i++)
708
+ if (hfi_id == array[i].hfi_id)
709
+ return array[i].v4l2_id;
710
+
711
+ return 0;
712
+}
713
+
714
+static u32 find_hfi_id(u32 v4l2_id, const struct id_mapping *array, unsigned int array_sz)
715
+{
716
+ unsigned int i;
717
+
718
+ if (!array || !array_sz)
719
+ return 0;
720
+
721
+ for (i = 0; i < array_sz; i++)
722
+ if (v4l2_id == array[i].v4l2_id)
723
+ return array[i].hfi_id;
724
+
725
+ return 0;
726
+}
727
+
728
+static void
729
+v4l2_id_profile_level(u32 hfi_codec, struct hfi_profile_level *pl, u32 *profile, u32 *level)
730
+{
731
+ u32 hfi_pf = pl->profile;
732
+ u32 hfi_lvl = pl->level;
733
+
734
+ switch (hfi_codec) {
735
+ case HFI_VIDEO_CODEC_H264:
736
+ *profile = find_v4l2_id(hfi_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
737
+ *level = find_v4l2_id(hfi_lvl, h264_levels, ARRAY_SIZE(h264_levels));
738
+ break;
739
+ case HFI_VIDEO_CODEC_MPEG2:
740
+ *profile = find_v4l2_id(hfi_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
741
+ *level = find_v4l2_id(hfi_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
742
+ break;
743
+ case HFI_VIDEO_CODEC_MPEG4:
744
+ *profile = find_v4l2_id(hfi_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
745
+ *level = find_v4l2_id(hfi_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
746
+ break;
747
+ case HFI_VIDEO_CODEC_VP8:
748
+ *profile = find_v4l2_id(hfi_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
749
+ *level = 0;
750
+ break;
751
+ case HFI_VIDEO_CODEC_VP9:
752
+ *profile = find_v4l2_id(hfi_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
753
+ *level = find_v4l2_id(hfi_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
754
+ break;
755
+ case HFI_VIDEO_CODEC_HEVC:
756
+ *profile = find_v4l2_id(hfi_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
757
+ *level = find_v4l2_id(hfi_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
758
+ break;
759
+ default:
760
+ break;
761
+ }
762
+}
763
+
764
+static void
765
+hfi_id_profile_level(u32 hfi_codec, u32 v4l2_pf, u32 v4l2_lvl, struct hfi_profile_level *pl)
766
+{
767
+ switch (hfi_codec) {
768
+ case HFI_VIDEO_CODEC_H264:
769
+ pl->profile = find_hfi_id(v4l2_pf, h264_profiles, ARRAY_SIZE(h264_profiles));
770
+ pl->level = find_hfi_id(v4l2_lvl, h264_levels, ARRAY_SIZE(h264_levels));
771
+ break;
772
+ case HFI_VIDEO_CODEC_MPEG2:
773
+ pl->profile = find_hfi_id(v4l2_pf, mpeg2_profiles, ARRAY_SIZE(mpeg2_profiles));
774
+ pl->level = find_hfi_id(v4l2_lvl, mpeg2_levels, ARRAY_SIZE(mpeg2_levels));
775
+ break;
776
+ case HFI_VIDEO_CODEC_MPEG4:
777
+ pl->profile = find_hfi_id(v4l2_pf, mpeg4_profiles, ARRAY_SIZE(mpeg4_profiles));
778
+ pl->level = find_hfi_id(v4l2_lvl, mpeg4_levels, ARRAY_SIZE(mpeg4_levels));
779
+ break;
780
+ case HFI_VIDEO_CODEC_VP8:
781
+ pl->profile = find_hfi_id(v4l2_pf, vp8_profiles, ARRAY_SIZE(vp8_profiles));
782
+ pl->level = 0;
783
+ break;
784
+ case HFI_VIDEO_CODEC_VP9:
785
+ pl->profile = find_hfi_id(v4l2_pf, vp9_profiles, ARRAY_SIZE(vp9_profiles));
786
+ pl->level = find_hfi_id(v4l2_lvl, vp9_levels, ARRAY_SIZE(vp9_levels));
787
+ break;
788
+ case HFI_VIDEO_CODEC_HEVC:
789
+ pl->profile = find_hfi_id(v4l2_pf, hevc_profiles, ARRAY_SIZE(hevc_profiles));
790
+ pl->level = find_hfi_id(v4l2_lvl, hevc_levels, ARRAY_SIZE(hevc_levels));
791
+ break;
792
+ default:
793
+ break;
794
+ }
795
+}
796
+
797
+int venus_helper_get_profile_level(struct venus_inst *inst, u32 *profile, u32 *level)
798
+{
799
+ const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
800
+ union hfi_get_property hprop;
801
+ int ret;
802
+
803
+ ret = hfi_session_get_property(inst, ptype, &hprop);
804
+ if (ret)
805
+ return ret;
806
+
807
+ v4l2_id_profile_level(inst->hfi_codec, &hprop.profile_level, profile, level);
808
+
809
+ return 0;
810
+}
811
+EXPORT_SYMBOL_GPL(venus_helper_get_profile_level);
812
+
813
+int venus_helper_set_profile_level(struct venus_inst *inst, u32 profile, u32 level)
814
+{
815
+ const u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
816
+ struct hfi_profile_level pl;
817
+
818
+ hfi_id_profile_level(inst->hfi_codec, profile, level, &pl);
819
+
820
+ return hfi_session_set_property(inst, ptype, &pl);
821
+}
822
+EXPORT_SYMBOL_GPL(venus_helper_set_profile_level);
823
+
566824 static u32 get_framesize_raw_nv12(u32 width, u32 height)
567825 {
568826 u32 y_stride, uv_stride, y_plane;
....@@ -607,6 +865,78 @@
607865 max(extradata, y_stride * 48), SZ_4K);
608866 }
609867
868
+static u32 get_framesize_raw_p010(u32 width, u32 height)
869
+{
870
+ u32 y_plane, uv_plane, y_stride, uv_stride, y_sclines, uv_sclines;
871
+
872
+ y_stride = ALIGN(width * 2, 256);
873
+ uv_stride = ALIGN(width * 2, 256);
874
+ y_sclines = ALIGN(height, 32);
875
+ uv_sclines = ALIGN((height + 1) >> 1, 16);
876
+ y_plane = y_stride * y_sclines;
877
+ uv_plane = uv_stride * uv_sclines;
878
+
879
+ return ALIGN((y_plane + uv_plane), SZ_4K);
880
+}
881
+
882
+static u32 get_framesize_raw_p010_ubwc(u32 width, u32 height)
883
+{
884
+ u32 y_stride, uv_stride, y_sclines, uv_sclines;
885
+ u32 y_ubwc_plane, uv_ubwc_plane;
886
+ u32 y_meta_stride, y_meta_scanlines;
887
+ u32 uv_meta_stride, uv_meta_scanlines;
888
+ u32 y_meta_plane, uv_meta_plane;
889
+ u32 size;
890
+
891
+ y_stride = ALIGN(width * 2, 256);
892
+ uv_stride = ALIGN(width * 2, 256);
893
+ y_sclines = ALIGN(height, 16);
894
+ uv_sclines = ALIGN((height + 1) >> 1, 16);
895
+
896
+ y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
897
+ uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
898
+ y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
899
+ y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
900
+ y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
901
+ uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
902
+ uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
903
+ uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
904
+
905
+ size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
906
+
907
+ return ALIGN(size, SZ_4K);
908
+}
909
+
910
+static u32 get_framesize_raw_yuv420_tp10_ubwc(u32 width, u32 height)
911
+{
912
+ u32 y_stride, uv_stride, y_sclines, uv_sclines;
913
+ u32 y_ubwc_plane, uv_ubwc_plane;
914
+ u32 y_meta_stride, y_meta_scanlines;
915
+ u32 uv_meta_stride, uv_meta_scanlines;
916
+ u32 y_meta_plane, uv_meta_plane;
917
+ u32 extradata = SZ_16K;
918
+ u32 size;
919
+
920
+ y_stride = ALIGN(width * 4 / 3, 256);
921
+ uv_stride = ALIGN(width * 4 / 3, 256);
922
+ y_sclines = ALIGN(height, 16);
923
+ uv_sclines = ALIGN((height + 1) >> 1, 16);
924
+
925
+ y_ubwc_plane = ALIGN(y_stride * y_sclines, SZ_4K);
926
+ uv_ubwc_plane = ALIGN(uv_stride * uv_sclines, SZ_4K);
927
+ y_meta_stride = ALIGN(DIV_ROUND_UP(width, 48), 64);
928
+ y_meta_scanlines = ALIGN(DIV_ROUND_UP(height, 4), 16);
929
+ y_meta_plane = ALIGN(y_meta_stride * y_meta_scanlines, SZ_4K);
930
+ uv_meta_stride = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
931
+ uv_meta_scanlines = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
932
+ uv_meta_plane = ALIGN(uv_meta_stride * uv_meta_scanlines, SZ_4K);
933
+
934
+ size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + uv_meta_plane;
935
+ size += max(extradata + SZ_8K, y_stride * 48);
936
+
937
+ return ALIGN(size, SZ_4K);
938
+}
939
+
610940 u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
611941 {
612942 switch (hfi_fmt) {
....@@ -615,6 +945,12 @@
615945 return get_framesize_raw_nv12(width, height);
616946 case HFI_COLOR_FORMAT_NV12_UBWC:
617947 return get_framesize_raw_nv12_ubwc(width, height);
948
+ case HFI_COLOR_FORMAT_P010:
949
+ return get_framesize_raw_p010(width, height);
950
+ case HFI_COLOR_FORMAT_P010_UBWC:
951
+ return get_framesize_raw_p010_ubwc(width, height);
952
+ case HFI_COLOR_FORMAT_YUV420_TP10_UBWC:
953
+ return get_framesize_raw_yuv420_tp10_ubwc(width, height);
618954 default:
619955 return 0;
620956 }
....@@ -704,19 +1040,35 @@
7041040 }
7051041 EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
7061042
707
-int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage)
1043
+int venus_helper_init_codec_freq_data(struct venus_inst *inst)
7081044 {
709
- const u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
710
- struct hfi_videocores_usage_type cu;
1045
+ const struct codec_freq_data *data;
1046
+ unsigned int i, data_size;
1047
+ u32 pixfmt;
1048
+ int ret = 0;
7111049
7121050 if (!IS_V4(inst->core))
7131051 return 0;
7141052
715
- cu.video_core_enable_mask = usage;
1053
+ data = inst->core->res->codec_freq_data;
1054
+ data_size = inst->core->res->codec_freq_data_size;
1055
+ pixfmt = inst->session_type == VIDC_SESSION_TYPE_DEC ?
1056
+ inst->fmt_out->pixfmt : inst->fmt_cap->pixfmt;
7161057
717
- return hfi_session_set_property(inst, ptype, &cu);
1058
+ for (i = 0; i < data_size; i++) {
1059
+ if (data[i].pixfmt == pixfmt &&
1060
+ data[i].session_type == inst->session_type) {
1061
+ inst->clk_data.codec_freq_data = &data[i];
1062
+ break;
1063
+ }
1064
+ }
1065
+
1066
+ if (!inst->clk_data.codec_freq_data)
1067
+ ret = -EINVAL;
1068
+
1069
+ return ret;
7181070 }
719
-EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
1071
+EXPORT_SYMBOL_GPL(venus_helper_init_codec_freq_data);
7201072
7211073 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
7221074 unsigned int output_bufs,
....@@ -952,6 +1304,17 @@
9521304 {
9531305 struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
9541306 unsigned int out_buf_size = venus_helper_get_opb_size(inst);
1307
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1308
+
1309
+ if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1310
+ if (vbuf->field == V4L2_FIELD_ANY)
1311
+ vbuf->field = V4L2_FIELD_NONE;
1312
+ if (vbuf->field != V4L2_FIELD_NONE) {
1313
+ dev_err(inst->core->dev, "%s field isn't supported\n",
1314
+ __func__);
1315
+ return -EINVAL;
1316
+ }
1317
+ }
9551318
9561319 if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
9571320 vb2_plane_size(vb, 0) < out_buf_size)
....@@ -964,6 +1327,15 @@
9641327 }
9651328 EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_prepare);
9661329
1330
+static void cache_payload(struct venus_inst *inst, struct vb2_buffer *vb)
1331
+{
1332
+ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1333
+ unsigned int idx = vbuf->vb2_buf.index;
1334
+
1335
+ if (vbuf->vb2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1336
+ inst->payloads[idx] = vb2_get_plane_payload(vb, 0);
1337
+}
1338
+
9671339 void venus_helper_vb2_buf_queue(struct vb2_buffer *vb)
9681340 {
9691341 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
....@@ -975,31 +1347,45 @@
9751347
9761348 v4l2_m2m_buf_queue(m2m_ctx, vbuf);
9771349
978
- if (!(inst->streamon_out & inst->streamon_cap))
1350
+ /* Skip processing queued capture buffers after LAST flag */
1351
+ if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
1352
+ V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1353
+ inst->codec_state == VENUS_DEC_STATE_DRC)
9791354 goto unlock;
9801355
981
- ret = is_buf_refed(inst, vbuf);
982
- if (ret)
1356
+ cache_payload(inst, vb);
1357
+
1358
+ if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
1359
+ !(inst->streamon_out && inst->streamon_cap))
9831360 goto unlock;
9841361
985
- ret = session_process_buf(inst, vbuf);
986
- if (ret)
987
- return_buf_error(inst, vbuf);
1362
+ if (vb2_start_streaming_called(vb->vb2_queue)) {
1363
+ ret = is_buf_refed(inst, vbuf);
1364
+ if (ret)
1365
+ goto unlock;
1366
+
1367
+ ret = session_process_buf(inst, vbuf);
1368
+ if (ret)
1369
+ return_buf_error(inst, vbuf);
1370
+ }
9881371
9891372 unlock:
9901373 mutex_unlock(&inst->lock);
9911374 }
9921375 EXPORT_SYMBOL_GPL(venus_helper_vb2_buf_queue);
9931376
994
-void venus_helper_buffers_done(struct venus_inst *inst,
1377
+void venus_helper_buffers_done(struct venus_inst *inst, unsigned int type,
9951378 enum vb2_buffer_state state)
9961379 {
9971380 struct vb2_v4l2_buffer *buf;
9981381
999
- while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
1000
- v4l2_m2m_buf_done(buf, state);
1001
- while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
1002
- v4l2_m2m_buf_done(buf, state);
1382
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1383
+ while ((buf = v4l2_m2m_src_buf_remove(inst->m2m_ctx)))
1384
+ v4l2_m2m_buf_done(buf, state);
1385
+ } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1386
+ while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
1387
+ v4l2_m2m_buf_done(buf, state);
1388
+ }
10031389 }
10041390 EXPORT_SYMBOL_GPL(venus_helper_buffers_done);
10051391
....@@ -1014,8 +1400,8 @@
10141400 if (inst->streamon_out & inst->streamon_cap) {
10151401 ret = hfi_session_stop(inst);
10161402 ret |= hfi_session_unload_res(inst);
1017
- ret |= session_unregister_bufs(inst);
1018
- ret |= intbufs_free(inst);
1403
+ ret |= venus_helper_unregister_bufs(inst);
1404
+ ret |= venus_helper_intbufs_free(inst);
10191405 ret |= hfi_session_deinit(inst);
10201406
10211407 if (inst->session_error || core->sys_error)
....@@ -1026,27 +1412,67 @@
10261412
10271413 venus_helper_free_dpb_bufs(inst);
10281414
1029
- load_scale_clocks(core);
1415
+ venus_pm_load_scale(inst);
10301416 INIT_LIST_HEAD(&inst->registeredbufs);
10311417 }
10321418
1033
- venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR);
1419
+ venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
1420
+ VB2_BUF_STATE_ERROR);
1421
+ venus_helper_buffers_done(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1422
+ VB2_BUF_STATE_ERROR);
10341423
10351424 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
10361425 inst->streamon_out = 0;
10371426 else
10381427 inst->streamon_cap = 0;
10391428
1429
+ venus_pm_release_core(inst);
1430
+
10401431 mutex_unlock(&inst->lock);
10411432 }
10421433 EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
10431434
1044
-int venus_helper_vb2_start_streaming(struct venus_inst *inst)
1435
+int venus_helper_process_initial_cap_bufs(struct venus_inst *inst)
10451436 {
1046
- struct venus_core *core = inst->core;
1437
+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1438
+ struct v4l2_m2m_buffer *buf, *n;
10471439 int ret;
10481440
1049
- ret = intbufs_alloc(inst);
1441
+ v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
1442
+ ret = session_process_buf(inst, &buf->vb);
1443
+ if (ret) {
1444
+ return_buf_error(inst, &buf->vb);
1445
+ return ret;
1446
+ }
1447
+ }
1448
+
1449
+ return 0;
1450
+}
1451
+EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs);
1452
+
1453
+int venus_helper_process_initial_out_bufs(struct venus_inst *inst)
1454
+{
1455
+ struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
1456
+ struct v4l2_m2m_buffer *buf, *n;
1457
+ int ret;
1458
+
1459
+ v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
1460
+ ret = session_process_buf(inst, &buf->vb);
1461
+ if (ret) {
1462
+ return_buf_error(inst, &buf->vb);
1463
+ return ret;
1464
+ }
1465
+ }
1466
+
1467
+ return 0;
1468
+}
1469
+EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs);
1470
+
1471
+int venus_helper_vb2_start_streaming(struct venus_inst *inst)
1472
+{
1473
+ int ret;
1474
+
1475
+ ret = venus_helper_intbufs_alloc(inst);
10501476 if (ret)
10511477 return ret;
10521478
....@@ -1054,7 +1480,7 @@
10541480 if (ret)
10551481 goto err_bufs_free;
10561482
1057
- load_scale_clocks(core);
1483
+ venus_pm_load_scale(inst);
10581484
10591485 ret = hfi_session_load_res(inst);
10601486 if (ret)
....@@ -1064,20 +1490,14 @@
10641490 if (ret)
10651491 goto err_unload_res;
10661492
1067
- ret = venus_helper_queue_dpb_bufs(inst);
1068
- if (ret)
1069
- goto err_session_stop;
1070
-
10711493 return 0;
10721494
1073
-err_session_stop:
1074
- hfi_session_stop(inst);
10751495 err_unload_res:
10761496 hfi_session_unload_res(inst);
10771497 err_unreg_bufs:
1078
- session_unregister_bufs(inst);
1498
+ venus_helper_unregister_bufs(inst);
10791499 err_bufs_free:
1080
- intbufs_free(inst);
1500
+ venus_helper_intbufs_free(inst);
10811501 return ret;
10821502 }
10831503 EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming);
....@@ -1155,6 +1575,27 @@
11551575 if (!caps)
11561576 return -EINVAL;
11571577
1578
+ if (inst->bit_depth == VIDC_BITDEPTH_10 &&
1579
+ inst->session_type == VIDC_SESSION_TYPE_DEC) {
1580
+ found_ubwc =
1581
+ find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
1582
+ HFI_COLOR_FORMAT_YUV420_TP10_UBWC);
1583
+ found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2,
1584
+ HFI_COLOR_FORMAT_NV12);
1585
+ if (found_ubwc && found) {
1586
+ /*
1587
+ * Hard-code DPB buffers to be 10bit UBWC and decoder
1588
+ * output buffers in 8bit NV12 until V4L2 is able to
1589
+ * expose compressed/tiled formats to applications.
1590
+ */
1591
+ *out_fmt = HFI_COLOR_FORMAT_YUV420_TP10_UBWC;
1592
+ *out2_fmt = HFI_COLOR_FORMAT_NV12;
1593
+ return 0;
1594
+ }
1595
+
1596
+ return -EINVAL;
1597
+ }
1598
+
11581599 if (ubwc) {
11591600 ubwc_fmt = fmt | HFI_COLOR_FORMAT_UBWC_BASE;
11601601 found_ubwc = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT,
....@@ -1185,52 +1626,3 @@
11851626 return -EINVAL;
11861627 }
11871628 EXPORT_SYMBOL_GPL(venus_helper_get_out_fmts);
1188
-
1189
-int venus_helper_power_enable(struct venus_core *core, u32 session_type,
1190
- bool enable)
1191
-{
1192
- void __iomem *ctrl, *stat;
1193
- u32 val;
1194
- int ret;
1195
-
1196
- if (!IS_V3(core) && !IS_V4(core))
1197
- return 0;
1198
-
1199
- if (IS_V3(core)) {
1200
- if (session_type == VIDC_SESSION_TYPE_DEC)
1201
- ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
1202
- else
1203
- ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
1204
- if (enable)
1205
- writel(0, ctrl);
1206
- else
1207
- writel(1, ctrl);
1208
-
1209
- return 0;
1210
- }
1211
-
1212
- if (session_type == VIDC_SESSION_TYPE_DEC) {
1213
- ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
1214
- stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
1215
- } else {
1216
- ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
1217
- stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
1218
- }
1219
-
1220
- if (enable) {
1221
- writel(0, ctrl);
1222
-
1223
- ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
1224
- if (ret)
1225
- return ret;
1226
- } else {
1227
- writel(1, ctrl);
1228
-
1229
- ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
1230
- if (ret)
1231
- return ret;
1232
- }
1233
-
1234
- return 0;
1235
-}
1236
-EXPORT_SYMBOL_GPL(venus_helper_power_enable);